CSS3图标图形生成技术个人攻略

这篇文章发布于 2014年04月23日,星期三,19:11,归类于 CSS相关。 阅读 128594 次, 今日 1 次 23 条评论

 

一、人生如戏、工作亦如戏,且戏且珍惜

坊间有云:“人生如戏,全靠演技”。意思是:人生坎坎坷坷,曲曲折折,跌宕起伏,不可预知,扑朔迷离,好比是戏一样;如果演技好,可以得到人生中最重要的一张卡片——奥斯卡(下图点击播放,401K)。

人生如戏,全靠演技

“工作如戏”是什么意思呢?此语既非来自茅草间,也非来自坊间,更非来自美利坚。虽然民间可能略闻一二,但意思与这里大不一样——这里意思是:“把工作任务的完成设计成一场精彩绝伦的游戏”。

人生如戏,不尽满意。

你可能会觉得你所做的工作并不是自己最想要的(我想做设计,可是领导让我捣鼓代码),你可能觉得你做的工作没有什么技术含量(我想写JS,但领导总是让我切图重构没有技术含量的页面),然后你觉得工作缺乏激情,工作得不到成长。此时,你可能不知不觉陷入一种称为”loser心态”中。

黑暗中寻找曙光,绝望中寻找希望,枯燥中寻找激情,永不放弃,永远积极,这样的心态会让你克服一个个困难,走得更高更远。

说起来容易,做起来难。如何才能让你觉得“重构”不是一门枯燥的工作呢?

前段时间看到个新闻,一个10岁很会游泳的小男孩被泳池过滤设备吸住了手,工作人员全部死命往外拉(大吸力,显然拉不出来),而没有一个人想到去切断电源,结果未来的游泳之星就这样陨落了!

人总是不自禁关注眼前,而忽略问题解决之根本。工作觉得枯燥了,想到的就是换份工作,多吐槽和抱怨,而不是想办法让原本枯燥的工作变得funny~

想想自己,你有没有如下的古怪或不古怪的行为:

  1. 每次使用不同的方式实现;
  2. 寻找规律,制作工具;
  3. 尝试自己发现的或业界流行的新技术;
  4. 故意去犯错去看看会不会有精彩的事情发生;
  5. 藏个彩蛋自娱自乐;
  6. 故意给自己出难题,去攻克它;
  7. 跟自己的爱好套近乎,动漫 or 游戏?

最现实的例子就是我写文章。每次都是一个调调的技术文章,很枯燥,如何变得funny~

  1. 尽量使用不同主题;
  2. 制作一些传图工具,表情集;
  3. 关注新技术,多些新段子;
  4. 抛出犀利话题引发争论快速成长;
  5. 我会告诉你右侧栏可以收起?
  6. 小tip也能写出大文章;
  7. 本文走“游戏”主题~

所以,如果有哪位盆友觉得整天切图无聊,没有技术含量,那是你自己没有让切图变得有趣,变得充满挑战。

拿我自己当板栗,鄙人不才,重构页面多年,经手的图标可估计以绕地球2圈了。而我现在的工作内容基本上还是如此,如果处理图标是枯燥,拿我岂不是要枯成荒草!然而,我现在依旧水灵灵帅锅锅一枚啊!//zxx: 我仿佛听到了我老婆在家里吐的声音

最近一个项目,有很多图标需要处理,最简单最省心的方式就是搞个格栅背景,蜂窝结构,把设计图上的图标一个一个放进去。CSS定个位,任务完成,跟设计图效果一样,保证没人会提bug. 但是,大家不觉得这样很不funny吗?

2年前我觉得不够funny的时候,基本上是国内非常早在实际项目中使用font-face自定义字体图标的。我刚查了下,原来不止2年了,11年时候就使用了。

但是,PC小尺寸下的锯齿以及额外的请求以及维护成本,也让我觉得也没那么funny. 目前在PC上更多的是小范围base64格式使用,既没有额外请求,也可以Gzip.
base64 font-face使用

据说阿里巴巴推出的矢量图标库,Iconfont.cn. 其中涵盖了1000多个常用图标,并在持续更新中,提供了如 在线图标搜索、图标分捡下载、在线储存、矢量格式转换、图标库管理 等功能。很类似于我几年前介绍的 IcoMoon, 不过早已多次换代整容不识旧貌了。

现在我又觉得不够funny, 我把眼光投向了CSS3图形生成,即没有严重的锯齿问题,也支持Retina, 也没有额外请求,自身维护也更方便。//zxx: 过两年,我说不定又觉得不够funny, 眼光投向了SVG图形生成。

CSS3图标图形的生成的灵感要追溯到差不多2年前,当时浏览过一个名叫one-div的网站,顾名思意,一层DIV实现各种各样的图标。来,给大家截个图瞅瞅:
one-div与图标生成 张鑫旭-鑫空间-鑫生活

当时扁平之风还未盛行,设计师的图标还是多彩+渐变,one-div的做法还实现不了;如今的设计趋势让font-face以及CSS3图形在web重构史上添加了浓重的一笔。或者可能是font-face以及CSS3图形的发展促使了设计的扁平化盛行。

font-face越发被人关注,使用日趋成熟。但是,CSS3图形想要实际应用,面向广大用户,还是需要一些挑战的,阻碍一定不小,挫折一定不少,犯错也逃脱不了。但是,这就是我想要的。有挑战的不枯燥的工作,充满funny, 有不断犯错的机会,这会让我更快速成长。

So, 如果你觉得切图无聊,到底是切图本身无聊,还是你自己就抱着那点通俗技术做重复工作而觉得无聊呢?机会是自己创造的,这点都不认识的人,还指望别人带你快速成长,指望呆在一个土豪团队,拜托,这跟小妹妹看童话故事没什么差别!

工作如戏
现在,不妨把CSS图标图形生成看做是自己设计的一款精彩游戏。有限资源高保真实现设计师所有图标为游戏通关,每一个技术难度为一个关卡。让我们像玩游戏一样,出色地完成我们的工作吧~~

//zxx: 本文篇幅不小,如果时间不充足,建议mark下下次时间充足时候再看,以免遗漏一些tips.

二、游戏的基本装备与道具

one-div所展示的图形实现只能称之为概念版,个人站点,内部项目可以直接套用。面向实际,则考虑的问题就多了——

  1. 兼容 IE7-IE8不支持CSS3, 如何向下兼容(IE6被砂糖变成玩具了);
  2. 工业化 如何大规模使用,如何规范化,如何传播与普及;
  3. hover态变化 图标有时候是按钮,需要hover态颜色变化,如何方便实现;
  4. 设计匹配 逼真模拟设计师图标,肉眼范围内看不出差异;

看来难度不小,所以,游戏开始的时候,我们需要准备适合的装备和道具。

装备
为了兼容,我们的装备只能是通过旧装备升级。

首先要明确我们游戏中的新旧对象分别指:IE9+/Chrome/FireFox/Opera/Safari和IE7-IE8.

以前,我们使用Sprite背景图片实现一个图标,可能是这样:

<i class="ico-example"></i>
.ico-example { display: inline-block; width: 20px; height: 20px; background: url(example.png) no-repeat 0 -20px; }

IE9+等现代浏览器显然不使用背景图片,因此,需要这么一句CSS:

:root .ico-example { background-image: none; }

配合特定道具,就可以开始我们正确的游戏征程了!

道具
CSS3图形生成的主要道具就是::before::after伪元素,这里的双冒号伪元素IE9+以及其他现代浏览器浏览器认识。IE7/IE8不能识别。//zxx: IE8只认识:before, :after.

因此,伪元素图形对旧方法实现的IE7/IE8浏览器不会产生任何影响。

但是一个标签最多::before::after两个伪元素。如果图标略复杂,两个标签是没法使用简单的方法模拟出来的,于是,我们需要新增一个装备,用来图形生成,同时,这个装备IE7/IE8浏览器不认识。

很简单,使用HTML5自定义标签。

我使用的标签是<z>. 你可以使用<m>, <n>, 或者<ico>等等,只要是IE7/IE8不认识,同时非标准HTML5标签即可(考虑到有些项目会使用html5shiv)。

我之所以使用<z>是因为我觉得比较简单以及霸气!

于是,<z>自身,以及<z>自身的::before::after伪元素,我们总共有5个元素供我们做图形生成,绰绰有余了!

综合一下~~

装备+道具

<i class="ico-example"><z></i>
.ico-example { display: inline-block; width: 20px; height: 20px; background: url(example.png); }
/* 下面均IE9+ */
:root .ico-example { background-image: none; position: relative; }
.ico-example::before {}
.ico-example::after {}
.ico-example > z {}  /* 不一定用得到 */
.ico-example > z::before {}  /* 不一定用得到 */
.ico-example > z::after {}  /* 不一定用得到 */

心得
为了更简单实现hover态颜色变化,尽量使用border实现。why? 后面会解释。

强势插入——Boss全攻略战果展示

对着游戏战果下面的更好讲,于是,此处强势插入战报。

您可以狠狠地对这里放大招:CSS3图标图形生成完全攻略演示demo

从效果上看,浏览器完全兼容(HTML骨架一致)。

例如,IE9浏览器下截图(CSS3生成):
IE9浏览器下CSS3生成小图标截图
IE8浏览器下截图(传统Sprite背景图):
IE8浏览器下传统Sprite图标效果

有个2倍放大按钮,我们点击一下,就看以看出CSS3生成的好处了:

2倍放大IE9浏览器:
2倍放大IE9浏览器CSS3小图标
2倍放大IE8浏览器:
2倍放大IE8 Sprite小图标

看以看到,CSS3生成的小图标在放大的时候,依然犀利哥的模样,但是IE8传统Sprite图标放大时候一副捣糨糊的模样。

Retina视网膜屏幕类似于2倍或其他倍数的放大效果。CSS3生成的图标在这些屏幕上的显示效果会让你爱不释手;传统的Sprite背景图标你需要准备2套尺寸,以后再来个设备像素比为3的屏幕,某非还要维护3套?!

我们还要认清一个事实,目前,凡是出现的Retina视网膜屏幕都不可能使用IE8浏览器。哦,原来你的mac装了win xp系统,抱歉,我纠正下,除了一些极品情况,我们可以放心使用这里的Sprite+CSS3兼容策略,绝不会玷污你的Retina屏幕的。

三、攻克点线关卡

有些小boss图标关卡是有点和线构成的。CSS生成点或者线方法很多,尤其我们这里是面向IE9+. 边框、背景色、盒阴影。正如我上面建议的,尽量使用border实现。一个元素可以准确控制两个平行对称的点或者线。

于是,下面这个图标,我们需要4个标签搞定(同色的为一个标签实现)。
同色的为一个标签实现

例如,左边的两个绿色点:

{ width: 2px; height: 8px; border-top: 2px solid #777; border-bottom: 2px solid #777; }

CSS2.1时代就兼容的生成小tip, 都懂的,就不再刷油漆了。

//zxx: 4标签生成建议使用后面四个选择器,便于定位。.example::before, .example::after, .example z::before, .example z::after.

四、攻克矩形关卡

有些小boss图标关卡是多条线合体的矩形。第一反应肯定就是border实现。

于是,下面这个图标,我们需要3层标签实现:
3元素矩形模拟示意

例如,左上的绿色折线:

{ width: 5px; height: 10px; border-top: 1px solid #777; border-left: 1px solid #777; }

//zxx: 3标签 建议使用后面3个选择器,便于定位。.example::before, .example::after, .example z.

五、攻克圆形关卡

有些小boss图标关卡是矩形整容的圆形。跟矩形相比,无非就是多了个border-radius.

于是,下面这个图标,我们需要2层标签实现:
圆形与CSS3生成

圆圈圈实现:

width: 14px; height: 14px; border: 1px solid #777; border-radius: 14px;

里面的感叹号使用border真正好:

width: 2px; height: 1px; border-top: 2px solid #878787; border-bottom: 5px solid #878787;

//zxx: 2标签 可以将z标签除去。直接.example::before, .example::after控制。

六、攻克三角关卡

border生成满色三角可参见我10年文章:“CSS border三角、圆角图形生成技术简介”。

本文攻略demo的那个三角是我自己P的,实际设计师设计的图标是三角折线(这个实现有难度,需要1像素折线拉伸),为了演示,所以这里为色块三角,所以风格略不入

于是,下面这个图标,我们需要4层标签实现:
三角与CSS模拟生成 张鑫旭-鑫空间-鑫生活

其实完全实现上面效果,完全线模拟是最好的。但是,我们是演示,演示,那句话怎么说来着。。。认真你就输了~~

例如,绿色三角实现:

{ width: 1px; height: 0; border: 3px solid; border-bottom-color: transparent!important;  border-left-color: transparent!important; border-right-color: transparent!important; border-top-color: #777; }

//zxx:上面的!important是为了可以通用hover变化CSS. 1像素的宽度是为了棒棒正好查到两腿的正中间。

七、攻克旋转关卡

越往后,boss越强。之前的boss都是傻不拉几方方正正规规矩矩的,例如会出现斜线,我们需要新技能,例如,旋转:

CSS3图标生成之旋转

跟我一起念:“巴拉巴拉小魔仙,转转转……”

.ico-share::before, .ico-share::after { border-top: 1px solid #6d6d6d; width: 7px; }
.ico-share::before { -webkit-transform: rotate(30deg); -ms-transform: rotate(30deg); transform: rotate(30deg); }
.ico-share::after { -webkit-transform: rotate(-30deg); -ms-transform: rotate(-30deg); transform: rotate(-30deg); }

于是,魔法生效,boss被攻略,上面绿色斜线效果实现,捡钱捡装备。

//zxx: transform变换中的-ms-前缀不能省,否则IE9浏览器它不认识。

八、攻克拉伸关卡

boss原来越强,越来越变态,怎么办?例如,梯形线,或者非对称折线。马上,奥特曼附体,新技能走起,例如,拉伸:

拉伸与CSS3图标生成

上面图标2标签实现,但是,下面的小尾巴是实现的难点。我们可以直角折线(矩形两邻边)skew拉伸一下下:

width: 3px; height: 3px; border-right: 1px solid #777; border-bottom: 1px solid #777; border-bottom-right-radius: 1px; border-bottom-right-radius: 1px; -webkit-transform: skewY(45deg); -ms-transform: skewY(45deg); transform: skewY(45deg);

//zxx: 1像素的border-radius可以去除部分浏览器下border交叉残留的杂点。

九、攻克弧线关卡

这个boss好生厉害,弧线,与“狐仙”谐音,莫非是狐仙女友所幻化,怪不得如此了得。

狐仙 弧线 CSS3图标生成

怎么破?

此时必须要开挂了!猪脚光环起~~潜力暴走,之前的border-radius技能瞬间照亮整个宇宙。

border-radius不仅仅生成圆和椭圆那么简单,还可以生成标准弧线。下面修正图(原图有错误)来自Vivien的border-radius不仅仅是圆角一文。

border-radius 圆角示意图 修正版

显然,设定不同的纵横圆角大小,就能实现我们想要的弧线效果:

width: 5px; height: 10px; border-top: 1px solid #6d6d6d; border-left: 1px solid #6d6d6d; border-top-left-radius: 5px 10px; border-bottom-left-radius: 5px 0;

如果一时间脑子没扭过来,可以自己再慢慢体味下~~非本文重点,不展开

十、无敌大招

如果遇到终极开挂,系统bug级的大boss, 前面的任何技能、大招、哪怕是挂上加挂都不管用,可以试试这个自损八百的大招——box-shadow终极生成。

继续下文之前请先参阅“CSS3 box-shadow盒阴影图形生成技术”一文,提供了一个box-shadow生成工具。简言之,box-shadow可以1个标签生成任意图形,小小图标boss更是不在话下。

CSS3图形生成与box-shadow盒阴影

这里也可以使用4标签border生成,演示需要,这里box-shadow实现,大家不要太认真。

我们可以把上图所有的灰色看成是绿色小矩形的投影,于是,如下技能攻略boss:

height: 2px; width: 0; border-left: 1px solid #777; box-shadow: 1px -1px #777, 2px -2px #777, 3px -3px #777, -1px -1px #777, -2px -2px #777, -3px -3px #777;

十一、结语与其他补充

其他transform技能
有时候,设计师设计的线条不是很干净的1像素或2像素,此时,单纯1像素模拟就显细,2像素又过粗。试试transform scale 1.5倍。利用浏览器自身的渲染。

以上所有技能几乎没有应付不了的小图标。包括这样子的:垃圾箱图标

所谓图形生成,本质上就是些零件的组装,技能的组合。

background-clip技能
单纯border只能2条平行线。活用background-clip + background-color可以3跳平行线,而且,中间那根可以不等宽,不等间距。

例如:

<div style="height: 1px; width: 20px; padding: 5px; border-top: 1px solid #777; border-bottom: 1px solid #777; background-color: #777; background-clip: content-box;"></div>

效果为:

关于为何推荐border模拟
单纯生成,我们可以大肆使用background以及box-shadow. 但是,实际开发的时候,图标常按钮,还有一个hover态,而且一个站点图标十几二十来个是很正常的。使用backgroundbox-shadow的问题在于,虽然hover上去变化的都是一个颜色,但是不能一段CSS通用。只有border可以解决,因为,没有宽度的border即使赋予的border-color也不会有任何变化.

demo通用hover CSS代码如下:
border生成的原因所在

一起加入CSS3图标图形生成的游戏中吧~~

对了,首先,你得有一个靠谱的设计师同事……

补充于2014年10月24日:此处实际上有更好的解决方案,就是使用currentColor关键字,background-color, box-shadow随便用,具体可参见一文“currentColor-CSS3超高校级好用CSS关键字”。

(本篇完)

分享到:


发表评论(目前23 条评论)

  1. 勇敢的南瓜说道:

    从围脖过来的

  2. ray说道:

    简直是丧心病狂的做法!不过实现的方法值得学习

  3. nevermore说道:

    第一个图标一个元素就可以搞定了。
    .sf {
    display: block;
    position: relative;
    width:200px;
    height: 200px;
    border-top:10px solid black;
    border-bottom:10px solid black;
    padding:85px 0;
    box-sizing: border-box;
    background: red;
    background-clip: content-box;
    box-shadow: 0 300px 0 0 black;
    }

    .sf::before {
    content: “”;
    position:absolute;
    width:10px;
    height: 10px;
    top:85px;
    right:-30px;
    background: red;
    box-shadow: 0 -95px 0 0 black,
    0 95px 0 0 black;
    }

  4. kiwi说道:

    奥斯卡你妹啊,被雷到了

  5. Coco说道:

    这个太屌。
    学习。

  6. mimull说道:

    国内全面普及css3的那一天我们是不是都老了

  7. vicunart说道:

    呵呵,看你得文章写得挺风趣的~

  8. guest说道:

    挺能折腾的,为什么不用svg呢?

  9. shaun说道:

    请教各位前辈,iconfont这个东西通常是使用网上提供好的icon模板。如果想自己制作一些icon的话,怎么办?我了解到的先做成svg然后再转换成字体文件。但是我不知道具体怎么做。各位前辈有没有这方面的资料可以分享? =D

  10. bjhhh说道:

    那个视网膜屏幕什么的,让用svg图标么?
    矢量图标不怕拉抻
    用Illustrator,建个文件:20px X 20px,画个圆。用Illustrator输出2.svg
    网页:

  11. 灯盏细辛说道:

    真牛逼!真折腾!!!佩服!!

  12. 口口一凡说道:

    看你的文章总让人很兴奋;但是兴奋之余也会有些担心~首先说下,我是个手机页面的,android手机的各种奇葩机型总能出现各种奇葩的bug;
    这个时候即想自己生成图标,可又不能忽略测试的提出的BUG,很是头疼啊~怎么办?
    比如某些机型上,border-radius画出的圆角会有锯齿怎么办?

  13. TQ说道:

    这么膜拜~
    好励志

  14. John说道:

    牛逼啊,张大

  15. exolution说道:

    border 三角形 在火狐下(mac) 锯齿十分明显。简直是狗牙=。= ie效果都比他好

  16. 大圆说道:

    这么做确实是有很多好处,我之前也看到外国友人贴出自己的图标集,只是这个图标的制作非常考验css功力,然后就是制作一套图标会比较费时间,不过一旦完成后肯定会超级酷炫!不知道会不会成为未来的潮流?
    打boss那个环节很有意思哈!能够把无趣的拼凑说得像玩游戏一样,鑫神果然不同凡响~

  17. tcdona说道:

    cool !!!

  18. Bob说道:

    怪不得前几天在研究弧线。
    box-shadow那个太凶残了。
    分享的图标右下角的圆圈位置有点小问题。

  19. wilee说道:

    鑫神这是把CSS用到极致的节奏啊