《重拾 CSS 的乐趣》问答环节
最后更新于:2022-04-01 03:11:22
> 我在第二届 CSS Conf(2015 中国 CSS 开发者大会)上的演讲主题为《重拾 CSS 的乐趣》。在演讲的问答环节,现场观众提了三个问题,整理记录如下。
### Q1 - CSS 图标的代码量会不会很大,在实际项目中使用可能会有什么问题?
虽然我在演讲中花了很多时间来介绍 CSS 图标,但我并不鼓励在生产环境中大量使用。我自己的项目 [CMUI](https://github.com/CMUI/CMUI)在后续版本中已经改用了其它的图标解决方案。我在演讲中也提到了,任何技术都有优缺点,需要看场景来选择使用。
我今天介绍 CSS 图标,主要目的在于分享它的乐趣,以及它所体现出的 “化整为零” 的 CSS 思维方式。
至于 CSS 图标的代码量,要看具体图标。根据我自己的经验,在常见的案例中,CSS 图标的代码量并不会很大,并不会明显比 SVG 或 icon font 更大;部分场景下甚至更小;Gzip 也有可能会进一步减少这几种方案的代码量差距。有兴趣可以自己实践对比一下。
另外 CSS 有它自己独有的代码复用机制(比如 class 和群组选择符等),可以进一步减少代码量,比如今天提到的 fileicon.css 项目就是一个典型的例子。
### Q2 - 是什么推动着你在这个领域一直不断地学习和探索?
其实我的真实身份并不是工程师,我是一名设计师。
2008 年的时候,我来上海想找的第一份工作是交互设计师。不过遗憾的是,当时上海的互联网行业还没有起来,我没有找到合适的职位。但我要生存啊,必须要找一份工作先干着。由于我有制作个人网站的经验,于是我选择以前端工程师的身份先进入这个行业。
我当时学习 CSS 的方法比较粗暴啊,就是把市面上所有的 CSS 书全部买来、全部啃光。于是在某个时间点,我忽然发现,好像一般的 CSS 问题都难不倒我了。从此我便在工程师的道路上越走越远。
回到你的问题,CSS 是一门非常有乐趣的技术——就像我今天展示的那样。在钻研它的过程中,我不会感到枯燥。
不过近些年来,CSS 早已不是我工作的主要部分,我更多地在使用 JS 甚至后端的东西。我并不在乎自己的身份是什么,我更在意的是我想做的那件事。我是一个想做些事情的人。比如说,在接下来的一个月里,我可能会发布一款重量级的产品,不过它跟 CSS 可能没有太大的联系。
因为我想做些什么,于是我选择各种语言和技术来实现它。所以真正不断推动我的不是各种语言或技术,而是我想做的那件事。
### Q3 - 你在实现多重边框这个案例时有没有遇到兼容性的问题?如何避免?
我只能说,如果旧版 IE 挂了,那就让它挂了吧。
这只是开个玩笑啊。我的建议如下:
* 先明确你的目标设备(目标浏览器),尽可能做到真机实测。
* 查询 [CanIUse](http://caniuse.com/) 这样的浏览器兼容性网站,提前评估可能遇到的兼容性问题。
* 在不支持某些特性的浏览器下,做好 fallback 措施,保证基本功能可用。比如说,不能因为某些浏览器不支持某个 CSS 特性而导致该浏览器下的文本和背景糊成一团无法正常阅读。
重拾 CSS 的乐趣(下)
最后更新于:2022-04-01 03:11:20
> 原文出处:https://github.com/cssmagic/blog/issues/54
接下来,要向大家介绍一件最近让我非常高兴的事情。我相信它也会是所有 CSS 开发者欢欣鼓舞的一件事。
[![一件乐事](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a55dc8b6.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a55dc8b6.jpg)
是关于一本书的。
我对这本书的评价是这样的:
[![“近十年来最重要的 CSS 图书,没有之一”](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a5e4d63a.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a5e4d63a.jpg)
说到 CSS 图书,问题来了。
[![如果你的书架只能放得下三本 CSS 书……](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6268538.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6268538.jpg)
如果你的书架只能放得下三本 CSS 书,我会推荐哪三本呢?
[![《CSS 权威指南》 - 2006](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6640c5b.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6640c5b.jpg)
第一本,《CSS 权威指南》。
这是一本非常经典的 CSS 参考书,它的经典之处在于,它用普通人类可以理解的语言系统、全面地讲解了 CSS 规范。这本书会告诉你,CSS 是什么、CSS 有什么、CSS 可以做什么。
这本书的最新版本——第三版——的英文版出版于 2006 年。
[![《精通 CSS》 - 2006](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a68021f8.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a68021f8.jpg)
第二本书,《精通 CSS》。这同样是一本非常经典的 CSS 图书,它侧重于实践,告诉你如何正确地使用 CSS。(封面图片采用了大家比较容易买到的中文版第二版。)
这本书的英文原版第一版出版于 2006 年。
大家可能注意到了,这两本都出版于 2006 年。而今年已经是 2015 年了。
[![? - 2015](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6941519.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6941519.jpg)
近十年来,我一直在等待第三本重量级 CSS 图书的出现。
终于,它来了:
[![《CSS Secrets》 - 2015](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a69c89b8.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a69c89b8.jpg)
这本书叫《CSS Secrets》,6 月份刚刚出版。(这本书的中文名还没有正式确定,封面图片暂采用英文原版。)
我们先来看看它的作者:
[![Lea Verou](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6b4759d.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6b4759d.jpg)
作者叫 Lea Verou,她是一位资深 Web 开发者,有着丰富的实践经验。更重要的是,她是 W3C CSS 工作组的特邀专家——CSS 工作组汇集了这个领域内的专家,他们是制定 CSS 规范、设计 CSS 这门语言的一群人——全球只有极少数顶尖的开发者才有机会获邀加入 CSS 工作组。
国内开发者亲切地称呼她为 “CSS 一姐”。
那这本书到底好在哪里呢?
[![专业的 CSS 开发者需要知道的知识和技巧 | 立足当下 | 面向未来 | “授人以渔”](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6bb969e.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6bb969e.jpg)
(此处略去两百字)
[![对不同类型的读者分别有什么帮助?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6c76750.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6c76750.jpg)
对 CSS 初学者来说,我强烈建议先去读前面两本书,因为读这本书还是需要有一定的基础的。如果实在等不及,可以把它当作 cookbook 来解决你迫在眉睫的问题。
对于中级的 CSS 开发者来说,这本书可以发挥最大的功效——它可以帮助你进阶。相信很多开发者在学习 CSS 到了一定阶段的时候,感觉自己好像什么都会了,但遇到复杂问题时往往又感觉捉襟见肘、力不从心。这就是遇到瓶颈了。如何突破瓶颈、进入下一个阶段?要做的无非是两件事——实践和思考。书并不能代替你思考,但一本好书可以向你示范,什么样的思考方式是正确的。
如果你已经是一位 CSS 专家了,已经有些飘飘然了,那这本书可以告诉你和这个星球上最顶尖的 CSS 专家的差距在哪里,从而帮助你找到人生下一阶段的目标和动力。
说了这么多,大家心里可能会想:你吹得挺玄乎,能不能举个书里面的例子来看一看?
[![举个例子?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6e099c6.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6e099c6.jpg)
好,我们来看个例子。
在这里我要强调一下,因为时间关系,我在这里引用的只是一个非常浅显的案例。书中的绝大多数案例都要比它复杂。
这个例子是这样的:
[![多重边框](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6f04b41.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6f04b41.jpg)
对于边框我们都非常熟悉了。边框是我们美化网页、增强样式最常用的手段之一。
[![有边框的方框](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6fa1981.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a6fa1981.png)
有些时候,我们的需求是给一个容器加上多重边框:
[![双层边框的方框](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a700070f.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a700070f.png)
对于这个需求,我们最容易想到的就是给它再加一层标签:
[![HTML 代码](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a707d258.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a707d258.png)
不过有些时候,我们可能无法修改结构,或者修改结构的成本很高,此时就需要我们在纯 CSS 层面解决这个问题。
说到边框,首先我们可能会联想到 `outline` 属性。
[![outline](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a71c61a7.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a71c61a7.png)
我们暂且把 `outline` 称作 “描边”。描边属性跟边框有很多相似之处,但由于早期的 IE 并不支持,了解它的人可能没有那么多。描边是绘制在边框的外圈的,因此,通过 `outline` 属性我们就可以很容易地实现双层边框了。
描边有一个好处在于,它跟边框类似,可以设置各种线型,比如虚线:
[![虚线描边](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a733fa71.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a733fa71.png)
而且更好玩的是,还有一个 `outline-offset` 属性,可以控制描边的偏移量。
[![outline-offset](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a74b75d9.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a74b75d9.png)
我们可以把这层描边扩展出去:
[![描边扩张](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a7e720fc.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a7e720fc.png)
这个属性甚至还可以接受负值。如果是负值,描边会向内收缩,并叠加在边框之上:
[![描边收缩](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a7fbb577.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a7fbb577.png)
利用这个特性可以玩出很多好玩的效果。
不过描边有一个缺陷——如果这个容器本身有圆角的话,描边并不能完全贴合圆角。目前所有浏览器的行为都是这样的:
[![描边与圆角](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a82931ac.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a82931ac.png)
所以,如果你需要圆角,就要另寻它法了。
于是接下来,我们又想到了投影这个属性。
[![box-shadow](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a840744f.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a840744f.png)
相信大家都用过投影,它可以让我们的网站更具立体感和层次感。
我们通常是这样设置投影的:
[![box-shadow: 0 0 0 brown;](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a930cbaa.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a930cbaa.png)
前面三个长度值,再加一个颜色值。
前两个长度值分别表示投影在水平和垂直方向上的偏移量,第三个长度值表示投影的模糊半径(也就是模糊的程度);颜色值就是投影的颜色。
如果我们把前三个值都设为零,实际上是没有任何效果的。因为如果投影即不偏移也不模糊,刚好会被这个元素自己严严实实地遮住。
很多人可能不知道的是,投影还可以有第四个长度值。这个值表示投影向外扩张的程度:
[![box-shadow: 0 0 0 5px brown;](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a93650f9.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a93650f9.png)
这样,投影就会从元素的底下露出一圈了。
关于投影,另外一个不是每个人都知道的特性是,投影属性其实可以接受一个列表,我们可以一次赋予它多层投影,像这样:
[![box-shadow: 0 0 0 5px brown, ...;](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a93d368c.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a93d368c.png)
这样我们就得到了超过两层的 “边框” 效果了。
投影的另外一个好处是,它的扩张效果是根据元素自己的形状来的。如果元素是矩形,它扩张开来就是一个更大的矩形;如果元素有圆角,它也会扩张出圆角。
[![多重边框与圆角](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9431759.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9431759.png)
所以对于圆角的场景,它也不在话下。
[![注意事项?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9990f75.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9990f75.png)
这两种方法还有什么需要注意的地方?这本书也很贴心地注明了。
由于描边和投影都是不影响布局的,所以如果这个元素和其它元素的相对位置关系很重要,就需要我们以外边距等方式来为这些多出来的 “边框” 腾出位置,以防被其它元素盖住。
因此,从这个意义上来说,使用内嵌投影似乎是更好的选择。因为内嵌投影让投影出现在元素内部,我们可以用内边距在元素的内部消化掉这些额外 “边框” 所需要的空间,处理起来更容易一些。
[![(笑脸)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9a0f888.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9a0f888.jpg)
好的,这个例子就讲完了。
(掌声。)
讲到这里,我看到有些同学一脸意犹未尽的表情,你们的心情可能是这样的:
[![再来一个?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9a81bc1.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9a81bc1.jpg)
OK,再来一个。
这个例子并不是书中直接提到的,而是我在读这本书的过程中,受它启发,再结合自己的实践所想到的,这里拿出来跟大家分享。
这个案例叫做:
[![圆润的标签页](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9aeeb7a.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9aeeb7a.jpg)
什么叫 “圆润的标签页” 呢?
标签页我们都很熟悉了,它是一种常用的 UI 元素。
[![三个标签页](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9b8c758.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9b8c758.png)
我们把它拉近来看一看:
[![放大的标签页](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9bd5311.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9bd5311.png)
这个标签还是比较美观的,我们用圆角让它看起来很接近真实的标签造型。不过我们也注意到,它底部的两个直角看起来似乎有点生硬。
所以设计师原本期望的效果可能是这样的:
[![所有边角均为圆弧的标签页](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9c34891.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9c34891.png)
这样就自然多了。但这看起来似乎很难实现啊!
我们的难点主要在这里:
[![标签页的内凹处高亮](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26aa7dee93.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26aa7dee93.png)
这个特殊的形状如何实现?
我们把它放大来看一下:
[![内凹形状](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab1df64b.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab1df64b.png)
首先我们可能会想到用图片。这当然是可行的,但图片有种种局限,我们最好还是完全用 CSS 来实现它。
好,接下来我们来分析一下它的形状。它其实就是一个方形,再挖掉一个 90° 的扇形。于是我们试着创建一个方形,再用背景色做出一个扇形叠加上去:
[![实色方块与白色扇形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab364964.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab364964.png)
看起来好像可以了。但这是骗人的啊!
把它放在复杂背景下,立马就露馅了——扇形部分不是透明的:
[![内凹形状在棋盘背景上](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab3d4b58.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab3d4b58.png)
所以,我们的问题就变成了:
[![如何用 CSS 实现内凹圆角?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab93043b.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ab93043b.jpg)
对于普通外凸的圆角,我们都已经非常熟悉了:
[![圆角矩形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26aba305a1.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26aba305a1.png)
我们用圆角属性就可以得到:
[![border-radius: 20px;](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abaa3a37.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abaa3a37.png)
但我们需要的是一个内凹的圆角形状。
这是一个实实在在的需求,于是有开发者曾经提议,扩展圆角属性,让它支持负值。如果是负值,圆角就不再是外凸的,而是内凹的。这个提议听起来似乎很有道理,语法设计也很紧凑。
[![圆角矩形与 border-radius: -20px;](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abaf0dc4.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abaf0dc4.png)
但实际上它的语义不够准确。因此 CSS 工作组并没有接受这个提议,并未将它纳入标准。
[![NOT APPROVED](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abb46c8c.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abb46c8c.png)
这条路走不通,我们还需要继续探索。
我们顺着这个方向,头脑中很自然地会迸出这个疑问:
[![CSS 还有没有其它跟圆形有关的特性?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abbc7a15.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abbc7a15.jpg)
答案当然是有的:
[![radial-gradient() 径向渐变](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abc79fd8.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abc79fd8.jpg)
“径向渐变” 特性就是跟圆形有关的。
不过它稍稍有些复杂。在讲解径向渐变之前,我们先来看一看比较简单的 “线性渐变”。
[![线性渐变 - 空容器](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abdb6387.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abdb6387.png)
说到渐变,那自然需要有一个容器。然后,还需要有两种颜色。渐变的颜色设置我们称之为 “色标”——每个色标不仅有颜色信息,还有位置信息。
我们给起点和终点的色标分别设置颜色,就可以得到一条渐变图案:
[![线性渐变 - 渐变 1](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abe3743f.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abe3743f.png)
我在这里使用了绿色来展示这个渐变,大家可能会觉得绿色很难看。实际上这是有意安排的——由于人眼对绿色的亮度变化是最为敏感的,这里使用绿色是为了让大家看得更清楚,而不是我的审美出了问题。(笑声。)
接下来,关于渐变,我们其实可以设置不止两个色标。比如我们可以在中央再增加一个色标。请注意我们特意选择了跟起点色标一样的颜色。我们得到的效果如下:
[![线性渐变 - 渐变 2](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abe854c0.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abe854c0.png)
我们发现,渐变只发生在颜色不同的色标之间。如果两个色标的颜色相同,则它们之间会显示为一块实色。
好的,我们继续增加色标。这次我们在渐变地带的中央增加一个色标,且让它的颜色和终点色标相同:
[![线性渐变 - 渐变 3](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abed8274.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abed8274.png)
根据上面的经验,这个结果正是我们所预料的——渐变只发生在颜色不同的色标之间。
接下来,我们玩点更特别的,我们把中间的两个色标相互靠近直至重合,会发生什么?
[![线性渐变 - 渐变 4](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abf51dcf.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26abf51dcf.png)
实际上这个渐变也会趋向于零。也就是说,虽然这本质上仍然是一个 “渐变” 图案,但经过我们的精心设计之后,我们最终得到了两个纯色的色块条纹。
如果我们把终点颜色换为透明色……
[![线性渐变 - 渐变 5](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac4d5636.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac4d5636.png)
我们甚至还会得到实色和透明色间隔的条纹。
好的,接下来我们来看径向渐变。它稍稍有些复杂,但原理是一样的。
同样,我们需要有一个容器。但对径向渐变来说,顾名思议,所有色标是排布在一条半径上的。也就是说,我们还需要有一个圆心。默认情况下,圆心就是这个容器的正中心:
[![径向渐变 - 空容器与圆心](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac54f137.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac54f137.png)
而这条半径就是圆心指向容器最远端的一条假想的线:
[![径向渐变 - 空容器、圆心与放射线](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac5979ad.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac5979ad.png)
接下来,我们要设置一些色标:
[![径向渐变 - 若干色标](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac6202ff.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac6202ff.png)
说到这里,就要讲解一下径向渐变的特别之处。所有色标的颜色变化推进不是像线性渐变那样平行推进的,而是以同心圆的方式向外扩散的——就像水池里被石子激起的涟漪那样。
看到这个色标的分布,我们应该可以想像出线性渐变的结果是什么;但这里我们把它按照径向渐变的特征来推演一下,实际上最终的效果是这样的:
[![径向渐变 - 渐变与色标](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac66e3c7.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac66e3c7.png)
我们把所有辅助性的标记都去掉,只留下渐变图案:
[![径向渐变 - 渐变](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac6db5b0.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac6db5b0.png)
这是一个穿了个窟窿的实色背景。很好玩是吧?不过不要忘了我们是为什么来到这儿的——我们是为了得到一个内凹圆角的形状。
细心的朋友可能已经发现了,我们需要的东西已经出现了:
[![径向渐变 - 框出内凹部分](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac754af2.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac754af2.png)
接下来,我们调整一下圆心的位置和容器的尺寸,就可以得到这个内凹圆角的造型了。
[![内凹形状](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac7a2b3c.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac7a2b3c.png)
利用这个技巧,我们用纯 CSS 最终实现了这个看似不可能的 “圆润的标签页” 效果!
[![所有边角均为圆弧的标签页](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9c34891.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26a9c34891.png)
(掌声。)
[![回顾一下](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac89da0e.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac89da0e.jpg)
好的,我们来回顾一下今天分享的主要内容:
[![一件趣事 | 一本书 | 两个例子](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac9560eb.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ac9560eb.jpg)
(现场的分享到这里就结束了。以下是因为时间关系被剪掉的片断。)
[![One more thing...](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26acb8f5e1.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26acb8f5e1.jpg)
关于《CSS Secrets》这本书,大家可能会有一个问题:
这本书有中文版吗?
[![这本书的中文版?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ad8a1552.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ad8a1552.jpg)
这本书已经由国内顶尖的计算机图书公司 “图灵文化” 引进;同时,我本人也很荣幸争取到了这本书的中文版翻译权。
[![年内上市](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ad9316aa.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ad9316aa.jpg)
在最理想的情况下,这本书的中文版在年内就可以在各大书店上架。当然,电子版会更快,图灵官网最快本月内就会发布免费试读章节。
在翻译这本书的过程中,我有很多想要补充的内容,但限于篇幅,不可能在原书中插入过多的译注。因此,我萌生了一个想法——为这本书写注解。
[![为这本书写注解](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26adf096fe.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26adf096fe.jpg)
萌生这个想法有两个原因:
一方面,这本书不适合初学者阅读,书中的很多难点都一笔带过了,而这些难点往往是值得展开讨论的。
另一方面,书中提供的解决方案以标准为导向,极少涉及浏览器的私有属性。部分解决方案所采用的 CSS 特性太新,以致于在眼下还没有浏览器很好地实现。而实际上有些非标准的解决方案已经比较成熟了,在特定场景下往往会发挥更好的作用。我认为有必要提供这些知识,以供国内的开发者们参考。
[![承诺](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26adf86fcf.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26adf86fcf.jpg)
在翻译完这本书之后,我一定会写。写多少字、什么时候写完,现在还不确定,但我在这里可以承诺的是,我一定会写。
而且,我会以免费、开源的方式来完成这个计划。原书是需要大家自己购买的,但我写的这份注解一定会在 GitHub 上免费发布!
(此处可能有掌声。)
[![135](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ae04332f.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26ae04332f.jpg)
我今天的分享到这里就结束了,大家有问题吗?
重拾 CSS 的乐趣(上)
最后更新于:2022-04-01 03:11:18
> 本文出处:https://github.com/cssmagic/blog/issues/52
## 前言
> 我在第二届 CSS Conf(2015 中国 CSS 开发者大会)上的演讲广受好评,很多网友向我索取现场视频。条件所限,这个演讲并没有留下视频存档。因此,本文尝试在静态幻灯片的基础上,以文字的方式还原现场讲解,尽可能为不能去现场的朋友呈现最完整的体验。
>
> 我在每幅图片之间补充了讲解文字。你不用分辨每段文字是配合上图还是下图的,只管顺序阅读即可。
* * *
[![重拾 CSS 的乐趣 - 幻灯片封面](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268cea522b.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268cea522b.jpg)
大家看到封面的画风,应该可以看出我今天走的不是技术路线,而是娱乐路线。如果说前面几位讲师的分享是烧脑的悬疑推理大片,我这个环节就是轻松愉快的爆米花电影了,大家可以放松一下。
[![CSS魔法 #百姓网#](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268cf3d5e8.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268cf3d5e8.jpg)
接下来,接照惯例,需要介绍一下 “这个人”。有两个标签可以描述这个人。
首先,他来自百姓网(此处省略百姓网的诱人之处一百字)。欢迎各位小伙伴到百姓网来看一看,我们一起来玩些好玩的。
第二个标签是这个:
[![#把 CSS 写进名字的男人#](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d54e672.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d54e672.jpg)
大家可能会说,“把 CSS 写进自己的名字”,听起来这么拽,那你上一届 CSS Conf 怎么没来?
[![CSS Conf](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d5c6824.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d5c6824.jpg)
上一届 CSS Conf 我确实没有来。我给自己找的理由是北京太远了,我就不去了。但实际上我自己很清楚,真正的原因是,我并不知道自己应该在这样的大会上分享什么。
第二届 CSS Conf 就在上海,我没有任何理由不来,但我仍然需要面对这个问题——我要为现场的观众分享些什么呢?
其实,最近这几年,在 CSS 领域出现了很多好东西:
[![Sass、Stylus、Less、PostCSS 等 logo](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d678c09.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d678c09.jpg)
当我听说它们、了解它们、使用它们的时候,我的心情是这样的——
[![插画:小男孩在游乐场](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d74f66e.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d74f66e.jpg)
右边的这个小男孩就是我。我的心情是激动、新奇、兴奋。
那么,我会在 CSS Conf 上分享它们吗?一番思索之后,我的答案是——“不”。
有几个原因:首先,我相信肯定会有其它同学会分享它们;此外,它们不是 CSS,它们并不能解决我们在 CSS 上遇到的问题。
[![灰化的各个 logo](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d80758d.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268d80758d.jpg)
更重要的是,它们其实跟我没什么关系,它们是别人写的优秀的工具,而我只是在享受别人的发明所带来的便利。就好像我在游乐场 high 了一天之后,我还是我,还是要回到自己平凡的生活。
那我应该分享些什么?我尝试在记忆的长河中逆流而上,找寻 CSS 最初带给我的欣喜和感动。
[![插画:小男孩蹲在地上玩积木](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268da3129c.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268da3129c.jpg)
我发现,有一件事情,即使在今天,仍然可以实实在在地带给我乐趣——那就是用 CSS 的各种神奇的特性,实现各种神奇的效果。有些效果甚至令人惊叹——“这怎么可能是用 CSS 实现的?!”
[![CSS魔法个人主页截图 - CSS 谜题 1](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268daae7fa.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268daae7fa.jpg)
在 [我的个人主页](http://www.cssmagic.net/#demo) 上,收录了一些 CSS 谜题。所谓 “谜题”,就是需要费一番脑筋才能实现的效果。每一道题都有我自己的解答和评述。
[![CSS魔法个人主页截图 - CSS 谜题 2](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268db65b22.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268db65b22.jpg)
在这些谜题中,收获最多赞叹的,应该是这个案例——弧形排列的可折叠二级导航。
[![弧形排列的可折叠二级导航](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dc1d33f.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dc1d33f.jpg)
这是 2009 年的时候,一位网友在论坛里求助,说他们公司的设计师想要实现这样一个效果。大家看到背景是一个弧形的造型,所有导航菜单需要顺着这个背景图案以弧形排列。
[![弧形排列的可折叠二级导航 - 红框标注](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dc8b265.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dc8b265.jpg)
而且,有些菜单是可以展开的(上图中加红框的部分)。当我点击第一个可展开菜单时,效果是这样的:
[![弧形排列的可折叠二级导航 - 导航展开演示 1](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dd1343b.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dd1343b.jpg)
点击第二和第三个,展开效果是这样的:
[![弧形排列的可折叠二级导航 - 导航展开演示 2](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dda4e9e.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268dda4e9e.jpg)
……和这样的:
[![弧形排列的可折叠二级导航 - 导航展开演示 3](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e3443ea.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e3443ea.jpg)
所有菜单项都需要顺滑地贴合这个弧形背景自然展开。
论坛里的网友纷纷表示,这样的效果应该用 Flash 来实现才对,用 CSS 怎么可能做到?!
我动了一番脑筋,[最终把这个效果做了出来](http://www.cssmagic.net/demo/20090215-arc-nav/)。当然,在这个例子里,我用到了一些 JS,用来监听点击事件、切换元素 class;除此以外所有的元素布局和定位都是由 CSS 来完成的,也就是说,你可以任意地改变菜单项的数量和内容。
大家可以试试,在 2009 年,要兼容 IE6,应该怎么做?
今天由于时间关系,我们不会讲解这个案例。我会跟大家聊一些跟 CSS 有关的趣事。我今天的分享分为两个部分:
[![幻灯片大纲:一件趣事、一件乐事](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e3b2257.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e3b2257.jpg)
第一部分会介绍一件 CSS 能做的有趣的事情;第二部分是我最近遇到的一件值得高兴的事情。
首先,这件趣事就是用 CSS 画图标。
[![CSS 图标](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e459c94.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e459c94.jpg)
请问现场有哪些同学尝试过?(仅前三排就有多人举手。)好的,试过的同学接下来一定会找到很多共鸣。
有同学可能会问:
[![为什么要用 CSS 画图标?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e4eb50f.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e4eb50f.jpg)
我这里不想找一些技术上的原因,单从感性的角度来回答这个问题。
[![为什么要用 CSS 画图标? - 好玩!](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e55fe8e.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e55fe8e.jpg)
它太好玩了!只有你试过,你才知道它有多好玩。
有一句话,大家可能听过,是说 JS 的:
[![“所有可以用 JS 写的项目,最终一定会用 JS 重写一遍”](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e5e13a4.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268e5e13a4.jpg)
我这里借用这个句型,说一个 CSS 的版本:
[![“所有可以用 CSS 画出来的图形,最终一定会用 CSS 再画一遍”](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268eb61577.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268eb61577.jpg)
不信?我们来看一些例子:
[![机器猫](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268ebe3896.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268ebe3896.jpg)
在 CSS3 刚开始火起来的时候,大家肯定见过这张图——用 CSS3 画的机器猫。
[![iPhone 3GS](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f18222f.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f18222f.jpg)
用纯 CSS 画的 iPhone。
[![小黄人](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f239dd0.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f239dd0.jpg)
用 CSS 画的小黄人。
很多公司的 logo 也是很有特点的,也被网友用 CSS 画了出来,比如 Opera 的 logo:
[![Opera logo](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f2cb18a.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f2cb18a.jpg)
最神奇的是下面这个:
[![IE8 logo](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f35962e.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f35962e.jpg)
(笑声。)
居然还有网友用 CSS3 画了一个 IE8 的图标。不过,讽刺的是,IE8 自己完全没有能力正常渲染这个图标。(笑声。)
这件事情这么好玩,我自己当然也是做过的。
[![CMUI demo 页面截图](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f425ea4.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f425ea4.jpg)
我写过一个移动端的 Web UI 框架叫 [CMUI](https://github.com/CMUI/CMUI),在最初的版本中,[图标的解决方案](http://cmui.net/demo/v0/html/element/icon.html) 就是用纯 CSS 来实现的。
我们来看一下用 CSS 画图标会用到哪些基本原理。
[![黑色矩形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f4d17e6.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f4d17e6.png)
怎样用 CSS 来画一个矩形?这没有任何难度,因为任何一个块元素本身就是矩形。
改变它的宽高,把它拉长,就可以得到一条线:
[![黑色水平线](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f535a7d.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f268f535a7d.png)
那怎样得到一个三角形?
[![黑色三角形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690000478.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690000478.png)
在早期的 CSS 中,没有任何特性是跟斜线直接相关的。但你要相信劳动人民的智慧是无穷的。很快 CSS 开发者们就发现了关于边框的一个秘密。
[![黑色方框](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269006da43.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269006da43.png)
这是一个加了边框的块元素。当我们把四个方向上的边框设置为不同的颜色时,效果会变成这样:
[![四边为彩色边框的矩形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26900bb486.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26900bb486.png)
我们会发现,在不同边框颜色的交界处,出现了一道斜边。接下来,我们逐渐减小这个元素的宽高至零,同时增加各条边框的厚度,最终会变成这个样子:
[![四个彩色三角形拼合的矩形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26901202c8.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26901202c8.png)
我们会得到四个头对头的三角形!
接下来,我们用透明色把不需要的三条边框隐去,就可以得到一个三角形:
[![绿色三角形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269016e4e5.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269016e4e5.png)
通过改变这个元素各条边框的厚度,就可以改变这个三角形各条边的角度。我们可以得到锐角三角形:
[![绿色三角形 - 顶角为锐角](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26901e053d.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26901e053d.png)
……或者直角三角形等等。
[![绿色三角形 - 某个角为直角](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690259c3d.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690259c3d.png)
以上是在 CSS2 时代用 CSS 画图标时我们可以做的。CSS3 为 CSS 增加了更加强大的能力,我们看来一个例子:
[![方框、圆角框、圆形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26902ad273.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26902ad273.png)
CSS3 增加了圆角属性,给一个矩形设置圆角,可以得到一个圆角矩形;逐渐增加圆角半径到一定的程度,我们就可以得到一个圆形。
[![线段、圆头线段、斜 45° 的圆头线段](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269032b313.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269032b313.png)
圆角除了对边框有效,还可以对实色矩形生效。比如这条短线,我们可以把它设置为圆头的样式;CSS3 还增加了旋转这样的变形属性,我们可以把它扭转一定的角度。
把这两个图形组合起来,我们就可以得到……
[![放大镜图标](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26903792bd.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26903792bd.png)
一个放大镜的图标。
根据这个思路,常见的图形都可以拆解开来,化整为零,用 CSS 画出来。比如下面这个:
[![加号](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26903e5f2d.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26903e5f2d.png)
……这个:
[![房子](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690445322.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690445322.png)
……和这个:
[![卡通小人半身像](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26904b236b.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26904b236b.png)
下面这个图标稍稍有些复杂:
[![iOS 6 的动作图标](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26905117ed.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26905117ed.png)
你可能会想,它居然也可以用 CSS 画出来?
我们先从简单的开始。三角形我们已经介绍过了,所以先把它隐去:
[![iOS 6 的动作图标 - 隐去三角形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269057eb3e.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269057eb3e.png)
再来看外层的那个有斜向缺口的矩形框。斜角缺口也需要利用边框交界处的斜边来实现,不过这个框无法用一个元素来实现,我们需要分两步走。完成一边:
[![iOS 6 的动作图标 - 隐去部分外框](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26905ec0cc.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26905ec0cc.png)
……再完成一边:
[![iOS 6 的动作图标 - 隐去外框](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690640aa8.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690640aa8.png)
最后我们剩下的难题似乎就是这个奇怪的形状了,好像是个鹰嘴的样子。
[![类似鹰嘴的图形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269068eee8.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269068eee8.png)
这个形状如何实现?给大家五秒钟的时间考虑一下。
在揭开谜底之前,我们需要了解一下:
[![关于圆角的两个真相](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269075b66d.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269075b66d.jpg)
这里有一个块元素,设置了边框和圆角,它的两条边框会通过一段圆弧连接起来:
[![边框和圆角](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269080d4e0.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269080d4e0.png)
首先,第一个真相,边框圆角可以指定两个半径值(下图中的 `r1` 和 `r2`):
[![边框和圆角 - 标示圆角的半径](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690d5d48a.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690d5d48a.png)
如果这两个半径值相等,则连接两条边框的圆弧就是一条相标准的 1/4 圆弧。如果不相等(比如我们把 `r2`减小),会得到这样的效果:
[![边框和椭圆圆角](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690de4847.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690de4847.png)
我们发现连接两条边框的圆弧会变成一道 1/4 椭圆弧。这个真相解决了我们在尺度上的问题。接下来,我们需要解决形状上的问题。
第二个真相,不同方向上的边框的厚度(下图中的 `w1` 和 `w4`)也是可以不一样的:
[![边框和圆角 - 标示边框的厚度](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690e3e9b3.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2690e3e9b3.png)
如果我们逐渐减小 `w4` 的值至零,我们会得到这个形状:
[![类似鹰嘴的图形,末端延长](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26913adbfa.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26913adbfa.png)
大家应该可以看出,我们需要的形状已经出现了。最后,我们调整一下这个元素的宽高,只保留我们需要的部分,就可以得到这个鹰嘴的形状。
[![类似鹰嘴的图形](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2691427180.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2691427180.png)
最终,我们就实现了这个乍看起来不可能用 CSS 实现的图标。
[![iOS 6 的动作图标](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26905117ed.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26905117ed.png)
看到这里,可能有同学会说:
[![“奇技淫巧”?](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26923ebffe.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26923ebffe.jpg)
“你这是奇技淫巧啊!”
事实上,我们刚刚介绍的技巧都是标准的 CSS 特性。只有那些对 CSS 的各种特性观察入微的人,才有可能在非常规的场景之下把这些特性发挥出来,从而完成不可能完成的任务。——这是我对所谓 CSS “奇技淫巧” 的理解。
说到 CSS 图标这件事,有一个网站不能不提。
[![one-div.com 网页截图](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269245fc4e.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269245fc4e.jpg)
这个网站叫 [one-div.com](http://one-div.com/),收录了这位站长制作的纯 CSS 图标。这个网站最大的特点在于,所有的图标只用到了一个 `<div>` 标签。(惊叹声。)很有创意,推荐大家观摩。
用 CSS 画图标这么好玩的事情,肯定不止我和这位站长会想到。我们搜索 “纯 CSS 图标” 这个关键字,可以发现有很多的案例和开源项目。
[![Google 搜索结果截图 1](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269250298d.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269250298d.jpg)
当然,我们也会听到反对的声音。比如这一条:
[![Google 搜索结果截图 2](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26926083e2.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26926083e2.jpg)
“用 CSS 画图标,这种疯狂的事情赶快停止吧!”
大家玩得这么开心,你一本正经地来教育大家,很无趣,对吧?当然,这篇文章的观点肯定有它的道理,但任何一门技术都是有优点和缺点的,要看使用场景。比如,下面就是一个正面的例子:
[![fileicon.css 项目主页截图](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269267fa16.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269267fa16.jpg)
这是一个开源项目,叫 [fileicon.css](https://github.com/picturepan2/fileicon.css),作者是中国人。
为什么说它是一个正面的例子呢?因为,作为一个样式库,它的接口非常清晰。
[![代码](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269278ffad.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f269278ffad.png)
你只需要使用一个空元素,再加上一些有意义的属性就可以了。
然后,你就可以得到一个设计精致的文件图标了——它有着优雅的圆角,还有一个可爱的折角效果。
[![文件图标](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26927de48f.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26927de48f.png)
我很喜欢这个项目。
不过在现有的版本中,它有一个小缺憾——只能把它放在纯白的背景上。如果你把它放在其它背景上,会发现它的折角的空缺位置是不透明的:
[![文件图标与透明背景](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2692838b2b.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2692838b2b.png)
实际上能做到这一步已经很不容易了。大家可以自己试一下,用一个空标签把这样的图标做出来。
我很喜欢这个项目,于是我花了一点时间,给作者写了一个 [demo](https://github.com/picturepan2/fileicon.css/issues/2#issuecomment-128747900)。我用了一些 CSS 奇技淫巧,把折角处做成了真正的透明:
[![文件图标与透明背景](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26928d4b1e.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f26928d4b1e.png)
同时,我还顺手支持了 IE8。
[![文件图标与透明背景](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2692e2fa87.png)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2692e2fa87.png)
因为 IE8 支持伪元素,我们没有理由放弃它。只不过 IE8 无法渲染圆角,我们在 IE8 下只有方角效果了。
[![笑脸](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2692e9ee3a.jpg)](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-09-11_55f2692e9ee3a.jpg)
好的,以上就是我的分享的第一部分——CSS 图标。
(掌声。)
* * *
#### 鸣谢
* 插画作者:[小妖](http://weibo.com/u/1793462007)(百姓网设计师)