【测试代码】

HTML

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="id=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>雪碧图练习</title>
</head>
<body>
<div class="footer">
<div class="wrap">
<div class="pic pic1 move"></div>
<div class="pic pic2 move "></div>
<div class="pic pic3 move"></div>
<div class="pic pic4 move"></div>
</div>
</div>
</body>
</html>

CSS

 *{margin:;padding:;}
html,body {
width: 100%;
height: 100%;
}
.footer {
position: relative;
width: 100%;
height: 100%;
background: url("https://xyq.res.netease.com/pc/gw/20170118103441/img/ft_e43a6db.webp") 0 0 no-repeat;
overflow: hidden: /*形成BFC盒模型,保证.wrap的margin在.footer内移动*/
}
.wrap {
width: 780px;
margin: 320px auto 0; /*未设置overflow: hidden;,保证在图片调整位置时的溢出仍能显示*/
}
.pic {
float: left;
}
.pic1 {
width: 200px;
height: 180px;
background: url("https://xyq.res.netease.com/pc/gw/20170118103441/img/west_01_3ca39fe.png") 0 0 no-repeat;
}
.pic2 {
width: 200px;
height: 180px;
background: url("https://xyq.res.netease.com/pc/gw/20170118103441/img/west_02_47bad19.png") 0 0 no-repeat;
}
.pic3 {
width: 170px;
height: 240px;
background: url("https://xyq.res.netease.com/pc/gw/20170118103441/img/west_03_f962447.png") 0 0 no-repeat;
margin-top: -30px;
}
.pic4 {
width: 210px;
height: 200px;
background: url("https://xyq.res.netease.com/pc/gw/20170118103441/img/west_04_6516d80.png") 0 0 no-repeat;
} /*动画*/
@keyframes move {
0% {
background-position: 0 0;
}
100% {
background-position: 114.2857% 0;
}
} .move {
-webkit-animation: move 1.4s steps(8) infinite;
-o-animation: move 1.4s steps(8) infinite;
animation: move 1.4s steps(8) infinite;
}

一、概念理解

 1.什么是雪碧图??

  CSS雪碧的基本原理,是把你的网站上用到的一些图片整合到一张单独的图片中,从而减少你的网站的HTTP请求数量。该图片使用CSS的background和background-position属性渲染,达到加在一次图片,可以实现复杂图片的效果,提高页面在使用时的效果响应速度。但相应的,缺点也十分明显,就是提高了页面的加载时间。

  CSS雪碧图的基本应用大多在鼠标滑过以及一些动图效果。

  2.什么是background和background-position??

  根据W3C的标准定义,background就是声明元素背景的属性,共有如下属性值:

    • background-color
    • background-position
    • background-size
    • background-repeat
    • background-origin
    • background-clip
    • background-attachment
    • background-image

  具体每个属性的含义及用法,这里不再阐述。

  从上我们可以看到,background-position是background众多属性中的一种。其含义就是声明背景在元素中的位置。其计算方式如下图所示:

  

   这里边的计算,由易到难,我一一进行一个简单的梳理。首先要明确的一点,所有位置的计算,都是基于元素的background-clip设定区域(如果未设置background-clip的话,就是元素的border-box)。明确了计算区域后,下面再来说计算规则:

   计算规则总共分为两大类,一类是根据设定好规则的方向值来声明位置。另一类是根据确定的数值或百分比来计算位置。

   1.首先是五个方向top lright bottom left center的计算。这个的位置是相对固定的。设定值总共有两个,默认为center。理解起来也很简单——就是把两个单词倒过来读。举个例子,top left就是左上角、bottom right就是右下角。

    

    2.然后是设定固定值或百分比,这两类都是根据确定的数值,在X、Y轴上进行调整。区别就是固定值是直接根据声明值进行调整,而百分比是由(背景区域的宽度/高度 - 图片的宽度/高度)*(X)%的计算式计算后的数值在X、Y轴上进行调整。

       

      1)固定值声明的位移

     

      2)百分比声明的计算

    

  

    结合上图,理解结论:1)固定值声明,正值即沿X、Y轴方向进行位移。负值即沿反方向位移;

              2)百分比声明,当图片宽度大于实际背景尺寸时(雪碧图原理),百分比正值时,计算值即为负;百分比负值时,计算值即为正。方向调整逻辑与固定值声明相同;

      好了,概念介绍完毕,下面进入正题。

二、雪碧图与background-position的爱恨纠缠

    1.直接上例子

    以网易梦幻西游官网的底部雪碧图为例——传送门http://xyq.163.com/

    

  

  从上面两张梦幻西游官网的图中可以看到,雪碧图由师徒四人共四张图片形成,并且每个图片都单独设置了动画样式。由此不难猜出,这个雪碧图是根据每个图片的实际宽度,通过steps属性,设定了固定的background值来完成的。大致代码如下:

/*假定图片宽度1600px*/
@keyframes play {
from {background-position: 0 0;}
to {background-position: -1600px 0}
} /*应用动画*/
.west-x {
animation: play 1.4s steps(8,end) infinite;
}

  当我看到这段代码时,我就思考一个问题。既然是将图片移动了100%的宽度,为什么不直接给所有的雪碧图,设定一个统一的动画,backgroun-position直接结束值为background-position: 100% 0;,这样就直接一步到位,还不用去计算每个图片的宽度。当我想出这个好方法,敲出简洁的代码,为自己的聪明才智美滋滋的时候。运行结果直接呼了我一个大嘴巴子,总结起来总共有如下几个问题:

  1)steps步数不对,按照官网的代码copy下来,steps(8)根本实现不了效果;

  2)将steps(8)改写成steps(7)时,人物确实是动起来了,但是在动画结束时会卡帧;

  3)将steps(7)改写为steps(7,start)后,卡帧现象不明显(只是不明显了),但仔细观察动画,与实际效果仍不一致;

  

  出现问题后,我逐步解决了问题1和问题2,但是问题3,着实费了好大力气才研究明白。接下来对问题3解决的讲解,将是本文的重点,重点,重点!!!敲黑板!

  

重点:

  针对问题3的解决思路,必须明确两点——background-position的计算方式;steps()函数的属性值;

  background-position的计算方式,上边已经说明。现在重点说一下steps()函数。

  steps()是针对帧数动画,专有的函数,可以说是没有steps就没有雪碧图了。它主要有两个函数值steps(number,start/end),第一个值number就是步数,理解起来也简单,一般雪碧图分为几张小图,number就设定为多少,几张图就走几步。第二个值是固定的两个值——start和end,这两个值理解起来就稍微有点难度了。还是举例说明,简单明了。

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>animation动画练习</title>
<style>
div {
width: 200px;
height: 200px;
background: black;
-webkit-animation: move 1s steps(1,start) infinite;
-o-animation: move 1s steps(1,start) infinite;
animation: move 1s steps(1,start) infinite;
}
@keyframes move {
0% {
background: red;
}
50% {
background: yellow;
}
100% {
background: blue;
}
}
</style>
</head>
<body>
<div></div>
</body>
</html>

  以上代码,如果粘贴到编辑器中并运行,会发生一个有趣的现象。元素的背景颜色,将在yellow和blue间来回切换,至于元素本身的背景色black以及0%时的背景色red,都不会显示。

  现在让我们把代码中的steps的属性值start改为end,再来看一下结果。此时,背景色在red和yellow间切换,black和blue将不再显示。

  我们先不考虑元素本身背景色的显示问题,这个相信不用说,大家也都明白。通过上面的例子,相信大家已经发现了其中的端倪——那就是start/end设置相应的属性值时,动画设定中的开始帧和结束帧就会跳过不显示,这就是它们的作用。

  明白了step()函数的作用之后,让我们返回去再看一下刚才出现的3个问题:

    1)steps步数不对,按照官网的代码copy下来,steps(8)根本实现不了效果;

    这个主要是background-position按%百分比设置属性值时,计算方式产生的影响。当我设置background-position: 100% 0;时,按照图片总共分为8张小图片,每张小图片宽度为200px,背景宽度为200px计算。实际上计算出来的位移值为(200-1600)*100%=1400px,所以我实际的设置值为background-position: -1400px 0;,结果一目了然,少走了一步,实际上只走了7张图片的步数。所以steps值应改为steps(7);

    2)将steps(8)改写成steps(7)时,人物确实是动起来了,但是在动画结束时会卡帧;

    因为background-position: -1400px 0;,而steps第二属性值start/end的默认属性值是end,所以最后一张图片并没有显示,衔接不上出现卡帧。

    3)将steps(7)改写为steps(7,start)后,卡帧现象不明显(只是不明显了),但仔细观察动画,与实际效果仍不一致;

    通过前两步的解读,到了这一步,其实很清晰了,设置成start后,轮到第一张没显示出来了。只是这次图片间的衔接并不像第二步时,卡帧那么明显而已。

  那么现在理解下来的话,问题3的重点就是2个问题:

    1)把少走的一步补回来;

    2)把steps函数没有播放的那一帧补回来;

  第一个问题还是回到background-position的计算问题上,既然设定100%时,是background-position: -1400px 0;走7步,那我设定多少才能是background-position: -1600px 0;走8步呢??这里我倒推了一个公式——[100% / (图片个数-1) + 100%],这样算出来的百分比数,就是应该设定的数值,以此例计算的话就是——100% / (8-1) + 100% = 114.2857%。这样计算下来的最终结果就是background-position: -1600px 0;,同时将steps(7,start)改为steps(8,start)。

  解决完第一个问题,再来解决第二个问题。设定了background-position: 114.2857% 0;之后,再看效果,发现不卡帧了。直接卡空白画面了??Excuse me??这不是刚改完steps第一个属性,还没改第二个属性值嘛。

  

  相信看完上面这张图,大家心里肯定是明明白白的了。修改完第一步之后,最后动画停留的位置。实际上是一片空白,因为图片已经完全溢出背景了。再来看steps的属性值steps(8,start),设置了动画第一帧不显示,显然是有问题了。那么只需要将start删除,让steps匹配默认属性end,按百分比设置的完美雪碧图就完成了~

  

  到这里,关于雪碧图、background-position与steps函数三角恋情就八卦完毕了,如果还想看更多的CSS花边新闻,敬请期待下一期CSS娱乐大搜查深入浅出!欢迎批评指正!

深入浅出CSS(二):关于雪碧图、background-position与steps函数的三角恋情的更多相关文章

  1. CSS3与页面布局学习笔记(五)——Web Font与CSS Sprites(又称CSS精灵、雪碧图)技术

    一.web font web font是应用在web中的一种字体技术,在CSS中使用font-face定义新的字体.先了解操作系统中的字体: a).安装好操作系统后,会默认安装一些字体,这些字体文件描 ...

  2. compass与css sprite(雪碧图)

    什么是css sprite? css sprite,中文叫雪碧图,也有人喊CSS精灵,就是一种背景拼合的技术,然后通过background-position来显示雪碧图中需要显示的图像. MDN相关链 ...

  3. CSS中的背景、雪碧图、超链接的伪类样式

    一.背景 1.背景颜色 background-color: red; 2.背景图片 background-image: url("../../img/l1.png"); 3.图片填 ...

  4. CSS Sprite 雪碧图制作

    CSS Sprite 雪碧图,简单来说就是: 为了提高网页的性能,减少加载次数,将一些不会经常随网站内容变化的小图标,集中放在一张大图上,将该图应作为background-image 嵌入页面中,在需 ...

  5. 前端优化:css雪碧图实践应用详解

    一 为什么需要使用雪碧图 二CSS雪碧图原理及应用 前端是接近用户体验的一个项目组成部分,合适的优化能够大大减少网页响应时间,合理的资源加载自然成为了工作中的要务,现在就结合实例讲解到底什么是css雪 ...

  6. css 雪碧图 及jquery定位代码

    无意间发现了一个很神奇的事情,就是 鼠标悬停在图片上方会切换,起初以为图标是单独插入的.但发现居然是一张完整的图片. 一万只草泥马在心中奔腾.这是怎么实现的? 后来询问得知,这是css精灵技术(spr ...

  7. 前端-如何用gulp快速搭建项目(sass预编译,代码压缩,css前缀,浏览器自动刷新,雪碧图合成)

    一:gulp优点: 易于使用 通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理: 插件高质 Gulp 严格的插件指南确保插件如你期望的那样简洁高质得工作. 构建快速 利用 Node ...

  8. Css雪碧图

    Css雪碧图: CSS雪碧 即CSS Sprite,也有人叫它CSS精灵,是一种CSS图像合并技术,该方法是将小图标和背景图像合并到一张图片上,然后利用css的背景定位来显示需要显示的图片部分. 原理 ...

  9. gulp填坑记(二)——gulp多张图片自动合成雪碧图

    为优化图片,减少请求会把拿到切好的图标图片,通过ps(或者其他工具)把图片合并到一张图里面,再通过css定位把对于的样式写出来引用的html里面,对于一些图片较多的项目,这个过程可能要花费我们一天的时 ...

随机推荐

  1. Scrum立会报告+燃尽图(十一月十六日总第二十四次):功能开发与设计页面

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2384 项目地址:https://git.coding.net/zhang ...

  2. Python:字符串中引用外部变量的3种方法

    方法一: username=input('username:') age=input('age:') job=input('job:') salary=input('salary') info1='' ...

  3. HDU 5501 The Highest Mark

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5501 The Highest Mark  Accepts: 32  Submissions: 193 ...

  4. Hibernate(五)

    注解高级(原文再续书接上一回) 7.继承映射 第一种:InheritanceType.JOINED 查询时会出现很多join语句. package com.rong.entity.joined; im ...

  5. WebService(二)

    使用eclipse开发webservice的服务器端以及客户端的简单实例 1.服务端 在eclipse中像建立一个web项目一样,new->Dynamic Web Project A.建一个需要 ...

  6. 0302借软件工程触IT

         没有不想学好的学生,也没有选择计算机软件专业后不想过能进军IT的行业的.就对于自己情况来说,大学选择计算机商业软件专业学习也有一年多时间了,未接触专业知识前IT是一个高大上的向往,在初学C语 ...

  7. 解决pciss_spc导入提示表空间不存在以及扩展失败的问题

    select NAME FROM USER$ ORDER BY NAME ; CREATE USER pciss IDENTIFIED BY pciss ; GRANT DBA TO pciss ; ...

  8. node.js入门(一)

    NodeJS是一个使用了Google高性能V8引擎的服务器端JavaScript实现.它提供了一个(几乎)完全非阻塞I/O栈,与JavaScript提供的闭包和匿名函数相结合,使之成为编写高吞吐 量网 ...

  9. (转)Elasticsearch search-guard 插件部署

    我之前写了ELK+shield的部署文档,由于shield是商业收费的,很多人都推崇开源项目search-guard来做ELK的安全组件,准确来说是elasticsearch的安全组件.search- ...

  10. Linux 常用指令【持续更新】

    在学校的时候学过一些简单的 Linux 命令,主要是文件的创建拷贝解压等操作,最近在电脑上安装了一个CentOS6.8版本的基本版,纯命令行操作. ../ 代表上一级目录 ./ 代表本级目录 / 代表 ...