奇妙的 CSS shapes(CSS图形)
CSS 發(fā)展到今天已經(jīng)越來(lái)越強(qiáng)大了。其語(yǔ)法的日新月異,讓很多以前完成不了的事情,現(xiàn)在可以非常輕松的做到。今天就向大家介紹幾個(gè)比較新的強(qiáng)大的 CSS 功能:
- clip-path
- shape-outside
shape 的意思是圖形,CSS shapes 也就是 CSS 圖形的意思,也就是使用 CSS 生成各種圖形(圓形、矩形、橢圓、多邊形等幾何圖形)。
CSS3之前,我們能做的只有矩形,四四方方,條條框框。
?
CSS3
CSS3出來(lái)后,我們有了更廣闊的施展空間,通過
- border-radius
- border
- transform
- 偽元素配合
- gradient 漸變
我們能夠作出非常多的幾何圖形。
除去最常見的矩形,圓形(
border-radius),下面稍微列舉一些其他幾何圖形:三角形
通常會(huì)使用透明的border模擬出一個(gè)三角形:
.traingle {width: 0;height: 0;border-left: 50px solid transparent;border-right: 50px solid transparent;border-bottom: 100px solid yellowgreen; }切角
《CSS Secret》里面的方法,采用多重線性漸變實(shí)現(xiàn)切角。
.notching {width: 40px;height: 40px;padding: 40px;background: linear-gradient(135deg, transparent 15px, yellowgreen 0) top left,linear-gradient(-135deg, transparent 15px, yellowgreen 0) top right,linear-gradient(-45deg, transparent 15px, yellowgreen 0) bottom right,linear-gradient(45deg, transparent 15px, yellowgreen 0) bottom left;background-size: 50% 50%;background-repeat: no-repeat; }梯形
利用偽元素加旋轉(zhuǎn)透視實(shí)現(xiàn)梯形:
.trapezoid{position: relative;width: 60px;padding: 60px; }.trapezoid::before{content:"";position: absolute;top: 0; right: 0; bottom: 0; left: 0;transform: perspective(20px) scaleY(1.3) rotateX(5deg);transform-origin: bottom;background: yellowgreen; }當(dāng)然,還有另一種更簡(jiǎn)單的方法是利用border實(shí)現(xiàn),借助上面的構(gòu)造三角形的方法,在矩形兩側(cè)構(gòu)造兩個(gè)透明的三角形:
.trapezoid {position: relative;width: 60px;border-top: 60px solid yellowgreen;border-left: 40px solid transparent;border-right: 40px solid transparent; }五邊形
梯形加上三角形,很容易就組合成一個(gè)五邊形,這里需要借助一個(gè)偽元素實(shí)現(xiàn):
.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è)六邊形呢?
.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; }八邊形
六邊形都解決了,八邊形也不在話下,一個(gè)矩形加上兩個(gè)梯形,可以合成一個(gè)八邊形。
.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)啦 -- ★☆
開個(gè)玩笑,這里使用 3 個(gè)三角形疊加旋轉(zhuǎn)在一起實(shí)現(xiàn)。
.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(35deg) 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(-35deg); } .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(-70deg); }六角星
六角星呢?想象一下,一個(gè)向上的三角形 ▲,疊加上一個(gè)向下的三角形 ▼,就可以得到一個(gè)六邊形:
.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)拼接就可以了。
.eightstar {position: relative;width: 100px;height: 100px;background-color: yellowgreen;transform: rotate(30deg); }.eightstar::before {content: "";position: absolute;top: 0;left: 0;width: 100px;height: 100px;transform: rotate(45deg);background-color: yellowgreen; }十二角星
好。最后多角星再來(lái)一個(gè)十二級(jí)角星。在八角星的基礎(chǔ)上,再增加一個(gè)矩形,就能得到十二角啦。也就是要過第一個(gè)偽元素。
.twelvestar {position: relative;width: 100px;height: 100px;margin-bottom: 100px!important;background-color: yellowgreen;transform: rotate(30deg); }.twelvestar::before {content: "";position: absolute;top: 0;left: 0;width: 100px;height: 100px;transform: rotate(30deg);background-color: yellowgreen; }.twelvestar::after {content: "";position: absolute;top: 0;left: 0;width: 100px;height: 100px;transform: rotate(60deg);background-color: yellowgreen; }橢圓
最后,再來(lái)使用傳統(tǒng)的方法畫一個(gè)橢圓,過去 CSS3 畫橢圓,基本上只能借助 border 實(shí)現(xiàn)。
這里使用 border 畫一個(gè)蛋的形狀:
.ellipse {width: 120px;height: 160px;background-color: yellowgreen;border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; }CodePen -- CSS Shapes(CSS 幾何圖形)
title="CSS shapes" src="https://codepen.io/Chokcoco/embed/NgxNrq/?height=265&theme-id=0&default-tab=css,result&embed-version=2" frameborder="no" scrolling="no" width="320" height="265">
上面所講述的是使用傳統(tǒng) CSS3 的方式繪制幾何圖形,前人栽樹后人乘涼,之前的大牛們?cè)?CSS 繪制幾何圖形上已經(jīng)做了非常深入的研究,更多的 CSS 圖形你可以戳這里:The?Shapes?of CSS?。接下來(lái)我們將要了解一些更高級(jí)的繪制幾何圖形的方法。
如果你看到了這里,恭喜你,本文的正文從這里開始。
??
clip-path
CSS 新屬性?
clip-path,意味裁剪路徑的意思,讓我們可以很便捷的生成各種幾何圖形。clip-path 通過定義特殊的路徑,實(shí)現(xiàn)我們想要的圖形。而這個(gè)路徑,正是 SVG 中的 path 。
看看它的 API:
{ /* Keyword values */ clip-path: none;/* Image values */ clip-path: url(resources.svg#c1);/* 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í)很好理解,如果接觸過 SVG 的 path,其實(shí)就是照搬 SVG 的 path 的一些定義。換言之,如果沒有接觸過 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 示例
下面分別列舉使用 clip-path 生成一個(gè)圓形和一個(gè)十邊形。
/* 圓形 */ .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 動(dòng)畫
clip-path 另外一個(gè)強(qiáng)大之處在于可以進(jìn)行 CSS transtion 與 CSS animation,也就是過渡和動(dòng)畫。
看一個(gè)多邊形的過渡切換動(dòng)畫。
CodePen Demo -- Clip-path 多邊形過渡動(dòng)畫
title="clip-path polygon-animate" src="https://codepen.io/Chokcoco/embed/LLNWyZ/?height=265&theme-id=0&default-tab=css,result&embed-version=2" frameborder="no" scrolling="no" width="320" height="265">
圖形變換動(dòng)畫
除此之外,我們還可以嘗試,將一個(gè)完整的圖形,分割成多個(gè)小圖形,這也是?
clip-path?的魅力所在,純 CSS 的圖形變換:CodePen Demo -- Clip-path triangle2rect
title="clip-path triangle2rect" src="https://codepen.io/Chokcoco/embed/yXOjZm/?height=265&theme-id=0&default-tab=css,result&embed-version=2" frameborder="no" scrolling="no" width="320" height="265">
?
clip-path 動(dòng)畫的局限
clip-path 動(dòng)畫雖然美好,但是存在一定的局限性,那就是進(jìn)行過渡的兩個(gè)狀態(tài),坐標(biāo)頂點(diǎn)的數(shù)量必須一致。
也就是如果我希望從三角形過渡到矩形。假設(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)行過渡動(dòng)畫時(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)
?
N邊形過渡動(dòng)畫
如果腦洞夠大,隨機(jī)生成 N(N>=1000)邊形,進(jìn)行變換,會(huì)是什么效果呢?
see one see:
CodePen Demo -- 2000邊形過渡動(dòng)畫
title="clip-path Fxxk" src="https://codepen.io/Chokcoco/embed/XgJRzO/?height=265&theme-id=0&default-tab=js,result&embed-version=2" frameborder="no" scrolling="no" width="320" height="265">
變換的瞬間很有爆炸的感覺。不過這里有個(gè)很大的問題,只是隨機(jī)生成了 2000 個(gè)坐標(biāo)點(diǎn),然后使用?
clip-path?將這些坐標(biāo)點(diǎn)連接起來(lái),并不是符合要求的多邊形。在?VUE官網(wǎng),有下面這樣一個(gè)例子,一個(gè)規(guī)則的多邊形進(jìn)行不斷的過渡動(dòng)畫,非常酷炫:
VUE官網(wǎng)使用的是 SVG 實(shí)現(xiàn)的,這里我稍微改變了下,使用 CSS?
clip-path?實(shí)現(xiàn):CodePen Demo -- clip-path N polygon?,感興趣可以看看。
title="clip-path N polygon" src="https://codepen.io/Chokcoco/embed/NgqGOo/?height=265&theme-id=0&default-tab=js,result&embed-version=2" frameborder="no" scrolling="no" width="320" height="265">?
?
shape-outside
最后再來(lái)看看?
shape-outside,另外一個(gè)有趣的有能力生成幾何圖形的屬性。 shape-outside?是啥?它也有制造各種幾何圖形的能力,但是它只能和浮動(dòng)? float?一起使用。雖然使用上有所限制,但是它賦予了我們一種更為自由的圖文混排的能力。
先看看它的 API,看上去貌似很復(fù)雜:
{/* 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);/* <url> value */shape-outside: url(image.png);/* Gradient value */shape-outside: linear-gradient(45deg, rgba(255, 255, 255, 0) 150px, red 150px);/* Global values */shape-outside: initial;shape-outside: inherit;shape-outside: unset; }但是,其實(shí)它和?
clip-path?的語(yǔ)法非常類似,很容易觸類旁通。看看實(shí)例,更易理解:大家自行去熟悉下 API,接著假設(shè)我們有下面這樣的結(jié)構(gòu)存在:
<div class="container"><div class="shape-outside"><img src="image.png"></div>xxxxxxxxxxx,文字描述,xxxxxxxxx </div>定義如下 CSS:
.shape-outside {width: 160px;height: 160px;shape-outside: circle(80px at 80px 80px);float: left; }注意,上面?
.shape-outside?使用了浮動(dòng),并且定義了? shape-outside: circle(80px at 80px 80px)?,表示在元素的 (80px, 80px) 坐標(biāo)處,生成一個(gè) 80px 半徑的圓。如此,將會(huì)產(chǎn)生一種圖文混排的效果:
CodePen Demo -- 圖文混排 shape-outside
title="shape-outside" src="https://codepen.io/Chokcoco/embed/owxedZ/?height=265&theme-id=0&default-tab=html,result&embed-version=2" frameborder="no" scrolling="no" width="320" height="265">
嗯?好像沒什么了不起啊?這不就是?
float?的效果嗎?不,不是的,看看?
float?和 加上 shape-outside?后的對(duì)比:看出區(qū)別了嗎?使用了?
shape-outside?,真正的實(shí)現(xiàn)了文字根據(jù)圖形的輪廓,在其周圍排列。上圖是使用開發(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í)是生成幾何圖形,并且裁剪掉其幾何圖形之外周圍的區(qū)域,讓文字能排列在這些被裁剪區(qū)域之內(nèi)。所以,了解了這個(gè)本質(zhì)之后,我們?cè)倏纯匆恍└鼜?fù)雜的圖文混排。
平行四邊形
CodePen Demo -- 圖文混排 shape-outside
心形、菱形
CodePen Demo -- 圖文混排 shape-outside
?
clip-path 與 shape-outside 的兼容性
額,比較遺憾,這兩個(gè)屬性的兼容性目前仍處于比較尷尬的境地。感興趣的可以看看 CANIUSE 。全面兼容使用仍需努力。
所以本文所展示的 Demo 都是在?
-webkit-?內(nèi)核瀏覽器下完成的。?
最后
系列 CSS 文章匯總在我的?Github?。
到此本文結(jié)束,如果還有什么疑問或者建議,可以多多交流,原創(chuàng)文章,文筆有限,才疏學(xué)淺,文中若有不正之處,萬(wàn)望告知。
總結(jié)
以上是生活随笔為你收集整理的奇妙的 CSS shapes(CSS图形)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Web前端行业的机遇与自我规划,如果你对
- 下一篇: CSS3 iphone式开关的推荐写法