CSS的clip-path 一


     首先介紹一下,我覺得前端開發都是很具有分享精神的,很多人都寫出了很多優秀的總結經驗供新手們參考,本人只是個搬運工,將別人優秀的文章進行了總結,本文主要轉載自  大漠  的文章  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中常見的矩形),也可以是一個復雜的多邊形(不規則的多邊形)。

裁剪區域是裁剪路徑閉合后所包含的全部區域。

 

這樣一來,元素分為兩部分,裁剪區域和裁剪區域外。瀏覽器會裁剪掉裁剪區域以外的區域,不僅是背景及其它類似的內容,也包括bordertext-shadow 等。更贊的是,瀏覽器不會捕獲元素裁剪區域以外的 hoverclick 等事件。

 即使如今一些特定元素不受長方形限制,但實際上元素周圍的內容還是會認為元素是原始形狀(長方形)的,並按此進行文檔流的布局。要想使周圍元素根據元素裁剪后的形狀進行布局,可以使用 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:relativeposition: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>
View Code

效果圖如下:

 

 

記得以前CSS繪制圖形總得束手束腳,而且還得想法設法,使用clip-path繪制什么六邊形、八邊形、五角形、心形等,都不再是難事了。OXXO.STUDIO有一篇文章《運用 clip-path 的純 CSS 形狀變換》詳細介紹了這些圖形是如何繪制的。當然除此之外,在線的CSS clip-path maker提供了很多不規則的圖形案例:

利用 geometry-box 裁剪元素

在具體使用geometry-box來裁剪元素之前,對geometry-box做一下相關的了解。

geometry-box可以是shape-boxfillstroke或者view-box。其中shape-box應用於HTML元素,它具有四種值:margin-boxborder-boxpadding-boxcontent-box

shape-box

來看個簡單的示例:

 

.clip-me {
    clip-path: polygon(10% 20%, 20% 30%, 50% 80%) margin-box;
    margin: 10%;
}
View Code

在上例中,元素的 margin-box 會作為參考,來決定裁剪點的實際位置。點(10%,10%)是 margin-box 的左上角,所以clip-path 的定位會根據此點進行計算。

其實shape-box和CSS Shapes中的引用框概念非常類似,有關於這方面的介紹,可以花點時間閱讀《理解CSS Shapes的引用框》一文。

如果geometry-boxbasic-shape一起使用,可以引用basic-shape提供的引用框。其作用和shape-outside屬性類似,更多的細節可以看看shape-outside屬性介紹

如果geometry-box由自身指定,那么它會使用指定盒子形狀作為裁剪的路徑,包括任何(由border-radius提供的)的角的形狀。

除了shape-box值,還可以運用SVG元素上,它具有另外三個值:fillstrokeview-box

clipPath 和clip-path

在SVG中有一個clipPath元素。<clipPath>元素不會直接在頁面上呈現,他唯一的作用就是可以通過clip-path來引用。它和CSS的clip-path還是有很大的區別。有關於兩者的詳細介紹可以閱讀《CSS和SVG中的剪切:clip-path屬性和<clipPath>元素》一文。

而很多時候兩者可以結合一起使用。

你不需要在CSS中定義clip-path的值,因為它能夠引用SVG中定義的 <clipPath>標簽元素。下面是它的使用示例:

HTML

 1 <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/Harry-Potter-1-.jpg" alt="" class="clip-svg">
 2 
 3 <svg width="0" height="0">
 4   <defs>
 5     <clipPath id="myClip">
 6       <circle cx="100" cy="100" r="40"/>
 7       <circle cx="60" cy="60" r="40"/>
 8     </clipPath>
 9   </defs>
10 </svg>
View Code

CSS

.clip-svg {
    clip-path: url(#myClip);
}
View Code

效果如下圖

clip-path和masking

剪裁和遮罩都是用來隱藏元素的一些部分、顯示其他部分的。當然了,這兩者還是有區別的。區別主要在於這幾方面:他們能做的東西,不同的語法,涉及到的不同技術,是新的還是舊的,以及瀏覽器支持的差異。

兩者最主要的區別:遮罩使用的是圖像,剪裁使用的是路徑

想象一張從左到右、從黑到白漸變的正方形圖像,它可以是一個遮罩。對於應用了這個漸變遮罩圖像的元素,它在遮罩圖像的黑色部分是透明(透視)的,而在遮罩圖像的白色的部分是不透明(正常)的。所以作出的結論是:這個元素是從左到右淡入的。

而剪裁一直都是矢量路徑的。路徑之外的部分是透明的,路徑里邊的部分是不透明的。

個人覺得有點混亂。因為很多時候可能會碰到某個關於遮罩的教程用的是一個在黑色上有白色矢量形狀的遮罩圖像,這和剪裁基本是同一個原理。但這還好,它只是混淆了一點東西。

有關於兩者相關的詳細介紹可以點擊這里閱讀

clip-path和CSS Shapes

前面已經多次提到CSS Shapes了,是的,因為CSS Shapes可以幫助我們打破常規則的Web排版,讓Web頁面可以像媒體雜志一樣布局,這將是激動人心的一件事情。

而在CSS Shapes中同樣會有clip-path的身影。

clip-path接收與basic-shape相同的形狀函數和值(前面提到過)。如果我們定義相同的多邊形形狀,同時用於shape-outsideclip-path屬性上,它將裁掉圖像上你定義的形狀之外的圖像。

 

1 img.right {
2     float: right;
3     height: 100vh;
4     width: calc(100vh + 100vh/4);
5     shape-outside: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
6     /* clip the image to the defined shape */
7     clip-path: polygon(40% 0, 100% 0, 100% 100%, 40% 100%, 45% 60%, 45% 40%);
8 }
View Code

結果如下:

下面有個示例

HTML

 1 <div class="container">
 2   <div class="element">
 3   </div>
 4   <h1>Cupcakes Recipe</h1>
 5   <p>
 6     Cupcake ipsum dolor sit. Amet sweet roll sweet roll cheesecake sweet roll apple pie ice cream. Toffee soufflé danish soufflé I love I love dessert I love. Lollipop carrot cake marshmallow I love caramels. Chocolate cotton candy unerdwear.com dessert gingerbread gummies I love. Bonbon chupa chups biscuit danish apple pie. Bonbon muffin dessert wafer chocolate cake sesame snaps candy canes marzipan.
 7   </p>
 8   <h3>Ingredients</h3>
 9   <ul>
10     <li>1/2 Lorem Ipsum</li>
11     <li>5g Sugar Ipsum</li>
12     <li>2 eggs</li>
13   </ul>
14   <p>
15     Dessert oat cake candy lollipop topping cotton candy jelly beans I love cake. Brownie sugar plum cotton candy wafer dragée pudding I love. I love I love chocolate. Topping danish carrot cake soufflé liquorice icing gummi bears liquorice dessert. Jujubes oat cake tootsie roll tart. 
16   </p>
17   <p>
18     Cookie lollipop cookie gingerbread danish muffin sweet chupa chups. Gingerbread donut muffin biscuit sesame snaps chocolate cake sweet. Sugar plum lemon drops pastry tiramisu chocolate gingerbread. I love pudding biscuit soufflé wafer biscuit.
19   </p>
20   <div class="clear"></div>
21 </div>
View Code

CSS

 1 * {
 2   margin: 0;
 3   padding: 0;
 4   box-sizing: border-box;
 5 }
 6 
 7 body {
 8   color: #555;
 9   font-size: 0.95em;
10   background-color: #eee;
11   font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
12 }
13 
14 .container {
15   width: 100%;
16   max-width: 1200px;
17   margin: 20px auto;
18   background-color: white;
19 }
20 
21 .element {
22   width: 40%;
23   height: 600px;
24   float: left;
25   background-image: url(http://tympanus.net/codrops-playground/assets/images/cssref/properties/clip-path/cupcakes.jpg);
26   background-size: cover;
27   background-position: -100px 0;
28   background-repeat: no-repeat;
29   -webkit-clip-path: ellipse(90% 70% at 0% 50%);
30   clip-path: ellipse(90% 70% at 0% 50%);
31   -webkit-shape-outside: ellipse(90% 70% at 0% 50%);
32   shape-outside: ellipse(90% 70% at 0% 50%);
33   -webkit-shape-margin: 2em;
34   shape-margin: 2em;
35 }
36 
37 p,
38 h1,
39 h3 {
40   padding: 1em 0;
41 }
42 
43 p {
44   margin-right: 4em;
45 }
46 
47 ul {
48   list-style: circle;
49 }
View Code

 

效果圖如下

 

 

 

clip-path示例和工具

前面內容簡單的提到過了,clip-path是一個強大的屬性,除了自身能實現一些特殊效果之外,還可以和SVG結合在一起。另外還可以和Masking以及CSS Shapes在一起,做出我們意想不到的效果。那么有關於clip-path相關的案例,網上已經有大把了。除此之外,clip-path還有一些在線的工具,可以直接幫助我們做一些事情。比如Chrome插件CSS Shapes 編輯器Clip Path生成器CSS clip-path Maker: Clippy

最后強列建議大家收藏好下面這篇文章,因為這篇文章整理了18個有關於clip-path的教程、案例和工具

 

 

參考資料

總結

本文介紹了有關 clip-path 的基本內容,可以幫助你入門。學習使用這個屬性並不會花費太多的時間,但是創造性的使用就需要多多練習了。當瀏覽器廣泛支持此屬性時,你就可以使用 clip-path制作出酷炫的效果了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM