腾讯云正在走向全面支持响应式和Retina屏的道路上,我们广泛使用了SVG Sprites技术。在实践过程出现了“某些元素的背景图片来自于一张SVG Sprites,同时该元素也需要支持响应式”的情况,就需要解决“在元素尺寸发生变化时,来自Sprites的这张背景图片如何同步等比缩放?“的问题。
我曾经探讨过“响应式图像”的实现方法,当然这些方法都不适用背景图。我们来分解下这个问题,具体要完成哪些任务?
HTML元素在缩放时,如何保持宽高比不变?
对于这个问题,我在“使用PADDING-TOP:(PERCENTAGE)实现响应式背景图片”这篇文章中给出了解决方法,不再赘述。
See the Pen responsive image sprites 1 by wenjul (@wenjul) on CodePen.
Sprites中的背景图片如何跟随容器尺寸的变化而等比缩放?
background-size
正是用来解决这个问题的。大家应该比较熟悉关键字“cover
“(缩放背景图片以完全覆盖背景定位区,可能背景图片部分看不见)和”contain
“(缩放背景图片以完全装入背景定位区,可能背景定位区部分空白)的效果,这两个关键字主要解决整张背景图如何适应容器,比较适用于单张图片,不适用于Sprites图。
如何计算background-size: <percentage>?
百分比值(<percentage>)是背景图相对于背景定位区(background positioning area)的百分比,可以控制在容器元素内仅显示Sprites图的部分内容。比如下图中,Sprites图是由四张头像拼成的,要想在容器内仅显示第一张头像,background-size
的值应该多少呢?
先看下100%的效果,也就是说Sprites图和容器是1:1的比例,显然不是我们要的效果。
我们仅需要Sprites图的1/4显示在容器内,那么Sprites图与容器的比例应该是4:1,计算公式为:
background-size : ( Sprites width / image width) (Sprites height / image height)
上面这个公式比较容易理解,但是如何在容器元素显示其他的头像呢?
当然是通过background-position
来改变背景图片的初始位置。我们通常使用<length>(如px)控制背景图片相对于容器元素的偏移量,显然不适用我们这种情况,因为整张Sprites图片是可以等比缩放的,那么单张图片的左上角相对于Sprites图片的左上角的距离也是变化的,所以使用<length>是会出错的,如下例。
如何计算background-position: <percentage>?
background-position
值还可以使用 <percentage>和关键词(top, bottom, left, right, center),可以把关键词理解为<percentage>特殊形式,两者的计算方式是相同的。但是,<percentage>和<length>的计算方式是不同的:<length>的参照点是图片的左上角,<percentage>的参照点是随着取值变化的。
以 background-position:30px 40px;
为例,计算方法为:Sprites图的左上角相对于容器元素的左上角向右偏移30px,向下偏移40px。
background-position:<percentage>
就大不同了:如background-position:0% 0%
(或top left)是将图片的左上角与容器元素的左上角对齐,background-position:100% 100%
(或bottom right)是将图片的右下角与容器元素的右下角对齐,background-position:50% 50%
(或center center)是将图片的中心点与容器元素的中心点对齐,background-position:33% 15%
是将图片的横向33%和纵向15%的交汇点放置在容器元素的横向33%与15%的交汇点上。
理解 <percentage>和<length>之间计算方式的差异是至关重要的。那么如果要在容器元素内显示第二张图片,怎么计算<percentage>的具体值呢?
我们已知的信息如下:
- 容器元素的尺寸:elW * elH
- 单张图片的尺寸:imgW * imgH
- Sprites图片的尺寸:spritesW * spritesH
- 单张图片在Sprites图上的位置:imgPosX, imgPosY
我们假设:
- 点的位置为 (x, y)
- 容器上的(x, y)点与容器左上角的距离为 cX, cY
- Sprites图上的(x, y)点与本张图片左上角的距离为 sX, sY
如果要把某张图片完全显示在容器元素内,我们可以推导出:
- elW = imgW, elH = imgH
- cX = sX, cY = sY
根据上面的信息,我就可以计算出具体的(x, y)值了,下面以 x% 为例:
- cX = elW * x
- sX = spritesW * x – imgPosX
- elW * x = spritesW * x – imgPosX
解方程后就得到计算公式了:
- x = imgPosX / (spritesW – elW) = imgPosX / (spritesW – imgW)
- y = imgPosY / (spritesH – elH) = imgPosY / (spritesH – imgH)
把我们上面例子的信息代入方程式:
- x = w / (4w -w) = 1/3
- y = 0 / (h – h ) = 0
手动计算累死人?Maxim来解救你!
Maxim是我们团队开发的可视化的构建工具,支持windows和Mac,开发时无需考虑background-size
和background-position
,发布时将文件拖入Maxim内,自动完成Sprites拼合,并补全background-size
和background-position
值,轻松实现响应式Sprites图。Maxim的更多功能也等你发现,赶快下载一个试试吧!!!