CSS規范新增了一個模塊:CSS Shapes,shape-outside屬性屬于該模塊,它能影響浮動元素周邊內容流的形狀(即浮動形狀),可接收三類值:形狀盒子、函數和圖像。
## 一、形狀盒子
  形狀盒子(shape box)會指定形狀的邊界,既能單獨使用,也能與另外兩類值組合使用,可選的關鍵字如下所列,其中margin-box是shape-outside屬性的默認值。
  (1)margin-box:以外邊距為界。
  (2)border-box:以邊框為界。
  (3)padding-box:以內邊距為界。
  (4)content-box:以內容為界。
  下圖演示了四種形狀盒子的效果,外邊距、邊框和內邊距都設為了10px,代碼中只列出了關鍵樣式,并只舉了其中的一種情況。
~~~html
<style>
.container {
overflow: hidden;
}
div {
float: left;
padding: 10px;
margin: 10px;
border: 10px solid #FC0;
background: #F60;
background-clip: content-box;
}
.border-box {
shape-outside: border-box;
}
</style>
<section class="container">
<div class="border-box">border-box</div>
<p>My name is Strick.</p>
<p>My name is Strick.</p>
<p>My name is Strick.</p>
<p>My name is Strick.</p>
<p>My name is Strick.</p>
</section>
~~~
:-: 
## 二、函數
  有4個形狀函數可供選擇,分別是circle()、ellipse()、inset()以及polygon()。
**1)circle()**
  第一種是圓形,可定義半徑和圓點位置,例如浮動元素的寬高都為100px,圓的半徑為50px,樣式如下所示,效果如下圖所示,其中白色邊框的圓就是計算出的浮動形狀。
~~~css
div {
float: left;
width: 100px;
height: 100px;
shape-outside: circle(50px);
}
~~~
:-: 
  接下來指定圓點的位置,需要使用at關鍵字將半徑和位置分隔。在下面的樣式中,圓點處在元素的右上角,注意觀察下圖中的浮動形狀,它超出了元素的邊界,超出部分默認會被裁剪掉。
~~~CSS
div {
shape-outside: circle(50px at right top);
}
~~~
:-: 
  當用百分數指定半徑時,需要有個參照值,該值得通過下面的公式計算得到,其中width是形狀盒子的寬,height是其高。
:-: 
  假設半徑為10%,浮動元素的上下外邊距為10px,因為默認是以外邊距為界限,所以此處形狀盒子的高度為120px,寬度仍然是100px,那么通過計算后得到的參照值約等于110px,半徑就是11px,效果如下圖所示。
~~~CSS
div {
margin: 10px 0;
shape-outside: circle(10%);
}
~~~
:-: 
**2)ellipse()**
  第二種是橢圓,與圓形類似,也需要定義半徑和圓點位置。只是它需要兩個半徑,第一個是橫軸半徑,第二個是縱軸半徑。在下面的示例中,浮動元素的寬為100px,高為60px,將浮動形狀聲明為橢圓,效果如下圖所示。
~~~CSS
div {
float: left;
width: 100px;
height: 60px;
shape-outside: ellipse(50px 30px);
}
~~~
:-: 
  橫軸上的百分數半徑參照形狀盒子的寬度,縱軸上的百分數半徑參照形狀盒子的高度,下面定義的百分數半徑經過計算后得到的值為50px和40px,效果如下圖所示。
~~~CSS
div {
margin: 10px 0;
shape-outside: ellipse(50% 50%);
}
~~~
:-: 
**3)inset()**
  第三種是嵌入在形狀盒子中的內部矩形,它能接收一組值,分別表示上右下左向內偏移的距離,還能接收一個可選的圓角,以round關鍵字分隔。
  在下面的示例中,雖然只提供了兩個值,但CSS會根據現有的值確定其余值,內部矩形距離形狀盒子的頂端和底端是20px,左右邊界是10px,形狀盒子的寬為100px,高為80px,效果如下圖所示。
~~~CSS
div {
float: left;
width: 100px;
height: 60px;
margin: 10px 0;
shape-outside: inset(20px 10px);
}
~~~
:-: 
  下面的樣式為內部矩形添加了20px的圓角,效果如下圖所示。
~~~CSS
div {
shape-outside: inset(20px 10px round 20px);
}
~~~
:-: 
  當內部矩形的偏移值是百分數時,左右偏移參照的是形狀盒子的寬,上下偏移參照的是其高。例如參數值為20%,那么計算出的左右偏移值是20px,上下偏移值是16px,效果如下圖所示。
~~~CSS
div {
shape-outside: inset(20%);
}
~~~
:-: 
**4)polygon()**
  第四種是多邊形,它能接收一系列坐標對,相對于形狀盒子的左上角計算,將所有的點連接起來就是最終的形狀。根據下面的polygon()函數中的四組坐標可描繪出一個直角梯形,如下圖所示。
~~~CSS
div {
float: left;
width: 100px;
height: 80px;
shape-outside: polygon(10px 10px, 20px 10px, 40px 50px, 10px 50px);
}
~~~
:-: 
  當坐標是百分數時,橫坐標參照形狀盒子的寬,縱坐標參照其高,下面定義的坐標,效果與上圖一致。
~~~CSS
div {
shape-outside: polygon(10% 12.5%, 20% 12.5%, 40% 62.5%, 10% 62.5%);
}
~~~
  有一種簡便的方式創建多邊形,那就是使用Chrome的瀏覽器插件:CSS Shapes Editor,用拖拽鼠標的方式得到想要的多邊形,再將參數復制到樣式表中,如下圖所示。
:-: 
## 三、圖像
  當形狀很復雜時,直接畫多邊形會非常麻煩,不過shape-outside屬性可基于圖像的透明度(alpha值)來繪制形狀,即形狀輪廓會沿著非透明區域的邊緣生成。
  例如有一個五角星,如果邊以外的地方都是透明的,那么周圍的內容就會貼著五角星的邊,如下圖所示。
~~~CSS
div {
float: left;
width: 100px;
height: 100px;
shape-outside: url(./star.png);
}
~~~
:-: 
注意,url()函數中的圖像不能直接從本地加載,必須從Web服務器中讀取,如此引用的圖像會有HTTP首部信息,用于判斷是否跨域。
**1)shape-image-threshold**
  該屬性可指定透明度閾值,修改形狀邊界,其取值范圍是0~1,值越小透明度越高。對于透明度低于該值的部分,會包含在浮動形狀中,而高于的則不包含。
  例如將該值設為1時,就表示沒有浮動形狀,即整張圖像都不在浮動形狀中,如下圖所示。
~~~CSS
div {
shape-image-threshold: 1;
}
~~~
:-: 
**2)shape-margin**
  該屬性可指定浮動形狀的外邊距。在下面的示例中會添加10px的外邊距,效果如下圖所示。
~~~CSS
div {
shape-margin: 10px;
}
~~~
:-: 
  注意,shape-margin屬性的百分數的計算方式與普通的外邊距相同,參照的也是包含塊的寬度。假設div元素的包含塊的寬度為220px,那么10%的外邊距經過計算后得到的值為22px,效果如下圖所示。
~~~CSS
div {
shape-margin: 10%;
}
~~~
:-: 
*****
> 原文出處:
[博客園-CSS躬行記](https://www.cnblogs.com/strick/category/1667864.html)
[知乎專欄-CSS躬行記](https://zhuanlan.zhihu.com/pwcss)
已建立一個微信前端交流群,如要進群,請先加微信號freedom20180706或掃描下面的二維碼,請求中需注明“看云加群”,在通過請求后就會把你拉進來。還搜集整理了一套[面試資料](https://github.com/pwstrick/daily),歡迎瀏覽。

推薦一款前端監控腳本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不僅能監控前端的錯誤、通信、打印等行為,還能計算各類性能參數,包括 FMP、LCP、FP 等。
- ES6
- 1、let和const
- 2、擴展運算符和剩余參數
- 3、解構
- 4、模板字面量
- 5、對象字面量的擴展
- 6、Symbol
- 7、代碼模塊化
- 8、數字
- 9、字符串
- 10、正則表達式
- 11、對象
- 12、數組
- 13、類型化數組
- 14、函數
- 15、箭頭函數和尾調用優化
- 16、Set
- 17、Map
- 18、迭代器
- 19、生成器
- 20、類
- 21、類的繼承
- 22、Promise
- 23、Promise的靜態方法和應用
- 24、代理和反射
- HTML
- 1、SVG
- 2、WebRTC基礎實踐
- 3、WebRTC視頻通話
- 4、Web音視頻基礎
- CSS進階
- 1、CSS基礎拾遺
- 2、偽類和偽元素
- 3、CSS屬性拾遺
- 4、浮動形狀
- 5、漸變
- 6、濾鏡
- 7、合成
- 8、裁剪和遮罩
- 9、網格布局
- 10、CSS方法論
- 11、管理后臺響應式改造
- React
- 1、函數式編程
- 2、JSX
- 3、組件
- 4、生命周期
- 5、React和DOM
- 6、事件
- 7、表單
- 8、樣式
- 9、組件通信
- 10、高階組件
- 11、Redux基礎
- 12、Redux中間件
- 13、React Router
- 14、測試框架
- 15、React Hooks
- 16、React源碼分析
- 利器
- 1、npm
- 2、Babel
- 3、webpack基礎
- 4、webpack進階
- 5、Git
- 6、Fiddler
- 7、自制腳手架
- 8、VSCode插件研發
- 9、WebView中的頁面調試方法
- Vue.js
- 1、數據綁定
- 2、指令
- 3、樣式和表單
- 4、組件
- 5、組件通信
- 6、內容分發
- 7、渲染函數和JSX
- 8、Vue Router
- 9、Vuex
- TypeScript
- 1、數據類型
- 2、接口
- 3、類
- 4、泛型
- 5、類型兼容性
- 6、高級類型
- 7、命名空間
- 8、裝飾器
- Node.js
- 1、Buffer、流和EventEmitter
- 2、文件系統和網絡
- 3、命令行工具
- 4、自建前端監控系統
- 5、定時任務的調試
- 6、自制短鏈系統
- 7、定時任務的進化史
- 8、通用接口
- 9、微前端實踐
- 10、接口日志查詢
- 11、E2E測試
- 12、BFF
- 13、MySQL歸檔
- 14、壓力測試
- 15、活動規則引擎
- 16、活動配置化
- 17、UmiJS版本升級
- 18、半吊子的可視化搭建系統
- 19、KOA源碼分析(上)
- 20、KOA源碼分析(下)
- 21、花10分鐘入門Node.js
- 22、Node環境升級日志
- 23、Worker threads
- 24、低代碼
- 25、Web自動化測試
- 26、接口攔截和頁面回放實驗
- 27、接口管理
- 28、Cypress自動化測試實踐
- 29、基于Electron的開播助手
- Node.js精進
- 1、模塊化
- 2、異步編程
- 3、流
- 4、事件觸發器
- 5、HTTP
- 6、文件
- 7、日志
- 8、錯誤處理
- 9、性能監控(上)
- 10、性能監控(下)
- 11、Socket.IO
- 12、ElasticSearch
- 監控系統
- 1、SDK
- 2、存儲和分析
- 3、性能監控
- 4、內存泄漏
- 5、小程序
- 6、較長的白屏時間
- 7、頁面奔潰
- 8、shin-monitor源碼分析
- 前端性能精進
- 1、優化方法論之測量
- 2、優化方法論之分析
- 3、瀏覽器之圖像
- 4、瀏覽器之呈現
- 5、瀏覽器之JavaScript
- 6、網絡
- 7、構建
- 前端體驗優化
- 1、概述
- 2、基建
- 3、后端
- 4、數據
- 5、后臺
- Web優化
- 1、CSS優化
- 2、JavaScript優化
- 3、圖像和網絡
- 4、用戶體驗和工具
- 5、網站優化
- 6、優化閉環實踐
- 數據結構與算法
- 1、鏈表
- 2、棧、隊列、散列表和位運算
- 3、二叉樹
- 4、二分查找
- 5、回溯算法
- 6、貪心算法
- 7、分治算法
- 8、動態規劃
- 程序員之路
- 大學
- 2011年
- 2012年
- 2013年
- 2014年
- 項目反思
- 前端基礎學習分享
- 2015年
- 再一次項目反思
- 然并卵
- PC網站CSS分享
- 2016年
- 制造自己的榫卯
- PrimusUI
- 2017年
- 工匠精神
- 2018年
- 2019年
- 前端學習之路分享
- 2020年
- 2021年
- 2022年
- 2023年
- 2024年
- 日志
- 2020