Skip to content

CssSprites实现原理

fansekey edited this page Aug 12, 2013 · 8 revisions

浏览器支持background-position,通过设置偏移量,显示一张图片的局部区域。这样就可以尝试把css所有用到的图片进行合并,然后设置background-position进行展示。 这就是csssprites的原理

###实现步骤 以下是实现csssprites步骤,包括

  • 分析css,拿到每一个规则集中的图片以及backgroud-repeatbackground-position、图片是否需要sprite。并且根据样式进行记录
  • 拿到所有的图片,根据no-repeatrepeat-xrepeat-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     |
                        +-------------+

###其他

###Q&A 0. 为啥repeat-x和no-repeat都是竖着排但不合并到一张图里面?这是由于repeat-x的图片一般比较窄,如果跟其他图片合并会重复复制自己平铺,导致图片大小成倍增加。

Clone this wiki locally