是時候繼續我的雲陪讀計劃了 😂。
《精通 CSS》往期陪讀章節:
今天我們要閱讀的章節是《精通 CSS》的第五章 漂亮的盒子。
前面我們了解過了盒模型,知道盒子由外邊距、邊框、內邊距和內容區組成。對於整個盒子,我們可以通過一系列的手段來美化,如指定盒子的背景、邊框以及盒子的陰影。
本文將從這三個方面來介紹如何美化一個盒子。
本章文中示例代碼託管在CodeSandbox[1],請按需取用
一、設置盒子的背景背景相關的屬性有很多,接下來歪馬一個一個給大家展示。先來看一下背景顏色。
1.1 設置背景顏色首先,我們創建一個盒子,然後我們給它設置一個顏色。設置什麼顏色好呢,呃,那就基佬紫吧。
可以通過下面兩種方式設置背景顏色,如下:
/* 方式1 */
background-color: #9a08e3;
/* 方式2 */
background: #9a08e3;這兩種方式設置之後,效果都如下:
雖然上面兩種方式都能設置背景顏色,不過我們需要注意的是,簡寫背景屬性不僅僅會設置背景顏色,還會把其他背景相關屬性設置為默認值,如果不注意可能會覆蓋其他值。
關於顏色,現在 CSS 支持設置 16 進位表示的顏色、rgb()/rgba()以及hsl()/hsla()。其中的rgba()和hsla()除了可以設置顏色值之外,還可以設置顏色的透明度。
CSS 中還有另外一個屬性opacity可以設置透明度,這個屬性會把整個盒子變的透明,而不單單是背景色。
關於顏色的原理大家感興趣可以參考文博大佬的這份 PPT[2]。
1.2 設置漸變色背景你可能會說,純色的基佬紫不夠「騷」,不符合你的氣質。如果是這樣的話,歪馬向你推薦漸變色背景。
雖然說叫作漸變色,但其實是一種繪製漸變圖的機制。這個機制可以與任何接受圖片的屬性一起使用,本文我們用到的是background-image。
漸變方案包括線性漸變、放射漸變、重複漸變。下面我們挨個看過。
1.2.1 線性漸變首先是linear-gradient()線性漸變函數,線性漸變會沿著一條假想線,繪製一個顏色漸變的圖片。它支持逗號分隔的多組值。如下:
background-image: linear-gradient(45deg, #d041e8 0%, #9a08e3 100%);其中第一組值可以表示這條假想線的延伸方向,可以是角度值也可以是關鍵字。假想的漸變線會按照指定的方向,穿過元素的中心區域。
其中,關鍵字形式是使用to後面加上某個邊(top/right/bottom/left)或某個角top left/top right/bottom-left/bottom right。使用角度值deg時,0deg表示垂直向上,增大角度值則沿順時針旋轉。
漸變線的示意圖如下:
圖片來源W3C表示方向的值可以省略,默認是to bottom,用角度值表示就是180deg。
表示方向的值後面的各組值表示漸變的顏色色標,至少要有兩組值,一組值時無漸變效果。
新增的色標如果未指定位置,則在 0%~100%範圍內取均值。
除了百分比,我們也可以使用絕對單位來指定色標位置。
各類用法的效果如下圖所示:
1.2.2 放射漸變除了上面按照直線進行漸變的線性漸變,還有一種可以從中心向四周漸變的效果,叫做放射漸變,也叫徑向漸變,對應的 CSS 屬性是radial-gradient。
放射漸變的語法比較複雜。主要有以下幾點:
首先,放射漸變也接受多組值,第一組可以指定放射漸變的類型(原型circle和橢圓形ellipse)以及漸變的起始位置,漸變半徑或者結束位置。默認的漸變類型是橢圓形。圓形放射漸變的射線半徑只接受一個半徑值,值類型為長度值,不能是百分比(這是因為盒子不是方的,百分比無法判斷用盒子的寬還是高)。橢圓形則可以接受 x 和 y 軸兩個方向的半徑值,值的類型可以是長度值和百分比。除此之外,半徑還可以使用關鍵字,closest-side表示最近的邊,farthest-side表示最遠的邊,closest-corner表示最近的角,farthest-corner表示最遠的角(默認值)。漸變的起始位置類似於backgound-positon 在第一組值中用at表示,默認為居中。除了第一組值(第一組值也可以省略),其後的值為色標,也可以像線性漸變一樣指定不同的色標加位置。如果指定的色標位置大於上面的漸變半徑,最後的漸變區域會變大,超過漸變半徑。具體的例子和效果如下。
1.2.3 重複漸變為了便於大家進行創作,上面的兩種漸變還有這對應的重複漸變。
重複漸變會自動重複給出的漸變色標組合,重複次數視其大小(由 background-size 決定)和盒子大小決定。
如下,我們可以使用重複線性漸變實現格子桌布的效果。
background-image: repeating-linear-gradient(
to bottom,
transparent 0,
transparent 10px,
rgba(208, 65, 232, 0.3) 10px,
rgba(208, 65, 232, 0.3) 20px
),
repeating-linear-gradient(
to right,
transparent 0,
transparent 10px,
rgba(208, 65, 232, 0.3) 10px,
rgba(208, 65, 232, 0.3) 20px
);使用重複放射漸變可以實現類似下面的效果:
background-image: repeating-radial-gradient(
circle closest-side,
transparent 0,
transparent 20px,
rgba(208, 65, 232, 0.3) 20px,
rgba(208, 65, 232, 0.3) 40px
);上面這些都是基本操作,CSS 是充滿想像力的,大家可以看一看 Lea Verou 的CSS3 Patterns Gallery[3],上面有很多更豐富的效果。下圖僅供參考。
比如我們也把上面的放射漸變改吧改吧,就可以實現美國隊長的盾牌的效果。
<div class="shield">
<span>★</span>
</div>.shield {
width: 400px;
height: 400px;
text-align: center;
line-height: 400px;
border-radius: 50%;
margin: 50px auto;
background-image: radial-gradient(
circle closest-side,
#2930ae 0,
#2930ae 50px,
#c8143c 50px,
#c8143c 100px,
#fff 100px,
#fff 150px,
#c8143c 100px,
#c8143c 100px
);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5), 0 1px 5px rgba(0, 0, 0, 0.5),
1px 0 5px rgba(0, 0, 0, 0.5);
}
.shield > span {
top: 50%;
transform: translate(-50%, -50%);
font-size: 80px;
color: #ffffff;
text-shadow: 0px 0px 5px #333, 0px 1px 5px #333, 1px 0px 5px #333,
1px 1px 5px #333;
}
1.3 設置背景圖片說到設置背景圖片,我們首先要想明白一個問題,什麼時候圖片應該用作背景圖片,而不是<img>。通常,如果把圖片從網頁中去掉,不會影響網頁的意義,那麼圖片就可以用作背景圖片。當然,如果為了實現特定效果,也可以稍微做一下妥協。
背景圖片的語法格式比較簡單,如下:backgroung-image: <url> | <gradient>。漸變作為背景,上面我們已經說了。常見的 URL 形式的背景圖片設置大家一定也用過。
如下我們簡單的設置下背景圖片:
.bg-iamge {
width: 1000px;
height: 600px;
margin: 40px auto;
border: 10px solid lightcoral;
background-image: url("https://p2.ssl.qhimg.com/t0127f74a63ca750596.png");
}如果只是這麼做的話,可能達不到你想要的效果,而是下面這樣的。
我們會發現,圖片重複平鋪了整個元素,這是因為除了設置背景圖片,我們還有很多屬性來操作背景圖片,從而達到我們想要的效果。
下面我們依次了解一下background-repeat、background-position、background-size、background-clip、background-origin、background-attach、background的簡寫形式以及多重背景。
1.3.1 background-repeat上面的背景圖片之所以會重複是因為background-repeat屬性的默認值是repeat。如果我們想要不重複,則可以設置no-repeat。當然也可以設置repeat-x和repeat-y來指定圖片沿著某個軸的方向重複。
除此之外,Backgrounds and Borders Level 3[4]進行了下面兩個擴展:
支持以空格分隔來指定針對兩個方向的關鍵字聲明語法,如background-repeat: repeat no-repeat;增加了新的關鍵字:space如果圖片可以在元素內重複兩次以上,則重複,且圖片之間填充空白。round則圖片會被縮放,從而重複整數次。哈哈,這些新的特性感覺並沒有太大用處,本文,我們先禁用圖片的重複background-repeat: no-repeat;,效果如下:
如上,我們雖然禁用了圖片的重複,但是最後的效果並不好,這是因為背景圖片的位置是在左上角。下面我們一起來看看如何調整背景圖片的位置。
1.3.2 background-positionbackground-position屬性的值既可以使用關鍵字,也可以是像素、em或百分比,可以指定兩個值,分別表示相對於左側的偏移量和相對於頂部的偏移量。關鍵字包括用於 x 軸的left/cener/right和用於 y 軸的top/center/bottom,規範沒有約定兩個值的先後順序。不過歪馬建議大家不管使用什麼值,都先指定 x 軸,再指定 y 軸。
使用像素和em與使用百分比進行背景定位時,計算方式是不一樣的。使用像素和em時,會一直以圖片的左上角相對於父元素(左側和頂部)來計算。使用百分比時,則是以圖片中對應比例的點定位到父元素對應比例的點。百分比的定位效果如下:
百分比的定位效果(圖片來源W3C)此外,還需要注意,關鍵字和其他值不可以混用,否則會失效。
除此之外,在CSS Backgrounds and Borders Module Level 3[5]中,background-position引入了新語法,可以先寫邊界關鍵字,再寫長度值。寫法如下:
background: url(https://p1.ssl.qhimg.com/t015bb5c7be246fb2af.jpg) no-repeat right center;
background-position: right 10px top 50%;關於背景的定位,歪馬前兩天單獨拎出了一篇相關的文章《CSS 實現背景圖片右側定位的 5 種小技巧》,沒有看到的各位可以點擊看一下。
本文,我們先將背景圖片的位置設為居中,如下:
background-position: center;這樣看起來正常多了,但是背景圖的大小和盒子的大小差距過大。下面我們來調整一下背景圖的大小。
1.3.3 background-sizebackground-size可以接受明確的長度值和百分比。可以指定兩個值,第一個值是 x 軸的尺寸,第二個是 y 軸的尺寸,如果第二個省略,則值為auto。
使用明確的長度值是,會將背景圖片設為固定大小。使用百分比,可以讓圖片隨著元素縮放,百分比是根據容器大小計算的。
由於圖片是有固定尺寸的,比較推薦將其中一個設為指定值,另一個設為auto。
除了指定值之外,background-size還可以接受關鍵字作為值:
contain: 保持圖片最大化,同時不改變圖片的寬高比,瀏覽器會自動決定哪一邊撐滿,哪一邊使用auto。cover: 縮放圖片直至圖片覆蓋整個元素,並且比例不變。本文,我們將背景大小設為cover,雖然會對元素進行一定的裁剪,但是會保證整個元素都有背景。效果如下:
1.3.4 background-clip背景裁剪與background-origin背景控制原點現在背景圖片是充滿整個元素的,但是現在我們想要給內部留一點空白間隙,這時我們可以藉助background-clip背景裁剪來實現。
background-clip支持的值有border-box(默認值)、padding-box、content-box。這三個值的含義顧名思義,歪馬就不多說了。指定不同的值,背景圖片會被裁成不同的大小。本文,我們將background-clip設為content-box,效果如下(加了內邊距):
background-clip是在原有背景圖片大小的基礎上進行裁剪。除了這樣,我們還可以藉助background-origin直接將背景元素限制在content-box內容盒子以內。
background-origin也支持border-box、padding-box、content-box這三個值,但是默認值是padding-box。同樣,我們將其值設為content-box,效果如下:
只是這樣你會發現,內邊距的空白間隙並不對,這是因為background-size: cover;導致圖片放大了,有一部分沒有被裁剪,所以顯示出來了。同時指定background-clip: content-box;就可以了。和上面的區別就在於背景圖被裁掉的區域減少了一點。
1.3.6 background的簡寫上面我們介紹了大部分背景相關的屬性,還有一個可以實現背景附著的background-attachment沒有介紹,它可以實現背景隨頁面滾動固定,感興趣的同學可以擴展一下。歪馬不多做介紹了。
下面我們要看一看background的簡寫形式,通過這個這個屬性可以設置上述跟背景相關的所有屬性,一般情況下屬性的順序值可以隨意,瀏覽器會自動識別。但有以下兩點特殊:
由於background-position和background-size都支持長度值,所以要求聲明時兩者都要聲明,以/隔開,先聲明background-position,後聲明background-size。background-clip和background-origin都支持border-box、padding-box和content-box。存在兩個時,第一個用於background-origin,第二個用於background-clip。特別注意,使用簡寫屬性時省略的值會使用默認值,可能會覆蓋其他值,所以建議放在其他背景屬性前面。
如果你也像歪馬一樣覺得這樣的規則不好記的話,那就單獨寫吧。清晰明了,而且對新手友好。
1.3.7 多重背景background可以與linear-gradient/radial-gradient類似,可以支持逗號分隔的多組值,最先聲明的背景在最上層,最後聲明的在最下面。並且可以在最後設置純色。
關於背景的內容就這麼多了,下面我們來看看如何給元素設置圓角邊框/圖片邊框。
二、設置圓角邊框/圖片邊框2.1 元素的邊框元素邊框的屬性比較簡單。可以給某一邊設置,也可以給四邊設置。涉及到的屬性如下:
border-width:設置邊框寬度,border-top-width可以設置上邊寬度,其他三邊類似。border-color: 設置邊框顏色,border-top-color可以設置上邊顏色,其他三邊類似。border-style: 支持以下關鍵字solid實線、dashed虛線、dotted點虛線、double雙平行線、groove和inset。後面三種比較不常用,主要是由於不能主動控制樣式,會受到瀏覽器限制。單邊樣式設置與上面類似。border: 簡寫屬性可以同時指定上面三個屬性,順序不限。2.2 圓角邊框border-radius圓角邊框的普通用法與margin/pading類似,從左上角開始,順時針指定四個值。如果缺少,則和對角的相同。如果只設定一個值,則四個角應用同一個值。
如下:
border-radius: 4em 8em;除此之外,我們還以分別指定水平方向和垂直方向的垂直半徑。中間用/分隔。
如下所示:
border-radius: 4em 8em / 6em 4em;除了上面同時指定多個角的圓角半徑之外,我們還可以使用border-top-left-radius、border-top-right-radius等來分別設定某個角的圓角半徑,如果要水平和垂直分開指定,則也以/分隔。
通過設置不同的值,我們還可以實現橢圓、半橢圓、四分之一橢圓。
.ellipse-1 {
border-radius: 50%;
}
.ellipse-2 {
border-radius: 50% 50% 0 0 / 100% 100% 0 0;
}
.ellipse-3 {
border-radius: 100% 0 0 0 / 100% 0 0 0;
}
.ellipse-4 {
border-radius: 50% 0 50% 0 / 100% 0 100% 0;
}
2.3 圖片邊框圖片邊框歪馬也單獨拎出過一篇文章進行詳細講解,有興趣朋友點過去看下吧。這裡就不浪費篇幅詳述了。連結如下:《玩轉 CSS Border-Image》。
三、盒陰影box-shadow在《第 4 章 網頁排版》中,我們介紹過text-shadow。box-shadow與其類似,語法格式為box-shadow: <x偏移量> <y偏移量> <模糊半徑> <擴展半徑> <顏色值>。其中,多了擴展半徑,如果為正值則陰影向外擴大(擴大的部分不模糊),若為負值,則陰影向內縮小。
具體效果如下:
.spread-shadow {
box-shadow: 15px 15px 15px 10px #555;
}
.shrink-shadow {
box-shadow: 15px 15px 15px -10px #555;
}此外,我們還可以使用inset關鍵字將陰影變為內陰影。
最後與text-shadow類似,我們也可以通過逗號分隔,指定多組陰影值。
總結至此,歪馬的《第 5 章 漂亮的盒子》雲陪讀內容就結束了,本文對原文的內容結構進行了一定的調整,並且將其中比較有意思的內容單獨拎了出來,當然也存在部分的刪減,但是整體的主題都是圍繞如何美化盒子。
讀完之後,相信你一定 get 到了以下幾點:
如果你 get 到了,那麼再發散一下,美化你想實現的盒子吧。
文內連結[1]CodeSandbox: https://codesandbox.io/embed/jingtongcss-l8tye?fontsize=14&hidenavigation=1&theme=dark
[2]這份 PPT: https://ppt.baomitu.com/d/c887a533#/
[3]CSS3 Patterns Gallery: https://leaverou.github.io/css3patterns/
[4]Backgrounds and Borders Level 3: https://www.w3.org/TR/css-backgrounds-3/
[5]CSS Backgrounds and Borders Module Level 3: https://www.w3.org/TR/css-backgrounds-3/