CSS如何实现内凹角效果 By 大漠
記得@Lea Verou的《CSS Secrets》一書和前幾天@Chris Coyier剛發(fā)的帖子都介紹了CSS怎么實(shí)現(xiàn)元素斜切口的效果。我也嘗試著借助Vue的能力,把這種效果構(gòu)建成一個(gè)Vue組件。我把這種效果定義為外切口。而今天將要聊的是與其剛好相反的一個(gè)效果:CSS如何實(shí)現(xiàn)內(nèi)凹角的效果。
上圖展示的效果就是接下來所要聊的內(nèi)凹角的效果。也就是說,通過下文的介紹,我們可以知道這種效果是如何做的,而且如何在多個(gè)元素上實(shí)現(xiàn)這樣的內(nèi)凹角效果。在實(shí)現(xiàn)這樣的效果當(dāng)中,將會(huì)遇到些什么棘手的問題,又是怎么繞過這些問題的。
最初的想法:box-shadow
對(duì)于box-shadow的屬性,想必大家已經(jīng)非常了解了,如果你從未接觸過box-shadow屬性,那么強(qiáng)烈建議您花一點(diǎn)時(shí)間去了解一下box-shadow相關(guān)的知識(shí)。這樣能幫助你更好的理解后續(xù)的內(nèi)容。
我先假設(shè)你對(duì)box-shadow有了一定的了解。就算你不了解,也沒有關(guān)系。你也可以繼續(xù)后面的內(nèi)容。假設(shè)我們有一個(gè)div的元素。給這個(gè)元素添加了一個(gè).box的類名:
我們可以顯式的給這個(gè).box元素設(shè)置大小或者通過其自己的內(nèi)容來決定大小,不管是哪種方式,都并不很重要。這里為了簡單起見,給其設(shè)置了max-width和min-height(也是用來設(shè)置其大小的)。另外為了能在瀏覽器中看到效果,其添加了一個(gè)outline的效果,讓其看起來有邊框的樣子?;蛟S你會(huì)問,為什么不直接使用border呢?這個(gè)問題留給大家去思考吧,因?yàn)椴皇沁@篇文章要探討的內(nèi)容。
接下來,通過偽元素::before來創(chuàng)建一個(gè)正方形,其邊長等于圓角的直徑(或者半徑--r的兩倍),而且對(duì)這個(gè)偽元素使用絕對(duì)定位。另外為了能在瀏覽器中看到效果,給這個(gè)偽元素添加了一個(gè)box-shadow和background屬性。這只是用來輔助大家理解的,后續(xù)會(huì)刪除的。
特別聲明:本文的實(shí)例代碼都來自于@ANA TUDOR的《Scooped Corners in 2018》一文。不同的是我把文章中的Sass變量換成了CSS自定義變量。后續(xù)內(nèi)容如無特別說明,都將類似的做了修改。
這個(gè)時(shí)候看到的效果如下:
效果如你所期望的一樣。接下來對(duì)偽元素::before的border-radius值設(shè)置為50%,讓它成為一個(gè)圓形,并且給它設(shè)置一個(gè)margin的負(fù)值,值等于它的半徑--r。偽元素的中心點(diǎn)和它的父容器.box的左上角(0,0)重合。為了讓溢出的.box的偽元素能隱藏起來,需要在.box中添加一個(gè)overflow:hidden。
現(xiàn)在的結(jié)果是這樣的:
但這樣的效果仍然不是我們想要的。為了達(dá)到我們想要的效果,我們需要使用box-shadow的第四個(gè)參數(shù)值:陰影擴(kuò)展半徑。如果你想了解box-shadow添加第四個(gè)參數(shù)值的效果,可以看下面這個(gè)Demo:
你可能已經(jīng)猜到我們下一步要做什么了。把background和box-shadow前三個(gè)值(x和y軸的偏移值以及模糊半徑)設(shè)置為0,并給box-shadow的擴(kuò)展半徑設(shè)置為一個(gè)較大的值。
下面的這個(gè)示例演示了box-shadow的擴(kuò)展半徑如何讓陰影效果覆蓋容器更多的面積。
這里用到的一個(gè)技巧是讓box-shadow有足夠大的擴(kuò)展半徑,這樣讓偽元素的陰影能覆蓋其容器更多的面積。這是非常有意思的一點(diǎn),給.box設(shè)置box-shadow以及給其偽元素添加一個(gè)半透明的陰影效果。
其實(shí)這是很關(guān)鍵的一步,如果你不仔細(xì)看,你或許會(huì)認(rèn)為,那個(gè)凹角的效果是box-shadow實(shí)現(xiàn)的?;蛟S你和我一樣會(huì)納悶,box-shadow是如何實(shí)現(xiàn)透明凹角的效果。事實(shí)并非如此,透明凹角部分是偽元素::before的background-color為transparent,而整個(gè)紫色部分是由::before的box-shadow實(shí)現(xiàn)的(就是陰影擴(kuò)散半徑有足夠大的值,能鋪滿.box的容器大小)。我錄一個(gè)視頻給大家看看,或許能比文字更好的說明一切原理:
是不是一圖勝過千言萬語呀。
上面看到的效果,不難發(fā)現(xiàn),凹角的大小是固定的。好在我們這里使用了CSS的自定義屬性。因?yàn)槭褂肅SS自定義屬性之后,可以很容易的通過JavaScript來修改這個(gè)屬性。這樣一來,就可以很好的控制凹角的大小。比如:
這是實(shí)現(xiàn)凹角效果的關(guān)鍵樣式。具體的不多說了,能只要仔細(xì)閱讀上面的內(nèi)容,你就能明白為什么。
值得一提的是,我們前面看到的效果都是.box中沒有任何內(nèi)容。也就是說.box里有內(nèi)容的時(shí)候,我們是需要在樣式上做一定的調(diào)整的。為什么這么說呢?先來看一個(gè)效果:
要解決這個(gè)問題,很簡單,咱們只需要在.box的偽元素::before上添加z-index屬性,并且給其設(shè)置值為-1。
另外通過.setProperty()來修改--r的值。這需要一些JavaScript代碼來支持:
現(xiàn)在離我們想要的效果越來越近了。我們已經(jīng)知道如何通過box-shadow給單個(gè).box設(shè)置單個(gè)凹角的效果。那么如果我們想要給一個(gè)元素添加四個(gè)凹角效果,怎么實(shí)現(xiàn)呢?想想,如果你想得出來,可以立馬動(dòng)手試試,就算你想不出來,也并不要緊,后面我們會(huì)介紹怎么給.box盒子的每個(gè)角添加凹角的效果。
那么到這一步,咱們先暫停一下。上面我們看到的是CSS的自定義屬性和JavaScript來實(shí)現(xiàn)想要的凹角效果。那么咱們先暫停一步,來看看怎么通過Vue來實(shí)現(xiàn)上面示例的效果。
有關(guān)于Vue的代碼這里就不展示了。詳細(xì)的可以查看上面Demo的代碼,其實(shí)你還可以添加其他的參數(shù),比如除了給scooped-corners組件傳凹角半徑值之外,還可以傳border-radius和background-color之類。感興趣的可以嘗試一下,并且歡迎在下面的評(píng)論中分享您的成果。
就用這種技術(shù)
接下來,咱們?cè)偕钊胍稽c(diǎn),看看怎么運(yùn)用這種技術(shù)來實(shí)現(xiàn)文章開頭展示的效果。這里有一點(diǎn)不一樣,偽元素的中心點(diǎn)與盒子不致,但他們都有一個(gè)共同點(diǎn),偽元素的中心點(diǎn),在每個(gè)盒子的頂點(diǎn)處。
使用的HTML結(jié)構(gòu)非常簡單,這里使用了4個(gè)<article>元素(相當(dāng)于前面所講的.box元素),在<article>元素中包含了一些文本內(nèi)容:
<body>包含了四個(gè)<article>元素,還有一個(gè)<header>元素,整個(gè)布局效果采用的是Flexbox。從文章開頭的效果上來看,<header>寬度非常寬,然后每行有一個(gè)個(gè)或兩個(gè)<article>元素。具體每行展示一個(gè)還是兩個(gè),這取決于瀏覽器視窗的寬度。
如果我們每一行只有一個(gè)<article>時(shí),那么元素上就不會(huì)有凹角的效果,這個(gè)時(shí)候需要把凹角的半徑設(shè)置為0。否則我們就要設(shè)置一個(gè)非零的半徑,也就是說--r的值不為0。
特別注意,CSS自定義屬性不能用于媒體查詢的條件中,但可以用于媒體查詢的區(qū)塊內(nèi)。
現(xiàn)在我們考慮一下,每行有兩個(gè)<article>元素(當(dāng)然,每個(gè)元素都有一個(gè)內(nèi)凹角,因?yàn)檫@個(gè)才是我們感興趣的東東)。
第一個(gè)元素中,凹角的圓形在它的父元素的最右邊邊,也就是left:100%。為了將凹角圓中心點(diǎn)x坐標(biāo)移到其父元素的右邊緣,我們就需要減去圓的半徑--r,那么left的值就變成了calc(100% - var(--r))。但我們不想讓它出現(xiàn)在右邊,而是希望它在<article>元素向右移--m。這樣我們就可以算出我們最終想要的一個(gè)值:
對(duì)于最后一個(gè),其水平方向的偏移量和第二個(gè)具有相同的值,垂直方向的偏移量和第三個(gè)具有相同的值。
所以四個(gè)元素對(duì)應(yīng)的left和top的偏移量如下:
這意味著凹角圓的中心位置取決于<article>元素之間的間距(這個(gè)間距是我們?cè)O(shè)置的margin: var(--m)的兩倍),凹角的半徑是--r。在一對(duì)水平和垂直的乘數(shù)因子分別是--i和--j,而且他們的最初的值都是-1。
對(duì)于第一行的兩個(gè)<article>元素(第一行是一個(gè)2 x 2的網(wǎng)格),我們需要改變垂直方向的乘數(shù)因子--j為1,這樣就可以讓凹角的圓心在y軸上低于父容器底部邊緣;而對(duì)于奇數(shù)的<article>(第一列),需要改變水平方向的乘數(shù)因子--i為1,這樣就可以讓凹角的圓心在x軸上位于父容器的右側(cè)邊緣。
@media (min-width: 2*($min-w + 2*$m)) {article {&:nth-of-type(-n + 2) h3, &:nth-of-type(n + 3) section { &:before { --r: 0 ; } }} }
以類似的方式,我們?yōu)?lt;article>元素的子元素添加不同的樣式:
h3, section { --p: .5rem;padding: $p; }@media (min-width: 2*($min-w + 2*$m)) {article {&:nth-of-type(-n + 2) section, &:nth-of-type(n + 3) h3 {padding-right: calc(.5*(1 + var(--i))*(var(--r) - var(--m)) + var(--p));padding-left: calc(.5*(1 - var(--i))*(var(--r) - var(--m)) + var(--p));}} }
最終效果如下:
特別聲明:今天使用CSS自定義屬性,在媒體查詢的條件中使用自定義屬性踩了一個(gè)坑。那是因?yàn)槲蚁朐诖a中統(tǒng)一使用CSS自定義屬性來替代Sass這樣處理器的變量。一直以為在CSS的媒體查詢的條件中使用CSS自定義屬性是OK的,結(jié)果實(shí)測代碼的時(shí)候才發(fā)現(xiàn)不支持。最后查找了一下原因:
The?var()?function can be used in place of any part of a value in any property on an element. The?var()?function can not be used as property names, selectors, or anything else besides property values. (Doing so usually produces invalid syntax, or else a value whose meaning has no connection to the variable.) —— From the?spec
值得慶達(dá)的是,你可以使用PostCSS插件postcss-media-variables來做處理。感興趣的可以自己試試。說實(shí)話,再一次感嘆PostCSS的神奇之處和無所不能。
潛在的問題
上面的示例看上去完美,方法簡單而又能跪?yàn)g覽器兼容。或許你已經(jīng)發(fā)現(xiàn)了,上例是在一個(gè)特定情況下想的結(jié)果,但很多時(shí)候我們總不是這么的幸運(yùn)。哪一天需求一變,是不是還能如此輕易而又完美的實(shí)現(xiàn)呢?
首先,我們需要用一個(gè)偽元素來做這個(gè)凹角,當(dāng)你只需要一個(gè)(比如上面看到的示例)或者兩個(gè)的時(shí)候,都不是問題,但有的時(shí)候元素的四個(gè)角都需要這樣的凹角時(shí),那么我們就需要引入一個(gè)額外的元素。另外當(dāng)你的偽元素被其他功能(比如Icon)占用時(shí),你也不得不為此效果添加一個(gè)額外的標(biāo)簽元素。蛋疼了吧!
其次上面示例中的background是一個(gè)純色,但我們不可能總是在使用純色背景的場景中。如果我們想要一個(gè)半透明的或者漸變的背景,或者在一張背景圖片之下,那么凹角將會(huì)成為我們的一個(gè)痛點(diǎn),甚至?xí)f,這個(gè)沒法實(shí)現(xiàn)。
因此,我們需要探索其他更可靠的方案,并且也能讓它得到眾多瀏覽器的支持。
靈活性和良好的瀏覽器支持?是SVG?
想到SVG并不奇怪,但是如果我們想要靈活一點(diǎn),瀏覽器兼容性全面一點(diǎn),SVG可以說是一個(gè)最好的解決方案。在.box容器中包含了一個(gè)<svg>元素,而且放置在內(nèi)容的前面。SVG中包含了一個(gè)<circle>元素,在這個(gè)元素上設(shè)置了r屬性。
讓svg相對(duì)于.box元素做相對(duì)定位,將將其大小設(shè)置為能完全覆蓋父容器:
.box { position: relative; }svg {position: absolute;width: 100%;height: 100%; }
到目前為止,沒有什么有趣的東西,所以給<circle>添加一個(gè)id屬性,并且使用SVG的<use>元素來復(fù)制多個(gè)id相同的<circle>:
看到這里,是不是會(huì)覺得比使用::before偽元素要來得簡便,而且也非常方便,就算你要移去一個(gè)或多個(gè)凹角(示例效果的紫色部分),你只需要少使用幾個(gè)<use>去克隆就行了。
從上例效果中可以看到,.box的四個(gè)角落都圓圈在那了,但這并不是我們想要的凹角,對(duì)吧!不要納悶了,我們的做法是對(duì)的。請(qǐng)接著往下看。接下來要做的就是把這些圓圈放到一個(gè)<mask>中,給這個(gè)<mask>設(shè)置一個(gè)white的填充色(fill屬性來搞定)。同時(shí)在其里面使用<rect>元素設(shè)置一個(gè)和SVG元素一樣大小的矩形,主要用來覆蓋整個(gè)SVG。然后我們?cè)诹硪粋€(gè)再次使用<use>來調(diào)用這個(gè)已創(chuàng)建好的<mask>:
最終效果如下:
同樣的,我錄制了一個(gè)動(dòng)圖來演示效果中的每一個(gè)元素:
特別注意:如果.box中有內(nèi)容,建議放置在svg元素之后。當(dāng)然也可以放置在其前面,如果放置在前面,svg在做定位時(shí),需要顯式的設(shè)置top、right、bottom和left之類的值。至于為什么,這里不做過多的闡述,感興趣的同學(xué)可以自己去深究其中的為什么。
如果.box有文本,需要把.box的padding的值和圓角的半徑設(shè)置相同,同樣的,如果使用了CSS自定義屬性,可以使用JavaScript來控制它。最好把圓的半徑和.box的padding使用同一個(gè)CSS自定義屬性--r。這樣會(huì)更好的控制一點(diǎn):
我喜歡的就是CSS
或許你會(huì)說,我不懂SVG,我就是想使用CSS來實(shí)現(xiàn)。其實(shí)很高興你能這樣的深究與思考。事實(shí)上我們的確可以使用CSS來實(shí)現(xiàn)這樣的效果。
遺憾的是,使用CSS的方案目前為止并不是所有瀏覽器都能支持,但使用CSS讓我們把事情變得更簡化,而且在不遠(yuǎn)的將來,它們肯定是能得到眾多瀏覽器支持的。
在HTML元素上使用CSS的mask
這里我們移除SVG所有的東西,然后使用CSS,可以在.box元素上設(shè)置一個(gè)background(可以是一個(gè)純色、半透明、漸變、圖像或者多背景,甚至是你任何你想要的CSS)和mask屬性。
使用CSS設(shè)置圓半徑
這意味著,需要把<circle>中的r屬性刪除,然后在CSS中給其設(shè)置半徑的大小,這里設(shè)置的半徑大小與.box容器的padding值一樣:
這樣一來,如果我們改變半么--r的值,凹角的大小和.box的padding也會(huì)隨著更新。
注意,在CSS中給SVG元素設(shè)置幾何屬性只在Blink瀏覽器中有效!
結(jié)合前兩種方法
雖然這很酷,但遺憾的是目前在任何瀏覽器中都看不到效果。但值得慶幸的是我們可以做得更好!
使用漸變來做朦層
Note that CSS masking on HTML elements doesn't work at all in Edge at this point, though it's?listed as "In Development"?and a flag for it (that doesn't do anything for now)?has already shown up?in?about:flags.
由于我們需要完全拋棄SVG,所以我們需要使用CSS的漸變?yōu)閙ask做些事情。這里將使用CSS徑向漸變來畫圓,下面就是CSS繪制的一個(gè)半徑為--r的圓,并且這個(gè)圓位于.box的左上角。
如果您對(duì)CSS的漸變不太了解,建議您花點(diǎn)時(shí)間閱讀這幾篇文章:《再說CSS3漸變:線性漸變》、《再說CSS3漸變:徑向漸變》、《為什么要使用repeating-linear-gradient》、《?你真的理解CSS的linear-gradient?》。
這個(gè)時(shí)候你可以看到像上面這樣的一個(gè)效果:
接下來在mask使用相同的漸變:
注意,Webkit瀏覽器仍然需要給mask屬性添加-webkit-前綴。如果你不知道m(xù)ask怎么使用,建議你花點(diǎn)時(shí)間閱讀《如何在CSS中使用遮罩》一文。因?yàn)楹竺婧芏鄡?nèi)容都會(huì)涉及到這個(gè)屬性,這樣能幫助更好的理解后續(xù)的內(nèi)容。
給.box每個(gè)角落都添加漸變繪制的圓:
上面這樣做還不是很好,可以借助CSS處理器的循環(huán)特性來做,會(huì)更好一些:
就代碼而言,這樣寫已經(jīng)很完美了。因?yàn)槲覀儾恍枰啻尉帉?#xff0c;并且以后在任何地方使用都不需要做任何更改。但到目前為止的結(jié)果并不是我們想要的:
從上面的示例中可以看出,我們除了凹角部分之外的東西都剪切掉了,這正好和我們想要的東西相反。要得到我們想要的效果,咱們只需要做一件事情,把漸變反過來。讓凹角的圓變成透明,剩余的部分全部是黑色。
--stop-list: transparent var(--r, 50px), #000 0;需要注意的是,如果我們只使用一個(gè)漸變的時(shí)候,那么上面的代碼就幫我們解決了問題:
但是,當(dāng)我們把所有的四個(gè)圓圈(甚至兩個(gè))都堆起來的時(shí)候,就會(huì)得到一個(gè)黑色的矩形,這個(gè)矩形的大小相當(dāng)于我們的mask的大小,這意味著沒有任何東西會(huì)被掩蓋掉。
因此,我們需要把每個(gè)漸變的大小限制在盒子的四分之處(width的50%和height的50%),從而得到25%的面積:
這個(gè)意思就是,我們需要設(shè)置mask-size的值為50% 50%,同時(shí)mask-repeat的值為no-repeat以及每個(gè)mask-image自身的位置。
$grad-list: ();@for $i from 0 to 4 {$x: ($i%2)*100%;$y: floor($i/2)*100%;$grad-list: $grad-list radial-gradient(circle at $x $y, var(--stop-list)) /* mask image */$x $y; /* mask position */ }.box {/* same as before *//* any CSS background we wish */--stop-list: transparent var(--r, 50px), #000 0;mask: $grad-list;mask-size: 50% 50%;mask-repeat: no-repeat; }但這里有一個(gè)大問題,一般情況下,我們的四分之一計(jì)算的每個(gè)部分會(huì)經(jīng)過四舍五入,那么這四個(gè)部分重新組合在一起的時(shí)候,width和height都有可能產(chǎn)生間距。如下圖所示:
好吧,我們不能用linear-gradient()來做這個(gè)線條或者說把mask-size的尺寸增加到51%。比如下面的這個(gè)示例,增加了mask-size的尺寸來處理四個(gè)漸變區(qū)載之間的間距。
但是,難道沒有更優(yōu)雅的方式來處理這個(gè)間距?不是的,可以使用mask-composite屬性來幫我們處理。當(dāng)我們返回全部漸變的全尺寸時(shí),可以把mask-composite的值設(shè)置為intersect。
$grad-list: ();@for $i from 0 to 4 {$grad-list: $grad-list, radial-gradient(circle at ($i%2)*100% floor($i/2)*100%, var(--stop-list)); }.box {/* same as before *//* any CSS background we wish */--stop-list: transparent var(--r, 50px), #000 0;mask: $grad-list;mask-composite: exclude; }這非常酷,因?yàn)樗羌僀SS的解決方案,沒有使用任何SVG代碼,但不幸的是,目前得能看到效果的也僅限于Firefox53+。
corner-shape
大約在五年前,@Lea Verou提出了一個(gè)想法,甚至還為它創(chuàng)建了一個(gè)預(yù)覽頁面。遺憾的是,它不僅沒有被任何瀏覽器實(shí)現(xiàn),而且在此期規(guī)范還沒有得到很大的提高。對(duì)于未來,它仍然是值得期待的,因?yàn)樗峁┝撕芏囔`活性,而且代碼非常少。比如說,實(shí)現(xiàn)我們前面所說的效果,只需要以下幾行代碼:
padding: var(--r); corner-shape: scoop; border-radius: var(--r);就是一個(gè)非常簡單的CSS。是不是值得期待,但最終還是要看瀏覽器什么時(shí)候會(huì)對(duì)其支持。
CSS Houdini
CSS Houdini慢慢的開始進(jìn)入大家的世界當(dāng)中,試問一下,我們使用CSS Houdini是不是可以更方便的實(shí)現(xiàn)這個(gè)內(nèi)凹角的效果呢?比如像下面這樣的一個(gè)效果,它就是使用CSS Houdini實(shí)現(xiàn)的:
咱們不仿嘗試一下使用Paint Worklet或者CSS Paint API來實(shí)現(xiàn)呢?請(qǐng)開動(dòng)你的大腦,動(dòng)手?jǐn)]一擼。希望您能把你的成果在下面的評(píng)論中與大家一起分享?如果你感興趣,也可以在下面的評(píng)論中留言,我們后續(xù)可以專門花一點(diǎn)時(shí)間來看看CSS Houdini可以實(shí)現(xiàn)內(nèi)凹角的效果,甚至是前面所講的斜外切口的效果。
構(gòu)建一個(gè)內(nèi)凹角的Vue組件
記得在《使用Vue制作切口盒子組件》一文中,咱們就嘗試使用Vue構(gòu)建了一個(gè)斜外切口的Vue組件c-noth:
那么我們來看看怎么使用Vue來構(gòu)建一個(gè)內(nèi)凹角的組件,具體代碼如下:
特別聲明,如果您的瀏覽器沒有看到任何效果,請(qǐng)使用Firefox 53+瀏覽器查閱。具體原因,前面文章已經(jīng)介紹過來了。
為了照顧其他同學(xué)查看最終的效果,我錄了一個(gè)屏:
這就是最終的效果。由于我自己是Vue的初學(xué)者,現(xiàn)在有一個(gè)病,看到什么東西都想用Vue來寫,而且想封裝成一個(gè)組件。如果寫得不好,或者有更好的方案,歡迎大家指點(diǎn),并且希望能看到您的分享的成果。如果你和我一樣,也是Vue的一個(gè)初學(xué)者,可以和我一起來學(xué)習(xí)Vue。整理了一些有關(guān)于Vue的學(xué)習(xí)筆記,希望大家能喜歡,更希望能幫助到初學(xué)者,同時(shí)也希望不會(huì)誤人子弟。
總結(jié)
文章開頭拋出了怎么實(shí)現(xiàn)內(nèi)凹角的一個(gè)效果。首先從CSS的box-shadow著手,使用CSS的box-shadow可以輕易的實(shí)現(xiàn)內(nèi)凹角的效果,但這個(gè)方案有一定的局限性,比如要多個(gè)內(nèi)凹角時(shí),需要通過增加元素標(biāo)簽來實(shí)現(xiàn),特別是在面對(duì)漸變,或者有背景圖像和半透明的情景之下,這個(gè)方案基本上無法來滿足我們的需求。
接著探索了SVG的方案,通過SVG的mask和use之類的一些獨(dú)有的特性,可能靈活的幫助我們實(shí)現(xiàn)想要的效果,而且能做到box-shadow無法做到的事情。特別是通過CSS自定義屬性來修改SVG的屬性,讓事情變得更具靈活性,只不過部分瀏覽器還不支持CSS來修改SVG的屬性,這算是其中的一個(gè)坑吧。不過我們還是可以規(guī)避掉的。
雖然SVG能實(shí)現(xiàn)想要的效果,但對(duì)于一位CSS執(zhí)著者而言,總是希望不借助其他的外力,通過純CSS來實(shí)現(xiàn)這個(gè)效果,事實(shí)上也是可以的,使用CSS的徑向漸變和mask相關(guān)的知識(shí),可以實(shí)現(xiàn)我們想要的效果。遺憾的是,目前眾多瀏覽器對(duì)mask還是有所保留,未能全面支持。比如文中提到的,很多mask相關(guān)的特性,僅能在Firefox 53+上看到。包括咱們寫的示例,有些僅能在Firefox上看到。
隨著CSS Houdini技術(shù)越來越成熟,我在試想,是否可以通過CSS Houdini來實(shí)現(xiàn)。正如@Lea Verou五年前提出的corner-shape屬性。我想是可以的,后面可以嘗試動(dòng)手寫寫。當(dāng)然,CSS Houdini雖然還沒有得到所有瀏覽器支持,但這并不防礙我們?nèi)L試著寫各種效果。有興趣的一起動(dòng)手寫寫,看看這個(gè)想法是否能成真。
最后為了能練習(xí)Vue相關(guān)的知識(shí),嘗試使用Vue封裝了一個(gè)簡單的凹角組件。寫得比較拙逼,希望能得到大神的指點(diǎn)。
最后的最后,需要特別感謝@ANA TUDOR寫了這么優(yōu)秀的教程。我在原作者的基礎(chǔ)上做過一些調(diào)整,如果你覺得這里整理和不好,可以查閱原文。
大漠
常用昵稱“大漠”,W3CPlus創(chuàng)始人,目前就職于手淘。對(duì)HTML5、CSS3和Sass等前端腳本語言有非常深入的認(rèn)識(shí)和豐富的實(shí)踐經(jīng)驗(yàn),尤其專注對(duì)CSS3的研究,是國內(nèi)最早研究和使用CSS3技術(shù)的一批人。CSS3、Sass和Drupal中國布道者。2014年出版《圖解CSS3:核心技術(shù)與案例實(shí)戰(zhàn)》。
原文發(fā)布時(shí)間為:2018年04月23日
原文作者:掘金
本文來源:?掘金?如需轉(zhuǎn)載請(qǐng)聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的CSS如何实现内凹角效果 By 大漠的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于Object.definePrope
- 下一篇: nginx basic auth配置踩坑