手把手教你打造一个纯CSS图标库
来,干了这碗安利
写这篇文章的目的其实就是为了安利一下我的图标库:iconoo,所以,开门见山,star吧少年少妇们!(这样的我是不是应该要加个github互粉的团伙了?)
主题说完了,下面进入正题。
在web开发中,我们经常要用到一些小图标(加减勾叉等)。通常做法就两种:
- 直接使用图片;
- 使用css/svg直接在浏览器中绘制图标。
方案1:由于图标图片比较多,而且体积很小,为了减少请求所以很多时候我们会用雪碧图这种技术来将图标拼凑在同一张图片里面。你也能想到,一堆图标的雪碧图,修改维护会相当麻烦!现在比较好的方案是使用webpack引入图片,小图直接转换成base64插入css中。直接使用图片比较简单,这也是目前比较主流的做法。
方案2: 相比方案1,明显可以减小资源的体积,只需要几条css/svg命令就可以绘制出精美的图标,而且不受图片尺寸限制,可大可小非常灵活。初看方案2的一堆代码可能会觉得非常难,但其实很多简单的图标都是非常容易实现的。
接下来就是妹子们最期待的茄果叔叔手把手教学时间啦。
手抓手教学时间
使用CSS绘制线条,用到的不外乎两个属性:border & box-shadow。而形状则可以用border-radius、transform控制变形,位置则会用到绝对定位、transform、margin等属性来调整。CSS的绘图,做过几个就知道大概是怎么回事了,归根到底,还是几何。如果觉得几何烧脑,那就直接用 iconoo 吧~~~
基本原理说了,下面来撸一发,先看看最简单的加号:
.plus { box-sizing : border-box; display : inline-block; position : relative; font-size : 20px; } .plus:before, .plus:after { content : ''; pointer-events : none; position : absolute; left : 50%; top : 50%; transform : translate(-50%, -50%); box-shadow : inset 0 0 0 1em; } .plus:before { width : 1em; height : 2px; } .plus:after { height : 1em; width : 2px; }
代码还是非常简单的,首先我们这里用到了before和after两个伪类增加可用的标签,不然只有一个标签,要玩出花来实在是太难。content顾名思义就是内容,里面可以加各种字符,甚至是换行之类的控制符。而pointer-events:none则是消除了鼠标指针事件,这样元素就具有穿透性了,具体细节还请自行搜索哈,这里就不多说了。绘图的核心,就是通过设置两个伪类的宽高和阴影来绘制横竖两条线,位置方面是通过绝对定位+反向偏移的方式,巧妙利用了这两个属性百分比参照的不同实现了横竖的居中。所有尺寸除了线宽(2px)外都使用em这个相对单位,所以调整font-size的值就可以调整图标的大小了。要调整线宽呢,就将所有px单位的尺寸都一并改了即可。
进阶玩法
首先来看看这个图片图标:
这个图形网上说的应该还是比较多的了,然而我第一眼看到的时候还是懵逼了。。。分析一下,最外层的边框明显可以用border来做,然后用个before来做圆点也非常简单,关键是两座大山要如何绘制呢?box-shadow貌似可以做多层边框呢,然后加个旋转是不是就出来了呢?最后隐藏边框之外的部分就可以了。绘制流程如下:
.icon-img { display: inline-block; position: relative; box-sizing: border-box; width: 90px; height: 80px; border: 5px solid; border-radius: 10px; color: #2ba5bb; overflow: hidden; } .icon-img:before,.icon-img:after { content: ''; pointer-events: none; position: absolute; } .icon-img:before { width: 10px; height: 10px; top: 18px; right: 20px; box-shadow: inset 0 0 0 1em; border-radius: 50%; } .icon-img:after { width: 60px; height: 50px; left: 0; bottom: -27px; box-shadow: inset 0 0 0 50px,30px -20px 0 0; transform: rotate(45deg); }
代码是临时拼的,就没做成em单位了。呃,为什么要做成em单位呢?
我们在使用图标的时候,可能尺寸每次都不一样,但图标的尺寸都是有关联的,调整起来相当费劲。当然你可以会想到用zoom、scale来做缩放,但是这样的缩放线宽也会随之变化了。设置em的话,在icon级设置font-size,然后icon本身以及后代都以这个font-size为参照,只调整font-size就完成了图标的等比缩放了。
再来看一个带变形的:
这个一看其实就能猜到是怎么画的,几何关系貌似也比较简单,但是要映射到css的规则里面却非常复杂。先看看流程:
.icon-codepen { display: inline-block; position: relative; box-sizing: border-box; color: #2ba5bb; width: 2px; height: 10px; box-shadow: inset 0 0 0 32px,0 15px,-11px 7px,11px 7px; } .icon-codepen:before, .icon-codepen:after { content: ''; pointer-events: none; position: absolute; width: 11px; height: 4px; } .icon-codepen:before { right: 2px; top: 3px; transform: skew(0,-35deg) scaleY(0.6); box-shadow: inset 0 0 0 32px,0 13px,11px 26px,12px 39px; } .icon-codepen:after { left: 2px; top: 3px; transform: skew(0,35deg) scaleY(0.6); box-shadow: inset 0 0 0 32px,0 13px,-11px 26px,-12px 39px; }
难点就在长宽的变形上,对于变形比较简单的方法是使用变换矩阵来求解。图形学学的不好的话,那就比较痛苦了,如果不追求单标签的话,可以将每条边用一个标签表示,这样就很好处理了。
叔叔,我想装逼
怎么样?觉得上面这些都是小玩意?想装逼了?好,叔叔教你!
蒙娜丽莎?什么鬼?我会告诉你这也可以用一个单标签纯CSS画出来的吗?
http://codepen.io/jaysalvat/p...点击预览 ,自己看去,几千条box-shadow构成的蒙娜丽莎,看的我内分泌都失调了。。。
静态的还不够,那来点动态的:
http://codepen.io/fbrz/pen/iqtlk点击预览 ,不多说,拿去不谢!
更多CSS玩意儿,请到codepen上去探宝吧!如果codepen都打不开,可以到我博客园去下载相应的css文件吧!什么,没有提供下载链接?F12大法搞起!