那些被忽略的盒子模型小知識
本文是筆者在學習CSS時的一些小白總結
我們知道的盒子模型主要由4個區域組成,分別是內容區域(content),內邊距區域(padding),邊框區域(border)和外邊距區域(margin)。 對於不瞭解盒子模型的朋友可以移步到這裡瞭解一下。

Content(內容)
1. 替換元素
替換元素(replaced element),顧名思義就是內容可以被替換的元素。
我們通常會把一些特殊意義的文字替換成圖片,比如一個網站的logo。

我們會在頁面上看到的不是h1標籤顯示的”Google“文字,而是谷歌logo的圖片。使用了content的元素的內容在html標籤中是不存在的。這樣做就有個好處,當爬蟲來訪問我們的網站,爬蟲可以知道我們這個主站的h1標題是”Google“而不是一個img標籤,且在視覺上給使用者更好的體驗。
2. 偽元素::before和::after

::before
和
::after
兩個偽元素,把這些與邏輯不相關的寫在css裡,react dom則專注於資料的表現。
<div className="price-panel"> <span className="price-panel__price"> ¥ {(totalPrice / 100).toFixed(1)} </span> <span className="price-panel__discount-price"> 已省¥ {(totalDiscountPrice / 100).toFixed(1)} </span> <span className="price-panel__discount"> ( {(discount / 10).toFixed(1)} 折) </span> </div> 複製程式碼
使用了偽元素後的react程式碼顯然更加清晰表示資料。 HTML:
<div className="price-panel"> <span className="price-panel__price"> {(totalPrice / 100).toFixed(1)} </span> <span className="price-panel__discount-price"> {(totalDiscountPrice / 100).toFixed(1)} </span> <span className="price-panel__discount"> {(discount / 10).toFixed(1)} </span> </div> 複製程式碼
SCSS:
.price-panel { &__price { &::before { content: '¥'; } } &__discount-price { &::before { content: '已省¥'; } } &__discount { &::before { content: '('; } &::after { content: '折)'; } } } 複製程式碼
我們還能使用偽元素幫助實現一些本來需要多個div實現的樣式,比如下面這個對話方塊。

HTML:
<div class="dialog">Hi,I’m a bubble dialog. Can you see me?</div> 複製程式碼
CSS:
.dialog { background: #f0f; padding: 10px; border-radius: 10px; color: white; max-width: 250px; position: relative; overflow: visible; } .dialog::after { position: absolute; content: ''; display: inline-block; border-width: 5px 10px; border-style: solid; border-color: transparent transparent #f0f #f0f; width: 0; height: 0; right: -20px; } 複製程式碼
Padding(內邊距)
padding的百分比值是非常有用的。需要注意的padding的百分比值,無論是水平方向還是垂直方向都是相對於 寬度 進行計算的。
如果需要弄一張16:9的等比縮放圖片,可以利用padding的這個特性,設定一個 padding-top
或者 padding-bottom
為56.25%即可(100\16*9)


Margin(外邊距)
1. margin合併
塊級元素的 margin-top
和 margin-bottom
有時候會合併為單個margin,這種現象叫 margin合併 。 margin合併發生兩個重要元素
- 必須是塊級元素
- 只發生在垂直方向。
margin合併的場景
1.1 相鄰兄弟元素

1.2 父級和第一個/最後一個子元素
在實際開發中,父子margin合併很有可能會帶給我們麻煩。 如下圖所示,div表現出和我們預想不一致的結果。

那麼怎麼才能防止這種父子margin合併導致的和預想不一致問題呢? 解決方法如下(這裡直接複製了張鑫旭老師書籍《CSS世界》的原話。): (1)對於margin-top合併(滿足一個即可):
border-top padding-top
(2)對於margin-bottom合併(滿足一個即可):
- 父元素設定為BFC
- 設定
border-bottom
(transparent也可以的) - 設定
padding-bottom
- 父元素和最後一個子元素之間新增一個內聯元素
- 父元素設定
height
、min-height
或者max-height
1.3 空塊級元素的margin合併

2. margin auto
每當說到 margin:auto
,我的第一反應是居中。但這個只是一個淺層應用的表象。 接下來我們去一起看看這個 margin:auto
究竟是‘何方神聖’。
margin:auto
的填充規則如下:
- 如果一側定值,一側auto,則auto為剩餘空間大小。注意auto並不是0的意思。
- 如果兩側都是auto,則平分剩餘的空間
我會疑惑為什麼我設定了 margin: auto
,卻在垂直方向上沒有居中。

這裡《css世界》中給出的答案讓人非常容易理解。假如把.son元素的height去掉,.son的高度會自動變成父元素的200px,顯然不會,所以無法觸發margin: auto。同理,如果把width為200px去掉,確實是會和父元素一樣寬。
那麼如何讓垂直居中呢? 子元素使用絕對定位後設置 margin: auto
即可

Border(邊框)
用border繪製三角形
我們可以利用border color為透明來繪製一些圖形,比如三角形

注意 border-color
這個屬性。
/* border-color: color; 單值語法 */ border-color: red; /* border-color: vertical horizontal; 雙值語法*/ border-color: red #f015ca; /* border-color: top horizontal bottom; 三值語法 */ border-color: red yellow green; /* border-color: top right bottom left; 四值語法 */ border-color: red yellow green blue; 複製程式碼
當然,我們繪製三角形不限於這種等腰三角。

這裡繪製了一個底邊分別是60px和160px的直角三角形。
參考
文章主要參考了張鑫旭老師的《css世界》並根據自己的業務做出的一些實踐總結。