1. 程式人生 > >css-overflow:hidden那點事兒

css-overflow:hidden那點事兒

最近遇到一個問題,現象是給元素設定了overflow:hidden,但超出容器的部分並沒有被隱藏,難道是設定的hidden失效了嗎?

首先了解一下overflow屬性值有這幾種:

visible:宣告內容不會被剪裁。比如內容可能被渲染到容器外面。
hidden:宣告內容將被剪裁,並且也甭想使用滾動條來檢視剪裁掉的內容。
scroll:宣告內容將被剪裁,但有可能出現滾動條來檢視被剪裁掉的內容。滾動條出現的位置在inner border adge和outer padding adge之間。
auto:宣告決策將依賴於客戶端,優先使用scroll。

W3C標準中指明:
通常一個盒子的內容是被限制在盒子邊界之內的。
但有時也會產生溢位,即部分或全部內容跑到盒子邊界之外。溢位將在滿足下列條件之一時出現:

1. 一個不換行的行元素寬度超出了容器盒子寬度。
2. 一個寬度固定的塊元素放在了比它窄的容器盒子內。
3. 一個元素的高度超出了容器盒子的高度。
4. 一個子孫元素,由負邊距值引起的部分內容在盒子外部。
5. text-indent屬性引起的行內元素在盒子的左右邊界外。
6. 一個絕對定位的子孫元素,部分內容在盒子外。但超出的部分不是總會被剪裁。子孫元素的內容就不會被子孫元素和其包含塊之間的祖先元素的overflow的設定所剪裁。

以下是別人講的一個簡單的故事

html片段:

<div class=”ocean”>
<div class=”land”>
<p class=”joke”>
Mrs. Smith couldn’t get her husband to exercise. 
She asked Mrs. Jones what she should do. Jones replied, 
“Tape the remote control between his toes.”
</p>
</div>
</div>

style:

div.ocean{
position:relative;
background-color:blue;
width:120px;
height:120px;
}
div.land{
width:100px;
height:100px;
background-color:red;
overflow:hidden;
}
p.joke{
width:150px;
height:110px;
margin-top:30px;
margin-left:30px;
background-color:yellow;
}

上面的程式碼講述的是這樣一個故事:藍色的海洋裡有塊紅色的大地,紅色大地內有個黃色的段子。由於段子樣式的設定,它的部分內容超出了紅色大地。為避免黃色段子汙染到藍色海洋,紅色大地警惕的為自己設定了overflow:hidden;這樣超出大地的黃色部分就被剪掉了,我們看到的將是這樣一派和諧景象,如圖1:
這裡寫圖片描述

圖1:和諧的星球

如果事物都是這樣有理有序,天下可不就太平了。沒多久,黃色段子覺得憑自己的顯赫身份不該受紅色大地的控制,於是絞盡腦汁將自己變改成了絕對定位,一下子就擺脫了大地的束縛,如圖2:

這裡寫圖片描述

p.joke{
position:absolute;
width:150px;
height:110px;
top:30px;
left:30px;
background-color:yellow;
}

圖2:猖獗的段子

為什麼會這樣呢?這便是創造了上面提到過的第6個條件。當黃色段子變成position:absolute時,它的包含塊已由原來的紅色大地的內容邊界升級到了離它最近的position不是static的藍色海洋了。而海洋此刻對此還一無所知呢,自身沒有設定overflow:hidden屬性,導致黃色段子本該被裁剪的部分全部可見,不僅汙染到海洋,還影響到整個星球,情況萬分火急啊。即使這時海洋設定上overflow:hidden,也只能將超出藍色海洋的黃色部分剪裁,就像圖3,海洋此時是手足無措啊。

這裡寫圖片描述
圖3:無辜的海洋

俗語說的好,魔高一尺道高一丈,解鈴還須繫鈴人。紅色大地怎就甘心段子跑出去呢。怎麼說大地終歸是段子的祖先元素,怎麼能甘心由著段子胡作非為呢。於是,大地歷盡千辛,尋得祕籍,在自己的樣式中新增position:relative屬性,將段子的包含塊又改成了大地來決定。這下段子就乖乖的被關起來了。星球看起來又回到了最初的狀態。

div.ocean{
position:relative;
background-color:blue;
width:120px;
height:120px;
}
div.land{
position:relative;
width:100px;
height:100px;
background-color:red;
overflow:hidden;
}
p.joke{
position:absolute;
width:150px;
height:110px;
top:30px;
left:30px;
background-color:yellow;
}

所以說,hidden並沒有失效,而是有可能我們遇到的情況恰好滿足了第6個條件,使得元素的包含塊發生了變化。上面的故事中,也提到了在遇到‘hidden’失效的情況時,可以根據需要來改變元素的包含塊來達到正義的目的。

然而“overflow:hidden”還有另外一個特殊的用途,那就是清除包含塊內子元素的浮動

html:

<body>
  <div class="parent">
    <div class="child1"></div>
    <div class="child2"></div>
  </div>
</body>

css:

.parent{
  width:300px; 
  background:#ddd; 
  border:1px solid;
} 
.child1{ 
  width:100px; 
  height:100px; 
  background:pink;
  float:left;
}
.child2{ 
  width:200px; 
  height:50px; 
  background:red;
}

結果:

這裡寫圖片描述

上面的例子中,我們沒有設定.parent的高度,所以.parent的高度預設為auto。由於.child1設定了浮動,脫離了文件流,所以.parent中只有.child2這一個文件流元素。現在我們給.parent新增”overflow:hidden”:

.parent{
  overflow: hidden; 
}

結果:

這裡寫圖片描述

我們看到,給父元素新增一句“overflow:hidden”,就能讓父元素包住這個脫離了文件流的浮動元素,換句話說,”overflow:hidden”可以清除包含塊內子元素的浮動的影響。

現在這個現象原因是什麼呢?—————BFC

BFC 神奇背後的原理

參考資料:
https://www.jianshu.com/p/7e04ed3f4bea
https://www.jb51.net/css/175723.html