CSS3系列-css3之線性漸變初探
CSS3系列-css3之線性漸變初探
1.寫在前面
入行前端一年多的時間,想提高自己的css技術水平,于是在網上看了些關于css的書籍,想買幾本比較好的css書籍啃啃,找來找去,終于找到了《CSS揭秘》這本書。入手這本書后,從開始看到后面,發現書中的很多效果都可以使用漸變來實現,于是,我對漸變產生了興趣,決定好好掌握css3中的這個屬性。結合 《CSS揭秘》 、 張鑫旭 大神的 深入理解CSS3 gradient斜向線性漸變 和 CSS3 radial-gradient徑向漸變語法及輔助理解案例10則 以及其他的文章,并總結自己的學習過程,于是誕生了這篇關于css3中的漸變文章。
漸變是是以背景圖的形式呈現在頁面中的, 漸變的本質是background-image 。在css3中,漸變可以分為線性漸變(linear-gradient)和徑向漸變(radial-gradient)。線性漸變是沿著漸變線進行漸變,而徑向漸變則是沿著橢圓或者圓形進行四周漸變。
2.線性漸變linear-gradient
2.1 基本語法
background-image: linear-gradient( [ <angle> | <side-or-corner> ,]? <color-stop> [, <color-stop>]+ );
[] 在正則表達式中是一個字符類,這里理解為一個小單元即可;
| 表示或者的意思,要么選擇前面,要么選擇后面;
?表示0個或者1個意思。即如果不指定方向,直接可以直接使用漸變色;
+加號, 表示1個或者多個。
2.1.1 角度angle
提問:如果angle是45deg,漸變顏色由 deepink 到 yellow 的漸變,請問下面哪副圖是正確的?
正確答案: B
這個理解與我們所熟知的css3旋轉某一個角度有一定的出入,比如,css3中旋轉90度的效果是這樣的:
而在線性漸變中,漸變的角度默認是從下到上的垂直方向開始順時針進行旋轉的,我們可以理解為時鐘針旋轉的方向,如下圖所示:
漸變角度指明了線性漸變的方向,0deg表示從上向下漸變;90deg表示從左向右漸變;180deg表示從下向上漸變;270deg表示從右向左漸變;360deg表示從下向上漸變。漸變的角度效果如圖所示:
在上面的這個例子中,0deg->360deg的效果其實就是順時針旋轉一圈。
2.1.2 side-or-corner
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的標準語法,低版本瀏覽器需要使用各瀏覽器前綴;
- IE10版本以下不支持漸變;
- 新版chrome和firefox已經去掉了私有前綴,加了私有前綴與不加私有前綴方向有出入(如果加了私有前綴,則right為0deg,然后逆時針轉一圈);
- oper從37開始支持,沒有私有前綴,加了反而不認;
本文將以W3C標準語法講解線性漸變 linear-gradient ,徑向漸變 radial-gradient 將在下一篇文章中推出
2.1.3 color-stop
<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;
}</code></pre>

對比想要的圖以及實際效果圖,為什么得到線條的寬度比我們想要的線條寬度要小,難道是瀏覽器出問題了,no,是我們自己錯了。這就需要深入理解漸變的長度了。
2.2 線性漸變的漸變長度的理解
如何確定漸變線的長度?我們可以從官網的解釋中找到答案:

漸變線是過漸變區域中心的一條直線,而漸變的起點和終點是在與漸變線的垂直線上。如果給定漸變的區域和漸變的方向,我們就能夠確定漸變的起始點和總長度了。因此在下面的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 后,得到了我們想要的效果圖。
2.3 線性漸變的案例
2.3.1 利用線性漸變生成條紋
在上面的例子中,我們已經使用線性漸變生成了水平和垂直條紋,這里就不在贅述。
2.3.2 利用線性漸變生成多背景圖片
在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)) )。
2.3.3 利用線性漸變生成比例可控的虛線
在實際開發中,如果需要虛線,我們一般會設置 border-style:dashed ,然而這種方法存在一個問題: 實線和虛線的比例是一定的 。在Chrome和Firefox瀏覽器下,顏色區的寬高比是 3:1 ,顏色和透明區的寬度比例是 1:1 :

而在IE瀏覽器下,顏色區的寬高比是 2:1 ,顏色區和透明區的寬度比例也是 2:1 :

如果設計師設計的UI中,要求虛線的顏色區的寬高比是 5:3 ,實線與虛線的比例是 1:1 ,此時使用 border-style:dashed 就達不到設計師設計的效果了。有兩種方法可以解決這個問題:
- 要求設計師改UI,這么low X的事難道是我們前端工程師做的嗎?
- 查閱資料,使用其他方法實現設計師想要的效果,正確選擇!
這里,我們就可以使用 linear-gradient 到達設計師想要的效果:
.demo{
height: 3px;
background: linear-gradient(to right, #000, #000 5px, transparent 5px, transparent);
background-size: 10px 100%;
}
對應的效果如下:

2.3.4 利用線性漸變生成帶線框的三角
考慮下面的場景,我們需要生成一個對話框:

我們可能絕大多數使用下面的做法:
.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;
}

哇,看起來不錯額,今晚可以和妹子約起了。。。 
2.3.5 利用線性漸變生成加號和減號
考慮有以下需求:

- 切圖,使用小圖片;
- 傳統方法,使用 ::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;
}</code></pre>
使用線性漸變方法:
.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;
}</code></pre>

這種方法生成加號和等號與傳統使用 ::before 和 ::after 以及配合 background-color 和 border 相比,使用漸變背景生成的好處是居中定位方便。
2.3.6 利用線性漸變生成切角效果
直接看代碼:
<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揭秘》相關章節),如:

2.3.7 利用線性漸變實現信封效果
<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;
}</code></pre>

2.3.8 利用線性漸變實現裁剪效果
<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%; }
}</code></pre>
在瀏覽器中的效果如下:

如果將 boder 修改為 1px solid transparent ,可以看到下面的效果:

2.4 更多線性漸變的應用
更多關于線性漸變的應用可以查看 這里
這里的圖形都是使用線性漸變實現的,可見CSS3中線性漸變功能之強大!

4 更多關于線性漸變的東西
除了線性漸變 linear-gradient ,css3中還支持重復線性漸變 reapting-linear-gradient 。
-
利用重復線性漸變實現斜向條紋的效果,與線性漸變相比,不需要苦苦思考生成一個重復單元,直接改變漸變的角度以及尺寸即可。
background: repeating-linear-gradient(60deg,#fb3, #fb3 15px, #58a 0, #58a 30px);
?

5 寫在最后
如果想對提高自己的csss水平,推薦《CSS揭秘》,很不錯額。

感謝閱讀。
6 參考鏈接
遇見了,不妨關注下我的微信公眾號「前端Talkking」

來自:https://segmentfault.com/a/1190000012882599