响应式下的雪碧图解决方案

一、概述

  在传统的居中布局时,我们常用background-position这个属性来进行雪碧图的定位,在减少数据量的同时,保证准确定位。在移动端使用越来越重的现在,以往的传统定位,已经无法达到目的,那么是否有合适的解决方案呢?答案是有的,让我们先来了解background的两个属性:

    background-position:背景图片相对容器原点的起始位置。详解可以查看另一篇博客:background-position 详解

    background-size: 规定背景图的尺寸;

      语法:background-size: width height;

      取值:auto | length percentage | cover | contain

    auto: 自适应;

    length:确定的宽高;

    cover:把背景图像扩展至足够大,以使背景图像完全覆盖背景区域;

    contain:把图像图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域;

    百分比:以父元素的百分比来设置背景图像的宽度和高度。

  

  预备知识已经ready,接下来如何解决问题。

  

  来看以下四种场景:

场景1、非响应式下的雪碧图,且子图尺寸相同

场景2、响应式下的雪碧图,且子图尺寸相同

场景3、非响应式下的雪碧图,且子图尺寸不同

场景4、响应式下的雪碧图,且子图尺寸不同

  

二、子图尺寸相同的情况下

  该场景下,由于子图的尺寸相同,完全可以使用%来减少人为计算。使用%需要用到换算公式,由background-position 详解的结论,可知:

background-position: a% b%; =》 background-position: x y;
其中:containerWidth为容器宽,containerHeight为容器高,bgWidth为雪碧图宽,bgHeight为雪碧图宽,则存在(公式1):
  x = (containerWidth - bgWidth) * a%
  y = (containerHeight - bgHeight) * b%

  示例如下: 

    

     图2.1  原图[654 vs 436 即 218 * 3 vs 218 * 2]

想要的结果:选择第一排,第二张图

    

      图2.2   预期结果

  2.1、场景1:传统布局

    传统布局下,容器尺寸与子图的尺寸相同,由公式1可推出以下结论:

由于子图尺寸相同,得出(公式2):  bgWidth = xTotal * containerWidth;
  bgHeight = yTotal * containerHeight;其中xTotal为雪碧图横向的子图数量,yTotal为雪碧图纵向的子图数量。

由公式1、公式2可推导出(公式3): 
  a% = x / (containerWidth - bgWidth)       = x / (containerWidth - xTotal * containerWidth)       = x / (1 - xTotal) * containerWidth 

  b% = y / (containerHeight - bgHeight)       = y / (containerHeight - yTotal * containerHeight)       = y / (1 - yTotal) * containerHeight

定位时,背景图的起始点,时常在某个子图的起始点上,所以可以推导出(公式4):  a% = x / (1 - xTotal) * containerWidth    = n * containerWidth / (1 - xTotal) * containerWidth    = n / (1 - xTotal)

  b% = y / (1 - yTotal) * containerHeight    = m * containerHeight / (1 - yTotal) * containerHeight      = m / (1 - yTotal)  其中,m、n一定是一个小于等于0的数。  

需要得到预期结果,使用公式4,  起始位置:x=-1 * containerWidth,y = 0 * containerHeight;     so: n=-1,m=0;  子图数:xTotal = 3; yTotal = 2;

要得到第二张图的显示定位应该为:        a% = n / (1 - xTotal) = -1 / (1 - 3) = 50%  b% = m / (1 - yTotal) = 0 / 1 - 2 = 0%

    以下代码得到预期结果:

width: 218px;
height: 218px;
background-position: 50% 0;
background-repeat: no-repeat;

  2.2、场景2:响应式布局下

    回顾公式1:   

      x = (containerWidth - bgWidth) * a%       

      y = (containerHeight - bgHeight) * b%

  响应式情景下,containerWidth会缩放,而此时bgWidth的值不会变化,使得公式2无法得到。
  解决该问题的关键是,使得bgWidth的大小,随着containerWidth的变化而变化。
  再回过头看看background-size这个属性,它可以使得背景图根据容器的变化而变化,且它的百分比属性可以以父元素的百分比来设置背景图像的宽度和高度,从而达到父容器与背景图的一个对应关系。

  如果需要获得公式2,那么需要将背景图按照怎样的方式变化呢?

  当 background-size: 100% auto;时,得到的结果:

  

      图2.3  100%

  由此可看出,当xpos为100%时,背景图缩放到父容器相同大小。

  当xpos为300%时,背景图缩放到父容器的3倍大,此时背景图与父容器的关系同场景一相同,从而可以应用公式2,此时的xTotal既代表子图横向的数量,也表示背景图横向的收缩比。

  由此当是如下代码,亦可得到预期的第二张图:

width: 118px;
height: 118px;
background-size: 300% auto;
background-position: 50% 0;
background-repeat: no-repeat;

  总结:在响应式下,且子图尺寸相同时,将background-size 的缩放比设置成与子图数量相同,再通过background-position可实现轻松定位。x,y任意方向设置缩放比,另一方向可使用auto值,实现背景图的等比例缩放。此例中,虽然子图的形状为正方形,但实际操作中,不要求。矩形一样可以按照同样的公式实现,因为纵轴和横轴的计算都是分开的,相互没有影响。

三、子图尺寸不同

  在子图尺寸不同的情况下,通常我们不会使用百分比定位,而是选择具体值定位。

  示例:

    

    图3.1 不规则雪碧图

   取到第一个下载按钮:

       

  3.1、场景3:传统布局下的定位

  代码如下:    

width: 49px;
height: 24px;
background-position: 0 -62px;
background-repeat: no-repeat;

    直接使用具体值定位,较为简单,结果与预期相符。

  3.2、场景4:响应式下的定位

   

  未完待续。。。。。。

   

 
时间: 2024-11-08 18:20:58

响应式下的雪碧图解决方案的相关文章

移动端rem布局雪碧图解决方案 以及分享腾讯团队的在线雪碧图工具

先分享一下地址:http://alloyteam.github.io/gopng/ 使用的方法也很简单,将需要的小图标拖进去,全部拖进去后再调位置(每拖一个进去都会帮你排列好,但是没有间隔,所以全部拖进去后自己调) 然后点击右边绿色的make按钮即可 点击后,上面的选项会高亮,提示你制作好了, 点击PNG选项即可下载制作好的雪碧图, 点击css选项即可查看每个小图标在雪碧图中对应的x和Y位置 对于PC端来说,基本就完成了. 对于移动端采用rem布局的,则需要多一些步骤: 首先将对应的x和y位置转

使用 Compass 生成雪碧图

使用 Compass 创建一个项目 要在一个新项目中使用 Compass,可以打开命令行工具并输入如下指令 compass create my-project 如果 my-project 目录不存在,上述命令会创建一个叫做 my-project 的目录,并在其中添加以下文件: 如果你没有为compass create命令传递一个目录参数,它将使用你当前所在的目录. 在config.rb文件中,你可以对Compass的一些配置进行修改,例如资源位置和压缩程度.sass目录包含了一些初始的样式表,你

自适应页面中如何使用雪碧图

自适应页面你肯定听说过,雪碧图想必你也听说过,不过在自适应页面中使用雪碧图应用的场景却不多,因为很多场景里自适应页面(移动端页面)的小图标啥的基本都做成字体图标了,操作起来也比较方便,不过有时候合成字体图标的时候也比较麻烦,AI制作复杂svg矢量图标很麻烦,今天说的这个应用场景用的就是这个情况: 首先你要知道什么是雪碧图,不知道的先科普之,百毒传送门: 上面说到有的场景添加字体图标很麻烦,如果不理解看下图就明白了: 没错,就是这个国旗,有几十个国家的,这要搞成svg矢量图那要累死了(如果有大神有

移动端适配之雪碧图(sprite)背景图片定位

为了减少网络请求个数量,提高网站的访问速度,我们一般都会把一些小的图片合并成一张sprite图,然后根据background-position来进行定位.在web端由于是固定的大小与left .top,所以定位起来会比较准确.简单.但是在移动端就不一样了,各种手机的屏幕大小不一样,很难做到使用sprite图然后根据background-position来定位.所以普遍的做法都是使用单张图片,然后使用background-size: cover|100%|contain来控制背景图的大小.其实这样

compass与css sprite(雪碧图)

什么是css sprite? css sprite,中文叫雪碧图,也有人喊CSS精灵,就是一种背景拼合的技术,然后通过background-position来显示雪碧图中需要显示的图像. MDN相关链接:https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/CSS_Image_Sprites 优点:1.减少页面请求数 2.降低图片占用字节 缺点:1.拼图麻烦 2.后期维护麻烦 为什么使用compass? 最近项目中需要使用到很多小图片,想用

使用Compass制作雪碧图

遇见好的文章,笔者也会转载.但是正所谓好记性不如烂笔头,单纯的拿来主义也不如自己的亲自实践.所以每次需要转载的文章,我都会自己敲一遍,中间加入一些自己的思考. 这篇文章转载自:http://www.hongkiat.com/blog/compass-image-sprite/ 作者Thoriq Firdaus 译者zEx 前端性能优化,一直是前端开发中非常重要的一环,而其中静态资源特别是图片的优化,又占据了很大的比重.图片优化的方法有很多种,其中非常基本而常用的,就是雪碧图. CSS雪碧图就是将

雪碧图

雪碧图技术(精灵图) 多个图合并后,根据位置出现特定的一张图片,只需加载一次,速度快. 前提:组合的每张图宽和高都要一致.出现图片的位置为循环式 代码:<style type="text/css"> div{ width: 150px; height: 120px; outline: 1px solid red; background-image: url("../images/sprites2.png"); background-position: 0

css 雪碧图 及jquery定位代码

无意间发现了一个很神奇的事情,就是 鼠标悬停在图片上方会切换,起初以为图标是单独插入的.但发现居然是一张完整的图片. 一万只草泥马在心中奔腾.这是怎么实现的? 后来询问得知,这是css精灵技术(sprite) 也叫雪碧图. CSS知识点: background-image backgorund-position 特点: 相对于当个小图标,它节省文件体积和服务请求次数.将所有零碎的网页背景图片整合到一起,这样做可以有效的减少http对图片的请求次数,而不需要加载多次加载零碎的背景图片,所以合理的利

compass做雪碧图

由于最近没什么时间好好写博文,我把用sass做雪碧图的关键点贴出来方便自己记忆: config.rb注释 # Set this to the root of your project when deployed: #配置服务器路径 http_path = "http//:www.baidu.com/" #配置css sass images javascripts路径 css_dir = "public/stylesheets" sass_dir = "pu