高階樣式效果

本文充當一個技巧寶典,介紹了諸如盒陰影、混合模式和濾鏡等一些有趣的進階樣式功能。

預備知識 HTML 基礎知識(學習 HTML 簡介)以及對 CSS 工作原理的瞭解(學習 CSS 樣式基礎)。
目標 瞭解如何在現代瀏覽器中使用一些高階樣式效果。

盒陰影

box-shadow 允許你對元素的盒子應用一個或多個投影。與文字陰影類似,盒陰影在瀏覽器中的支援度相當好,包括 IE9+ 和 Edge。使用較舊 IE 版本的使用者可能不得不接受沒有陰影的情況,因此請測試你的設計,確保在沒有陰影的情況下內容仍然清晰可讀。

一個簡單的盒陰影

讓我們看一個簡單的例子來開始。首先,一些 HTML 程式碼

html
<article class="simple">
  <p>
    <strong>Warning</strong>: The thermostat on the cosmic transcender has
    reached a critical level.
  </p>
</article>

現在是 CSS 程式碼

css
p {
  margin: 0;
}

article {
  max-width: 500px;
  padding: 10px;
  background-color: red;
  background-image: linear-gradient(to bottom, transparent, rgb(0 0 0 / 25%));
}

.simple {
  box-shadow: 5px 5px 5px rgb(0 0 0 / 70%);
}

這給了我們以下結果:

你會看到 box-shadow 屬性值中有四個項

  1. 第一個長度值是水平偏移——陰影從原始盒子向右偏移的距離(如果值為負,則向左偏移)。
  2. 第二個長度值是垂直偏移——陰影從原始盒子向下偏移的距離(如果值為負,則向上偏移)。
  3. 第三個長度值是模糊半徑——應用於陰影的模糊量。
  4. 顏色值是陰影的基色

你可以使用任何有意義的長度和顏色單位來定義這些值。

多個盒陰影

你也可以在單個 box-shadow 宣告中指定多個盒陰影,透過用逗號分隔它們

css
p {
  margin: 0;
}

article {
  max-width: 500px;
  padding: 10px;
  background-color: red;
  background-image: linear-gradient(to bottom, transparent, rgb(0 0 0 / 25%));
}

.multiple {
  box-shadow:
    1px 1px 1px black,
    2px 2px 1px black,
    3px 3px 1px red,
    4px 4px 1px red,
    5px 5px 1px black,
    6px 6px 1px black;
}

現在我們得到這個結果

我們透過建立帶有多個彩色圖層的凸起盒子來做了一些有趣的事情,但你可以以任何你想要的方式使用它,例如建立具有基於多個光源的陰影的更逼真的外觀。

其他盒陰影特性

text-shadow 不同,box-shadow 有一個 inset 關鍵字可用——將其放在陰影宣告的開頭會導致它成為內陰影,而不是外陰影。讓我們來看看這意味著什麼。

首先,我們將為此示例使用一些不同的 HTML 程式碼

html
<button>Press me!</button>
css
button {
  width: 150px;
  font-size: 1.1rem;
  line-height: 2;
  border-radius: 10px;
  border: none;
  background-image: linear-gradient(to bottom right, #777777, #dddddd);
  box-shadow:
    1px 1px 1px black,
    inset 2px 3px 5px rgb(0 0 0 / 30%),
    inset -2px -3px 5px rgb(255 255 255 / 50%);
}

button:focus,
button:hover {
  background-image: linear-gradient(to bottom right, #888888, #eeeeee);
}

button:active {
  box-shadow:
    inset 2px 2px 1px black,
    inset 2px 3px 5px rgb(0 0 0 / 30%),
    inset -2px -3px 5px rgb(255 255 255 / 50%);
}

這給了我們以下結果:

在這裡,我們設定了一些按鈕樣式以及聚焦/懸停/活動狀態。預設情況下,按鈕上設定了一個簡單的黑色盒陰影,以及幾個內陰影,一明一暗,放置在按鈕的相對角上,以提供漂亮的陰影效果。

當按鈕被按下時,活動狀態會導致第一個盒陰影被替換為一個非常暗的內陰影,從而產生按鈕被按下的外觀。

注意:box-shadow 值中還可以設定另一個項——一個可選的長度值可以在顏色值之前設定,即擴散半徑。如果設定,這會導致陰影比原始盒子更大。它不常用,但值得一提。

過濾器

雖然你不能使用 CSS 改變影像的構圖,但你可以做一些有創意的事情。一個非常好的屬性,可以幫助你為你的設計帶來興趣,是 filter 屬性。這個屬性可以直接從 CSS 啟用類似於 Photoshop 的濾鏡。

在下面的示例中,我們使用了兩個不同的濾鏡值。第一個blur()——這個函式可以傳遞一個值來指示影像應該模糊多少。

第二個是 grayscale();透過使用百分比,我們設定了我們想要去除多少顏色。

在下面的示例中調整百分比和畫素引數,看看影像如何變化。你也可以將這些值替換為其他值。在上面的即時示例中嘗試 contrast(200%)invert(100%)hue-rotate(20deg)。檢視 MDN 上的 filter 頁面,瞭解你可以嘗試的許多其他選項。

html
<div class="wrapper">
  <div class="box">
    <img
      alt="balloons"
      class="blur"
      src="https://mdn.github.io/shared-assets/images/examples/balloons.jpg" />
  </div>
  <div class="box">
    <img
      alt="balloons"
      class="grayscale"
      src="https://mdn.github.io/shared-assets/images/examples/balloons.jpg" />
  </div>
</div>
css
img {
  height: 100%;
  width: 100%;
  display: block;
  object-fit: cover;
}

.blur {
  filter: blur(10px);
}

.grayscale {
  filter: grayscale(60%);
}

你可以將濾鏡應用於任何元素,而不僅僅是影像。一些可用的濾鏡選項與其他的 CSS 功能做著非常相似的事情,例如 drop-shadow() 的工作方式與 box-shadowtext-shadow 類似,併產生相似的效果。然而,濾鏡真正好的一點是,它們作用於盒子內部內容的精確形狀,而不僅僅是整個盒子作為一個大塊,因此瞭解其中的區別是值得的。

在下一個示例中,我們將濾鏡應用於一個盒子,並將其與盒陰影進行比較。如你所見,投影濾鏡遵循文字和邊框虛線的精確形狀。盒陰影只遵循盒子的正方形。

html
<p class="filter">Filter</p>
<p class="box-shadow">Box shadow</p>
css
body {
  font-family: sans-serif;
}
p {
  margin: 1em 2em;
  padding: 20px;
  width: 100px;
  display: inline-block;
  border: 5px dashed red;
}

.filter {
  filter: drop-shadow(5px 5px 1px rgb(0 0 0 / 70%));
}

.box-shadow {
  box-shadow: 5px 5px 1px rgb(0 0 0 / 70%);
}

混合模式

CSS 混合模式允許我們為元素新增混合模式,這些模式在兩個元素重疊時指定混合效果——每個畫素最終顯示的顏色將是原始畫素顏色與其下方圖層畫素顏色組合的結果。混合模式再次讓像 Photoshop 這樣的圖形應用程式使用者感到非常熟悉。

CSS 中有兩個屬性使用混合模式

  • background-blend-mode,它將設定在單個元素上的多個背景影像和顏色混合在一起。
  • mix-blend-mode,它將自身元素與與其重疊的元素(包括背景和內容)混合在一起。

你可以在我們的 blend-modes.html 示例頁面(請參閱原始碼)以及 <blend-mode> 參考頁面上找到比這裡更多的示例。

注意:混合模式也非常新,並且支援度略低於濾鏡。Edge 尚不支援,Safari 只支援部分混合模式選項。

background-blend-mode

同樣,讓我們看一些例子,以便更好地理解。首先,background-blend-mode——這裡我們將展示幾個簡單的 <div> 元素,這樣你就可以比較原始版本和混合版本

html
<div></div>
<div class="multiply"></div>

現在是一些 CSS——我們正在為 <div> 新增一個背景影像和一個綠色背景顏色

css
div {
  width: 250px;
  height: 130px;
  padding: 10px;
  margin: 10px;
  display: inline-block;
  background: url("colorful-heart.png") no-repeat center 20px;
  background-color: green;
}

.multiply {
  background-blend-mode: multiply;
}

我們得到的結果是這樣——你可以看到左邊是原始的,右邊是乘法混合模式

mix-blend-mode

現在讓我們看看 mix-blend-mode。這裡我們將展示相同的兩個 <div> 元素,但每個元素現在都位於一個帶有紫色背景的簡單 <div> 之上,以展示元素將如何混合在一起

html
<article>
  No mix blend mode
  <div></div>
  <div></div>
</article>

<article>
  Multiply mix
  <div class="multiply-mix"></div>
  <div></div>
</article>

這是我們將用於樣式設定的 CSS

css
article {
  width: 280px;
  height: 180px;
  margin: 10px;
  position: relative;
  display: inline-block;
}

div {
  width: 250px;
  height: 130px;
  padding: 10px;
  margin: 10px;
}

article div:first-child {
  position: absolute;
  top: 10px;
  left: 0;
  background: url("colorful-heart.png") no-repeat center 20px;
  background-color: green;
}

article div:last-child {
  background-color: purple;
  position: absolute;
  bottom: -10px;
  right: 0;
  z-index: -1;
}

.multiply-mix {
  mix-blend-mode: multiply;
}

這給了我們以下結果

你可以看到,乘法混合模式不僅混合了兩個背景影像,還混合了其下方 <div> 的顏色。

注意:如果對上面的一些佈局屬性(如 positiontopbottomz-index 等)不理解,請不用擔心。我們將在 CSS 佈局模組中詳細介紹這些內容。

CSS 形狀

雖然 CSS 中的所有內容都是矩形框,影像也是物理矩形框,但我們可以透過使用 CSS Shapes 讓內容看起來像是環繞著非矩形物件流動。

CSS Shapes 規範允許文字圍繞非矩形形狀環繞。當處理具有一些你可能希望文字環繞的空白區域的影像時,它特別有用。

在下面的圖片中,我們有一個討人喜歡的圓形氣球。實際檔案是矩形的,但是透過浮動影像(形狀僅適用於浮動元素)並使用值為 circle(50%)shape-outside 屬性,我們可以實現文字沿著氣球線條流動的效果。

html
<div class="wrapper">
  <img
    alt="balloon"
    src="https://mdn.github.io/shared-assets/images/examples/round-balloon.png" />
  <p>
    One November night in the year 1782, so the story runs, two brothers sat
    over their winter fire in the little French town of Annonay, watching the
    grey smoke-wreaths from the hearth curl up the wide chimney. Their names
    were Stephen and Joseph Montgolfier, they were papermakers by trade, and
    were noted as possessing thoughtful minds and a deep interest in all
    scientific knowledge and new discovery. Before that night—a memorable night,
    as it was to prove—hundreds of millions of people had watched the rising
    smoke-wreaths of their fires without drawing any special inspiration from
    the fact.
  </p>
</div>
css
body {
  font-family: sans-serif;
}
img {
  float: left;
  shape-outside: circle(50%);
}

此示例中的形狀沒有對影像檔案的內容做出反應。相反,circle 函式從影像檔案的中心點獲取其中心點,就好像我們在檔案的中間放置了一個指南針並繪製了一個適合檔案內部的圓。文字就是圍繞著這個圓流動的。

注意:在 Firefox 中,你可以使用 DevTools Shapes Inspector 來檢查形狀。

circle() 函式只是少數幾個基本形狀中的一個,然而,有多種不同的方法來建立形狀。有關 CSS Shapes 的更多資訊和示例程式碼,請參閱 MDN 上的CSS Shapes 指南

-webkit-background-clip: text

我們想簡要提及的另一個功能是 background-cliptext 值。當與專有的 -webkit-text-fill-color: transparent; 功能結合使用時,這允許你將背景影像裁剪到元素的文字形狀,從而產生一些不錯的效果。這不是官方標準,但由於其受歡迎和開發人員的廣泛使用,已在多個瀏覽器中實現。在這種情況下,這兩個屬性都需要一個 -webkit- 供應商字首,即使對於非 WebKit/基於 Chrome 的瀏覽器也是如此。你可以在下面的即時示例中看到它的實際應用

html
<h2>WOW</h2>
<h2 class="text-clip">WOW</h2>
css
h2 {
  color: white;
  display: inline-block;
  background: url("colorful-heart.png") no-repeat center;
}

.text-clip {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

那麼為什麼其他瀏覽器也實現了 -webkit- 字首呢?主要是為了瀏覽器相容性——許多網頁開發者已經開始使用 -webkit- 字首來實現網站,以至於其他瀏覽器看起來像是損壞了,而實際上它們是遵循標準的。因此它們被迫實現了一些這樣的功能。這突顯了在你的工作中使非標準和/或帶有字首的 CSS 功能的危險——它們不僅會導致瀏覽器相容性問題,而且也可能隨時更改,因此你的程式碼可能隨時崩潰。堅持標準要好得多。

如果你確實想在生產工作中使用這些功能,請務必在各種瀏覽器上進行徹底測試,並檢查在這些功能不起作用的情況下,網站是否仍然可用。

總結

我們希望這篇文章很有趣——玩閃亮的玩具通常很有趣,而且看到現代瀏覽器中正在提供哪些高階樣式工具總是很有趣。