- 原文地址:An Introduction to CSS Shapes
- 原文做者:Tania Rascia
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:xilihuasi
- 校對者:ElizurHz, Moonliujk
CSS Shapes 容許咱們經過定義文本內容能夠環繞的幾何形狀、圖像和漸變,來建立有趣且獨特的佈局。本次教程會教你如何使用它們。css
在 CSS Shapes 問世以前,爲網頁設計文本自由環繞的雜誌式佈局幾乎是不可能的。相反,網頁設計佈局傳統上一直用網格、盒子和直線構造。前端
CSS Shapes 容許咱們定義文本環繞的幾何形狀。這些形狀能夠是圓、橢圓、簡單或複雜的多邊形,甚至圖像和漸變。Shapes 的一些實際設計應用多是圓形頭像周圍顯示圓形環繞文本,全屏背景圖片的簡單部位上面展現文本,以及在文章中顯示首字下沉。android
如今 CSS Shapes 已經得到了現代瀏覽器的普遍支持,值得一看的是它們提供的靈活性和功能,以肯定它們在你的下一個設計項目中是否能派上用場。ios
注意:截至攥寫本文時,CSS Shapes 支持 Firefox、Chrome、Safari 和 Opera,以及 iOS Safari 和 Chrome for Android 等移動瀏覽器。Shapes 不支持 IE,對 Microsoft Edge 的支持正在考慮中。git
CSS Shapes 的當前實現是 CSS Shapes Module Level 1,它主要包含 [shape-outside](https://tympanus.net/codrops/css_reference/shape-outside/)
屬性。shape-outside
定義了文本環繞的形狀。github
考慮到有 shape-outside
屬性,你可能會想到還有一個相應的 shape-inside
屬性,它包含形狀內的文本。shape-inside
屬性可能會在未來實現,目前它只是 CSS Shapes Module Level 2裏面的一個草案,並無被任何瀏覽器實現。web
在本文中,咱們將演示如何使用 數據類型,並使用形狀函數值設置它,以及使用半透明 URL 或漸變設置形狀。chrome
咱們能夠經過將下列函數值應用於 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
樣式中,咱們設置元素左浮動,設定等值的 height
和 width
,而且設置 shape-outside
爲 circle()
。
.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
}
複製代碼
若是咱們訪問頁面,會看到以下場景。
如你所見,文本圍繞圓形環繞,可是咱們並無看到任何形狀。使用開發工具審查元素,咱們能夠看到已經設置好的實際形狀。
此時,你可能會認爲,給元素 background
設置顏色或者圖片就能看到形狀了。咱們來試一下。
.circle {
float: left;
height: 200px;
width: 200px;
shape-outside: circle();
background: linear-gradient(to top right, #FDB171, #FD987D);
}
複製代碼
不幸的是,給 circle
設置 background
後會顯示一個矩形,這是咱們一直試圖避免的事情。
咱們能夠清晰地看到文本在它周圍環繞,但元素自己沒有形狀。若是咱們想要真實地顯示形狀函數,須要使用 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);
}
複製代碼
在本文剩下的部分,我將使用
clip-path
幫助咱們辨認形狀。
circle()
函數接收可選的 radius 參數。在本例中,默認 radius 是 50%
或者 100px
。使用 circle(50%)
或者 circle(100px)
都將產生和咱們已經完成樣例的一樣結果。
你可能注意到文本恰好和形狀貼合。咱們可使用 shape-margin
屬性給形狀添加 margin,單位能夠是 px
、em
、%
和其餘標準的 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
的例子。
除了 radius,形狀函數可使用 at
定位。默認位置是圓心,所以 circle()
也能夠被顯式設置爲 circle(50% at 50% 50%)
或 circle(100px at 100px 100px)
,兩個值分別是水平和垂直位置。
爲了搞清楚 position 的做用,咱們能夠設置水平位置值爲 0
來創造一個完美的半圓。
circle(50% at 0 50%);
複製代碼
該座標定位系統稱爲引用框。
稍後,咱們將學習如何使用圖像代替形狀或者漸變。如今,咱們將繼續進行下一個形狀函數。
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);
}
複製代碼
此次,咱們設置不一樣的 height
和 width
建立一個垂直拉長的橢圓。
ellipse()
和 circle()
的區別在於橢圓有兩個半徑 —— _r_x
和 _r_y
,或者 X 軸半徑和 Y 軸半徑。所以,上面的例子也能夠寫成:
ellipse(75px 150px);
複製代碼
circles 和 ellipses 的位置參數是同樣的。除了是測量單位,半徑也包括 farthest-side
和 closest-side
的選項。
closest-side
表明引用框的中心到最近側的長度,相反,farthest-side
表明引用框中心到最遠側的長度。這意味着若是未設置默認值之外的位置,則這兩個值無效。
這裏演示了在 ellipse()
上翻轉 closest-side
和 farthest-side
的區別,它的 X 和 Y 軸的偏移量是 25%
。
ellipse(farthest-side closest-side at 25% 25%)
複製代碼
ellipse(farthest-side closest-side at 25% 25%)
複製代碼
目前爲止咱們只處理了圓形,可是咱們可使用 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
空間。
咱們能夠看到矩形是內嵌的,文本忽略了內嵌區域。
inset()
形狀也可使用 round
參數接收 border-radius
,而且文本會識別圓角,就像本例中全部邊都是 25px
內嵌和 75px
圓角。
inset(25px round 75px)
複製代碼
像 padding
或 margin
簡寫,inset 值以順時針方式(inset(25px 25px 25px 25px)
)接收 top
right
bottom
left
,而且只傳一個值將使四條邊都相同(inset(25px)
)。
形狀函數最有趣和靈活的是 polygon()
,它能夠採用一系列 x
和 y
點來製做任何複雜形狀。數組裏的每一個元素表明 _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 0
,div
中最左上角的點。第二個點是 0 300px
,它是 div
中最左下角的點。第三個也就是最後一個點是 200px 300px
,它在 X 軸的 2/3 處而且也在底部。最終的形狀是這樣:
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;
}
複製代碼
顯然,想要手動創造你本身的複雜形狀是很是困難的。幸運的是,你能夠用一些工具來建立多邊形。Firefox 有一個內置的形狀編輯器,你能夠在 Inspector 中經過點擊多邊形使用。
目前,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 一個使人激動的特性是你沒必要每次都經過形狀函數明肯定義;你也可使用半透明圖像的 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')
}
複製代碼
由於我使用了透明背景的星星圖像,文本知道哪些區域是透明的哪些是不透明的,並進行自適應佈局。
最後,漸變也能夠用來當成形狀。漸變和圖像同樣,就像咱們上面用到的圖像例子,文本也將知道在透明部分環繞。
咱們將使用漸變的一個新屬性 —— shape-image-threshold
。shape-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 的三個屬性 shape-outside
、shape-margin
和 shape-image-threshold
。咱們也瞭解到如何使用函數值建立可供文本環繞的圓、橢圓、內嵌矩形以及複雜的多邊形,而且演示了形狀如何檢測圖像和漸變的透明部分。
你能夠在以下 demo 中找到本文中用到的全部例子,也能夠下載源文件。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。