《精通CSS》第5章 漂亮的盒子

2021-03-02 奇舞精選

是時候繼續我的雲陪讀計劃了 😂。

《精通 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-position

background-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-size

background-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/

相關焦點

  • 《精通CSS》第2章 添加樣式
    本書《精通 CSS》之前的章節:有效且結構良好的文檔是添加樣式的基礎。上一章,我們一起學習了相關的知識。現在是時候學習一下如何添加樣式了。參考資料[1]CSS Reset: https://meyerweb.com/eric/tools/css/reset/[2]Nicolas Gallagher 的 Normalize.css: http://nicolasgallagher.com/about-normalize-css/[3]CSS Pseudo-Elements Module Level
  • CSS的盒子模型和浮動,都在這了
    點關注,不迷路,每天分享大量前端知識css中的盒子模型 css處理網頁時,他認為每個元素都包含在一個不可見的矩形盒子 盒子是由 內容區,內邊距(padding),邊框,外邊距(margin)組成在瀏覽器中,其默認樣式中存在一些body等元素存在的默認樣式,比如一些外邊距
  • DIV+CSS學習筆記總結篇:盒子模型和塊元素、行元素與溢出
    第十三章 盒子模型盒子模型:盒子模型就是一個有高度和寬度的矩形區域所有html標籤都是盒子模型div標籤自定義盒子模型所有的標籤都是盒子模型class和id的主要差別是:class用於元素組(類似的元素,或者可以理解為某一類元素
  • 5日精通CSS層疊樣式表之第一天
    之後的5天,我們將漫遊樣式表的世界。你將學到樣式表的基本知識並將其應用於你的網頁中。你還將學到如何處理字體、圖文、色彩、背景及定位等的詳細技巧。今天,我們先瀏覽一下樣式表的基本內容。第1個問題;樣式表能為我們做什麼? 1.2 樣式表能為我們做什麼?
  • 【專欄試讀】(07)CSS 基本視覺格式化:① 「塊盒子」格式化 | CSS
    每個盒子的「布局」由以下因素決定(本篇文章和下一篇文章主要講解第 ①、② 點,其屬於「最基本的視覺格式化」,而對於剩下的要點,我們在接下來的系列文章中會挨個討論):① 盒子的尺寸:精確指定、由約束條件指定或沒有指定;② 盒子的類型:行內盒子(inline box)、行內級盒子(inline-level box)、原子行內級盒子(atomic
  • 弄懂css盒子模型從這幾點入手,新手建議收藏!
    怎麼理解盒子模型?盒子模型是樣式表(css)控制頁面的很重要的概念。如果理解了盒子模型和其中每個元素的用法,才能熟練使用css的定位方法和技巧。所有的頁面的元素都可以看成是一個盒子,佔據一定的頁面空間。佔據的空間要比實際使用的空間要大得多。
  • 《SamsaraRoom》第5章怎麼過 第5...
    導 讀 Samsara Room第5章(也就是蛋房間)怎麼過?
  • JYFrontEndTutorial-html5+css3^1.0.0【第1節】
    第一節:【初識html5+css3 -1】版本:【 "JYadmin-html5+css3": "^1.0.0"】版本説明
  • 一文了解CSS clear both清除浮動
    案例說明設置一個css寬度(css width)為500px;  盒子(div   ),css邊框(css border)為紅色,css背景(css background)為黑色、css padding為10px盒子,裡面包裹著2個小盒子,一個css 浮動靠右(float:right)、一個css float靠左(float:left),兩者邊框為白色,背景顏色為灰色
  • 這些資源讓你成為CSS專家 (二)​
    http://code.tutsplus.com/tutorials/10-challenging-but-awesome-css-techniques--net-62798、50多個漂亮整潔的CSS Tab 導航 — 搜集了大量用CSS製作的tab導航。
  • 一篇文章帶你了解css z-index(重疊順序)
    通常CSS讓不同的對象盒子以不同順序重疊排列,CSS就是要z-index樣式屬性。三、案例1.  z-index重疊順序案例為了方便觀察,設置3個DIV盒子,分別設置不同css背景顏色,設置相同CSS高度、CSS寬度。
  • 一篇文章帶你了解CSS clear both清除浮動
    案例說明設置一個css寬度(css width)為500px;  盒子(div   ),css邊框(css border)為紅色,css背景(css background)為黑色、css padding為10px盒子,裡面包裹著2個小盒子,一個css 浮動靠右(float:right)、一個css float靠左(float:left)
  • CSS學習筆記總結
    CSS(層疊樣式)由網景公司在1996年發布,取代了html 專門用來渲染頁面的樣式,文件以.css結尾 嚴重區分大小寫 毫無容錯性css的第一個宗旨是將頁面的結構和樣式解耦引入css的三種方式內嵌式直接將css代碼書寫head標籤內style:專門用來放置css代碼進入此標籤內語法改變為css語法type:MIME數據類型,此數據類型囊括了數十種後綴名,專門用來提示瀏覽器按照何種語法解析因為在h5技術中
  • CSS網頁的布局設置
    1.網頁的布局2.內容垂直居中盒子中只有一行文本 ,讓內容在盒子中垂直居中,設置行高的高度(line-height)和內容的高度(height)一致3.行內元素和塊元素行內元素:一行內可以有多個標籤,寬度是由內容決定例如 img a span ins b 默認的css樣式display:inline;塊元素:自己獨佔一行,縱向排列 ul,li,ol,dt,dd,div 默認的css樣式display:block;塊轉化行內元素: display
  • WEB前端開發,第十一及十二章 CSS盒陰影及文字操作和媒體查詢
    默認省略就是在外面 inset就是裡面 第二個值:具體的數值 可以正數,可以是負數,為盒子陰影X軸的大小 第三個值:具體的數值,可以是正數,也可以是負數,為盒子陰影Y軸的大小 第四個值:具體的數值 可以是正數,不可以說負數,可以省略 省略之後,沒有模糊面積 為盒子陰影模糊面積 第五個值:具體的顏色值,英文單詞 十六進位 rgb rgba 盒陰影可以不斷的添加,中間用逗號隔開。
  • 5分鐘實現漂亮的CSS加載動畫,純CSS實現加載動畫
    iteration-count direction fill-mode知識要點簡寫屬性裡面不包含 animation-paly-state暫停動畫 animation-paly-state: paused; 經常和滑鼠經過等其他配合使用要想動畫走回來,而不是直接調回來:animation-direction: alternate盒子動畫結束後
  • HTML--盒子模型的應用
    通過元素定位器定位到一個li標籤,然後看開發者選項卡的右側:這裡就是這個li標籤裡的所有屬性了,我們在做開發時可以直接修改這裡的屬性值,然後直接在頁面中查看效果,比如我現在在這裡加一個margin-bottom: 20px:回車後即可在頁面查看效果:也可以在盒子上直接調整大小來進行盒子樣式的調試
  • 記憶重構攻略打開第四個盒子密碼 第一章第4個盒子過關技巧
    在記憶重構中,女主角被鐵鏈綁在一個密室中,我們要解開四個盒子才能逃出密室,那麼記憶重構第四個盒子怎麼打開?下面小編為您帶來記憶重構第四個盒子攻略。  記憶重構第四個盒子怎麼打開?  第四個:  待水位上升後,可以發現一個紅色小開關。點擊關閉開關後,燈光關閉。
  • 26天學通前端開發(學習路徑, 並非精通)
    文章用下面七個目標引導學習,只要依次完成,就可以踏進前端開發的大門將設計稿還原成html頁面(5天)在網頁中添加圖片切換的效果(2天)學會使用git管理你的代碼,並且用markdown格式做筆記(2天)系統地學習javaScript(8天)搭建一個web伺服器(5天)。熟悉ajax和跨域請求。
  • 【專欄試讀】(10)讓「盒子」動起來:① 浮動 | CSS
    html,css,outputHTML<!html,css,outputHTML<!html,css,outputHTML<!2.5 塊級元素浮動寬度收縮,行內元素浮動以塊級特性去呈現🔗源碼及效果展示https://jsbin.com/sotonifaqu/edit?html,css,outputHTML<!