【譯】CSS Shapes 簡介

希裡花斯發表於2019-01-10

CSS Shapes 簡介

CSS Shapes 允許我們通過定義文字內容可以環繞的幾何形狀、影象和漸變,來建立有趣且獨特的佈局。本次教程會教你如何使用它們。

cssshapes_featured

CSS Shapes 問世之前,為網頁設計文字自由環繞的雜誌式佈局幾乎是不可能的。相反,網頁設計佈局傳統上一直用網格、盒子和直線構造。

CSS Shapes 允許我們定義文字環繞的幾何形狀。這些形狀可以是圓、橢圓、簡單或複雜的多邊形,甚至影象和漸變。Shapes 的一些實際設計應用可能是圓形頭像周圍顯示圓形環繞文字,全屏背景圖片的簡單部位上面展示文字,以及在文章中顯示首字下沉。

現在 CSS Shapes 已經獲得了現代瀏覽器的廣泛支援,值得一看的是它們提供的靈活性和功能,以確定它們在你的下一個設計專案中是否能派上用場。

注意:截至攥寫本文時,CSS Shapes 支援 Firefox、Chrome、Safari 和 Opera,以及 iOS Safari 和 Chrome for Android 等移動瀏覽器。Shapes 不支援 IE,對 Microsoft Edge 的支援正在考慮中

CSS Shapes 初探

CSS Shapes 的當前實現是 CSS Shapes Module Level 1,它主要包含 [shape-outside](https://tympanus.net/codrops/css_reference/shape-outside/) 屬性。shape-outside 定義了文字環繞的形狀。

考慮到有 shape-outside 屬性,你可能會想到還有一個相應的 shape-inside 屬性,它包含形狀內的文字。shape-inside 屬性可能會在將來實現,目前它只是 CSS Shapes Module Level 2裡面的一個草案,並沒有被任何瀏覽器實現。

在本文中,我們將演示如何使用 資料型別,並使用形狀函式值設定它,以及使用半透明 URL 或漸變設定形狀。

基本的形狀函式

我們可以通過將下列函式值應用於 shape-outside 屬性來定義 CSS 中的各種基本形狀:

  • circle()
  • ellipse()
  • inset()
  • polygon()

要給元素設定 shape-outside 屬性,該元素必須是浮動的並且已設定寬高。讓我們逐個來看四個基本形狀,並演示它們的使用方法。

我們將從 circle() 函式開始。設想如下場景,有一個圓形的作者頭像,我們想讓頭像左浮動並且作者的描述文字環繞它。僅對頭像元素使用 border-radius: 50% 不足以使文字呈圓形;文字仍將把頭像當成矩形元素。

通過圓形,我們可以演示文字如何按圓形環繞。

首先我們在一個普通的 div 上建立 circle 樣式,並且寫幾段文字。(我使用 Bob Ross 語錄作為 Lorem Ipsum 文字。)

<div class="circle"></div>
<p>Example text...</p>
複製程式碼

circle 樣式中,我們設定元素左浮動,設定等值的 heightwidth,並且設定 shape-outsidecircle()

.circle {
  float: left;
  height: 200px;
  width: 200px;
  shape-outside: circle();
}
複製程式碼

如果我們訪問頁面,會看到如下場景。

【譯】CSS Shapes 簡介

如你所見,文字圍繞圓形環繞,但是我們並沒有看到任何形狀。使用開發工具審查元素,我們可以看到已經設定好的實際形狀。

【譯】CSS Shapes 簡介

此時,你可能會認為,給元素 background 設定顏色或者圖片就能看到形狀了。我們來試一下。

.circle {
  float: left;
  height: 200px;
  width: 200px;
  shape-outside: circle();
  background: linear-gradient(to top right, #FDB171, #FD987D);
}
複製程式碼

不幸的是,給 circle 設定 background 後會顯示一個矩形,這是我們一直試圖避免的事情。

【譯】CSS Shapes 簡介

我們可以清晰地看到文字在它周圍環繞,但元素本身沒有形狀。如果我們想要真實地顯示形狀函式,需要使用 clip-path 屬性。clip-path 採用許多和 shape-outside 相同的值,因此我們可以給它同樣的 circle() 值。

.circle {
  float: left;
  height: 200px;
  width: 200px;
  shape-outside: circle();
  clip-path: circle();
  background: linear-gradient(to top right, #FDB171, #FD987D);
}
複製程式碼

【譯】CSS Shapes 簡介

在本文剩下的部分,我將使用 clip-path 幫助我們辨認形狀。

circle() 函式接收可選的 radius 引數。在本例中,預設 radius 是 50% 或者 100px。使用 circle(50%) 或者 circle(100px) 都將產生和我們已經完成樣例的同樣結果。

你可能注意到文字剛好和形狀貼合。我們可以使用 shape-margin 屬性給形狀新增 margin,單位可以是 pxem% 和其他標準的 CSS 測量單位。

.circle {
  float: left;
  height: 200px;
  width: 200px;
  shape-outside: circle(25%);
  shape-margin: 1rem;
  clip-path: circle(25%);
  background: linear-gradient(to top right, #FDB171, #FD987D);
}
複製程式碼

這裡有個 circle radius 設定 25% 並且使用 shape-margin 的例子。

【譯】CSS Shapes 簡介

除了 radius,形狀函式可以使用 at 定位。預設位置是圓心,因此 circle() 也可以被顯式設定為 circle(50% at 50% 50%)circle(100px at 100px 100px),兩個值分別是水平和垂直位置。

為了搞清楚 position 的作用,我們可以設定水平位置值為 0 來創造一個完美的半圓。

circle(50% at 0 50%);
複製程式碼

該座標定位系統稱為引用框。

【譯】CSS Shapes 簡介

稍後,我們將學習如何使用影象代替形狀或者漸變。現在,我們將繼續進行下一個形狀函式。

橢圓

ellipse()circle() 函式類似,只是它會創造橢圓。為了演示,我們建立一個 ellipse 元素和樣式。

<div class="ellipse"></div>
<p>Example text...</p>
複製程式碼
.ellipse {
  float: left;
  shape-outside: ellipse();
  clip-path: ellipse();
  width: 150px;
  height: 300px;
  background: linear-gradient(to top right, #F17BB7, #AD84E3);
}
複製程式碼

這次,我們設定不同的 heightwidth 建立一個垂直拉長的橢圓。

【譯】CSS Shapes 簡介

ellipse()circle() 的區別在於橢圓有兩個半徑 —— _r_x_r_y,或者 X 軸半徑和 Y 軸半徑。因此,上面的例子也可以寫成:

ellipse(75px 150px);
複製程式碼

circles 和 ellipses 的位置引數是一樣的。除了是測量單位,半徑也包括 farthest-sideclosest-side 的選項。

closest-side 代表引用框的中心到最近側的長度,相反,farthest-side 代表引用框中心到最遠側的長度。這意味著如果未設定預設值以外的位置,則這兩個值無效。

這裡演示了在 ellipse() 上翻轉 closest-sidefarthest-side 的區別,它的 X 和 Y 軸的偏移量是 25%

ellipse(farthest-side closest-side at 25% 25%)
複製程式碼

【譯】CSS Shapes 簡介

ellipse(farthest-side closest-side at 25% 25%)
複製程式碼

【譯】CSS Shapes 簡介

內嵌

目前為止我們只處理了圓形,但是我們可以使用 inset() 函式定義內嵌矩形。

<div class="inset"></div>
<p>Example text...</p>
複製程式碼
.inset {
  float: left;
  shape-outside: inset(75px);
  clip-path: inset(75px);
  width: 300px;
  height: 300px;
  background: linear-gradient(#58C2ED, #1B85DC);
}
複製程式碼

在本例中,我們創造了一個 300px 的正方形,每條邊內嵌 75px。這將給我們留下 150px 周圍有 75px 空間。

【譯】CSS Shapes 簡介

我們可以看到矩形是內嵌的,文字忽略了內嵌區域。

【譯】CSS Shapes 簡介

inset() 形狀也可以使用 round 引數接收 border-radius,並且文字會識別圓角,就像本例中所有邊都是 25px 內嵌和 75px 圓角。

inset(25px round 75px)
複製程式碼

【譯】CSS Shapes 簡介

paddingmargin 簡寫,inset 值以順時針方式(inset(25px 25px 25px 25px))接收 top right bottom left,並且只傳一個值將使四條邊都相同(inset(25px))。

多邊形

形狀函式最有趣和靈活的是 polygon(),它可以採用一系列 xy 點來製作任何複雜形狀。陣列裡的每個元素代表 _x_i _y_i,將被寫成 polygon(x1 y1, x2 y2, x3 y3...) 等等。

我們可以為多邊形設定的點集數量最少為 3,這將建立一個三角形。

<div class="polygon"></div>
<p>Example text...</p>
複製程式碼
.polygon {
  float: left;
  shape-outside: polygon(0 0, 0 300px, 200px 300px);
  clip-path: polygon(0 0, 0 300px, 200px 300px);
  height: 300px;
  width: 300px;
  background: linear-gradient(to top right, #86F7CC, #67D7F5);
}
複製程式碼

在這個形狀中,第一個點是 0 0div 中最左上角的點。第二個點是 0 300px,它是 div 中最左下角的點。第三個也就是最後一個點是 200px 300px,它在 X 軸的 2/3 處並且也在底部。最終的形狀是這樣:

【譯】CSS Shapes 簡介

polygon() 形狀函式的一個有趣用法是文字內容可以在兩個或以上形狀中環繞。因為 polygon() 形狀是如此靈活和動態,這給我們製作真正獨特的雜誌式佈局提供了一個最好機會。在本例中,我們將把文字放在兩個多邊形中。

<div class="left"></div>
<div class="right"></div>
<p>Example text...</p>
複製程式碼
.left {
  float: left;
  shape-outside: polygon(0 0, 0 300px, 200px 300px);
  clip-path: polygon(0 0, 0 300px, 200px 300px);
  background: linear-gradient(to top right, #67D7F5, #86F7CC);
  height: 300px;
  width: 300px;
}

.right {
  float: right;
  shape-outside: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
  clip-path: polygon(200px 300px, 300px 300px, 300px 0, 0 0);
  background: linear-gradient(to bottom left, #67D7F5, #86F7CC);
  height: 300px;
  width: 300px;
}
複製程式碼

【譯】CSS Shapes 簡介

顯然,想要手動創造你自己的複雜形狀是非常困難的。幸運的是,你可以用一些工具來建立多邊形。Firefox 有一個內建的形狀編輯器,你可以在 Inspector 中通過點選多邊形使用。

【譯】CSS Shapes 簡介

目前,Chrome 有一些你可以使用的擴充套件程式,比如 CSS Shapes Editor

多邊形可以用來剪下影象或其他元素周圍的形狀。在另一個例子中,我們可以通過在大字母周圍繪製多邊形來建立首字下沉。

<div class="letter">R</div>
<p>Example text...</p>
複製程式碼
.letter {
  float: left;
  font-size: 400px;
  font-family: Georgia;
  line-height: .8;
  margin-top: 20px;
  margin-right: 20px;
  shape-outside: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px) content-box;
  clip-path: polygon(5px 14px, 233px 20px, 246px 133px, 189px 167px, 308px 304px, 0px 306px);
}
複製程式碼

【譯】CSS Shapes 簡介

URLs

CSS Shapes 一個令人激動的特性是你不必每次都通過形狀函式明確定義;你也可以使用半透明影象的 url 來定義形狀,這樣文字就會自動環繞它。

重要的是要注意影象使用必須要相容 CORS,否則你將會遇到如下錯誤。

Access to image at 'file:///users/tania/star.png' from origin 'null' 
has been blocked by CORS policy: The response is invalid.
複製程式碼

在同一個伺服器上提供影象將會保證你不會遇到上面的錯誤。

與其他例子不同,我們將使用 img 代替 div。這次的 CSS 很簡單——只用把 url() 放進 shape-outside 屬性,就像 background-image 一樣。

<img src="./star.png" class="star">
<p>Example text...</p>
複製程式碼
.star {
  float: left;
  height: 350px;
  width: 350px;
  shape-outside: url('./star.png')
}
複製程式碼

【譯】CSS Shapes 簡介

因為我使用了透明背景的星星影象,文字知道哪些區域是透明的哪些是不透明的,並進行自適應佈局。

漸變

最後,漸變也可以用來當成形狀。漸變和影象一樣,就像我們上面用到的影象例子,文字也將知道在透明部分環繞。

我們將使用漸變的一個新屬性 —— shape-image-thresholdshape-image-threshold 定義形狀的 alpha 通道閾值,或者影象透明的百分比值。

我們將製作一個漸變例子,它是 50%/50% 的顏色和透明分割,並且設定 shape-image-threshold.5,意味著超過 50% 不透明的所有畫素都應被視為影象的一部分。

<div class="gradient"></div>
<p>Example text...</p>
複製程式碼
.gradient {
  float: left;
  height: 300px;
  width: 100%;
  background: linear-gradient(to bottom right, #86F7CC, transparent);
  shape-outside: linear-gradient(to bottom right, #86F7CC, transparent);
  shape-image-threshold: .5;
}
複製程式碼

【譯】CSS Shapes 簡介

我們可以看到漸變在不透明和透明的中心對角線完美分割。

結語

在本文中,我們學習了 CSS Shapes 的三個屬性 shape-outsideshape-marginshape-image-threshold。我們也瞭解到如何使用函式值建立可供文字環繞的圓、橢圓、內嵌矩形以及複雜的多邊形,並且演示了形狀如何檢測影象和漸變的透明部分。

你可以在如下 demo 中找到本文中用到的所有例子,也可以下載原始檔

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章