天天看點

關于overflow,你知道多少?

關于overflow,你知道多少?

最近,在研究OOCSS,當打開template.css閱讀第一行時,震驚了,第一眼居然沒看懂。。。。。。以下就是OOCSS下的template.css第一行代碼:

.body{overflow:hidden; _overflow:visible; _zoom:1;}
.main{overflow:hidden; _overflow:visible; _zoom:1;}      

後來分析這段代碼,不分析不知道,一分析吓一跳,短短三個屬性竟然包含了浮動、浮動清除、Haslayout、IE6相容性、最小高度不同浏覽器下實作、浏覽器Hack、overflow的各種用途等等一系列的問題及知識點。

廢話不多說,且榮我細細道來這行代碼的可怕之處!

在分析之前,先補充一下是基本知識,否則等最後分析了半天你聽的一頭霧水這不是本文想達到的效果。

overflow是什麼,有什麼用途:

overflow屬性規定當内容溢出元素框時發生的事情。——W3shcool

根據CSS的盒模型概念,頁面中的每個元素,都是一個矩形的盒子。這些盒子的大小、位置和行為都可以用CSS來控制。對于行為,我的意思是當盒子内外的内容改變的時候,它如何處理。

比如,如果你沒有設定一個盒子的高度,該盒子的高度将會根據它容納内容的需要而增長。但是當你給一個盒子指定了一個高度或寬度而裡面的内容超出的時候會發生什麼?這就是該添加CSS的overflow屬性的時候了,它允許你設定該種情況下如何處理。

overflow屬性有四個值:visible (預設), hidden, scroll, 和auto。這裡我們隻分析 overflow:visible和hidden其他倆屬性這裡不多做展開,有興趣的讀者可以上網查一下另外倆個屬性的知識。

知識:overflow:hidden的用途

我們平時最常用到的即overflow:hidden,一般用在固定寬高的div裡面,目的是隐藏溢出使内部元素高度即使超過父元素也能夠被隐藏。

overflow:hidden另一個流行的用途是用在沒有寬高的div裡,其目的是清除浮動。應用了overflow(auto或hidden)的元素(預設高度height:auto),将會擴充到它需要的大小以包圍它裡面的浮動的子元素。

這是一個很奇特的特性,因為他的簡潔,許多coder都喜歡利用這個特性來清除浮動。

overflow還有一個鮮為人知的特性,那就是可觸發IE7的hasLayout,讓我們來看看觸發hasLayout不完全清單吧:

可觸發hasLayout的CSS特性:

display: inline-block
height: (除 auto 外任何值)
width: (除 auto 外任何值)
float: (left 或 right)
position: absolute
writing-mode: tb-rl
zoom: (除 normal 外任意值)      

IE7可觸發hasLayout的CSS 特性:

min-height: (任意值)
min-width: (任意值)
max-height: (除 none 外任意值)
max-width: (除 none 外任意值)
overflow: (除 visible 外任意值,僅用于塊級元素)
overflow-x: (除 visible 外任意值,僅用于塊級元素)
overflow-y: (除 visible 外任意值,僅用于塊級元素)
position: fixed      

對于IE6/7特有的hasLayout特性,開發時需要特别留意,某些重要部件盡量以最小的代價來觸發他的hasLayout,使得各個浏覽器達到相容。

最小的代價指的是用标準的CSS屬性(如with, height, IE7下還能用overflow)來觸發hasLayout,避免使用不符合規範的zoom屬性,為日後的再次開發打下基礎。

知識:如何實作最小高度

最小高度min-height已經被大多浏覽器所支援,而且他的實用性也使得他被廣泛的使用,但其中唯一的遺憾那就是IE6不支援min-height!是以,為了相容性,你必須得使IE6也能相容min-height。

所幸的是這并不難實作,IE6在設計之初就有一個問題,他雖有height屬性,但是一旦内部元素高度超出父元素,其父元素也會很跟着内部元素一起增高,外部元素高度值會等于内部元素的高度值,是以說IE6下天生就有猥瑣的min-height屬性,帶着height的面具,幹着min-height的活,頗有點垂簾聽政一感覺。是以遇到實作最小高度的情況我們利用IE6的Hack來實作。

/* IE6利用_height實作min-height */
.wrap{width:100px; min-height:100px; _height:100px; background:#ccf;}
.inner{width:50px; height:150px; background:#cfc}      

知識:IE6下的overflow:visible的bug

IE6會扭曲預設的overflow visible值并将水準的擴充一個盒子一比對内容。

在IE6下(當div有具體height)應用預設的visible是沒有一點效果的,因為IE6的高度會自适應(IE6沒有min-height,但height就是min-height),子元素增大,父元素也會跟着一起增大,你想讓子元素超出父元素,且父元素高度不變,在IE6下是行不通的。舉個例子:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>IE6下的overflow:visible的bug</title>
<style>
.wrap{width:100px; height:100px; background:#ccf;}
.inner{width:50px; height:150px; background:#cfc;}
.next{width:100px;}
</style>
</head>


<body>
<div class="wrap">
  <div class="inner"></div>
</div>
<div class="next">标準浏覽器下wrap的内部元素不會破壞文檔流。而IE6下父元素會被撐開,最終影響到正常的文檔流</div>
</body>
</html>      

overflow:visible在IE6的表現和别的浏覽器的在預設情況下的表現不同,IE6下父元素會被撐開,最終影響到正常的文檔流,而其他浏覽器下撐出部分不會影響正常的文檔輸出流,即下面的元素還是按上面元素規定的高度來顯示。

要達到IE6下擁有真正意義上的overflow:visible效果的話,需要這麼做,包裹父元素設定為_overflow:hidden;接着繼續設定它的子元素為_position:relative;即可。

回歸正題,接下來分析這行代碼裡面各個屬性真正的意義:

1.overflow:hidden寫在應用在包裹元素上的.body和.main,其目的是利用其清除浮動的特性而非隐藏内部元素特性。

2.為了相容性要觸發IE6/7的hasLayout。這裡運用overflow:hidden的特性以最小的代價在IE7下清除浮動效果同時并觸發hasLayout,一舉二得。IE6用的是專有Hack和zoom屬性(_zoom:1)來觸發hasLayout。

3.既然我們使用overflow:hidden是為了清除浮動,是以我們絕對不能讓元素有高度屬性。

而實際工作中,往往要求必要的基本高度來達到合理的布局要求,那麼這個時候需要使用最小高度min-height,根據前面的知識我們得知IE6實作最小高度的方法是用height實作,而我們的overflow:hidden為了清除浮動大局觀是不允許出現固定高度的,使用了hidden再添加了height,那麼overflow的特性則發生轉變,變成了隐藏溢出的功能。

這裡次利用IE6下的overflow:visible的bug,讓IE6下的父元素自動撐開,達到了所謂的清除浮動的目的,可以說的上是歪打正着,于是乎,産生了_overflow:visible的寫法。

短短的一行代碼,總結下來也不過是上面短短的幾句話,但是其一系列的知識點串聯往往發現還有很長的一段路要走,希望這篇文章能夠帶給你些許的啟示,謝謝!

本文完〜