1. 背景样式,先把它彻底玩明白
CSS背景样式,说简单也简单,说复杂也复杂。日常开发里你可能天天都在写background-color或者background-image,但真到了要用雪碧图、渐变、多背景叠加的时候,不少同学还是容易卡壳。这一篇我不打算把文档翻译一遍,而是挑那些真正影响出图效果、真正让新手挠头的点来讲透。
先说个基本的判断:背景样式是整个CSS里性价比很高的一块,学会了它能省掉无数张切图和无数个多余的DOM节点。你看很多复杂的视觉效果,按钮纹理、卡片毛玻璃、渐变边框、带光影的色块,用背景属性几行就能搞定,完全没有必要去堆图片或者嵌套多层div。
1.1 日常高频背景属性怎么搭配才不翻车
先把常用属性列出来,别嫌基础,我见过不少写了两年CSS的人还搞混background-size和background-position传参顺序的。
background-color:纯色打底,永远最先设置。一个常见场景:图片还没加载出来,或者加载失败的时候,背景色至少能兜住页面,不至于一片惨白。background-image:放图片或者渐变,支持多个值,用逗号分隔。background-repeat:默认是repeat,但是绝大多数情况下你会改成no-repeat、repeat-x、repeat-y或者round/space。background-position:定位背景图片位置,两个值分别是水平方向和垂直方向,可以是像素、百分比、关键字(center、top、left等)。background-size:很多人一开始会搞混cover和contain。记住一句话:cover是让图片完全覆盖容器,超出部分裁剪掉;contain是让图片完整放进容器,可能留白。做轮播图封面、卡片头图,几乎只会用到这两个值。background-attachment:控制背景是否跟随滚动。fixed能做出视差滚动效果,但移动端有兼容性问题,后面细说。background-origin和background-clip:进阶选手用得多,一个决定背景定位的参考区域,一个决定背景绘画的范围。做渐变边框、文字渐变必须用到background-clip,下面专门讲。background-blend-mode:让背景图片之间、背景图和背景色之间做混合。这个属性视觉效果很强,处理商品图、氛围背景很好用。
还有个容易被忽略的点,background-position如果传百分比,它的计算方式不是你想当然的“图片左边缘和容器左边缘对齐百分之多少”,而是图片上的某个点和容器上的某个点对齐。比如background-position: 50% 50%,意思是图片50%位置的点对准容器50%位置的点,这才是居中的本质逻辑。这个理解了,后面搞雪碧图定位才能透。
1.2 多背景叠加与background-attachment
多背景是CSS3开始支持的特性,写法是在一个background里用逗号分隔多层背景,排在前面的覆盖在后面。听起来简单,但实际使用中有两个坑。
第一个坑是背景图尺寸和位置必须配套。你写多背景的时候,如果只给一个background-size或者background-position,那这个值会应用到所有背景层上,很容易出现其中一张图错位的状况。解决办法是给每层单独写,中间用逗号分隔,放在同一属性里对应位置,但一般人很容易记混。所以我的习惯是拆开写:background-image: url(a.png), url(b.png);,然后单独一行background-size: 100px 100px, cover;,再单独一行background-position: 20px 30px, center;。这样一层对应一组参数,肉眼扫过去就知道谁是谁。
第二个坑是background-attachment: fixed。桌面端做好好的,一拿到手机上看,背景直接原地起飞,因为移动端浏览器对fixed的支持并不一致。常见替代方案是用position: fixed的伪元素来做背景层,把z-index设成负数,这样既保留固定背景效果,又能在相对老旧的移动端WebView里稳定运行。
多背景的实用场景太多了。比如卡片要实现一张底图加一层半透明渐变压暗文字区域的效果,你完全不用在HTML里加一层遮罩,直接写两层背景就行。第一层写线性渐变(从透明到黑色),第二层写图片,出来的效果就是图片底部带一道渐变蒙版,文字放上面清清楚楚。
1.3 移动端坑:背景图片加载与闪白
移动端背景图片经常有两个问题:一是白屏等待,二是闪一下才出图。
白屏等待的原因很直白,CSS背景图不像img标签那样能触发浏览器的预加载机制,尤其是写在样式表里的背景图,浏览器解析到那一步才会去请求。所以碰到首屏关键图用背景实现的,建议在HTML里放一个隐藏的img标签提前加载,或者直接把关键图改成img标签。
闪白问题,常见于有背景图的页面切换或滚动时。解决办法是给背景图加上-webkit-transform: translateZ(0)或者`w
