margin系列之bug巡演(三)
原文地址:margin系列之bug巡演(三) by @doyoe
IE8按鈕margin auto居中失效Bug
你會猛然覺得,這是正解啊,因為 button
或者 input type button型別
的元素是 inline-level
的。
不對啊,button
應該是 inline
的吧?哦,可能是 inline-block
?
在這之前,我們似乎要先明確一些基礎知識。
什麼是 inline-level 元素?
要知道 inline-level
元素並不等於 inline
元素,也就是說 行內級元素
與 行內元素
是兩個不同的概念。
inline-level
元素包含 display
值為:
- inline
- inline-block
- inline-table
- inline-flex
- other inline-*
以上情況時,元素可被稱之為 inline-level
元素,但不都是 inline
元素。
什麼是 block-level 元素?
block-level
指的是 display
值為 block
的元素嗎?我知道不少人一直有這樣的認知,不過這不完全準確。
block-level
元素包含 display
值為:
- block
- list-item
- table
- table-*
- flex
- 如果position既不是static也不是relative、float不是none或者元素是根元素,當display:inline-table時,display的計算值為table;當display值為 inline | inline-block | run-in | table-* 時,display的計算值為block
有如上情況時的元素均被稱之為 block-lavel
元素。同時 block-level
和 block
也不是同一個概念,所以如果你認為 display
值為 list-item
的 li 不是 塊級元素,那就錯了。
看到這裡,你對 塊級元素
,塊元素
,行內級元素
,行內元素
這個4個概念,應該已經有了比較清晰的瞭解?
margin keyword auto只能應用在常規流中的 block-level 元素上
- 當一個塊級元素定義了
position
值為非static
和relative
之外的值時,margin-right/left auto 的計算值為0; - 當一個塊級元素定義了
float
值為非none
之外的值時,margin-right/left auto 的計算值為0; - 非塊級元素的margin-right/left auto 的計算值為0;
計算值為0,即說明其應用使用值的意圖失敗。所以在有如上情形的場景中,都無法使用 auto
來實現水平居中。同時也說明了,只有 normal flow
的 block-level
才能應用 margin keyword auto。
margin可以應用於所有元素嗎?
這顯然不行。準確的說:margin可以應用在除某些table-*元素和某些行內元素之外的所有元素上。
和margin親近的table-*系元素
- table
- inline-table
- table-caption
除了 display
值為以上3種之外的 table系
元素,都不能應用 margin
,比如:th, td。
和margin親近的 inline-level 元素
我之前面試的時候常會問候選人,行內元素不能設定寬高對嗎?大部分人會告訴我說是;然後我又會問,那為什麼 img
元素可以設定寬高呢?有人會告訴我,因為 img
是個特殊的元素?接著我又會問題,img
是如何特殊的?然後,然後就沒然後了,因為沒聲音了。
恩,img
確實是個特殊的元素。它特殊在哪裡?它的特殊就在於它是一個行內建換元素。
所有的置換元素都可以設定 margin
屬性,並且可以設定寬高,這就是為什麼 img
是行內元素卻可以設定 width
和 height
。
什麼是置換元素(Replaced elements)?
一個元素擁有內在的二維屬性,其寬高屬性受外部資源影響,預設擁有CSS格式,這樣的元素被稱為置換元素。
意思就是說置換元素的寬高不完全由CSS決定,還受其自身內容和外部資源所影響。
舉個例子來說,仍然說 img
元素吧,你會發現,如果你 src
進來不同尺寸的資源,那麼在 viewport 上顯示的圖片寬高也是不同的,也就是說 img
元素的寬高會受外部資源影響。
再說說 input
元素,隨便在頁面上扔一個input,你都能發現它擁有一個預設的寬高,這就是它所具有的內在二維寬高屬性,並且該類元素會受UA影響,不同UA下所呈現外觀會有不同。
常見的置換元素有哪些?
img, object, button, input, textarea, select等
行內非置換元素真的不能應用margin嗎?
什麼是非置換元素?除了置換元素之外的元素,我想將這樣的元素稱之為非置換元素是沒有大礙的。
那麼行內非置換元素真的無法設定 margin
嗎?我想在工作中你一定碰到過很多這樣的場景,給一個 a
或者 span
定義間隙。這時我們寫:
CSS
span{margin:5px 10px;}
結果發現 span
的水平方向上的 margin
定義生效了,但垂直方向上的 margin
定義卻沒被應用。
是的,這就是行內非置換元素使用 margin
時的表徵,所以對各種特性的理解,在讓自己的程式碼更有效上是大有裨益的。
迴歸正題
我們本來是想說IE8按鈕margin auto居中失效Bug的,扯了不少題外話。
我們知道 margin keyword auto 不能應用在處於常規流中的 block-level 之外的元素上,所以我有這樣的一段程式碼:
CSS
button{display:block;margin:auto;}
HTML
<div id="demo">
<button>按鈕</button>
</div>
恩,我們將 button
顯式的轉換為了 block
,同時我們知道 button
作為置換元素,本身具備內在寬高,也就是說這時,我只需要加上 margin:auto
,該按鈕就應該在其包含塊裡水平居中。
是的,所有瀏覽器都和預期是一樣,實現了水平居中,但是卻出現了奇葩的IE8,完全無效,甚至不如原始社會的IE6。來看看示例 DEMO1
:IE8按鈕margin auto居中失效Bug
通過以上例子,你有沒有突然感覺到,如果要讓一個置換元素在包含塊中水平居中,出乎預料的簡單,只需要 display:block;margin:auto;
即可。
注意事項
令人意外的是,只有 button
和 input type 為 button 相關元素的時候,在IE8中才會水平居中失效;如: input type text
或 img
時,margin keyword auto 運作正常。
解決方案
- 給其顯示的定義寬度
- 不改變其display值,包含塊text-align:center
- 其它水平居中方案,如:absolute + 負margin
margin系列文章:
相關文章
- margin系列之bug巡演
- margin系列之bug巡演(二)
- margin系列之佈局篇
- margin系列之keyword auto
- margin系列之內秀篇
- margin系列之內秀篇(二)
- margin系列之百分比
- margin系列之與相對偏移的異同
- IE CSS Bug系列:IE8中按鈕使用Auto-Margin居中失效CSS
- margin系列之外邊距摺疊
- ITPUB SQL大賽之BUG(三)SQL
- Margin 的特異之處
- 使用oradebug dump hanganalyze 分析oracle hang系列三Oracle
- css之margin && padding講解CSSpadding
- vue原始碼分析系列之入debug環境搭建Vue原始碼
- 【JVM】JVM系列之Class檔案(三)JVM
- IE CSS Bug系列:自定義游標BugCSS
- 解決margin塌陷和margin合併
- IE CSS Bug系列:圖片標籤聚焦 BugCSS
- IE CSS Bug系列:通配選擇符BugCSS
- prometheus之docker監控與告警系列(三)PrometheusDocker
- Android 註解系列之APT工具(三)AndroidAPT
- canvas系列三之《煙花》效果實現Canvas
- 【學習筆記】CSS深入理解之margin筆記CSS
- css marginCSS
- margin 塌陷
- IE CSS Bug系列:IE6忽略!important的BugCSSImport
- Go語言系列(三)之陣列和切片Go陣列
- 軟體測試之資料庫系列三資料庫
- oracle 11g latch之v$latch系列三Oracle
- IE CSS Bug系列:不正確的浮動伸縮BugCSS
- IE CSS Bug系列:邊框在:hover狀態下消失 BugCSS
- IE CSS Bug系列:高度額外擴充套件的BugCSS套件
- margin小結
- oracle之BUG 7497640Oracle
- IE CSS Bug系列:noscript 幽靈CSS
- IE CSS Bug系列:背景溢位CSS
- oradebug工具使用系列一