-
Notifications
You must be signed in to change notification settings - Fork 37
CssSprites实现原理
浏览器支持background-position
,通过设置偏移量,显示一张图片的局部区域。这样就可以尝试把css所有用到的图片进行合并,然后设置background-position
进行展示。
这就是csssprites
的原理
###实现步骤 以下是实现csssprites步骤,包括
- 分析css,拿到每一个规则集中的图片以及
backgroud-repeat
、background-position
、图片是否需要sprite。并且根据样式进行记录 - 拿到所有的图片,根据
no-repeat
,repeat-x
,repeat-y
进行分类合并图片 - 修改css
####分析css 现在开源社区应该有很多css词法分析器,但此工具中只需要知道几个简单信息,完全能用正则搞定,所以实现了一个简单的css词法分析器,拿到需要的数据保存到一个Map中。
现在详细说明css解析器的实现。假如给定了如下css代码
.nav {
background: url('img/nav.png?__sprite') no-repeat left top;
}
分析得到
property | value | 说明 |
---|---|---|
image_url | img/nav.png | 使用的图片url |
isSprites | true | 是否需要csssprites处理 |
position | [left, top] | background-position的x,y值 |
repeat | false | 表示不进行repeat,为了区分做合并 |
####图片合并 css解析到了一个图片规则的列表,根据class区分。 根据repeat对得到的规则列表分类,分成三类no-repeat,repeat-x,repeat-y;它们最后会分别通过不同的算法进行合并后产出z,x,y三张图。
####repeat-x
repeat-x的图片竖着进行合并
。需要注意一点,图片的宽度不是相同宽度的的,所以竖着排后发现某一个图片的宽度小于最大宽度,需要在x轴方向重复平铺自己直到铺面整个最大宽度。
如下图,a、b、c、d四张图进行合并。
+----------------------+
| a |
| |
+----------------------+
+---------+---------+--+
| b | b | b|
+---------+---------+--+
+-----+-----+-----+----+
| c | c | c | c|
+-----+-----+-----+----+
+-------------------+--+
| | |
| d | d|
+-------------------+--+
a的宽度最大,所以b,c,d需要在x轴方向平铺自己。
####repeat-y
repeat-y的图片横着进行合并
。和repeat-x的合并算法一样,如果发现高度小于最大高度,也进行在y轴方向平铺自己。
如下图a, b, c三张图进行合并。
+------------+----+---------------------+
| a | | |
+------------+ | |
| a | | c |
+------------+ | |
| a | b | |
+------------+ +---------------------+
| a | | |
+------------+ | c |
| a | | |
+------------+----+---------------------+
b的高度最高,所以a,c需要在Y轴平铺自己。
####no-repeat
no-repeat的图片都靠右竖着合并
。 为了支持background-position: right (?:\d+px|top)
的情况,no-repeat的图片全部靠右合并。
如下图a,b,c,d,f五图进行合并,都向右靠,这样有效的解决了图片右浮的情况。
+----------------------------+
| a |
| |
+-----------------------+----+
| |
| b |
+--------------+----+
| |
| c |
| |
+-----------+-------+
| |
| d |
+-----------+-------+
| |
| e |
+-----+-------------+
| |
| f |
+-------------+
###其他
- node-images 图片解码转码合并工具,感谢@zhangyuanwei同学。
- node-pngquant-native 图片转png8工具,解决ie6下透明问题。
- node-pngcrush png图片压缩工具
###Q&A 0. 为啥repeat-x和no-repeat都是竖着排但不合并到一张图里面?这是由于repeat-x的图片一般比较窄,如果跟其他图片合并会重复复制自己平铺,导致图片大小成倍增加。