每次要用到图标的时候都会到 icono 去copypaste,但每次用到的时候尺寸都各不一样,总是要调整参数,巨烦。当然你可以会想到用zoom、scale来做缩放,但是这样的缩放会使得线宽也变粗了,不甚满意。

终于下定心思来改造一个可缩放的图标库。github先上:https://github.com/qieguo2016/iconoo目前提供下载link标签引入和npm+webpack的引入方式,详见项目的readme。(喂,来个star!)。上图:

关于改造,一开始的想法就是使用百分比尺寸来改造,然后马上发现不可行了,绘制图标最依赖的两种手段:border、box-shadow都不可以用百分比,所以这个想法,pass!然后很自然就想到了在单位上做文章,rem?No、No、No,一个库依赖全局变量那简直是个笑话。剩下的自然就是em了,在icon级设置font-size,然后icon本身以及后代都以这个font-size为参照,Perfect!

CSS绘图的原理

使用CSS绘制线条,用到的不外乎两个属性:border & box-shadow。而形状则可以用border-radius、transform控制,位置会用到绝对定位、transform、margin等。CSS的绘图,做过几个就知道大概是怎么回事了,归根到底,还是几何。

比如最简单的加号:

 .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;
}

实现非常简单,通过设置两个伪类的宽高形成横竖两个小矩形,接着用阴影填充满,这样一个加号必需的图形就出来了。然后就是调整位置了,将这两个矩形居中,加号就出来了。具体是通过绝对定位+反向偏移的方式,巧妙利用了这两个属性百分比参照的不同实现居中。尺寸方面,所有尺寸除了线宽(2px)外都使用em这个相对单位,所以调整font-size的值就可以调整图标的大小了。如果要调整线宽,那就需要改变这个2px了,引入less、sass将线宽定义成变量就可以很方便地改变线宽了。

CSS的各种玩法

原理虽然简单,但是很多图标还是相当有意思的,通过分析这些图标也能加深对css的认识。例如:

这个图形网上说的应该还是比较多的了,第一眼看到懵逼了。。。分析一下,最外层的边框明显可以用border来做,然后用个before来做圆点也非常简单,关键是两座大山要如何绘制呢?box-shadow貌似可以做多层边框呢,然后加个旋转是不是就出来了呢?绘制流程如下:

上CSS代码吧:

 .icon-test {
display: inline-block;
position: relative;
box-sizing: border-box;
width: 90px;
height: 80px;
border: 5px solid;
border-radius: 10px;
color: #2ba5bb;
overflow: hidden;
} .icon-test:before,.icon-test:after {
content: '';
pointer-events: none;
position: absolute;
} .icon-test:before {
width: 10px;
height: 10px;
top: 18px;
right: 20px;
box-shadow: inset 0 0 0 1em;
border-radius: 50%;
} .icon-test:after {
width: 60px;
height: 50px;
left:;
bottom: -27px;
box-shadow: inset 0 0 0 50px,30px -20px 0 0;
transform: rotate(45deg);
}

再来一个:

看起来跟上一个有点像,然而,按照上一个的绘制方式却怎么也画不出来~~~还是分解几步来画,边框很容易解决,一个box-shadow就完事。这两座大山其实形状都一样,都是一个三角形下接一个矩形,三角形显然可以用border来画,而矩形用box-shadow就可以了!这里还用了透明border来做左侧和下侧的留白,比直接用尺寸对齐要好很多。

 .icon-test {
display: inline-block;
position: relative;
box-sizing: border-box;
color: #2ba5bb;
width: 60px;
height: 40px;
border-top-width:;
border-right-width:;
border: 4px solid;
border-color: transparent;
box-shadow: -4px 5px;
overflow: hidden;
} .icon-test:before,.icon-test:after {
content: '';
pointer-events: none;
position: absolute;
} .icon-test:before {
left:;
bottom: 8px;
border: 14px solid transparent;
border-bottom-color: currentColor;
box-shadow: 0 16px;
} .icon-test:after {
left: 28px;
bottom: 9px;
border-width: 0 9px 21px;
border-style: solid;
border-color: transparent transparent currentColor;
box-shadow: 0 17px;
}

怎么样?觉得这些都是小玩意?好吧,都让开,我要开始装逼了!

 
 

蒙娜丽莎?什么鬼?我会告诉你这也是一个单标签纯CSS画出来的吗?

几千条box-shadow构成的蒙娜丽莎,看的我内分泌都失调了。。。

(author:Jay Salvat, 来源:http://codepen.io/jaysalvat/pen/HaqBf)

如此变态的绘图,都没有怎么用到CSS中最强大的变形,如果加入变形,那可以画出来的形状就更多了。。。更多CSS玩意儿,请到codepen上去探宝吧!

PS: 蒙娜丽莎这种图形,可以读取原图信息转换成单位面积的box-shadow,前端用canvas就可以做的,其实这货的技术含量比一个图片图标还要少呢。话虽如此,复杂图形使用CSS来绘制的话,性价比还是太低,建议还是使用图片,这样会更具表现力一些,操作起来也更加简单!专业的绘图还是交给专业的UI去做吧!

大大小小的坑

其实,遇到的这些都不能叫做坑,是自己对CSS的理解度不够而已。原以为,将原来icono使用的单位换算成em就算完事了,然而,一改font-size就变形了,顿时懵逼!究其原因,其实也很简单,并不是所有地方与font-size都是正比的,很多地方混入了线宽的影响,所以要剔除线宽的影响。

去除线宽影响的方法不外乎两种:

1)去掉线宽,例如使用box-shadow等不影响尺寸的属性

2)将线宽纳入计算内,比如translate反向偏移掉线宽,这样整体缩放就不会受到线宽的影响了。

另外一个比较烦的就是居中,其实居中基本上就只用到了下面两种方式,还是蛮简单的。只是,这个反复的copypaste,烦哪!

1. 绝对定位+margin:auto。

position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;

实现原理:利用css定位规则,设置左右、上下方向定位为0,margin为auto,让css根据定位计算margin值,用hack的方式实现居中。居中块的尺寸需要可控,因为css计算margin时也需要参考尺寸值,由于四周为0,所以自动计算得到的盒子尺寸(含margin)是与父容器一样的。无论是设置居中块的width、height或者是max-height、max-width,都是让尺寸不会扩大到与父级一样。

局限:在参考系父级(position!=static)大小比本身要小的时候,水平方向的居中就会失效。(垂直方向依然居中)

2. 绝对定位 + transform反向偏移。

position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
margin: auto; 

实现原理:先绝对定位相对父级偏移50%,然后使用transform来反向偏移。由于transform的计算基准是元素本身,所以这里可以用50%来做反向偏移。

局限:这个方案需要固定居中块的尺寸值(不能设置max-width等范围限制),浏览器需要以此为基准来计算定位!

综合来说,方案2的居中方式明显会比方案1要好,但是在绘制图标的时候会用到transform来做一些偏移,为了不覆盖偏移效果所以要用到方案的方式来做居中。除了这两种居中方式,还有inline-block对齐after/before子元素的方式,还有table和flexbox的方式来实现居中,但是画图标本身层级有限而且也用到了before/after,所以不适用图标绘制。

最后一点

目前纯CSS的图标还是挺多应用场景的,这种图标的方案免去了做雪碧图和维护雪碧图的麻烦,而且减少了图片资源的请求,从性能上来说会有那么0.01s的提高吧。不用堆雪碧图还方便调整颜色,性能还有0.01s的优化,这套CSS图标你还不赶紧用起来?!

PS:各位看官觉得不错的话,还请顺手给个github星星哈。多攥几颗星星,说不定就升职加薪赢取白富美了呢~~~

PPS:再附上几个神级的CSS效果吧(by Fabrizio Bianchi  来源: http://codepen.io/fbrz/pen/iqtlk):

 
 

一个标签的72变,打造一个纯CSS图标库的更多相关文章

  1. 手把手教你打造一个纯CSS图标库

    来,干了这碗安利 写这篇文章的目的其实就是为了安利一下我的图标库:iconoo,所以,开门见山,star吧少年少妇们!(这样的我是不是应该要加个github互粉的团伙了?) 主题说完了,下面进入正题. ...

  2. 实现一个成熟的底层毛玻璃效果(纯CSS)

    写在前面 毛玻璃背景是一个很常见的网页样式,想要实现,其实并不难,但经过我在网上的搜索发现,大量实现方法都较为不规范,且把问题复杂化了(例如各种z-index属性和position的定位)现提供一个代 ...

  3. 一步步打造自己的纯CSS单标签图标库

    图标作为网页设计中的一部分,其在凸显网页重要元素特性,视觉交互.引导以及网页装饰等充当的角色作用举足轻重.由于图标普遍具有尺寸小的特点,在项目实践时不宜将每个图标作为单个图片元素进行加载,这会增加Ht ...

  4. jquery判断一个标签是否包含另外一个标签

    jquery判断一个标签是否包含另外一个标签 一.总结 一句话总结: jquery的find方法配合length属性:if($("#video_md_9_1").find(&quo ...

  5. 纯CSS实现一个微信logo,需要几个标签?

    博客已迁移至http://lwzhang.github.io. 纯CSS实现一个微信logo并不难,难的是怎样用最少的html标签实现.我一直在想怎样用一个标签就能实现,最后还是没想出来,就只好用两个 ...

  6. Python分布式爬虫打造搜索引擎完整版-基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站

    Python分布式爬虫打造搜索引擎 基于Scrapy.Redis.elasticsearch和django打造一个完整的搜索引擎网站 https://github.com/mtianyan/Artic ...

  7. [.NET] 一步步打造一个简单的 MVC 电商网站 - BooksStore(一) (转)

    http://www.cnblogs.com/liqingwen/p/6640861.html 一步步打造一个简单的 MVC 电商网站 - BooksStore(一) 本系列的 GitHub地址:ht ...

  8. 大神写的一个纯CSS圆角框,膜拜!(支持IE9一下的低版本)

    留着提醒自己,底层才是最重要的,不要一直傻瓜的编程下去! <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...

  9. RethinkDB创始人教你如何打造一个伟大的互联网产品

    关于作者 我叫Slava Akhmechet,本人是 RethinkDB 的创始人之一,RethinkDB是开源,分布式数据库,旨在帮助开发人员与运营商在打造实时应用时处理无结构数据 如何打造一个伟大 ...

随机推荐

  1. boosting、adaboost

    1.boosting Boosting方法是一种用来提高弱分类算法准确度的方法,这种方法通过构造一个预测函数系列,然后以一定的方式将他们组合成一个预测函数.他是一种框架算法,主要是通过对样本集的操作获 ...

  2. ArcGIS 10.0紧凑型切片读写方法

    首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...

  3. Windows server 2012 添加中文语言包(英文转为中文)(离线)

    Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...

  4. js实现前端分页页码管理

    用JS实现前端分页页码管理,可以很美观的区分页码显示(这也是参考大多数网站的分页页码展示),能够有很好的用户体验,这也是有业务需要就写了一下,还是新手,经验不足,欢迎指出批评! 首先先看效果图: 这是 ...

  5. nginx+php的使用

    原文来自:windows下配置nginx+php环境 按照他的步骤走,亲测可用! 但是这里他后面说的根目录可能有些人有点懵. 其实在设置的时候就设置了: 网站根目录就是www这个目录,如果没创建请自行 ...

  6. Python-Jenkins API使用 —— 在后端代码中操控Jenkins

    最近在工作中需要用到在后台代码中触发Jenkins任务的构建,于是想到Jenkins是否有一些已经封装好的API类库提供,用于处理跟Jenkins相关的操作.下面就简单介绍下我的发现. Linux C ...

  7. win8.1硬盘安装ubuntu14.04双系统

    在网上找了很多方法都失败了,原因是大多数方法都是用mbr方式安装的,如grub4dos,easybcd.以至于连自己都怀疑win8能不能用硬盘安装,差点就去买个u盘来安装了,就在打算放弃的时候在ubu ...

  8. ASP.NET加密和解密数据库连接字符串

    大家知道,在应用程序中进行数据库操作需要连接字符串,而如果没有连接字符串,我们就无法在应用程序中完成检索数据,创建数据等一系列的数据库操作.当有人想要获取你程序中的数据库信息,他首先看到的可能会是We ...

  9. C#——传值参数(2)

    //我的C#是跟着猛哥(刘铁猛)(算是我的正式老师)<C#语言入门详解>学习的,微信上猛哥也给我讲解了一些不懂得地方,对于我来说简直是一笔巨额财富,难得良师! 这次与大家共同学习C#中的 ...

  10. python10作业思路及源码:类Fabric主机管理程序开发(仅供参考)

    类Fabric主机管理程序开发 一,作业要求 1, 运行程序列出主机组或者主机列表(已完成) 2,选择指定主机或主机组(已完成) 3,选择主机或主机组传送文件(上传/下载)(已完成) 4,充分使用多线 ...