CSS 發(fā)展到今天已經(jīng)越來(lái)越強(qiáng)大了。其語(yǔ)法的日新月異,讓很多以前完成不了的事情,現(xiàn)在可以非常輕松的做到。今天就向大家介紹幾個(gè)比較新的強(qiáng)大的 CSS 功能:
shape 的意思是圖形,CSS shapes 也就是 CSS 圖形的意思,也就是使用 CSS 生成各種圖形(圓形、矩形、橢圓、多邊形等幾何圖形)。
CSS3之前,我們能做的只有矩形,四四方方,條條框框。
CSS3出來(lái)后,我們有了更廣闊的施展空間,通過(guò)
border-radius
border
transform
我們能夠作出非常多的幾何圖形。
除去最常見(jiàn)的矩形,圓形(border-radius
),下面稍微列舉一些其他幾何圖形:
通常會(huì)使用透明的border模擬出一個(gè)三角形:
《CSS Secret》里面的方法,采用多重線(xiàn)性漸變實(shí)現(xiàn)切角。
1 2 3 4 5 6 7 8 9 10 11 | .notching { width : 40px ; height : 40px ; padding : 40px ; background : linear-gradient( 135 deg, transparent 15px , yellowgreen 0 ) top left , linear-gradient( -135 deg, transparent 15px , yellowgreen 0 ) top right , linear-gradient( -45 deg, transparent 15px , yellowgreen 0 ) bottom right , linear-gradient( 45 deg, transparent 15px , yellowgreen 0 ) bottom left ; background- size : 50% 50% ; background-repeat : no-repeat ; } |
利用偽元素加旋轉(zhuǎn)透視實(shí)現(xiàn)梯形:
當(dāng)然,還有另一種更簡(jiǎn)單的方法是利用border實(shí)現(xiàn),借助上面的構(gòu)造三角形的方法,在矩形兩側(cè)構(gòu)造兩個(gè)透明的三角形:
梯形加上三角形,很容易就組合成一個(gè)五邊形,這里需要借助一個(gè)偽元素實(shí)現(xiàn):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | .pentagon { position : relative ; width : 60px ; border-bottom : 60px solid yellowgreen; border-left : 40px solid transparent ; border-right : 40px solid transparent ; } .pentagon::before { content : '' ; position : absolute ; top : 60px ; left : -40px ; border-top : 60px solid yellowgreen; border-left : 70px solid transparent ; border-right : 70px solid transparent ; } |
看看上面的梯形,如果兩個(gè)反方向且底邊同樣大小的梯形,疊加在一起,是不是就能得到一個(gè)六邊形呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | .pentagon { position : relative ; width : 60px ; border-bottom : 60px solid yellowgreen; border-left : 40px solid transparent ; border-right : 40px solid transparent ; } .pentagon::before { content : '' ; position : absolute ; width : 60px ; height : 0px ; top : 60px ; left : -40px ; border-top : 60px solid yellowgreen; border-left : 40px solid transparent ; border-right : 40px solid transparent ; } |
六邊形都解決了,八邊形也不在話(huà)下,一個(gè)矩形加上兩個(gè)梯形,可以合成一個(gè)八邊形。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | .octagon { position : relative ; width : 40px ; height : 100px ; background : yellowgreen; } .octagon::before { content : '' ; height : 60px ; position : absolute ; top : 0 ; left : 40px ; border-left : 30px solid yellowgreen; border-top : 20px solid transparent ; border-bottom : 20px solid transparent ; } .octagon::after { content : '' ; height : 60px ; position : absolute ; top : 0 ; left : -30px ; border-right : 30px solid yellowgreen; border-top : 20px solid transparent ; border-bottom : 20px solid transparent ; } |
好的,探索完多邊形,我們繼續(xù)探索X角星。
先來(lái)看看五角星,要怎么實(shí)現(xiàn)呢?當(dāng)然是直接打出來(lái)啦 -- ★☆
開(kāi)個(gè)玩笑,這里使用 3 個(gè)三角形疊加旋轉(zhuǎn)在一起實(shí)現(xiàn)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | .star { margin : 50px 0 ; position : relative ; width : 0 ; border-right : 100px solid transparent ; border-bottom : 70px solid yellowgreen; border-left : 100px solid transparent ; transform: rotate( 35 deg) scale(. 6 ); } .star:before { content : '' ; position : absolute ; border-bottom : 80px solid yellowgreen; border-left : 30px solid transparent ; border-right : 30px solid transparent ; top : -45px ; left : -65px ; transform: rotate( -35 deg); } .star:after { content : '' ; position : absolute ; top : 3px ; left : -105px ; border-right : 100px solid transparent ; border-bottom : 70px solid yellowgreen; border-left : 100px solid transparent ; transform: rotate( -70 deg); } |
六角星呢?想象一下,一個(gè)向上的三角形 ▲,疊加上一個(gè)向下的三角形 ▼,就可以得到一個(gè)六邊形:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | .sixstar { position : relative ; width : 0 ; border-left : 50px solid transparent ; border-right : 50px solid transparent ; border-bottom : 100px solid yellowgreen; } .sixstar:after { content : '' ; position : absolute ; border-left : 50px solid transparent ; border-right : 50px solid transparent ; border-top : 100px solid yellowgreen; top : 30px ; left : -50px ; } |
八角星呢?八個(gè)角那么多呢。其實(shí)使用兩個(gè)矩形進(jìn)行旋轉(zhuǎn)拼接就可以了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | .eightstar { position : relative ; width : 100px ; height : 100px ; background-color : yellowgreen; transform: rotate( 30 deg); } .eightstar::before { content : '' ; position : absolute ; top : 0 ; left : 0 ; width : 100px ; height : 100px ; transform: rotate( 45 deg); background-color : yellowgreen; } |
好。最后多角星再來(lái)一個(gè)十二級(jí)角星。在八角星的基礎(chǔ)上,再增加一個(gè)矩形,就能得到十二角啦。也就是要過(guò)第一個(gè)偽元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | .twelvestar { position : relative ; width : 100px ; height : 100px ; margin-bottom : 100px !important ; background-color : yellowgreen; transform: rotate( 30 deg); } .twelvestar::before { content : '' ; position : absolute ; top : 0 ; left : 0 ; width : 100px ; height : 100px ; transform: rotate( 30 deg); background-color : yellowgreen; } .twelvestar::after { content : '' ; position : absolute ; top : 0 ; left : 0 ; width : 100px ; height : 100px ; transform: rotate( 60 deg); background-color : yellowgreen; } |
最后,再來(lái)使用傳統(tǒng)的方法畫(huà)一個(gè)橢圓,過(guò)去 CSS3 畫(huà)橢圓,基本上只能借助 border 實(shí)現(xiàn)。
這里使用 border 畫(huà)一個(gè)蛋的形狀:
CodePen -- CSS Shapes(CSS 幾何圖形)
如果你看到了這里,恭喜你,本文的正文從這里開(kāi)始。
上面所講述的是使用傳統(tǒng) CSS3 的方式繪制幾何圖形,接下來(lái)我們將要了解一些更高級(jí)的繪制幾何圖形的方法。
CSS 新屬性 clip-path
,意味裁剪路徑的意思,讓我們可以很便捷的生成各種幾何圖形。
clip-path 通過(guò)定義特殊的路徑,實(shí)現(xiàn)我們想要的圖形。而這個(gè)路徑,正是 SVG 中的 path 。
看看它的 API:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | { /* Keyword values */ clip-path: none ; /* Image values */ clip-path: url (resources.svg#c 1 ); /* Box values clip-path: fill-box; clip-path: stroke-box; clip-path: view-box; clip-path: margin-box clip-path: border-box clip-path: padding-box clip-path: content-box /* Geometry values */ clip-path: inset ( 100px 50px ); clip-path: circle ( 50px at 0 100px ); clip-path: polygon( 50% 0% , 100% 50% , 50% 100% , 0% 50% ); /* Box and geometry values combined */ clip-path: padding-box circle ( 50px at 0 100px ); /* Global values */ clip-path: inherit; clip-path: initial; clip-path: unset; } |
看上去很多,其實(shí)很好理解,如果接觸過(guò) SVG 的 path,其實(shí)就是照搬 SVG 的 path 的一些定義。換言之,如果沒(méi)有接觸過(guò) SVG,看完本文后再去學(xué)習(xí) SVG 路徑 ,也會(huì)十分容易上手。
根據(jù)不同的語(yǔ)法,我們可以生成不同的圖形。
例如 clip-path: circle(50px at 50px 50px)
表示在元素的 (50px, 50px)處,裁剪生成一個(gè)半徑為 50px 的圓。
以元素的左上角為坐標(biāo)起點(diǎn)
而整個(gè) clip-path
屬性,最為重要的當(dāng)屬 polygon
,可以利用 polygon
生成任意多邊形。
下面分別列舉使用 clip-path 生成一個(gè)圓形和一個(gè)十邊形。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /* 圓形 */ . circle { width : 100px ; height : 100px ; background-color : yellowgreen; clip-path: circle ( 50px at 50px 50px ); } /* 十邊形 */ .polygon { width : 100px ; height : 100px ; background-color : yellowgreen; clip-path: polygon( 50% 0% , 80% 10% , 100% 35% , 100% 70% , 80% 90% , 50% 100% , 20% 90% , 0% 70% , 0% 35% , 20% 10% ); } |
clip-path: circle(50px at 50px 50px)
上文也講了,表示在元素的 (50px, 50px)處,裁剪生成一個(gè)半徑為 50px 的圓。
而在 clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%)
中,依次列出了 10 個(gè)坐標(biāo)點(diǎn)。我們的圖形就是依次連接這 10 個(gè)坐標(biāo)點(diǎn)形成一個(gè)裁切圖形。
當(dāng)然,這里采用的是百分比,也可以使用具體的數(shù)值。
clip-path 另外一個(gè)強(qiáng)大之處在于可以進(jìn)行 CSS transtion 與 CSS animation,也就是過(guò)渡和動(dòng)畫(huà)。
看一個(gè)多邊形的過(guò)渡切換動(dòng)畫(huà)。
CodePen Demo -- Clip-path 多邊形過(guò)渡動(dòng)畫(huà)
除此之外,我們還可以嘗試,將一個(gè)完整的圖形,分割成多個(gè)小圖形,這也是 clip-path
的魅力所在,純 CSS 的圖形變換:
CodePen Demo -- Clip-path triangle2rect
clip-path 動(dòng)畫(huà)雖然美好,但是存在一定的局限性,那就是進(jìn)行過(guò)渡的兩個(gè)狀態(tài),坐標(biāo)頂點(diǎn)的數(shù)量必須一致。
也就是如果我希望從三角形過(guò)渡到矩形。假設(shè)三角形和矩形的 clip-path
分別為:
clip-path: polygon(50% 0, 0 100%, 100% 0)
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%)
進(jìn)行過(guò)渡動(dòng)畫(huà)時(shí)候,直接從 polygon(50% 0, 0 100%, 100% 0)
--> polygon(0 0, 100% 0, 100% 100%, 0 100%)
是不行的,因?yàn)槭菑?3 個(gè)坐標(biāo)點(diǎn)變換到 4 個(gè)坐標(biāo)點(diǎn)。
因此這里需要這用一個(gè)討巧的辦法,在三角形的表示方法中,使用四個(gè)坐標(biāo)點(diǎn)表示,其中兩個(gè)坐標(biāo)點(diǎn)進(jìn)行重合即可。也就是:
clip-path: polygon(50% 0, 0 100%, 100% 0)
-> clip-path: polygon(50% 0, 50% 0, 0 100%, 100% 0)
如果腦洞夠大,隨機(jī)生成 N(N>=1000)邊形,進(jìn)行變換,會(huì)是什么效果呢?
see one see:
CodePen Demo -- 2000邊形過(guò)渡動(dòng)畫(huà)
變換的瞬間很有爆炸的感覺(jué)。不過(guò)這里有個(gè)很大的問(wèn)題,只是隨機(jī)生成了 2000 個(gè)坐標(biāo)點(diǎn),然后使用 clip-path
將這些坐標(biāo)點(diǎn)連接起來(lái),并不是符合要求的多邊形。
在 VUE官網(wǎng),有下面這樣一個(gè)例子,一個(gè)規(guī)則的多邊形進(jìn)行不斷的過(guò)渡動(dòng)畫(huà),非??犰牛?/p>
VUE官網(wǎng)使用的是 SVG 實(shí)現(xiàn)的,這里我稍微改變了下,使用 CSS clip-path
實(shí)現(xiàn):
CodePen Demo -- clip-path N polygon ,感興趣可以看看。
最后再來(lái)看看 shape-outside
,另外一個(gè)有趣的有能力生成幾何圖形的屬性。
shape-outside
是啥?它也有制造各種幾何圖形的能力,但是它只能和浮動(dòng) float
一起使用。
雖然使用上有所限制,但是它賦予了我們一種更為自由的圖文混排的能力。
先看看它的 API,看上去貌似很復(fù)雜:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | { /* Keyword values */ shape-outside: none ; shape-outside: margin-box; shape-outside: content-box; shape-outside: border-box; shape-outside: padding-box; /* Function values */ shape-outside: circle (); shape-outside: ellipse(); shape-outside: inset ( 10px 10px 10px 10px ); shape-outside: polygon( 10px 10px , 20px 20px , 30px 30px ); /* shape-outside: url (image.png); /* Gradient value */ shape-outside: linear-gradient( 45 deg, rgba( 255 , 255 , 255 , 0 ) 150px , red 150px ); /* Global values */ shape-outside: initial; shape-outside: inherit; shape-outside: unset; } |
但是,其實(shí)它和 clip-path
的語(yǔ)法非常類(lèi)似,很容易觸類(lèi)旁通??纯磳?shí)例,更易理解:
大家自行去熟悉下 API,接著假設(shè)我們有下面這樣的結(jié)構(gòu)存在:
注意,上面 .shape-outside
使用了浮動(dòng),并且定義了 shape-outside: circle(80px at 80px 80px)
,表示在元素的 (80px, 80px) 坐標(biāo)處,生成一個(gè) 80px 半徑的圓。
如此,將會(huì)產(chǎn)生一種圖文混排的效果:
CodePen Demo -- 圖文混排 shape-outside
嗯?好像沒(méi)什么了不起?。窟@不就是 float
的效果嗎?
不,不是的,看看 float
和 加上shape-outside
后的對(duì)比:
看出區(qū)別了嗎?使用了 shape-outside
,真正的實(shí)現(xiàn)了文字根據(jù)圖形的輪廓,在其周?chē)帕小?/p>
上圖是使用開(kāi)發(fā)者工具選取了作用了 shape-outside
的元素,可以看到,使用了特殊的藍(lán)色去標(biāo)記幾何圖形的輪廓。在這個(gè)藍(lán)色區(qū)域之外,文字都將可以進(jìn)行排列。
shape-outside
的本質(zhì)劃重點(diǎn),劃重點(diǎn),劃重點(diǎn)。
所以,shape-outside
的本質(zhì)其實(shí)是生成幾何圖形,并且裁剪掉其幾何圖形之外周?chē)膮^(qū)域,讓文字能排列在這些被裁剪區(qū)域之內(nèi)。
所以,了解了這個(gè)本質(zhì)之后,我們?cè)倏纯匆恍└鼜?fù)雜的圖文混排。
CodePen Demo -- 圖文混排 shape-outside
CodePen Demo -- 圖文混排 shape-outside
額,比較遺憾,這兩個(gè)屬性的兼容性目前仍處于比較尷尬的境地。感興趣的可以看看 CANIUSE 。全面兼容使用仍需努力。
所以本文所展示的 Demo 都是在 -webkit-
內(nèi)核瀏覽器下完成的。
系列 CSS 文章匯總在我的 Github 。
到此本文結(jié)束,如果還有什么疑問(wèn)或者建議,可以多多交流,原創(chuàng)文章,文筆有限,才疏學(xué)淺,文中若有不正之處,萬(wàn)望告知。
聯(lián)系客服