前言
接著上一篇,這篇主要集中對BFC、浮動、定位、負margin和相對定位的區別、偽類和偽元素進行整理。
一、BFC(塊級格式化上下文)
1、如何形成BFC
對元素設置以下屬性:(嵌套元素時則對父元素設置)
float:left/right
overflow:scroll/hidden/auto;
display:inline-block/table-cell/table-caption
position:absolute/fixed
2、設置BFC能解決的問題
(1)同屬一個BFC的兩個相鄰或嵌套元素,外邊距margin的設置會產生合并。
相鄰元素垂直外邊距合并情況。
這時對兩個相鄰元素其中一個設置BFC,形成一個新的BFC就可以清除這個問題:
(2)嵌套元素的外邊距合并情況
在父元素中使用BFC,讓子元素的margin設置生效:
(3)BFC不會重疊浮動元素
如下:浮動元素和文檔中正常流的元素重疊
對正常元素設定BFC之后:
(4)BFC解決浮動后的高度坍塌:因為BFC可以包含浮動
看下面例子:子元素全部浮動,父元素高度坍塌,父元素背景顏色設置無效。
對父元素設置BFC之后,父元素能夠包裹住兩個浮動子元素,背景顏色設置生效
二、浮動
1、重要特性
設置浮動的元素,不在文檔的普通流中,文檔的普通流中的元素表現的就像浮動元素不存在一樣。**
設置浮動,元素漂浮直至碰到邊框為止停止。
2、文字環繞特性
注意:跟在浮動元素后面的正常文檔流中的元素,會當浮動元素不存在,但該元素中的文字卻能感知浮動元素的存在,會移動給浮動框留出空間,所以常見文字環繞浮動元素的現象。
設置浮動后:文字并不會跟隨置頂(可以設置BFC,讓浮動元素和正常流元素不重疊)
3、浮動引起的高度坍塌問題
如果不清除浮動,那么父容器元素就會出現高度坍塌。
如下,本來父元素的高度是靠子元素的高度來撐開的。
4、清除浮動
(1)使用clear屬性:clear:both/left/right/none
記住:clear屬性只對自身有效,是作用于自己的。
比如三個豎排的div,都設定右浮動,就會并排為一列,向右靠。
然后想讓第二個div向下一行,就需要對第二個設定clear:right,讓它的右邊不允許出現浮動元素的意思。而不是對第一個元素設定clear,這樣是無效的。常見直接了當設置為clear:both
(2)清除浮動方法一:
在子元素后面再添加一個空div,對它設定清除兩邊浮動。
但這樣就增加一個無意義的標簽,所以不建議。
(3)清除浮動方法二:BFC清除浮動
根據BFC的特性,可以通過對元素屬性設定BFC屬性就可以清除浮動。
但是父容器解決了坍塌,父容器的父容器呢?沒辦法一次解決;
而且因為BFC的形成是需要對元素設置屬性的,所以都會產生屬性設置帶來的影響。有些可能還是我不想要的。而且像display:inline-block的設置,在IE67中是無效的。所以這并不是好辦法。
(4)最通用清除浮動方法:(且兼容IE67的方法)
對父容器設置一個class——clearfix,然后對其設置如下屬性:
.clearfix{
*zoom:1;
}
.clearfix:after{ /*記得寫after,最后一個子元素插入內容*/
content:" "; /*注意是content*/
display:block;
clear:both;
}
這種方法可以清除浮動,且不會增加一個無用的標簽
總而言之:清除浮動有兩種方法:使用clear屬性;讓父元素形成BFC,靈活靈用。很多時候,像父容器本身就需要設置position:absolute的時候,剛好也就形成BFC了,所以我們不再需要額外設置什么。
三、定位
1、定位屬性
(1)position:inherit,繼承父元素的position屬性設置
(2)position:static,定位的默認設置,相當于沒有設置的效果。元素在文檔正常流中。自然top/left/right/bottom/z-index的設置對其都無效
(3)position:relative,相對定位。相對元素在正常文檔流中的位置進行定位移動。無論元素是否移動,只要設置了相對定位,元素在文檔流中的空間位置還是不變的,只是看上去位置移動了。其他元素還是認定該元素的原有空間位置的。
(4)position:absolute,絕對定位。元素脫離了正常的文檔流。
注意:設定絕對定位的元素位置是相對其有設定position屬性(除設置static之外)的父元素進行定位。如果父元素沒有設置定位屬性,則再往上找父元素的父元素,一直往上,直至html的根節點,則相對html根節點的位置進行top/left/right/bottom屬性的設置移動
2、驗證1:絕對定位是相對html的位置做定位,而不是body
父節點body設置相對定位后,就相對body的位置定位:
3、驗證2
如果父元素中有設置padding/border/margin,那么設定絕對定位的子元素的top/left/right/bottom的屬性是相對內邊距、外邊距還是邊框呢?受誰影響?
測試可知,設定position:absolute后,如果不設定top/left/right/bottom(則默認為top/left/right/bottom:auto),那么元素就相對內邊距padding而定。(如果父元素有設置padding的話),所以一定要記得position:absolute設置后,隨手設定top/left/right/bottom,設定為0也行。
這也是為什么要設定“父相子絕”的原因,讓子元素可以相對父元素做位置設定,而且不會超出父元素位置,同時父元素設定相對定位,而不設置top/left/right/bottom這些設置的話,父元素位置是不變的
4、絕對定位是脫離文檔流的
這點和浮動有點小區別。浮動元素也是脫離文檔流,但是相鄰元素里的文本還是能感知浮動元素的存在而產生環繞。而絕對定位的設置,其他元素都會完全當這個元素不存在一樣。
5、設置z-index來控制疊放順序
絕對定位因為和文檔流無關,所以可以覆蓋其他元素,兩個絕對定位元素也可以覆蓋。可以通過設置z-index來控制疊放順序。
6、設置絕對定位后寬度也做設置
絕對定位設置后,元素的寬度是會收縮的,默認會根據內容而定,由內容多少來撐開。所以設定絕對定位后,需要把寬度值也一并做設定
7、關于寬度100%
一般如果父子元素都沒有特別設置,那么子元素的width:100%,就是子元素的content寬度等于父元素content寬度(這個日常要記住)
如果是子元素設定絕對定位,那么子元素的width:100%,就是子元素的content寬度等于父元素padding+content的寬度
同理的,對于設置絕對定位后,left/top/right/bottom的寬度設置%百分比,也是相對父元素的content寬度而取的。
8、position:fixed,絕對定位
細分叫固定定位。相對瀏覽器窗口定位,通過top/left/right/bottom屬性的設置移動。
9、position:sticky
CSS3的新屬性,兼容性差,表現類似position:relative和position:fixed的合體,在目標區域在屏幕中可見時,它的行為就像position:relative; 而當頁面滾動超出目標區域時,它的表現就像position:fixed,它會固定在目標位置。IE11、chrome部分支持。手機瀏覽器不支持。
10、絕對定位的使用場景
重要常見的是:垂直、水平的絕對居中
/*父元素的設置*/
.wrapper{
border:2px solid black;
width:200px;
height:200px;
padding:20px;
position:relative
}
/*子元素的設置*/
.one{
border:2px solid yellow;
width:100px;
height:100px;
position:absolute;
top:50%; /*取父元素content寬度的一半*/
left:50%;
margin-left:-50px; /*取子元素寬度的一半*/
margin-top:-50px; /*取子元素高度的一半*/
}
四、負margin和相對定位的區別:
一個元素設置負margin,它的相鄰元素位置也是會受影響,跟隨做移動的。
而相對定位的設置,它的相鄰元素位置是不受影響的。還是認該元素在文檔流中本來的位置而定位
五、偽類和偽元素
1、偽類
偽類用于元素在某種狀態下時,進行樣式的變化設置。記得是元素的狀態變化。
(1)常見的表單類的偽類:
:checked
:disabled
:read-only
:valid,:invalid
(2)對于偽類,常見的知識點就是,區分a鏈接的狀態:
:hover 當鼠標放在元素上時
:link 作為一個a鏈接元素時
:active 鼠標放在元素上,按下鼠標的時候
:focus 鼠標獲取焦點的時候
:visited 鏈接被訪問過后
明白這幾個偽類的書寫順序,不至于讓有些偽類的狀態樣式設置失效:記住樣式的設置,越往后的權重越高,設置就會保留。
擺放順序是:
a:link
a:visited
a:hover
a:active
這個順序可由測試得知,當然要記憶的話,就可以理解來記憶:首先先是個a鏈接,:link這個偽類設置可設可不設。然后:visited這個偽類,是肯定放在link后面,才點擊后的設置生效。然后是:hover,是鼠標略過時候的變化,這個是放在:visited后面,才不會被visited覆蓋。然后active這個操作,是鼠標按下之后的操作,相比hover還有進一步動作的,為避免被覆蓋,還得放在更后面。
(3)first-child和first-of-type
h1:first-child,意思就是是h1元素下的第一個子元素
h1:first-of-type,意思選擇是h1元素,并且它是它父親元素下的子元素中第一個h1元素的子元素。
5、偽元素
偽元素是很廣泛的應用,可以創建不在文檔樹中的元素,并設置其樣式。這樣可以省標簽。很常見的用法,要學會記得使用。
(1)偽元素常見的偽元素有:
::after/:after,::before/:before,兩者寫法相同,雙冒號是CSS3的寫法
::first-letter/:first-letter,就是單詞首字母的設置
::first-line/:first-line,就是多行文字中第一行的設置
重點區分,:before和:after偽元素,是分別生成作為所在元素內部創建第一個子元素和最后一個元素,content這一行是一定要有的,即使是content:' ',沒有寫的話,設置偽元素就失效
<!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>
結果:
(2)after和before偽元素的應用
1)生成最后一個或第一個子元素
2)清除浮動
3)小三角的實現:
<!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>
實現效果:
3)字體圖標的使用:
我們使用審查元素來看一個icon的時候,常看到的是有::before
背后這個icon的顯示就是使用了偽元素。當我們打開icon的引用src路徑時,可以看到,前面的樣式設置都是些兼容的寫法,作用于靠before生成的元素,元素的內容也就是這個content就是一個Unicode碼。因此字體圖標其實都是偽元素來生成的。
(3)其他應用
實現input的默認樣式的修改,已經狀態值變化后的樣式:
修改input的復選框的默認樣式的關鍵:
-webkit-appearance: none;
appearance: none;
關鍵點就是使用: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>
實現效果:
(4)還有下面的常見偽元素,僅能雙冒號:
:selection,用于設置被選中的文字的樣式
:input-placeholder,這個挺好的。就是用于設置input元素的placeholder的樣式
//記住要兼容寫法才生效
input::-webkit-input-placeholder{
color: blue
}
input::selection{
color:red;
}