我想你天天寫css代碼有時候也會以爲很痛苦:這個佈局的css怎麼這麼難實現!我也常常會有這種感受,一個看似簡單的佈局老是要琢磨半天才能實現,偶爾還會出現一些怪異的超出理解的現象。這是由於咱們對css只是大概知道個形,並無看透css的本質。在同事的推薦下我閱讀了張鑫旭老師的《css世界》,才發現css跟想象中的不太同樣。本文爲《css世界》我的總結筆記,爲縮減篇幅丟棄了張老師冗餘的小幽默,丟掉了些含金量較低的章節內容,由於ie已經被淘汰出局,因此有關css兼容性的地方也所有忽略不記,同時對我的以爲不易理解的地方加上了一些本身的理解和驗證,因此錯誤之處還望指正。順便推薦個好用的在線代碼編輯工具,國內鏡像站點,方便各位對本文實例進行測試。另外本文會隨着做者對css的更深刻理解而逐步更新,但願到最後可以文如標題展示出真正的css世界。css
這些基本概念有些可能不易理解但卻都很重要,若是看完仍是很不理解的話須要本身谷歌或百度,網上關於這些概念的文章很多。html
「流」又叫文檔流,是css的一種基本定位和佈局機制。流是html的一種抽象概念,暗喻這種排列布局方式好像水流同樣天然自動。「流體佈局」是html默認的佈局機制,如你寫的html不用css,默認自上而下(塊級元素如div
)從左到右(內聯元素如span
)堆砌的佈局方式。前端
這個你們確定都知道。css3
塊級元素是指單獨撐滿一行的元素,如div、ul、li、table、p、h1
等元素。這些元素的display值默認是block、table、list-item
等。git
內聯元素又叫行內元素,指只佔據它對應標籤的邊框所包含的空間的元素,這些元素若是父元素寬度足夠則並排在一行顯示的,如span、a、em、i、img、td
等。這些元素的display值默認是inline、inline-block、inline-table、table-cell
等。github
實際開發中,咱們常常把display
計算值爲inline
inline-block
inline-table
table-cell
的元素叫作內聯元素,而把display
計算值爲block
的元素叫作塊級元素。web
width
、height
的默認值都是auto
。面試
對於塊級元素,流體佈局之下width: auto
自適應撐滿父元素寬度。這裏的撐滿並不一樣於width: 100%
的固定寬度,而是像水同樣可以根據margin
不一樣而自適應父元素的寬度。segmentfault
對於內聯元素,width: auto
則呈現出包裹性,即由子元素的寬度決定。瀏覽器
不管內聯元素仍是塊級元素,height: auto
都是呈現包裹性,即高度由子級元素撐開。
注意父元素height: auto
會致使子元素height: 100%
百分比失效。
css的屬性很是有意思,正常流下,若是塊級元素的width
是個固定值,margin
是auto
,則margin
會撐滿剩下的空間;若是margin
是固定值,width
是auto
,則width
會撐滿剩下的空間。這就是流體佈局的根本所在。
外在盒子是決定元素排列方式的盒子,即決定盒子具備塊級特性仍是內聯特性的盒子。外在盒子負責結構佈局。
內在盒子是決定元素內部一些屬性是否生效的盒子。內在盒子負責內容顯示。
如 display: inline-table;
外在盒子就是inline
,內在盒子就是table
。外在盒子決定了元素要像內聯元素同樣並排在一排顯示,內在盒子則決定了元素能夠設置寬高、垂直方向的margin等屬性。以下圖
右側的table和左側的文字在一行排列(外在盒子inline的表現特徵),同時有擁有自定義寬度111px(內在盒子table能夠設置寬高)。
!important
曾經有道面試題把我難住了:
// 假設下面樣式都做用於同一個節點元素`span`,判斷下面哪一個樣式會生效
body#god div.dad span.son {width: 200px;}
body#god span#test {width: 250px;}
複製代碼
可憐當時作了三年前端的我居然還不知道css有權重😓
css選擇器權重列表以下:
權重值 | 選擇器 |
---|---|
1,0,0,0 | 內聯樣式:style="" |
0,1,0,0 | ID選擇器:#idName{...} |
0,0,1,0 | 類、僞類、屬性選擇器:.className{...} / :hover{...} / [type="text"] ={...} |
0,0,0,1 | 標籤、僞元素選擇器:div{...} / :after{...} |
0,0,0,0 | 通用選擇器(*)、子選擇器(>)、相鄰選擇器(+)、同胞選擇器(~) |
之前想固然的覺得權重是十進制的,即十個class選擇器等於一個id選擇器,這是錯誤的。CSS權重進制在IE6爲256,後來擴大到了65536,而現代瀏覽器則採用更大的數量。因此咱們能夠忽略進制的問題,從高往低比較權重值。
若是權重是十進制的比較方式,則十一個class選擇器的權重高於一個ID選擇器。但經測試並不是如此:地址。
能夠看到十一個class選擇器的樣式並無覆蓋一個id選擇器的樣式,由於:
當兩個權值進行比較的時候,是從高到低逐級將等級位上的權重值來進行比較的,而不是 1000個數 + 100個數 + 10個數 + 1個數 的總和來進行比較的,換句話說,低等級的選擇器個數再多也不會超太高等級的選擇器的優先級的。
正確規則:
所以上面那道的面試題比較應該是在第二等級id選擇器的比較就結束了:(#god + #test = 0,2,0,0) > (#god = 0,1,0,0);而上圖種例子中兩個權重分別是:(#test = 0,1,0,0) > (.test....test10 = 0,0,11,0),也是在第二等級id選擇器的比較時就結束了。因此之後比較權重,就先比較id選擇器個數,若是id同樣多,再比較class選擇器個數。哇,感受這能夠是一道專坑中文社區的面試題啊。
在css中,!important
的權重至關的高。若是出現了!important
,則無論權重如何都取有!important
的屬性值。可是寬高有例外狀況,因爲寬高會被max-width
/min-width
覆蓋,因此!important
會失效。
width: 100px!important;
min-width: 200px;
複製代碼
上面代碼計算以後會被引擎解析成:
width: 200px;
複製代碼
元素的內在盒子是由margin box
、border box
、padding box
、content box
組成的,這四個盒子由外到內構成了盒模型。
IE模型: box-sizing: border-box
此模式下,元素的寬度計算爲border+padding+content
的寬度總和。
w3c標準模型): box-sizing: content-box
此模式下,元素的寬度計算爲content
的寬度。
因爲content-box
在計算寬度的時候不包含border pading
很煩人,並且又是默認值,業內通常採用如下代碼重置樣式:
:root {
box-sizing: border-box;
}
* {
box-sizing: inherit;
}
複製代碼
內聯元素是指外在盒子是內聯盒子的元素。從表現來講,內聯元素的典型特徵就是能夠和文字在一行顯示。文字也是內聯元素。圖片、按鈕、輸入框、下拉框等替換元素也是內聯元素。內聯盒模型是指內聯元素包含的幾個盒子,理解記憶下面的幾個概念對css的深刻學習極其重要。
div
標籤,則不會造成行框盒子。行框盒子由一個個內聯盒子組成,若是換行,那就是兩個行框盒子。好比一個包含了不少字符的換行的的p
標籤,每一行都存在一個行框盒子。值得注意的是,若是給元素設置display: inline-block
,則建立了一個獨立的行框盒子。line-height
是做用在行框盒子上的,並最終決定高度。替換元素是指內容能夠替換的元素,實際上就是content box
能夠被替換的元素。如存在src=""
屬性的<img> <audio> <video> <iframe>
元素和能夠輸入文本的<input> <select> <textarea>
元素等。
全部替換元素都是內聯元素,默認display
屬性是inline
或inline-block
(除了input[type="hidden"]
默認display: none;
)。
替換元素有本身默認的樣式、尺寸(根據瀏覽器不一樣而不一樣),並且其vertical-align
屬性默認是bottom
(非替換元素默認值是baseline
)。
對於非替換元素如div
,其content
就是div內部的元素。 而對於替換元素,其content
就是可替換部分的內容。
CSS中的content
屬性主要用於僞元素:before/:after
中,除了作字體庫或少寫個div,對於通常開發來講並沒有卵用。
padding
是四大金剛中最穩定的了,少見有什麼異常。儘管如此仍是有些須要注意的地方:
box-sizing: border-box
,寬高的計算是包含了padding
的,給人一種padding
也是content box
一部分的感受,好像line-height
屬性也做用於padding
上。但實際上,元素真正的內容的寬高只是content box
的寬高,而line-height
屬性是不做用於padding
的。padding
不可爲負值,可是能夠爲百分比值。爲百分比時水平和垂直方向的padding
都是相對於父級元素寬度計算的。將一個div
設爲padding: 100%
就能獲得一個正方形,padding: 10% 50%
能夠獲得一個寬高比 5:1 的矩形。body {
width: 400px;
}
.box {
padding: 10% 50%;
}
複製代碼
padding
配合background-clip
屬性,能夠製做一些特殊形狀:/*三道槓*/
.icon1 {
box-sizing: border-box;
display: inline-block;
width: 12px;
height: 10px;
padding: 2px 0;
border-top: 2px solid currentColor;
border-bottom: 2px solid currentColor;
background: currentColor; /*注意若是此處背景顏色屬性用縮寫的話,須要放到其餘背景屬性的前面,不然會覆蓋前面的屬性值(此處爲background-clip)爲默認值*/
background-clip: content-box;
}
/*雙層圓點*/
.icon2 {
display: inline-block;
width: 12px;
height: 12px;
padding: 2px;
border: 2px solid currentColor;
border-radius: 50%;
background-color: currentColor;
background-clip: content-box;
}
複製代碼
預覽以下:(currentColor是css中爲數很少的變量,指當前文字的顏色值,很是好用)
margin
屬性並不會參與盒子寬度的計算,但經過設置margin
爲負值,卻能改變元素水平方向的尺寸:<div>asdf</div>
<style> div { margin: 0 -100px; } </style>
複製代碼
此時div
元素的寬度是比父級元素的寬度大200px
的。可是這種狀況只會發生在元素是流佈局的時候,即元素width
是默認的auto
而且能夠撐滿一行的時候。若是元素設定了寬度,或者元素設置了float: left
/ position: absolute
這樣的屬性改變了流體佈局,那麼margin
爲負也沒法改變元素的寬度了。
margin
合併,存在如下三種場景:margin
合併;margin-top
和子元素margin-top
,父元素margin-bottom
和子元素margin-bottom
;margin-top
和margin-botom
合併,例子以下。要阻止margin
合併,能夠:1. 把元素放到bfc
中;2. 設置border
或padding
阻隔margin
;3. 用內聯元素(如文字)阻隔;4. 給父元素設定高度。
margin
的百分比值跟padding
同樣,垂直方向的margin
和水平方向上的同樣都是相對於父元素寬度計算的。<div class="box">
<div></div>
</div>
<style> .box{ overflow: hidden; background-color: lightblue; } .box > div{ margin: 50%; } </style>
複製代碼
此時 .box 是一個寬高比 2:1 的矩形,由於空塊級元素自身的垂直方向的margin
發生了合併。
這裏父元素設置overflow: hidden
是利用 bfc
的特性阻止子元素的margin
和父元素合併,換成其餘 bfc
特性或者設置 1px
的 border
/ padding
都是能夠達到效果的。
margin: auto
能在塊級元素設定寬高以後自動填充剩餘寬高。margin: auto
自動填充觸發的前提條件是元素在對應的水平或垂直方向具備自動填充特性,顯然默認狀況下塊級元素的高度是不具有這個條件的。典型應用是塊級元素水平局中的實現:display: block;
width: 200px;
margin: 0 auto;
複製代碼
auto
的特性是,若是兩側都是auto
,則兩側均分剩餘寬度;若是一側margin
是固定的,另外一側是auto
,則這一側auto
爲剩餘寬度。栗子:
這個特性不爲人知,且很實用。
除了水平方向,垂直方向的margin
也能實現垂直居中,可是須要元素在垂直方向具備自動填充特性,而這個特性能夠利用position
實現:
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
width: 200px;
height: 200px;
margin: auto;
複製代碼
border
主要做用是作邊框。border-style
屬性的值有none/solid/dashed/dotted/double
等,基本看名字就能猜出什麼來了:
border-width
屬性的默認值是3px
,是爲了照顧小弟border-style: double
,你懂的。值得注意的是,border-color
默認是跟隨字體的顏色,至關於默認設置了border-color: currentColor
同樣。
border
另外一廣受歡迎的功能就是圖形構建,特別是作應用普遍的三角形,其原理可看下圖的1-3:
div{
float: left;
margin: 20px;
}
div:nth-child(1){
width: 20px;
height: 20px;
border: 20px solid;
border-color: blue red orange green;
}
div:nth-child(2){
width: 20px;
height: 20px;
border: 20px solid;
border-color: blue transparent transparent transparent;
}
div:nth-child(3){
border: 20px solid;
border-color: blue transparent transparent transparent;
}
div:nth-child(4){
border-style: solid;
border-width: 40px 20px;
border-color: blue transparent transparent transparent;
}
div:nth-child(5){
border-style: solid;
border-width: 40px 20px;
border-color: blue red transparent transparent;
}
複製代碼
其實就是將其餘三個邊框的顏色設置透明,並把寬高設爲 0 。圖中4-5兩個圖形,是經過調整邊框寬度和顏色調整三角形的形狀,把最後一個圖的紅色改成藍色,則是一個直角三角形了。
line-height
和vertical-align
line-height
和vertical-align
是控制元素垂直對齊的兩大屬性,也是最難理解搞懂的屬性。
在內聯元素的垂直方向對齊中,基線是最爲重要的概念。line-height
定義的就是兩基線之間的距離,vertical-align
的默認值就是基線。基線的定義則是字母 x 的下邊緣。
css中有個概念叫x-height
,指的是小寫字母 x 的高度。vertical-align: middle
對齊的就是基線往上1/2x-height
高度的地方,能夠理解爲近似字母 x 的交叉點。
css中除了px/em/rem
等,還有個單位是ex
。指的就是小寫字母x的高度,即x-height
。用處不大,再也不介紹。
line-height
各種屬性值normal
: 默認值normal
實際上是類型爲數值的變量,根據瀏覽器和字體'font-family'不一樣而不一樣,通常約爲 1.2 。
數值和百分比:最終會被計算爲帶單位的值,具體計算方法就是乘以字體大小font-size
。
長度值:就是100px
這樣帶單位的值。
這幾類值的繼承特性不一樣:line-height
是數值的元素的子元素繼承的就是這個數值,百分比/長度值繼承的都是計算後得出的帶單位的值(px)。
line-height
的做用:line-height
屬性用於設置多行元素的空間量,如多行文本的間距。
對塊級元素來講,line-height
決定了行框盒子的最小高度。注意是行框盒子的最小高度,而不是塊級元素的實際高度。(圖中兩個div
行高同樣,div.one
的背景色區域就是行框盒子的高度,而 div.two
的背景區域則是實際高度,其行框盒子高度和 div.one
是同樣的。)
對於非替代的 inline 元素,它用於計算行框盒子的高度。此時內聯元素的行框盒子的高度徹底由line-height
決定,不受其餘任何屬性的影響。
line-height
實現垂直居中的本質:行距行距是指一行文本和相鄰文本之間的距離。行距 = line-height
— font-size
。行距具備上下等分的機制:意思就是文字上下的行距是同樣的,各佔一半,這也是line-height
能讓內聯元素垂直居中的緣由。下圖中字母x上下行距各佔一半,共同撐起了div
。
下圖中和上圖惟一不一樣之處就是多了個display: inline-block
的span
元素,可是此處的span
元素並無影響div
元素的高度,而只是靠着vertical-align: middle
屬性將自身中心點對齊了字母x的交叉點實現垂直居中而已。div
元素的高度仍然和上圖如出一轍,由字母x和行距共同撐起。此時若是刪除字母x,div
的高度不變,由於span
元素的行框盒子前會產生幽靈空白節點,而幽靈空白節點+行高也能撐起div
。
<div class="box">
<span>asdf</span>
</div>
複製代碼
樣式1:此時 .box 高度是多少?
.box {
line-height: 100px;
background: lightgreen;
}
.box span {
line-height: 30px;
}
複製代碼
樣式2:此時 .box 高度是多少?
.box {
line-height: 30px;
background: lightgreen;
}
.box span {
line-height: 100px;
}
複製代碼
先說結論:不管內聯元素的line-height
如何設置,最終父元素的高度都是數值大的那個line-height
決定的。
樣式1中,span
元素的行框盒子前存在一個幽靈空白節點,而這個幽靈空白節點的行高是100px;樣式2中,幽靈空白節點的行高是30px,可是這時span元素的行高是100px。兩種狀況其實同樣,取大值而已。
vertical-align
的屬性值線類: 如baseline(默認值)
top
middle
bottom
(baseline
使元素的基線與父元素的基線對齊,middle
使元素的中部與父元素的基線往上x-height
的一半對齊。top
bottom
使元素及其後代元素的底部與整行或整塊的底部對齊。)
文本類: text-top
text-bottom
(使元素的頂部與父元素的字體頂部對齊。)
上標下標: sub
super
(使元素的基線與父元素的下標基線對齊。)
數值: 20px
2em
(默認值baseline
至關於數值的 0 。使元素的基線對齊到父元素的基線之上的給定長度,數值正值是基線往上偏移,負值是往下偏移,藉此能夠實現元素垂直方向精確對齊。)
百分比: 20%
(使元素的基線對齊到父元素的基線之上的給定百分比,該百分比是line-height屬性的百分比。)
vertical-align
的做用前提vertical-align屬性起做用的前提必須是做用在內聯元素上。 即display
計算值爲inline
inline-block
inline-table
table-cell
的元素。因此若是元素設置了float: left
或者position: absolute
,則其vertical-align
屬性不能生效,由於此時元素的display
計算值爲block
了。
line-height
、vertical-align
和第三者幽靈空白節點的愛恨情仇有時候會碰見下面這樣高度和設置不一致的狀況:
div
的實際高度比設定的行高大了,爲何呢?
內聯元素的默認對齊方式是baseline
,因此此時此時span
元素的基線是和父元素的基線相對齊的,而此時父元素的基線在哪呢?
父元素的基線其實就是行框盒子前的幽靈空白節點的基線。把幽靈空白節點具象化爲字母x
可能容易理解些:
因爲div
行高是30px
,因此字母x
和span
元素的高度都是30px
。可是字母x的font-size
較小,span
元素的font-size
較大,而行高同樣的狀況下font-size
越大基線的位置越偏下,因此二者的基線不在同一水平線上。以下圖左邊部分:
因爲內聯元素默認基線對齊,因此字母x
和span
元素髮生了位移以使基線對齊,致使div
高度變大。而此時字母x
的半行距比span
元素的半行距大,大出的部分就是div
的高度增長的部分。
display: inline-block
基線的不一樣之處先看例子,圖中span
元素設置了display: inline-block
和寬高,從而撐起了父元素div
的高度,但span
自己並沒有margin
屬性,那爲何底部和div
下邊緣之間會有空隙呢?地址
這就要說到inline-block
的不一樣之處了。一個設置了display: inline-block
的元素:
overflow
爲hidden auto scroll
,則其基線就是該元素下邊緣;知道了這點,那麼再回到上面的例子:
原來是第三者幽靈空白節點搞的鬼。此時span
的行框盒子前,還存在一個幽靈空白節點。因爲span
元素默認基線對齊,因此span
元素的基線也就是其下邊緣是和幽靈空白節點的基線對齊的。從而致使幽靈空白節點基線下面的半行距撐高了div
元素,形成空隙。以下圖:
若是span
元素中存在內聯元素呢?
能夠看到,此時span
元素下邊緣的空隙沒了,由於此時span
元素的基線是內部最後一行內聯元素的基線。
值得一提的是,因爲替換元素內部不可能再有別的元素,因此其基線位置永遠位於下邊緣。
間隙產生本質上是由基線對齊引起的錯位形成的,源頭上是vertical-align
和line-height
共同形成的,因此要想解決這個問題,只要直接或間接改造兩個屬性中的一個就好了:
display: block
使vertical-align
屬性失效;vertical-align
值如bottom/middle/top
;line-height
值;line-height
爲相對值如1.4
,設置font-size: 0
間接改變line-height
。下面是張鑫旭大佬推薦的利用vertical-align
實現的水平垂直居中彈框,可以理解的話就說明你已經徹底掌握了好基友和第三者的關係了。
<div class="container">
<div class="dialog">自適應彈出層</div>
</div>
<style> .container{ position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, .15); text-align: center; font-size: 0; white-space: nowrap; overflow: auto; } .container:after{ content: ''; display: inline-block; height: 100%; vertical-align: middle; } .dialog{ display: inline-block; width: 400px; height: 400px; vertical-align: middle; text-align: left; font-size: 14px; white-space: normal; background: white; } </style>
複製代碼
如今UI框架橫行的年代,咱們的css寫的愈來愈少了。這對於不少老鳥來講是件好事,可是對於初入前端的小白卻未必。由於寫的少了,就少了不少練手和總結的機會,對於不少樣式理解就不透徹。本章介紹的float
、position
和BFC
對於前端頁面佈局很是重要,但願諸位看官們靜下心來仔細研讀。
float
屬性的特性float
屬性應該是css世界最使人意外的屬性了,倒不是由於他的表現,而是他的設計初衷居然只是爲了實現「文字環繞圖片」的效果。只不過由於float
屬性的一些特性,才致使其被處處使用以至於產生了諸多不利於維護的頁面。 下面看看float
屬性的特性:
width
會像height
同樣由子元素決定,而不是默認撐滿父元素。float: left
以後,其display
的計算值就成了block
。格式化上下文是指會建立一個BFC,這個後面會講。margin
合併;float
設計的初衷就是爲了「文字環繞」效果,爲了讓文字環繞圖片,就須要具有兩個條件。第一是元素高度坍塌,第二是行框盒子不可與浮動元素重疊。而元素高度坍塌就致使元素後面的非浮動塊狀元素會和其重疊,因而他就像脫離文檔流了。前三個特性都是正能量滿滿,可是最後一個特性卻給咱們開發者帶來了不少麻煩,須要用到clear
來清除浮動。
clear
的做用和不足你們都知道clear: both
能夠清除前面浮動元素的浮動,但實際上,他並非真的清除了浮動。
clear
的定義是:元素盒子的邊不能與前面的浮動元素相鄰。也就是雖然浮動元素高度坍塌,可是設置了clear: both
的元素卻將其高度視爲仍然佔據位置。
clear
只能做用於塊級元素,而且其並不能解決後面元素可能發生的文字環繞問題。
BFC是一個獨立的渲染區域,只有Block-level box
參與, 它規定了內部的Block-level Box
如何佈局,而且與這個區域外部絕不相干。 BFC 就好像一個結界,結界裏面的東西不能影響外面的佈局,也就是說,BFC的子元素再翻江倒海,都不會影響外面的元素。 因此:
margin
重疊。float
不爲none
的元素);position
爲absolute
或fixed
);inline-blocks
(元素的 display: inline-block
);display: table-cell
,HTML
表格單元格默認屬性);overflow
的值不爲visible
的元素;flex boxes
(元素的display: flex
或inline-flex
);BFC包含建立該上下文元素的全部子元素,但不包括建立了新BFC的子元素的內部元素。
margin
決定。屬於同一個BFC的兩個相鄰Box的margin
會發生重疊;float box
重疊;乍一看還挺多的,但真正要注意並用心理解的只有 3 4 6 。
特性 1 中內部的盒是指塊級盒。由於<html>
根元素也是BFC,因此咱們日常寫的div p
都是獨自佔一行。
特性 2 <html>
是BFC,因此裏面的元素垂直方向的margin
會發生摺疊。可是,直接子孫元素與該BFC上下邊界margin
不能摺疊,保證了BFC內部的元素不會影響外部的元素。兩個上下相鄰的BFC之間折不折疊要看具體狀況,如display: inline-block
float: left
不會摺疊,而overflow: hidden
則會摺疊。
特性 3 徹底解讀:
In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box's line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
網上不少翻譯成「每一個元素的margin box
的左邊, 與包含塊border box
的左邊相接觸」的,這樣的翻譯是不許確甚至錯誤的,曾給我形成莫大的困惑和迷茫(這翻譯太坑爹了一度讓我懷疑人生)。正確的翻譯是「每個盒子的左外邊距應該和包含塊的左邊緣相接觸」。
第一,包含塊未必就是父級元素。對於position: absolute
來講,包含塊是指第一個positoin
不爲static
的祖先元素。
第二,BFC中的盒子應該與其自身的包含塊相接觸,而非與BFC盒子自己相接觸。
第三,BFC中的盒子是與其包含塊的 left edge
相接觸,而不是包含塊的 left-border
相接觸。left edge
正確的翻譯爲左邊緣。左邊緣多是content box
的左邊緣(非絕對定位如position: relative
float: left
),也多是padding box
的左邊緣(如絕對定位position: absolute
position: fixed
)。
理解了上面三點,其實特性 3 就是普通的流佈局和定位佈局默認貼着「左側」思想的總結。
如圖,aside
元素的margin box
的左邊距和BFC元素的左邊緣相接觸。而且因爲float box
高度坍塌,main
佔據了body
所有空間而且和包含塊BFC盒子左邊緣相接觸(特性3「即便存在浮動也是如此」)。
特性 4 正是BFC存在的意義。它規定了BFC子元素不管margin-top: -10000px
float: left
等都不會影響到BFC外部的元素的佈局。因此BFC是最好的清除浮動的方式,連浮動的文字環繞問題都能解決。
特性 5 BFC計算高度時包含浮動元素的高度。能夠利用BFC此特性解決浮動元素高度坍塌的問題。
特性 6 實現自適應兩欄佈局。此時main
寬度是自適應的。
除了 BFC ,還有 IFC GFC FFC 等佈局,瞭解便可,想看點 這裏。
position: absolute
和浮動元素同樣,絕對定位也具備塊狀化、BFC、包裹性、脫離文檔流、沒有margin
合併的特性。
但和浮動不一樣的是,絕對定位是徹底的脫離文檔流。你們還記得浮動產生的目的就是爲了實現文字環繞效果,因此浮動元素雖然脫離了文檔流,可是後面的文字仍是會環繞在浮動元素周圍。而絕對定位一但產生,就不會再對周圍元素產生任何影響。
並且二者包含塊不一樣,浮動元素包含塊只能是父級元素,絕對定位的包含塊則是距離最近的position
不爲static
的祖先元素。
大多數用到絕對定位的時候,都是存在包含塊和left/top
等方向屬性的。但其實position: absolute
是很是獨立的css屬性,其樣式和行爲表現不依賴任何css屬性就能夠完成。
能夠看出,無依賴的position: absolute
元素定位的位置和其自己無定位屬性時候的位置和display
的值有關。若是元素在沒有position
的狀況下是內聯元素,則和內聯元素在同一行顯示;若是元素在沒有position
屬性的狀況下是塊級元素,則換行顯示。
無依賴絕對定位的實用性雖然還行,可是其功能卻徹底能夠用left/top
實現。因此瞭解便可,若是有興趣能夠自行嘗試。
overflow: hidden
其實一句話就能夠表示二者之間的關係:當overflow: hidden
元素在絕對定位元素和其包含塊之間的時候,絕對定位元素不會被剪裁。
如下兩種絕對定位元素不會被剪裁:
<div style="overflow: hidden;">
<img src="big.jpg" style="position: absolute;">
</div>
<div style="position: relative;">
<div style="overflow: hidden;">
<img src="big.jpg" style="position: absolute;">
</div>
</div>
複製代碼
如下兩種絕對定位元素會被剪裁:
<div style="overflow: hidden; position: relative;">
<img src="big.jpg" style="position: absolute;">
</div>
<div style="overflow: hidden;">
<div style="position: relative;">
<img src="big.jpg" style="position: absolute;">
</div>
</div>
複製代碼
position: absolute
的流體特性當絕對定位元素的水平方向(left/right
)或垂直方向(top/bottom
)的兩個定位屬性同時存在的時候,絕對元素在該方向上便具備了流體特性。此時的width/height
屬性具備自動撐滿的特性,和一個正常流的div
元素的width
屬性別無二致。如圖,設置了固定margin
值的元素,寬高auto
可以自動適應剩餘空間:
一樣的,設置了固定寬高的元素,若是margin: auto
,則margin
平分剩餘空間致使垂直水平居中:
層疊規則是指當網頁中的元素髮生層疊時侯的遵循的規則。
層疊上下文好像是一個結界,層疊上下文內的元素若是跟層疊上下文外的元素髮生層疊,則比較該層疊上下文和外部元素的層疊上下文的層疊水平高低。
建立一個層疊上下文的方法就是給position
值爲relative/aboslute/fixed
的元素設置z-index
不爲auto
的值。
層疊上下文內元素的層疊水平以下圖:
border/background
是指當前層疊上下文元素的邊框和背景色。z-index
爲負值的元素在其之上。以下圖所示.dad
元素默認設置z-index: auto
,沒有建立層疊上下文,此時其就是一個普通的塊級盒子,因此設置了z-index: -1
的.son
元素跑到了爸爸身後看不見了。
而因爲.mom
設置了z-index: 0
,建立出了一個層疊上下文,因此.son
元素就算設置了z-index: -1
也跑不出老媽的視線。地址
z-index
爲auto
的定位元素。下圖span
就是普通定位元素:地址CSS3帶來了不少新屬性,其中很不惹人注意的一點就是增長了不少會自動建立層疊上下文的屬性:
opacity
值不爲1
,也就是透明元素;transform
值不爲none
;filter
值不爲none
;-webkit-overflow-scrolling: touch
;z-index
不爲auto
的彈性盒子的子元素;isolation
值爲isolate
;mix-blend-mode
值不爲normal
;will-change
值爲opacity/transform/filter/isolation/mix-blend-mode
中的一個。這些屬性大都不支持z-index
,因此他們都默認z-index: auto
,跟普通定位元素層疊水平同樣,因此若是發生層疊會後來居上:地址
可是彈性盒子display: flex
不一樣,彈性盒子的子元素支持設置z-index
,且設置了數值的z-index
也會自動建立層疊上下文。以下圖,能夠看到設置了z-index: 0
的元素層疊水平更高。地址
如下css屬性爲文本相關。
::first-letter
應用實例::first-letter
選中首個字符:地址
text-transform
應用假設有個輸入框只能輸入大寫字母,那麼以下設置,輸入小寫字母出現的倒是大寫字母,可用於身份證輸入框或驗證碼輸入框等:
input {
text-transform: uppercase;
}
複製代碼
word-spacing
空格間隙不要被表面意思誤導,word-spacing
指的是字符「空格」的間隙。若是一段文字中沒有空格,則該屬性無效。下面代碼設定空格間隙是20px
,也就是說空格如今佔據的寬度是原有的空格寬度+20px
的寬度:
<p>我有空 格,我該死......</p>
<style> p { word-spacing: 20px; } </style>
複製代碼
white-space
空白處理咱們都知道若是在html
中輸入多個空白符,默認會被當成一個空白符處理,實際上就是這個屬性控制的:地址
text-align: justify
(本文重點例子!)text-align: justify
爲兩端對齊。除了實現文字的兩端對齊,還能用來作一些兩端對齊的佈局。下面介紹個兩端對齊佈局的實例:地址
因爲text-align: justify
最後一行是左對齊,因此利用了三個空的i
標籤模擬最後一行。雖然實現了兩端對齊,可是最後一行卻出現間隙。根據以前的經驗應該是vertical-align
和line-height
搞的鬼,咱們給i
標籤加上outline
並用字母 x 模擬幽靈空白節點,現形:地址
上圖分析:首先第一個i
標籤基線與第二行的span
標籤中的數字的基線對其,因此其位置在中間。其次最後一行的i
標籤基線對齊幽靈空白節點字母x的基線,沒有錯位,因此此時最後一行的間隙高度就是字母x的高度。因此很容易想到把幽靈空白節點的行高設爲 0 來解決問題:地址
然而間隙雖然縮小了,可是仍是存在。此時因爲行高爲 0 ,幽靈空白節點也就是字母x在頁面中佔用的真實位置實際上是紅線所示。也就是說雖然字母 x 還顯示在頁面上,可是其真實高度已經爲0,此時其中線、上邊緣線、下邊緣線合一,都在紅線位置,其真實位置天然也就在紅線位置。然而其基線卻不會改變,在字母 x 下邊緣。
此時i
標籤的基線發生錯位,位移到下面與幽靈空白節點基線對齊,致使產生了間隙。
因此只須要再改變i
標籤的對齊方式,就能完全清除間隙:地址
此時i
標籤的基線對齊其幽靈空白節點的下邊緣線,沒有了錯位,也就沒有了間隙。
若是改成vertical-align: top
是同樣的,由於合一了。可是vertical-align: middle
卻不行,由於此middle
的位置是基線往上 1/2 個e-height
的地方。
好吧本例結束了,沒想到解釋起來這麼複雜。雖然當下兩端對齊佈局使用這種方法已通過時了(沒 flex 實現起來簡單,更沒 grid 實現好),可是好好學習這個方法能加深對vertical-align
和line-height
的理解。
元素的顯示隱藏方法不少,不一樣方法的在不一樣的場景下頁面效果不一,對頁面的性能也有不一樣的影響。
display: none
;visibility: hidden
;transition
淡入淡出效果:地址div{
position: absolute;
visibility: hidden;
opacity: 0;
transition: opacity .5s linear;
background: cyan;
}
div.active{
visibility: visible;
opacity: 1;
}
複製代碼
這裏使用visibility: hidden
而不是display: none
,是由於display: none
會影響css3的transition
過渡效果。 可是display: none
並不會影響cssanimation
動畫的效果。
opacity: 0
;opacity: 0; position: absolute;
;position: relative; z-index: -1;
;position: absolute ; z-index: -1;
;display: none
與visibility: hidden
的區別display: none
的元素不佔據任何空間,visibility: hidden
的元素空間保留;display: none
會影響css3的transition
過渡效果,visibility: hidden
不會;display: none
隱藏產生重繪 ( repaint ) 和迴流 ( relfow ),visibility: hidden
只會觸發重繪;(迴流重繪知識點參考:真正理解重繪和迴流)display: none
的節點和子孫節點元素全都不可見,visibility: hidden
的節點的子孫節點元素能夠設置 visibility: visible
顯示。visibility: hidden
屬性值具備繼承性,因此子孫元素默認繼承了hidden
而隱藏,可是當子孫元素重置爲visibility: visible
就不會被隱藏。若是面試問到這個問題,回答出來這四點應該是極好的。
彈性佈局是指display: flex
或display: inline-flex
的佈局。注意,設爲彈性佈局之後,子元素的float、clear、vertical-align
屬性都會失效。參見阮一峯大佬的 Flex 佈局教程。
主要屬性應用以下:
能夠看到 .container
容器中加了不少 i
空元素,這是爲了模擬項目佔位,也是彈性佈局實現兩端對齊的惟一不足之處~
網格佈局是目前最強大的 CSS 佈局方案。這裏總結了用 Grid 實現的經常使用 css 佈局:Grid網格佈局實例
css權重和超越!important
章節中權重部分的錯誤知識;(2019.10.16)彈性佈局實現兩端對齊尾行左對齊
實例;(2019.10.16)text-align: justify
連接中實例的顯示,固定了容器寬度;(2019.10.16)