入行前端一年多的時間,想提升本身的css技術水平,因而在網上看了些關於css的書籍,想買幾本比較好的css書籍啃啃,找來找去,終於找到了《CSS揭祕》這本書。入手這本書後,從開始看到後面,發現書中的不少效果均可以使用漸變來實現,因而,我對漸變產生了興趣,決定好好掌握css3中的這個屬性。結合《CSS揭祕》、張鑫旭大神的深刻理解CSS3 gradient斜向線性漸變和CSS3 radial-gradient徑向漸變語法及輔助理解案例10則以及其餘的文章,並總結本身的學習過程,因而誕生了這篇關於css3中的漸變文章。javascript
漸變是是以背景圖的形式呈如今頁面中的,漸變的本質是background-image。在css3中,漸變能夠分爲線性漸變(linear-gradient)和徑向漸變(radial-gradient)。線性漸變是沿着漸變線進行漸變,而徑向漸變則是沿着橢圓或者圓形進行四周漸變。css
background-image: linear-gradient( [ <angle> | <side-or-corner> ,]? <color-stop> [, <color-stop>]+ );
[] 在正則表達式中是一個字符類,這裏理解爲一個小單元便可;html
| 表示或者的意思,要麼選擇前面,要麼選擇後面;前端
?表示0個或者1個意思。即若是不指定方向,直接能夠直接使用漸變色;java
+加號, 表示1個或者多個。css3
提問:若是angle是45deg,漸變顏色由deepink
到yellow
的漸變,請問下面哪副圖是正確的?正則表達式
正確答案:Bchrome
這個理解與咱們所熟知的css3旋轉某一個角度有必定的出入,好比,css3中旋轉90度的效果是這樣的:瀏覽器
而在線性漸變中,漸變的角度默認是從下到上的垂直方向開始順時針進行旋轉的,咱們能夠理解爲時鐘針旋轉的方向,以下圖所示:微信
漸變角度指明瞭線性漸變的方向,0deg表示從上向下漸變;90deg表示從左向右漸變;180deg表示從下向上漸變;270deg表示從右向左漸變;360deg表示從下向上漸變。漸變的角度效果如圖所示:
在上面的這個例子中,0deg->360deg的效果其實就是順時針旋轉一圈。
side-or-corner的中文意思是邊或者角的意思。在垂直方向的可選值有:top
、center
、bottom
,在水平方向的可選值有left
、center
、right
。默認值爲center bottom,即從上向下漸變。能夠用to + side-or-corner關鍵字聯合起來使用,若是不加to,則表示漸變的起始點,加上to則表示漸變的方向。例如:to top等價於0deg,to right等價於90deg,to bottom等價於180deg,to left等價於270deg。相關效果以下圖所示:
不一樣版本瀏覽器中使用注意:
本文將以W3C標準語法講解線性漸變linear-gradient
,徑向漸變radial-gradient
將在下一篇文章中推出
<color> [ <percentage> | <length> ]
指明線性漸變的顏色、起點、終點。翻譯成中文就是:顏色+空格+百分比或者長度值。
background: linear-gradient(#fb3 20%, #58a 80%);
如今頂部20%的區域被填充爲#fb3
的實色,底部20%的區域被填充爲#58a
的實色,真正漸變的區域在20%到80%高度的區域。若是將兩個色標拉近,將兩個色標重合在一塊兒:
background: linear-gradient(#fb3 50%, #58a 50%);
「若是多個色標具備相同的位置,它們會產生一個無限小的過渡區域,過渡的起止色分別是第一個和最後一個指定值。從效果上看,顏色會在那個位置忽然變化,而不是一個平滑的漸變過程。」
——CSS 圖像(第三版)( http://w3.org/TR/css3-images)
由於漸變是一種由代碼生成的圖像,咱們能像對待其餘任何背景圖像那樣對待它,並且還能夠經過background-size 來調整其尺寸:
<div class="box"></div>
.box{ width: 200px; height: 90px; background: linear-gradient(#fb3 50%, #58a 50%); background-size: 100% 30px; }
若是是垂直條紋,代碼以及效果以下:
<div class="box"></div>
.box{ width: 210px; height: 90px; background: linear-gradient(to right, #fb3 50%, #58a 50%); background-size: 30px 100%; }
爲了不每次改動條紋寬度時都要修改兩個數字,咱們能夠再次從規範那裏找到捷徑。
「若是某個色標的位置值比整個列表中在它以前的色標的位置值都要小,則該色標的位置值會被設置爲它前面全部色標位置值的最大值。」
——CSS 圖像(第三版)( http://w3.org/TR/css3-images)
對於水平和垂直漸變條紋咱們很好理解。若是是斜向漸變,咱們想獲得條紋的寬度爲15px,咱們能夠這樣寫:
<div class="box"></div>
.box{ width: 200px; height: 100px; background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0); background-size: 30px 30px; }
對比想要的圖以及實際效果圖,爲何獲得線條的寬度比咱們想要的線條寬度要小,難道是瀏覽器出問題了,no,是咱們本身錯了。這就須要深刻理解漸變的長度了。
如何肯定漸變線的長度?咱們能夠從官網的解釋中找到答案:
漸變線是過漸變區域中心的一條直線,而漸變的起點和終點是在與漸變線的垂直線上。若是給定漸變的區域和漸變的方向,咱們就可以肯定漸變的起始點和總長度了。所以在下面的css樣式中:
.box{ width: 200px; height: 100px; background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0); background-size: 30px 30px; }
咱們能夠用下面的這幅圖來計算漸變的長度,咱們指定了區域的大小時30px,根據勾股定理
,能夠計算直角三角形的斜邊長度。所以,咱們計算獲得的條紋的寬度實際是:15/1.414=10.606
,比咱們須要的寬度15p要小。
$$ 15/√2 $$
這就意味着,若是想要讓條紋的寬度變化爲咱們本來想要的15px,就須要將background-size
指定爲2*15*1.4=42.426px
。
咱們來看下修改後的效果,修改background-size
後,獲得了咱們想要的效果圖。
在上面的例子中,咱們已經使用線性漸變生成了水平和垂直條紋,這裏就不在贅述。
在CSS3中,backgrounds支持多背景,越前面的背景越處於上面,也就是背景能夠無限累加,而漸變的本質是background-image,因此咱們能夠實現任意數量的漸變背景圖的疊加效果。
有以下圖片:
咱們添加透明值:linear-gradient(to bottom left, #fc3, rgba(255,255,255,0))
.demo{ width: 250px; height: 156px; background: linear-gradient(to bottom left, #fc3, rgba(255,255,255,0)), url(./flower.jpg); }
獲得的效果以下:
咱們能夠利用這一點,來給背景添加不一樣的效果,如讓圖片不可見(修改成:linear-gradient(to bottom left, #fff, rgba(255,255,255,0))
)。
在實際開發中,若是須要虛線,咱們通常會設置border-style:dashed
,然而這種方法存在一個問題:實線和虛線的比例是必定的。在Chrome和Firefox瀏覽器下,顏色區的寬高比是3:1
,顏色和透明區的寬度比例是1:1
:
而在IE瀏覽器下,顏色區的寬高比是2:1
,顏色區和透明區的寬度比例也是2:1
:
若是設計師設計的UI中,要求虛線的顏色區的寬高比是5:3
,實線與虛線的比例是1:1
,此時使用border-style:dashed
就達不到設計師設計的效果了。有兩種方法能夠解決這個問題:
這裏,咱們就可使用linear-gradient
到達設計師想要的效果:
.demo{ height: 3px; background: linear-gradient(to right, #000, #000 5px, transparent 5px, transparent); background-size: 10px 100%; }
對應的效果以下:
考慮下面的場景,咱們須要生成一個對話框:
咱們可能絕大多數使用下面的作法:
.talk { display: inline-block; max-width: 80%; border: 1px solid blue; border-radius: 3px; padding: 6px 10px; font-size: 14px; position: relative; }
.talk:before { content: ''; position: absolute; width: 6px; height: 6px; border: 1px solid blue; border-right: 0; border-bottom: 0; left: -4px; top: 13px; transform: rotate(-45deg); background-color: #fff; }
若是背景不是白色:
.talk { display: inline-block; max-width: 80%; border: 1px solid blue; border-radius: 3px; padding: 6px 10px; background: linear-gradient(to right, deeppink, yellow); font-size: 14px; position: relative; }
能夠看到若是背景色不是白色,旋轉後的效果就有一個多餘的三角形,不是咱們想要的效果,咱們可能嘗試這樣修改css代碼:
.talk:before { content: ''; position: absolute; display: inline-block; width: 0; height: 0; border-top: 5px solid transparent; border-right: 5px solid blue; border-bottom: 5px solid transparent; left: -5.1px; top: 12px; }
額,比上面的效果好多了,可是三角與邊框交接的區域多了一個線條,與咱們想要的效果仍是有出入,此時咱們使用線性漸變看看,以下css所示:
.talk:before { content: ""; position: absolute; width: 6px; height: 6px; background: linear-gradient(to top, blue, blue) no-repeat, linear-gradient(to right, blue, blue) no-repeat, linear-gradient(135deg, #fff, #fff 5.2px, hsla(0, 0%, 100%, 0) 5.2px) no-repeat; background-size: 60px 1px, 1px 60px, 60px 60px; transform: rotate(-45deg); left: -4px; top: 13px; }
哇,看起來不錯額,今晚能夠和妹子約起了。。。
考慮有如下需求:
::before
和::after
僞元素配合實現;<a href="javascript:" class="btn btn-plus" role="button"></a> <a href="javascript:" class="btn btn-minus" role="button"></a>
傳統方法:
.btn { display: inline-block; background: #f0f0f0 no-repeat center; border: 1px solid #d0d0d0; width: 24px; height: 24px; border-radius: 2px; color: #666; transition: color .2s; } .btn-plus{ position: relative; } .btn-plus:before{ content: ''; position: absolute; width: 10px; height: 2px; background-color: currentColor; left: 50%; top: 50%; margin-top: -1px; margin-left: -5px; } .btn-plus:after{ content: ''; position: absolute; width: 2px; height: 10px; background-color: currentColor; left: 50%; top: 50%; margin-top: -5px; margin-left: -1px; }
使用線性漸變方法:
.btn { display: inline-block; background: #f0f0f0 no-repeat center; border: 1px solid #d0d0d0; width: 24px; height: 24px; border-radius: 2px; color: #666; transition: color .2s; } .btn-plus { background-image: linear-gradient(to top, currentColor, currentColor), linear-gradient(to top, currentColor, currentColor); background-size: 10px 2px, 2px 10px; } .btn-minus { background-image: linear-gradient(to top, currentColor, currentColor); background-size: 10px 2px; }
這種方法生成加號和等號與傳統使用::before
和::after
以及配合background-color
和border
相比,使用漸變背景生成的好處是居中定位方便。
直接看代碼:
<div class="clip"></div>
.clip{ width: 150px; height: 150px; background: #58a; background: linear-gradient(135deg, transparent 15px, deeppink 0) top left, linear-gradient(-135deg, transparent 15px, yellow 0) top right, linear-gradient(-45deg, transparent 15px, blue 0) bottom right, linear-gradient(45deg, transparent 15px, green 0) bottom left; background-size: 50% 50%; background-repeat: no-repeat; }
利用線性漸變還能夠實現折角效果(計算稍微複雜,詳細計算步驟能夠看《css揭祕》相關章節),如:
<div class="demo2">重複漸變實現信封效果</div>
.demo2{ width: 300px; font-size: 18px; padding: 10px; border: 10px solid transparent; background: linear-gradient(white, white) padding-box, repeating-linear-gradient(-45deg, red 0, red 12.5%, transparent 0, transparent 25%, #58a 0, #58a 37.5%, transparent 0, transparent 50%) 0 / 60px 60px; }
<div class="clip">這裏是文字</div>
.clip{ padding: 1em; border: 10px solid transparent; background: linear-gradient(white, white) padding-box, repeating-linear-gradient(-45deg, black 0, black 25%, transparent 0, transparent 50%) 0 / 10px 10px; animation: ants 12s linear infinite; max-width: 20em; } @keyframes ants { from { background-position: 0 0; } to { background-position: 100% 100%; } }
在瀏覽器中的效果以下:
若是將boder
修改成1px solid transparent
,能夠看到下面的效果:
更多關於線性漸變的應用能夠查看這裏
這裏的圖形都是使用線性漸變實現的,可見CSS3中線性漸變功能之強大!
除了線性漸變linear-gradient
,css3中還支持重複線性漸變reapting-linear-gradient
。
利用重複線性漸變實現斜向條紋的效果,與線性漸變相比,不須要苦苦思考生成一個重複單元,直接改變漸變的角度以及尺寸便可。
background: repeating-linear-gradient(60deg,#fb3, #fb3 15px, #58a 0, #58a 30px);
若是想對提升本身的csss水平,推薦《CSS揭祕》,很不錯額。
喜歡的話,就點個贊吧。感謝閱讀。
碰見了,不妨關注下個人微信公衆號「前端Talkking」