咱們在平時的網頁中,常常會見到這樣的優惠券或者其餘的券(特徵就是會有反方向的圓角)。html
可能大部分前端人員爲了簡單,直接採用圖片的方式,直接把整張圖做爲背景。其實這也沒什麼很差的,簡單,方便,尚未兼容性問題,ie6跑起來都沒得問題。前端
若是不考慮那些低舊瀏覽器的話,仍是有辦法直接用css來實現,有幾個好處css3
1.擴展方便,好比以前是300 100的,如今要改爲300 150的,就一行代碼的事
2.沒有圖片,加載起來也更快了,也節省了帶寬程序員
咱們先實現大體的框架,左右兩部分瀏覽器
<style> html,body{ box-sizing:border-box; margin:0; padding:20px; height:100%; background:#fadaa7; } .coupon{ display:inline-block; overflow:hidden; border-radius:10px; } .coupon-left{ float:left; width:150px; height:150px; background:#252525; } .coupon-con{ float:left; width:350px; height:150px; background:#fff; } </style> <div class="coupon"> <div class="coupon-left"></div> <div class="coupon-con"></div> </div>
下面就來實現中間看着比較複雜的"凹槽"部分框架
我能想到跟圓角相關的有圓角、圓形、徑向...這些吧svg
有人說svg
也能夠,確實svg
什麼均可以作,不光是這種形狀,只要畫個路徑,填充一下就完事,這個比較通用,並非這個特例,因此在這裏不討論用這個方式。
還有一個緣由,svg
生成的形狀也是固定了的,只能等比縮放,不能作其餘自適應了。wordpress
看到這樣的形狀,通常人可能會想會不會能夠用border-radius
的負值呢,畢竟像margin
那些,使用負值每每能夠帶來意想不到的效果spa
.con{ border-radius:-10px; }
很惋惜,這種寫法根本就是不合法的,在谷歌瀏覽器上打開控制檯能夠看到直接被刪除了。
雖說這種思路不行,可是咱們能夠換一種思路。
假設咱們如今有一個圓,它自己沒有顏色,可是它有一個黑色的邊框
如今咱們想象一下,假如這個圓的邊框愈來愈大,外面有個容器若是超出就會隱藏,會發生什麼呢
若是這個圓在右下角,那麼就變成了這樣
這不就是咱們須要的嗎?
如今咱們用css來實現
根據上面的分析,咱們背景的顏色應該是圓的邊框的顏色,因此原背景要去掉
.coupon-left{ position:relative; overflow:hidden; /*background:#252525*/ } /*爲了減小html的結構,咱們使用僞元素*/ .coupon-left::before{ position:absolute; width:20px; height:20px; top:-210px; right:-210px; border-radius:50%; border:200px solid #252525;/*邊框只要可以覆蓋整個容器就行*/ }
這樣就實現了一個凹槽。
原本覺得這樣下去,複製一下,改寫一下就完事了的,結果發現沒這麼簡單,由於如今形狀是被裁剪出來的,因此咱們不能讓上一個圓角把整個都覆蓋,否則下面的圓角就出不來了,這時咱們要用到clip
裁剪功能
關於clip
這裏簡單介紹一下,咱們通常會用到rect
這個功能,有四個值,分別是上右下左
clip: rect(<top>, <right>, <bottom>, <left>);
這裏咱們改造一下咱們剛纔寫的樣式,添加以下代碼
.coupon-left::before{ clip: rect(0,210px,285px,0); }
這樣就和下半部分隔離開來了,下面作下半部分的凹槽,咱們用::after
,寫法徹底一致,注意一下座標就好了
.coupon-left::after{ content: ''; position: absolute; top: -210px; display: block; right: -210px; width: 20px; height: 20px; border-radius: 50%; border: 200px solid #252525; clip: rect(135px,210px,285px,0); }
這樣就完美的實現了兩個凹槽,右邊的原理一樣,下面是完整的css代碼
html,body{ box-sizing:border-box; margin:0; padding:20px; height:100%; background:#fadaa7; } .coupon{ display:inline-block; overflow:hidden; border-radius:10px; } .coupon-left{ float:left; width:150px; height:150px; position:relative; } .coupon-left::before{ content: ''; position: absolute; top: -210px; display: block; right: -210px; width: 20px; height: 20px; border-radius: 50%; border: 200px solid #252525; clip: rect(0,210px,285px,0); } .coupon-left::after{ content: ''; position: absolute; bottom: -210px; display: block; right: -210px; width: 20px; height: 20px; border-radius: 50%; border: 200px solid #252525; clip: rect(135px,210px,285px,0); } .coupon-con{ float:left; width:350px; height:150px; position:relative; } .coupon-con::before{ content: ''; position: absolute; top: -410px; display: block; left: -410px; width: 20px; height: 20px; border-radius: 50%; border: 400px solid #fff; clip: rect(0,800px,485px,410px); } .coupon-con::after{ content: ''; position: absolute; bottom: -410px; display: block; left: -410px; width: 20px; height: 20px; border-radius: 50%; border: 400px solid #fff; clip: rect(335px,800px,485px,410px); }
下面是codepen演示
https://codepen.io/xboxyan/pe...
還有一個思路就是徑向漸變。
關於徑向漸變的具體使用能夠參考張鑫旭的文章CSS3 radial-gradient徑向漸變語法及輔助理解案例10則
那麼怎樣實現咱們要的效果呢
咱們先看看徑向漸變的語法
radial-gradient([[<shape> || <size>] [at <position>]?,| at <position>,]?<color-stop>[,<color-stop>]+);
徑向漸變由它的中心定義。
用法
{ background:radial-gradient(circle at 50px 50px, yellow, orange 33.33%, red 66.666%, white) }
咱們把漸變的顏色改爲透明到黑色的漸變
{ background:radial-gradient(circle at 50px 50px, transparent, #252525) }
如今把透明的部分給一個距離,灰色的部分也給一個距離,讓他們以前的漸變區域重合,就變成純色了
{ background:radial-gradient(circle at 50px 50px, transparent 20px, #252525 20px) }
如今把這個空心圓移到邊緣
{ background:radial-gradient(circle at right top, transparent 20px, #252525 20px) }
如今就是如何作出兩個凹槽的問題
咱們有兩種方式,一種是和上面的同樣,用兩個僞元素拼接而成,第二種就是直接利用css3的多背景拼接
咱們先說說第二種
{ background:radial-gradient(circle at right top, transparent 20px, #252525 20px, #252525 100px, transparent 100px),radial-gradient(circle at right bottom, transparent 20px, #252525 20px, #252525 100px, transparent 100px) }
咱們能夠繼續拼接,可能能夠實現咱們想要的效果
如今來講說第一種方法
咱們把代碼放入咱們的例子當中
.coupon-left::before{ content: ''; position: absolute; top: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at right top, transparent 10px, #252525 10px, #252525 10px) } .coupon-left::after{ content: ''; position: absolute; bottom: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at right bottom, transparent 10px, #252525 10px, #252525 10px) } .coupon-con::before{ content: ''; position: absolute; top: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at left top, transparent 10px, #252525 10px, #fff 10px) } .coupon-con::after{ content: ''; position: absolute; bottom: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at left bottom, transparent 10px, #252525 10px, #fff 10px)
怎麼樣,是否是很方便?裏面都是相對值,意味着有更好的適應性
下面是codepen演示
https://codepen.io/xboxyan/pe...
相比於用圓形來實現,這種徑向漸變動方便擴展,寫起來也容易。
可是並非說圓形的思路不對,若是隻是作一個圓形缺口的話,那種寫法更方便,在思惟上,也更領先一步,更能鍛鍊一我的的空間思考和想象能力,更有設計師角度的意味,這大概是和通常程序員思惟最大的不一樣之處吧徑向漸變一直以來的兼容性問題要比圓角大的多,每種瀏覽器內核的寫法都不盡相同,雖然目前都基本支持標準寫法了,但平時的項目仍是要注意一些。實在是兼容性要求,那隻能用圖片代替了,誰叫客戶第一呢