前言
接著上一篇,這篇主要集中對BFC、浮動、定位、負margin和相對定位的區(qū)別、偽類和偽元素進行整理。
一、BFC(塊級格式化上下文)
1、如何形成BFC
對元素設(shè)置以下屬性:(嵌套元素時則對父元素設(shè)置)
float:left/right
overflow:scroll/hidden/auto;
display:inline-block/table-cell/table-caption
position:absolute/fixed
2、設(shè)置BFC能解決的問題
(1)同屬一個BFC的兩個相鄰或嵌套元素,外邊距margin的設(shè)置會產(chǎn)生合并。
相鄰元素垂直外邊距合并情況。

這時對兩個相鄰元素其中一個設(shè)置BFC,形成一個新的BFC就可以清除這個問題:

(2)嵌套元素的外邊距合并情況

在父元素中使用BFC,讓子元素的margin設(shè)置生效:

(3)BFC不會重疊浮動元素
如下:浮動元素和文檔中正常流的元素重疊

對正常元素設(shè)定BFC之后:

(4)BFC解決浮動后的高度坍塌:因為BFC可以包含浮動
看下面例子:子元素全部浮動,父元素高度坍塌,父元素背景顏色設(shè)置無效。

對父元素設(shè)置BFC之后,父元素能夠包裹住兩個浮動子元素,背景顏色設(shè)置生效

二、浮動
1、重要特性
設(shè)置浮動的元素,不在文檔的普通流中,文檔的普通流中的元素表現(xiàn)的就像浮動元素不存在一樣。**
設(shè)置浮動,元素漂浮直至碰到邊框為止停止。




2、文字環(huán)繞特性
注意:跟在浮動元素后面的正常文檔流中的元素,會當(dāng)浮動元素不存在,但該元素中的文字卻能感知浮動元素的存在,會移動給浮動框留出空間,所以常見文字環(huán)繞浮動元素的現(xiàn)象。

設(shè)置浮動后:文字并不會跟隨置頂(可以設(shè)置BFC,讓浮動元素和正常流元素不重疊)

3、浮動引起的高度坍塌問題
如果不清除浮動,那么父容器元素就會出現(xiàn)高度坍塌。
如下,本來父元素的高度是靠子元素的高度來撐開的。

4、清除浮動
(1)使用clear屬性:clear:both/left/right/none
記住:clear屬性只對自身有效,是作用于自己的。
比如三個豎排的div,都設(shè)定右浮動,就會并排為一列,向右靠。
然后想讓第二個div向下一行,就需要對第二個設(shè)定clear:right,讓它的右邊不允許出現(xiàn)浮動元素的意思。而不是對第一個元素設(shè)定clear,這樣是無效的。常見直接了當(dāng)設(shè)置為clear:both

(2)清除浮動方法一:
在子元素后面再添加一個空div,對它設(shè)定清除兩邊浮動。
但這樣就增加一個無意義的標(biāo)簽,所以不建議。

(3)清除浮動方法二:BFC清除浮動
根據(jù)BFC的特性,可以通過對元素屬性設(shè)定BFC屬性就可以清除浮動。
但是父容器解決了坍塌,父容器的父容器呢?沒辦法一次解決;
而且因為BFC的形成是需要對元素設(shè)置屬性的,所以都會產(chǎn)生屬性設(shè)置帶來的影響。有些可能還是我不想要的。而且像display:inline-block的設(shè)置,在IE67中是無效的。所以這并不是好辦法。
(4)最通用清除浮動方法:(且兼容IE67的方法)
對父容器設(shè)置一個class——clearfix,然后對其設(shè)置如下屬性:
.clearfix{
*zoom:1;
}
.clearfix:after{ /*記得寫after,最后一個子元素插入內(nèi)容*/
content:" "; /*注意是content*/
display:block;
clear:both;
}
這種方法可以清除浮動,且不會增加一個無用的標(biāo)簽
總而言之:清除浮動有兩種方法:使用clear屬性;讓父元素形成BFC,靈活靈用。很多時候,像父容器本身就需要設(shè)置position:absolute的時候,剛好也就形成BFC了,所以我們不再需要額外設(shè)置什么。
三、定位
1、定位屬性
(1)position:inherit,繼承父元素的position屬性設(shè)置
(2)position:static,定位的默認設(shè)置,相當(dāng)于沒有設(shè)置的效果。元素在文檔正常流中。自然top/left/right/bottom/z-index的設(shè)置對其都無效
(3)position:relative,相對定位。相對元素在正常文檔流中的位置進行定位移動。無論元素是否移動,只要設(shè)置了相對定位,元素在文檔流中的空間位置還是不變的,只是看上去位置移動了。其他元素還是認定該元素的原有空間位置的。
(4)position:absolute,絕對定位。元素脫離了正常的文檔流。
注意:設(shè)定絕對定位的元素位置是相對其有設(shè)定position屬性(除設(shè)置static之外)的父元素進行定位。如果父元素沒有設(shè)置定位屬性,則再往上找父元素的父元素,一直往上,直至html的根節(jié)點,則相對html根節(jié)點的位置進行top/left/right/bottom屬性的設(shè)置移動
2、驗證1:絕對定位是相對html的位置做定位,而不是body

父節(jié)點body設(shè)置相對定位后,就相對body的位置定位:

3、驗證2
如果父元素中有設(shè)置padding/border/margin,那么設(shè)定絕對定位的子元素的top/left/right/bottom的屬性是相對內(nèi)邊距、外邊距還是邊框呢?受誰影響?
測試可知,設(shè)定position:absolute后,如果不設(shè)定top/left/right/bottom(則默認為top/left/right/bottom:auto),那么元素就相對內(nèi)邊距padding而定。(如果父元素有設(shè)置padding的話),所以一定要記得position:absolute設(shè)置后,隨手設(shè)定top/left/right/bottom,設(shè)定為0也行。


這也是為什么要設(shè)定“父相子絕”的原因,讓子元素可以相對父元素做位置設(shè)定,而且不會超出父元素位置,同時父元素設(shè)定相對定位,而不設(shè)置top/left/right/bottom這些設(shè)置的話,父元素位置是不變的
4、絕對定位是脫離文檔流的
這點和浮動有點小區(qū)別。浮動元素也是脫離文檔流,但是相鄰元素里的文本還是能感知浮動元素的存在而產(chǎn)生環(huán)繞。而絕對定位的設(shè)置,其他元素都會完全當(dāng)這個元素不存在一樣。
5、設(shè)置z-index來控制疊放順序
絕對定位因為和文檔流無關(guān),所以可以覆蓋其他元素,兩個絕對定位元素也可以覆蓋??梢酝ㄟ^設(shè)置z-index來控制疊放順序。
6、設(shè)置絕對定位后寬度也做設(shè)置
絕對定位設(shè)置后,元素的寬度是會收縮的,默認會根據(jù)內(nèi)容而定,由內(nèi)容多少來撐開。所以設(shè)定絕對定位后,需要把寬度值也一并做設(shè)定
7、關(guān)于寬度100%
一般如果父子元素都沒有特別設(shè)置,那么子元素的width:100%,就是子元素的content寬度等于父元素content寬度(這個日常要記住)
如果是子元素設(shè)定絕對定位,那么子元素的width:100%,就是子元素的content寬度等于父元素padding+content的寬度
同理的,對于設(shè)置絕對定位后,left/top/right/bottom的寬度設(shè)置%百分比,也是相對父元素的content寬度而取的。
8、position:fixed,絕對定位
細分叫固定定位。相對瀏覽器窗口定位,通過top/left/right/bottom屬性的設(shè)置移動。
9、position:sticky
CSS3的新屬性,兼容性差,表現(xiàn)類似position:relative和position:fixed的合體,在目標(biāo)區(qū)域在屏幕中可見時,它的行為就像position:relative; 而當(dāng)頁面滾動超出目標(biāo)區(qū)域時,它的表現(xiàn)就像position:fixed,它會固定在目標(biāo)位置。IE11、chrome部分支持。手機瀏覽器不支持。
10、絕對定位的使用場景
重要常見的是:垂直、水平的絕對居中
/*父元素的設(shè)置*/
.wrapper{
border:2px solid black;
width:200px;
height:200px;
padding:20px;
position:relative
}
/*子元素的設(shè)置*/
.one{
border:2px solid yellow;
width:100px;
height:100px;
position:absolute;
top:50%; /*取父元素content寬度的一半*/
left:50%;
margin-left:-50px; /*取子元素寬度的一半*/
margin-top:-50px; /*取子元素高度的一半*/
}

四、負margin和相對定位的區(qū)別:
一個元素設(shè)置負margin,它的相鄰元素位置也是會受影響,跟隨做移動的。

而相對定位的設(shè)置,它的相鄰元素位置是不受影響的。還是認該元素在文檔流中本來的位置而定位

五、偽類和偽元素
1、偽類
偽類用于元素在某種狀態(tài)下時,進行樣式的變化設(shè)置。記得是元素的狀態(tài)變化。
(1)常見的表單類的偽類:
:checked
:disabled
:read-only
:valid,:invalid
(2)對于偽類,常見的知識點就是,區(qū)分a鏈接的狀態(tài):
:hover 當(dāng)鼠標(biāo)放在元素上時
:link 作為一個a鏈接元素時
:active 鼠標(biāo)放在元素上,按下鼠標(biāo)的時候
:focus 鼠標(biāo)獲取焦點的時候
:visited 鏈接被訪問過后
明白這幾個偽類的書寫順序,不至于讓有些偽類的狀態(tài)樣式設(shè)置失效:記住樣式的設(shè)置,越往后的權(quán)重越高,設(shè)置就會保留。
擺放順序是:
a:link
a:visited
a:hover
a:active
這個順序可由測試得知,當(dāng)然要記憶的話,就可以理解來記憶:首先先是個a鏈接,:link這個偽類設(shè)置可設(shè)可不設(shè)。然后:visited這個偽類,是肯定放在link后面,才點擊后的設(shè)置生效。然后是:hover,是鼠標(biāo)略過時候的變化,這個是放在:visited后面,才不會被visited覆蓋。然后active這個操作,是鼠標(biāo)按下之后的操作,相比hover還有進一步動作的,為避免被覆蓋,還得放在更后面。

(3)first-child和first-of-type
h1:first-child,意思就是是h1元素下的第一個子元素
h1:first-of-type,意思選擇是h1元素,并且它是它父親元素下的子元素中第一個h1元素的子元素。
5、偽元素
偽元素是很廣泛的應(yīng)用,可以創(chuàng)建不在文檔樹中的元素,并設(shè)置其樣式。這樣可以省標(biāo)簽。很常見的用法,要學(xué)會記得使用。
(1)偽元素常見的偽元素有:
::after/:after,::before/:before,兩者寫法相同,雙冒號是CSS3的寫法
::first-letter/:first-letter,就是單詞首字母的設(shè)置
::first-line/:first-line,就是多行文字中第一行的設(shè)置
重點區(qū)分,:before和:after偽元素,是分別生成作為所在元素內(nèi)部創(chuàng)建第一個子元素和最后一個元素,content這一行是一定要有的,即使是content:' ',沒有寫的話,設(shè)置偽元素就失效
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="box">
<p>這是第一段</p>
<p>這是第二段</p>
</div>
<style>
.box:before{
content: 'start'
}
.box:after{
content: 'end'
}
</style>
</body>
</html>
結(jié)果:

(2)after和before偽元素的應(yīng)用
1)生成最后一個或第一個子元素
2)清除浮動
3)小三角的實現(xiàn):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.bubble{
border:1px solid black;
width:200px;
height:30px;
line-height:30px;
background:#fff;
border-radius:5px;
position:relative;
top:20px;
text-align:center;
}
.bubble:before{
content:'';
display:inline-block;
width:10px;
height:10px;
border-top:1px solid red;
border-left:1px solid red;
transform:rotateZ(45deg);
position:absolute;
top:-6px;
left:20px;
background:#fff;
}
</style>
</head>
<body>
<div class="bubble">hi, 這里是饑人谷</div>
</body>
</html>
實現(xiàn)效果:

3)字體圖標(biāo)的使用:
我們使用審查元素來看一個icon的時候,??吹降氖怯?:before

背后這個icon的顯示就是使用了偽元素。當(dāng)我們打開icon的引用src路徑時,可以看到,前面的樣式設(shè)置都是些兼容的寫法,作用于靠before生成的元素,元素的內(nèi)容也就是這個content就是一個Unicode碼。因此字體圖標(biāo)其實都是偽元素來生成的。

(3)其他應(yīng)用
實現(xiàn)input的默認樣式的修改,已經(jīng)狀態(tài)值變化后的樣式:
修改input的復(fù)選框的默認樣式的關(guān)鍵:
-webkit-appearance: none;
appearance: none;
關(guān)鍵點就是使用:checked的偽元素:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
今天的心情: <input type="checkbox">
<style>
input[type=checkbox]{
-webkit-appearance: none;
appearance: none;
background: url(http://7xpvnv.com2.z0.glb.qiniucdn.com/b6dcd011-23cc-4d95-9e51-9f10100103bd.png) 0 0 no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: contain;
vertical-align: middle;
outline: none;
}
input[type=checkbox]:checked{
-webkit-appearance: none;
appearance: none;
background: url(http://7xpvnv.com2.z0.glb.qiniucdn.com/538f26f0-6f3e-48d5-91e6-5b5bb730dd19.png) 0 0 no-repeat;
display: inline-block;
width: 20px;
height: 20px;
background-size: contain;
vertical-align: middle;
}
</style>
</body>
</html>
實現(xiàn)效果:


(4)還有下面的常見偽元素,僅能雙冒號:
:selection,用于設(shè)置被選中的文字的樣式
:input-placeholder,這個挺好的。就是用于設(shè)置input元素的placeholder的樣式
//記住要兼容寫法才生效
input::-webkit-input-placeholder{
color: blue
}
input::selection{
color:red;
}