一般一个网页上面,或多或少都会用到一些小图标,展示这些小图标的方法有很多种。最简单的做法就是将UI图上面的每个小图标都保存为图片,一个小图标就一张图片。但这也是比较笨的方法,因为浏览器同一时间最多加载的资源是有限的,例如IE7是2个,IE8是6个,chrome是6个,火狐是8个。如果网页上面有很多张零碎的小图片,导致请求的次数太多,等待加载状态中的资源会很多,明显影响性能。因此,一个改进的办法是使用sprites图,将多张小图放在一张大图,然后限定展示区域的大小,同时改变图片的显示位置background-position来显示不同的图标,游戏里面经常使用这种技术,大大减少浏览器请求的次数。淘宝网就使用这种技术:

但是要看到这种方法也是有缺点的,即内存和CPU的使用增加,对于移动端低内存和CPU的设备来说,可能会有压力。使用sprites图,网上有很多在线的功具可以生成,同时会生成各个小图标的position位置,例如http://csssprites.com/

  第二种改进的办法是使用base64的编码方式。将原始二进制的图片编码为base64,然后使用css的background: url(data:image/png;base64,%encoding%)的方式,例如百度的首页搜索栏右边的话筒就是用这样的方式:

  将图片进行编码,可以使用在线工具base64 image,进行转换。转换之后,你会发现生成的编码特别长,其字节数甚至比原始的照片大,大约大33%。以上面的话筒为例,原始照片为1.3kb,而base64的编码需要1.7kb。同时,另外一个问题是对base64的解析速度比原始二进制的要慢。更严重的一个问题是,如果使用太多的base64,会使得css文件太大,下载和解析的时间较长,导致页面短时间的空白loading状态,效果可能还不如分开使用一张张图片。它的优点是不需要借用额外的图片文件,详细的分析可以看这篇文章。

  第三种方法是使用CSS的技巧,这种方法一般只适用于比较简单的图案,例如三角形、五角星、爱心等。例如,如果想要画一个向上的三角形可以使用下面的方法:

.tri{width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid red;
}

  它的原理是将一个div的width和height设置成0,那就剩下四个border,四个角都是三角形,令其它三个角不显示,只留下底部那个角,就是一个向上的三角形。要注意设置左右角的宽度,目的是设置三角形上面两条边的长度,再将它们隐藏。更多CSS图形参考css shape。这种方法看似完美,因为无论是空间占用还是解析速度都比前面两个方法好,但是这种方式是不自然的,你无法轻易地改变图形的大小去适应你的页面,如果你不知道它画的原理是怎么样的。第二是无法容易地画出一些较为复杂的图案,例如为了画三个小黄人,花费了2000多行的CSS代码。另外一个缺点是,它是一个空的span或者div,对于屏幕阅读者来说是不可见的。

  第四种方法是使用icon font,将ui图里的icon导出制作成一个字体库,然后跟正常的字体一样使用,具体制作的方法可参考这篇文章。一般来说,icon font是从svg等矢量格式来的,通过PS导出png的方法可能会存在一些问题。boostrap的glyphicon就是使用icon font。使用时,先用@font-face导入字体(font-face的使用见这篇文章),然后利用一个span,设置font-family为刚刚导入的字体,再通过伪类before或after,属性content的值为对应图标的编码。或者是,直接在html文件里直接插入该图标的编码。如下所示:

  使用这种方法的优点是很大程序上减少了图片需要的空间,可以自由改变大小,改变颜色,支持IE6及以上。缺点是只适用于纯色的图标。手机淘宝和百度就使用了这种技术

icon-font的制作方法可参见博主的另外一篇文章:把UI图里小图标制成icon font

  还有一种办法是使用Unicode字符,Unicode也提供了很多的图标和表情,例如打勾,✔ ✓ ☑,使用起来最为简单,可惜的是,不同的字体差别很大,有些字体没有这些符号,甚至是同一个字体在不同的设备上看起来也会有差异,例如✔在安卓机上的形状这是样的(中间的勾),而在ios上是这样的,同样都是使用了微软雅黑字体。

  上面提及的各种方法都存在一个缺点,没有语义性,都是一个空的span和div,对屏幕阅读者不可见。本文介绍一种新的画小图标的方法,使用svg结合css3的新属性clip-path。这种方法的优点是具备语义性,无论在性能还是占用的空间都具有优势。clip就是裁剪的意思,clip-path原本的用处是用来裁剪图片,如:

  上面,指定裁剪的路径为一个椭圆,x轴上的半径为裁剪区域的50%,y轴的半径为裁剪区域的40%,圆心在(50%, 50%)的位置。在这个椭圆形的封闭区域外的所有元素都不会被浏览器渲染出来,使用时要带有-webkit-前缀和标准的两种形式。Clippy这个网站可以在线裁剪,当前最新版本的chrome和safari都支持基本形状的裁剪。除了椭圆外还支持rect(长方形)、cirle(圆形)、inset(带圆角的长方形)、polygon(多边形),具体使用可结合上面的博客和网站进行探索。最后一种形式,是使用html里定义的svg元素作为裁剪的目标,这也正是clip-path的生命力所在。因为svg本身提供了丰富的语义定义,可以制作丰富多彩的矢量图形,更重要的是svg可进行可视化编辑,如AI,inkscape,还有一些在线的编辑器,如svg-editor。关于svg的基本介绍,可参考mdn的教程。

  除了裁图片,利用clip-path的裁剪功能,可以用来制作图标。原理就是用一个div,设置background颜色和width/height值,然后制作一个图标的svg路径,用来裁剪div,就会显示出相应的小图标了。以打勾的图标为例

  首先,制作一个打勾的svg:

<svg width="0" height="0"><defs><clipPath id="tick-mask" clipPathUnits="objectBoundingBox"><path fill="red" stroke="red" stroke-width="1" stroke-miterlimit="10" d="m0.1165671,0.4703638l0.0852069,-0.0852042l0.2337128,0.2335306l0.389592,-0.3894064l0.0852045,0.0852087l-0.4747964,0.4747913z" id="svg_8" clip-rule='evenodd'/></clipPath></defs>
</svg>

  注意这里,不是使用基本形状,而是使用了svg里的path,贝塞尔曲线,也就是PS/AI里面的钢笔工具,在d里面定义路径是如何移动和弯曲的。绘出的形状要放在clipPath标签里,给这个clipPath添加一个id,在下面的CSS里将会使用到,同时设置clipPathUnits为objectBoundingBox,作用是将单位设置成比例[0,1],这样就可以适配出不同大小的形状。clipPathUnits有两个取值,另外一个取值是userSpaceOnUse,是默认值,一般单位为px。

  形状画好了之后,由于要求背景是红色的,勾是白色的,因此先用一个div,设置红色背景和圆角,再用一个白底的span裁出一个勾的形状。如下:

<div class="icon"><span class='tick'></span>
</div>

.icon{width: 100px;height: 100px;background: #ff7443;text-align: center;background: #ff7443;border-radius: 100px;
}.tick{display: inline-block;-webkit-clip-path: url(#tick-mask);clip-path: url(#tick-mask);  /* 在这里对白底的span进行剪切 */width: 90%;height: 90%;background: white;margin-top: 5%;
}

  这样就可以了。这篇文章作者作了一个圆形菜单,还有结合css3的动画,作了一些很有趣的动态效果。

  关于兼容性,IE和edge所有版本不支持clip-path,android的浏览器支持url参数的clip-path,但是UC和微信的内置浏览器不支持,微博的浏览器是支持的,firefox支持带url参数的。chrome支持-webkit-前缀的,包括基本的形状和url,safari/ios支持标准形式的,但是safari/ios在渲染上有bug,只要css文件里出现了clip-path,任何元素只要带position为relative/absolute的都会隐藏掉了,解决办法是,在这些元素里加多一个css属性:-webkit-transform: translateZ(0)加大渲染权重,这样就能显示出来了。还有可能会出现其它无法渲染的情况,例如,同一个id的clip-path只能渲染出第一个,接下来的都消失了,也可以用这种办法解决,但是如果渲染过重,在chrome等其它浏览器会出现显示的问题,会显示错乱。因此这个问题比较麻烦,h5开发的时候需要注意。

  对于无法支持的浏览器,改用其它的办法,得做个区分。可以借鉴modernizr提供的办法,页面加载时,首先创建一个svg和一个div,设置这个div的clip-path CSS属性,然后调用getComputedStyle看是否仍有刚刚设置的属性,如果有说明支持,没有说明不支持。如果支持就给body添加一个has-clip-path的类,不支持就为no-clip-path,然后在需要使用图标的元素的css前面加多一个clip-path的类,有和没有两个。这样就达到了区分的目的,不支持的就使用其它的方式。

<body><svg style="display:none" width="0" height="0"><defs><clipPath id="_svg"><path d="M 0 0 L 0 0"></path></clipPath></defs></svg><div style="-webkit-clip-path:url(#_svg);clip-path:(#_svg);display:none" id="_test"></div><script>var style = document.defaultView.getComputedStyle(document.getElementById("_test"), null);var body = document.getElementsByTagName("body")[0];if(style.WebkitClipPath !== "url(#_svg)" && style.clipPath !== "url(#_svg")body.className = "no-clip-path";elsebody.className = "has-clip-path";</script>   <!--body的其它元素-->
</body>

  本来可以使用svg和clip-path做为h5开发,但是考虑到安卓上的某些国内浏览器不支持,以及safari让人头疼的渲染问题,所以就目前的情况来说应用到生产环境仍不太乐观。所以在PC的web端使用sprites图,在移动的h5端使用icon font并灵活结合其它方法。

  注意到,icon-font和clip-path本质都是一样的,都是使用了svg,只是使用的方式不同。因此在提供icon font图标的网站上,如icomoon和fontello上,可将图标的svg制作字体,也可作为clip-path使用。

参考:

1. CSS vs. SVG: Shapes and Arbitrarily-Shaped UI Components 这篇文章比较了使用CSS和svg画图标的两种方法,强调了使用svg画图的优点。

2. SVG Tutorial,MDN一个关于svg的简明易懂的入门教程。

3. icomoon和fontello,提供icon-font/svg小图标的网站。

4. Clippy在线操作clip-path

转载于:https://www.cnblogs.com/yincheng/p/4869812.html

使用css3新属性clip-path制作小图标相关推荐

  1. 两点补充——CSS3新属性以及弹性布局

    CSS3 新属性 一.[ CSS3新增属性前缀 ] 1.-webkit-:chrome/safari 2.-moz-:火狐 3.-mo-:IE 4.-o-: Opera 欧朋 二 .[CSS 长度单位 ...

  2. 从零开始学前端:css3新属性scss和less --- 今天你学习了吗?(CSS:Day22)

    从零开始学前端:程序猿小白也可以完全掌握!-今天你学习了吗?(CSS) 复习:从零开始学前端:形变 - 今天你学习了吗?(CSS:Day21) 文章目录 从零开始学前端:程序猿小白也可以完全掌握!-今 ...

  3. 前端基础8:HTML5新增标签及CSS3新属性 viewport 动画

    HTML5新增标签 标签名 描述 header 头部 section 区分大模块 nav 导航 footer 尾部 article 文章 aside 侧边栏 audio 音频 video 视频 fig ...

  4. 通过css伪属性给div加小图标

    通过css伪属性给div加小图标 不换行,同时变... .freak{width: 100px;height: 100px;background-color: pink;position: relat ...

  5. matlab绘制布尔运算图,干货丨最全的布尔运算制作小图标教程!

    昨天,一位小伙伴在后台跟小研说到了相交的问题!也有很多人跟小研反应大神们常说的布尔运算在PPT中根本找不到!今天小研就来解决你这方面的所有问题!最全的布尔运算教程!教你制作PPT中精美小图标! 我们经 ...

  6. Dreamwear CS6 , 树莓派Python,PP制作小图标集合 下载链接

    1. 中文版Dreamweaver CS6完全自学教程_PDF_高清带目录:https://pan.baidu.com/s/1SHIxFxhOb3Cggz6fawMSKg 2. Raspberry P ...

  7. “约见”面试官系列之常见面试题第三十七篇之CSS3新属性(建议收藏)

    目录 CSS3 结构(位置)伪类选择器(CSS3) 目标伪类选择器(CSS3) 属性选择器(CSS3) 伪元素选择器(CSS3,重要) CSS3盒模型(重要) 颜色模式 盒子阴影(CSS3) 文本阴影 ...

  8. Css3新属性:calc()

    一.前言 calc()看起来像是javascript中的一个函数,而事实上它是用在Css中的,可以用它来计算长度(宽度或高度),能够自动根据不同尺寸的屏幕自动调接数值,从而很轻松的实现自适应布局展示在 ...

  9. css 一些好玩的属性,推荐一些比较有用的css3新属性

    css3刚推出不久,虽然大多数的css3属性在很多流行的浏览器中不支持,但我个人觉得还是要尽量开始慢慢的去了解并使用css3(还有html5),因为我觉得这是一种趋势,它是一种已经被制定的标准.我并不 ...

最新文章

  1. SAP MM 明明已经扩展供应商到采购组织下,采购订单里还是报错?
  2. 使用LVS+TUN搭建集群实现负载均衡
  3. linux全自动安装光盘,CentOS7全自动安装光盘制做详解
  4. 华为真的注册鸿蒙,“鸿蒙”真的来了!华为注册了整本山海经?
  5. Oceanus:基于Apache Flink的一站式实时计算平台
  6. sas table将缺失值计入百分比_医药SAS编程及应用之爱情草全部发芽啦
  7. Linux第一条指令地址,arm-linux 启动代码分析——stage1 (1)
  8. 【BZOJ 4103】 [Thu Summer Camp 2015]异或运算 可持久化01Trie
  9. 想要酷炫大气的网页设计?这样做超吸睛
  10. startService和onBinderService混合开发音乐播放器
  11. 使用Mongo Shell和Java驱动程序的MongoDB Map Reduce示例
  12. 【Linux】快速入门gdb调试工具
  13. 机器学习十大算法案例
  14. matlab 泊松分布作图,matlab用一组数据画泊松分布图
  15. 电脑C盘满了如何扩充C盘内存?
  16. A bank is a place that will lend you money if you can prove that you don't need it.
  17. openssl下载与安装
  18. 计算机领域nt=p,计算机考试范题-pwerpoint操作.doc
  19. CMS 执行的七个阶段
  20. QingCloud首届用户大会亮点抢先看

热门文章

  1. 简单 Python 快乐之旅之:Python 基础语法之文件操作专题
  2. 计算机主机的物理硬件组成,计算机硬件组成和功能
  3. HTML中设置鼠标悬停状态伪类,四大伪类,css鼠标样式设置,reset操作,静止对文本操作...
  4. mysql未将对象引用设置到对象的实例_记一次未将对象引用设置到对象的实例问题的排查过程...
  5. 猿代码首届团课免单节火热进行中!|猿代码科技
  6. Day9-2021.1.17-剑指offer的八道二叉树题目的整理。涉及递归调用+广度优先遍历。
  7. 网络安全咨询合规-APP合规检测
  8. Linux中的程序和进程的概念,PID和PPID的区别
  9. 窑鸡厂Java大数据岗二面相关面试题
  10. 面向对象分析与设计(OOAD)