前言
我們經常使用CSS
,但是卻不怎麼了解CSS
,本文主要對vertical-align
、BFC
、position
中開發過程不怎麼注意的特性進行簡要總結,從本文中,你將瞭解到以下內容:
vertical-align
為何時靈時不靈BFC
是什麼?有何作用- 絕對定位的奇淫技巧
CSS特性
vertical-align為什麼時靈時不靈
生效條件
只能應用在display
為inline
、inline-block
、inline-table
、table-cell
上。
有個高頻面試題,“如何使一個不定寬高div
垂直水平居中?”,有的萌新竟然回答用vertical-align: middle
。這個回答是減分的,至少在某種程度上給人一種感覺CSS
基礎比較薄弱。
內聯元素垂直居中對齊
開發中會遇到用字幕x
代替關閉icon
,用...
顯示溢位或者載入中。但是會發現字母x
、省略號並沒有與文字垂直方向居中對齊,這是因為文字預設是基線對齊,x
、省略號預設底部在基線處。如下圖所示:
如下,為文字對齊demo
:
<div class="container">
<span>你好,世界</span>
<span class="more">...</span>
</div>
實際顯示效果如下:
如果要實現垂直居中,利用vertical-align
,搭配line-height
即可,vertical-align
不僅可以設定middle/top/bottom/baseline...
關鍵字,也可以設定常用的度量單位,正負值均可,使用比較靈活。為什麼要給.more
設定line-height
屬性呢?其實是因為line-height
屬性可以繼承,如果不縮小.more
的行高,就會撐大父元素的尺寸。
<style>
.container{
font-size: 64px;
line-height: 64px;
}
.more{
line-height: 16px;
vertical-align: 16px;
}
</style>
BFC究竟有什麼作用
什麼是BFC
BFC
全稱block formatting context
,即“塊狀格式化上下文”,與外界元素相對獨立的一片區域,具有以下特性:
- 計算
BFC
高度時,浮動元素也參與計算 - 屬於同一
BFC
容器的元素垂直方向的margin
會合並 BFC
容器是獨立容器,不會影響外部元素的佈局
利用BFC
的特性,我們可以實現以下功能:
- 清除浮動
- 防止垂直方向
margin
合併 - 實現多欄彈性佈局
BFC的生效條件
以下CSS
屬性會觸發元素生成BFC
結界:
- 根元素(
<html>
) - 浮動元素(元素的
float
不是none
) - 絕對定位元素(元素的
position
為absolute
或fixed
) - 行內塊元素(元素的
display
為inline-block
) - 表格單元格(元素的
display
為table-cell
,HTML
表格單元格預設為該值) - 表格標題(元素的
display
為table-caption
,HTML
表格標題預設為該值) - 匿名錶格單元格元素(元素的
display
為table
、table-row
、table-row-group
、table-header-group
、table-footer-group
(分別- 是HTML table
、row
、tbody
、thead
、tfoot
的預設屬性)或inline-table
) overflow
計算值(Computed
)不為visible
的塊元素display
值為flow-root
的元素contain
值為layout
、content
或paint
的元素- 彈性元素(
display
為flex
或inline-flex
元素的直接子元素) - 網格元素(
display
為grid
或inline-grid
元素的直接子元素) - 多列容器(元素的
column-count
或column-width
不為auto
,包括column-count
為 1) column-span
為all
的元素始終會建立一個新的BFc
BFC使用案例
- 清除浮動
<style>
.container{
/* overflow: hidden; */
/* position: absolute; */
/* float: left; */
}
.left{
float: left;
width: 200px;
height: 200px;
}
</style>
<div class="container">
<div class="left"></div>
</div>
以上程式碼,container
容器高度為0
,因為子元素left
浮動。我們只需要把container
容器轉成BFC
容器,即可清楚浮動,註釋的幾種方法都可以。
- 防止垂直方向
margin
合併
<style>
.blue, .red-inner {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red-outer {
overflow: hidden;
background: red;
}
</style>
<div class="blue"></div>
<div class="red-outer">
<div class="red-inner">red inner</div>
</div>
- 自適應佈局
左側固定,右側自適應。
<style>
.left{
height: 200px;
width: 200px;
float: left;
background-color: burlywood;
}
.right{
height: 200px;
margin-left: 200px;
background-color: cadetblue;
}
</style>
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
絕對定位還能玩出什麼花樣
簡介
絕對定位使用場景非常多。絕對定位元素脫離文件流,相對於最近的非 static
祖先元素定位,可以利用left/right/top/bottom
定位元素位置。我們通常都是設定垂直方向與水平方向的的位置,如果四個方向都不設定或者四個方向都設定會出現什麼彩蛋呢?下文會給出揭曉。
left/top/right/bottom都有值的定位
- 當對立位置(
left
與right
,top
與bottom
)都設定值且元素沒用固定寬高
此時元素的寬高是根據元素位置決定的,張鑫旭大佬在《CSS
世界》中定義為格式化寬高,如下程式碼,最終box-item
的寬高計算為:width = 200 - 50 -50 = 100px;width = 200 - 50 -50 = 100px;
<style>
.box{
position: relative;
width: 200px;
height: 200px;
margin: 50px;
background-color: bisque;
}
.box-item{
position: absolute;
left: 50px;
right: 50px;
top: 50px;
bottom: 50px;
background-color: coral;
}
</style>
<div class="box">
<div class="box-item"></div>
</div>
這種行為特性對於我們做自適應佈局非常有用,而且相容性非常好,比如我們要做左側固定寬度,右側自適應,除了以上BFC
的寫法,我們還可以採用以下方法:
<style>
.container{
position: absolute;
top: 100px;
bottom: 100px;
left: 0;
right: 0;
}
.left{
position: absolute;
top: 0;
bottom: 0;
width: 200px;
background-color: burlywood;
}
.right{
position: absolute;
left: 200px;
right: 0;
top: 0;
bottom: 0;
background-color: cadetblue;
}
</style>
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
- 當對立位置都設定了值且元素設定了固定寬高
這個時候你會發現,元素的寬高時以width/height
為準,上述說的格式化寬度、高度並沒有生效。這是因為在高度計算過程中,元素的內部尺寸優先順序大於外部尺寸,width/height
影響的是元素內部尺寸,絕對定位影響的是外部尺寸,當元素絕對定位四個方向都設定值,此時外部尺寸會被內部尺寸覆蓋,導致實際元素寬度是width/height
的值。
我們經常用margin: 0 auto;
實現元素水平居中,但是不定寬高元素垂直水平居中就有些麻煩。但是有個神奇的現象,絕對定位配合margin: auto;
,可以實現元素垂直水平居中,如下所示:
<style>
.box{
position: relative;
width: 200px;
height: 200px;
margin: 50px;
background-color: bisque;
}
.box-item{
position: absolute;
margin: auto;
width: 50px;
height: 50px;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: coral;
}
</style>
<div class="box">
<div class="box-item"></div>
</div>
出現這種現象是因為margin:auto
本質上是平分元素剩餘可用空間,塊級元素一般是水平方向自動充滿,垂直方向順序排列。平常我們用margin: 0 auto;
之所以能夠使塊級元素水平居中,是因為水平方向元素存在剩餘可用空間,而auto
平分剩餘可用空間,因此就產生居中效果。而垂直方向不存在剩餘可用空間,因此無法垂直居中。
上述demo
,box-item
之所以能夠垂直居中,得益於top/bottom
設定了值,使元素產生高度100%
的外部尺寸,而width/height
固定元素的內部尺寸,使得 外部尺寸高度-內部尺寸高度=元素剩餘可用空間高度,而auto
等分剩餘可用空間,可以使元素達到垂直居中效果。可以嘗試調整四個方向的值,看看box-item
位置是怎麼移動的。
無依賴的絕對定位
當絕對定位沒有設定四周定位尺寸時,會發生神奇的一幕,當前元素沒有相對於最近的非 static
祖先元素定位,而是在當前位置不變,並且當前元素脫離文件流,不佔據頁面空間。這個特性某些情況下非常有用,比如給box-card
加一個圖示,藉助無依賴定位 + padding/margin
即可。寫法比較簡潔,建議嘗試一下。
小結
比起其他的開發語言,想要深入瞭解CSS
,並不是一件容易事,大多數人都是停留在用的基礎上,知道這個屬性/方法,至於為什麼會這樣瞭解較少。張鑫旭大佬CSS
高度讓人歎為觀止,繼續加油吧!!!
參考資料
- 《
CSS
世界》 - BFC