首先介绍一下,我觉得前端开发都是很具有分享精神的,很多人都写出了很多优秀的总结经验供新手们参考,本人只是个搬运工,将别人优秀的文章进行了总结,本文主要转载自 大漠 的文章 http://www.w3cplus.com/css3/introducing-css-clip-path-property.html
在Web网页中主要是以矩形分布的。而平面媒体则倾向于更多不同的形状。造成这种差异的原因是因为缺少合适的工具去实现我们平面媒体中的内容。这也就造成了很多设计师的创意发挥,就算是有创意,前端实现也将付出巨大的开发成本。
虽然CSS Shapes Module Level 1(CSS形状模块标准1)的规范出现,可以打破矩形设计的限制。但仍需要一些不规则的图形。而早前实现一些不规则的图形,都需借助其它的元素功能,比如CSS绘制图形,很多时候就依赖于伪元素,或多个元素。如此一来,CSS Shapes依旧无法发挥其强大的功能,让我们的Web打破常规的矩形布局。不过值得庆幸的是,CSS的clip-path出现,它可以帮助我们绘制很多特殊的图形(不规则的图形),地址是 http://bennettfeely.com/clippy/ 比如:
那么这篇文章,我们就一起来了解这个属性。
学习这个属性之前我们先了解一下兼容性
浏览器兼容性
看到这里,大家肯定会问,浏览器兼容性如何?
IE 和 Edge 不支持这个属性。Firefox 仅部分支持 clip-path (它只支持 url() 语法)。但是 47 以上的版本,激活 Firefox 的layout.css.clip-path-shapes.enabled选项就可以支持这个属性了。
Chrome、Safari 和 Opera 需要使用 -webkit- 前缀支持此属性。不幸的是,它们还不支持外部的 SVG 形状。更多浏览器支持性信息如下:
基本概念
clip-path从单词"clip path"的直译上来说,表示的就是裁剪路径。既然有裁剪,咱们就来了解这里面的几个简单的概念。
裁剪就是从某样东西剪切一块。比如说,我们在<img>元素上,根据需要,剪切一部分需要留下的区域。而在整个裁剪中,将会碰到两个相关的概念:裁剪路径(Clipping Path)和裁剪区域(Clipping Region)。
裁剪路径是我们用来裁剪元素的路径,它标记了我们需要裁剪的区域。它可以是个简单的形状(比如Web中常见的矩形),也可以是一个复杂的多边形(不规则的多边形)。
裁剪区域是裁剪路径闭合后所包含的全部区域。
这样一来,元素分为两部分,裁剪区域和裁剪区域外。浏览器会裁剪掉裁剪区域以外的区域,不仅是背景及其它类似的内容,也包括border、text-shadow 等。更赞的是,浏览器不会捕获元素裁剪区域以外的 hover、click 等事件。
即使如今一些特定元素不受长方形限制,但实际上元素周围的内容还是会认为元素是原始形状(长方形)的,并按此进行文档流的布局。要想使周围元素根据元素裁剪后的形状进行布局,可以使用 shape-outside属性。有关于shape-outside相关详细的介绍,可以阅读有关于CSS Shapes相关的教程,这里不进行过多阐述。
旧的clip
CSS Masking Module Level 1中也提供了一个clip属性。可以说clip是CSS中出现的第一种裁剪技术。其实了解过clip的同学都知道,它就是通过overflow:hidden将裁剪区域外的元素隐藏掉了。可以说它不是真正的裁剪。
clip属性到目前为止,仅支持rect()函数,就是裁剪出一个矩形(其它形状还无法实现)。
clip: rect(<top>, <right>, <bottom>, <left>);
在CSS2.1中,rect()和<top>和<bottom>指定偏移量是从元素盒子顶部边缘算起;<left>和<right>指定的偏移量是从元素盒子左边边缘算起。
更为无奈的是,clip属性只能在元素设置了position:absolute或者position:fixed起作用。无法在设置position:relative和position:static上工作。
在CSS中,clip 属性是已过时的,也就是说它已经不再建议被使用,因为有一个更新的、规范的版本,各个浏览器也将集中努力使用它。
当然,clip也是有一些优势的:因为clip是运行在浏览器中的,它可能会一直有效。而浏览器对它的支持是非常强大的:几乎是有史以来的每一个浏览器。另外,我也听说过了,它作出的动画效果胜过其它的新方法。
但是比起它的优势,clip有两个更为重要的弱点,这也使得它难以被广泛地使用:
-
clip只对绝对定位的元素有效 -
clip只能用于矩形,即rect()函数
这真的是非常大的限制!所以来让我们接着说接下来更为重要的属性clip-path。
如果你是第一次接触过clip属性,我建议您花点时间阅读一下这篇文章,它能帮助你对clip有一个简单的了解。
clip-path语法
W3C官方规范提供的clip-path语法:
clip-path: <clip-source> | [ <basic-shape> || <geometry-box> ] | none
其默认值是none。另外简单介绍clip-path几个属性值:
-
clip-source: 可以是内、外部的SVG的<clipPath>元素的URL引用 -
basic-shape: 使用一些基本的形状函数创建的一个形状。主要包括circle()、ellipse()、inset()和polygon()。具体的说明可以看CSS Shapes中有关于说明。另外在CSS Shapes 101一文中也有详细介绍。 -
geometry-box: 是可选参数。此参数和basic-shape函数一起使用时,可以为basic-shape的裁剪工作提供参考盒子。如果geometry-box由自身指定,那么它会使用指定盒子形状作为裁剪的路径,包括任何(由border-radius提供的)的角的形状。
开始使用clip-path
在开始使用clip-path绘制图形,或者说裁剪图形之前,有两点需要大家注意:
- 使用
clip-path要从同一个方向绘制,如果顺时针绘制就一律顺时针,逆时针就一律逆时针,因为polygon是一个连续线段,若线段彼此有交集,裁剪区域就会有相减的情况发生,当然如果你特意需要这样的效果除外。 - 如果绘制时采用比例的方式绘制,长宽就必须要先行设定,不然有可能绘制出来的长宽和我们想像的就会有差距,使用像素绘制就不会有这样的现象。
先来看一个使用polygon()函数绘制的示例:
img { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); }
这段代码会将所有的图片裁剪为菱形。但是为什么图片会被裁剪为菱形而不是梯形或平行四边形之类的呢?这主要取决于函数顶点的值。下图将说明一切:
每个点的第一个坐标值决定了它在 x 轴上的位置,第二个坐标值指定了它在 y 轴的位置,所有点是顺时针绘制的。比如菱形最右边的点,它位于 y 轴下方一半处,所以它的 y 坐标是 50%。同时这个点位于 x 轴的最右侧,所以它的 x 坐标是 100%。其它点的坐标同理可得。
最后效果如下所示:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Clip path</title> 6 <style type="text/css"> 7 body { 8 margin: 20px auto; 9 text-align: center; 10 font-family: 'Lato'; 11 max-width: 640px; 12 } 13 14 h1 { 15 margin-bottom: 100px; 16 font-size: 1.8em; 17 } 18 19 div { 20 display: inline-block; 21 margin: 50px 0px; 22 width: 250px; 23 height: 250px; 24 border-radius: 200px; 25 filter: grayscale(0.9); 26 cursor: pointer; 27 } 28 29 div:hover { 30 filter: none; 31 } 32 33 div:hover .text { 34 opacity: 1; 35 } 36 37 .text { 38 position: absolute; 39 background: rgba(200, 0, 0, 0.5); 40 padding: 20px 0; 41 top: 90px; 42 width: 250px; 43 opacity: 0; 44 text-align: center; 45 color: white; 46 font-size: 1.4em; 47 } 48 49 .left .text { 50 background: rgba(0, 0, 200, .5); 51 } 52 53 .right .text { 54 background: rgba(200, 100, 0, 0.5); 55 } 56 57 .bottom .text { 58 background: rgba(0, 200, 0, 0.5); 59 } 60 61 .top { 62 background: url('http://t.imgbox.com/KXaGvTFB.jpg'); 63 clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); 64 background-size: contain; 65 position: relative; 66 left: -125px; 67 top: -130px; 68 } 69 70 .left { 71 background: url('http://t.imgbox.com/LHPFYSYE.jpg'); 72 clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); 73 background-size: contain; 74 position: relative; 75 } 76 77 .right { 78 background: url('http://t.imgbox.com/tlgvPjwn.jpg'); 79 clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); 80 background-size: contain; 81 position: relative; 82 top: -352px; 83 left: 256px; 84 } 85 86 .bottom { 87 background: url('http://t.imgbox.com/R7h6VtZr.jpg'); 88 clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); 89 background-size: contain; 90 position: relative; 91 top: -220px; 92 left: -126px; 93 } 94 </style> 95 </head> 96 <body> 97 <h1>Images clipped with <code>clip-path</code> Property</h1> 98 <div class="left"><p class="text">SPORTS</p></div> 99 <div class="top"><p class="text">TECHNOLOGY</p></div> 100 <div class="right"><p class="text">FOOD</p></div> 101 <div class="bottom"><p class="text">NATURE</p></div> 102 </body> 103 </html>