li標簽之間的空隙問題(轉)


原文地址:http://www.cnblogs.com/laogao/archive/2012/08/13/2636419.html

css li 空隙問題

 

IE6/7的Bug:縱向排列的li中加浮動元素產生向下3px的空隙

最近做頁面時,經常碰到用 li 標簽做縱向列表的時候,會在li的下面產生3px的空隙,之前也碰到過,但都用簡單的方法解決了。搜索了一下,網上已經有人給出一些解決方案,但細看之后發現他們的解決方案和找到的原因都有些問題,甚至是錯誤。要么只單純地提出問題,解決問題,沒有更詳細的探討。所以這二天抽空寫了一個demo,對這個bug做了一點研究。

bug實例如下:

li與li之間應該是沒有任何空隙的,因為我沒有設置margin-top,或margin-bottom的值。這就是3px的bug。

HTML原代碼 :

<ul class="list-1"> <li> <span>我有浮動</span> <a href="#">我有浮動</a> <strong class="red">這里所有的元素都浮動</strong></li> <li> <em>inline元素</em> <span>Span float:left;</span> <a href="http://hadaiye.blog.163.com/blog/#">A float:left;</a> <div class="red">我不浮動,且不是最后一個元素</div> <strong>Strong float:right;</strong> </li> <li> <span>我有浮動</span> <a href="http://hadaiye.blog.163.com/blog/#">我有浮動</a> <strong>我有浮動</strong> </li> </ul>

主要的CSS樣式: .list-1{width:502px; padding-bottom:30px;} .list-1 li{list-style:none; border:1px solid #ccc; padding:5px; background:#FFC; line-height:1.7; width:500px;} .list-1 li span{padding:3px;margin-right:5px; background:#f2f2f2; float:left; } .list-1 li a{padding:3px;margin-right:5px; background:#9CF; float:left;} .list-1 li strong{padding:3px; background:#C6FDCB; float:right; }

並不是所有的li都會有這個問題,只有縱向排列的li才有可能出現,觸發的情況有2種: 1.li中所有的子元素均浮動,並設置了寬、高或zoom中的一項或多項。 2.li中最后一個不浮動的子元素為塊級元素,且不是最后一個子元素,同時li設置了寬、高或zoom中的一項或多項。PS:寬width( min-width, max-width), 高height(min-height, max-height)

有必要解釋一下這2個結論得出的過程: li元素默認是block的,縱排的時候不需要加float,可以給ul加一個寬度——以此為基礎進行測試,因為這是正常的正確的coding思路。

根據大家的經驗,li中沒有浮動的子元素不會產生3px的bug,那么這個條件就不再考慮。重點考慮子元素全部浮動 和浮動與非浮動混合這二種情況。為了便於解釋,把 ”設置寬、高或zoom中的一項或多項“ 簡稱為 ”設置寬/高“

第1種情況: 子元素全部浮動,在不設置寬/高的情況下,不會有bug;一旦設置寬/高,bug就產生了。

【友情PS:浮動的元素都成為了塊級元素,浮動元素會脫離了正常的文檔流,但不完全脫離,它不會跑到父元素的外面去,但是,它們的位置會空出來,父元素卻不能完全擁有它們,此時的父元素沒有了高度。如果你在FF下用Firebug查看,它的高度是0,寬度是其父元素的寬度(為了不混淆視聽,圖就不放了,大家自己可以試一下)。在這種情況下設置高或寬,li元素就能在形式上擁有元素。設置zoom:1所達到的效果也是一樣的。】

 

第2種情況: 這種就比較復雜。不浮動的元素可以是block, inline,和 line-block的任何一種。根據測試inline 和 inline-block可歸為一類(以下均用inline 類代表inline 和 inline-block )。混搭的情況又有 ”非浮動元素都是inline類元素“ 和 ”非浮動元素既有inline類又有block元素“ 2種。

非浮動元素都是inline類元素的情況下,不會bug,加上高/寬也不會bug。非常好!

非浮動元素既有inline類又有block元素的情況下,會出現的情況很多,但不管怎么組合,最后一個不浮動是inline類元素,就不會出bug,不管它在哪個位置,前面有多少非浮動的元素;最后一個不浮動的是block元素,且是最后一個元素(代碼上,不是指表現上),也不會出Bug。只有最后一個不浮動的是block元素,且不是最后一個元素才會有bug。

經測試,有懷疑性的margin, padding, border, background 在何種情況下都不影響3px bug的產生,於是就有了上面的2個結論。

推測原因: 根據經驗推測此3px bug 產生和 IE 特有的 haslayout 有關,因為在 ie8(ie取消了haslayout)和其它瀏覽器中沒有這個問題。但是又不完全依賴haslayout,並不是所有觸發haslayout的屬性都會產生3px的bug。

從解決方法上來看,這個bug與float元素的顯示有關,當li的子元素均有浮動,其文檔流就改變了,當li重新擁有高寬后,bug就產生了(可能與並沒有真正擁有子元素有關)。但是,當浮動的元素被其它因素影響(加入了非浮動的元素,或浮動元素有vertical- align屬性)時,bug就有可能消失。

但目前任何一款調試工具都沒法看出這多出來的3px是從哪里產生的,真正的原因估計只有ie自己知道了(我覺得跟ie中文檔流的表現有關,另一個詭異的3px問題,也跟浮動有關)。

 

解決方案: 找到了起因就有了解決方案,這里提供4種解決思路。

1、給li添加浮動,如有需要可設置寬度。

PS:給li加浮動,讓它和子元素一樣浮動起來,並真正擁有子元素,而不止是形式上

2、把li設置成display:inline-block(變成inline也可以,但是樣式就杯具了)

 

3、為li中所有元素都設置vertical-align值,此值可為top, bottom, middle, text-top, text-bottom, middle, sub, super中的一項(有博文說可設置vertical-align的任何值,這是錯的,有些值不能解決bug,比如auto,centrial )

 

 

4、從代碼設計上避免bug的產生:在li中有意識地加入inline 或 inline-block的元素,放在哪里都可以;或者使最后一個元素不浮動,不管它是不是塊級元素、前面還有沒有不浮動的元素

 

一點補充說明: 之前看到一些博文中這個bug產生的原因是“ li的子元素浮動,並且li設置了以下CSS屬性之一:width、height、zoom、padding-top、padding-bottom、margin-top、margin-bottom”,這種說法不夠准確,而且有誤導。因為它沒有指出子元素浮動是個別的還是全部的,個別浮動不一定會觸發此bug。它所說的li的設置中有margin 和 padding,而這二項是不會對bug的產生起任何作用的,如果沒有width, height, zoom中的一項,加不加padding 和 margin都不會產生3px問題。

 

 

還有一篇博文中說“通過添加相應的CSS屬性來激發li的haslayout來解決”,這種說法也不對。因為在bug產生的時候haslayout就已經存在了,從鏈接中的博文可以看到,bug產生的時候,它對li設置了width:400px,就已經觸發了li的haslayout屬性。對於可觸發haslayout的因素可參見百度百科的haslayout。

如果你還發現其它情況 ,請通過評論或郵件告訴我,謝謝~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM