小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

整理:子容器垂直居中于父容器的方案

 心然之月 2016-05-24

本文在evernote里有備份。如果evernote的閱讀區(qū)域嫌窄了,那么可以把這個(gè)鏈接拖入書簽并點(diǎn)擊javascript:jQuery("#container").width(980);


本文從這個(gè)回答整理而來。對于當(dāng)今出現(xiàn)的一些CSS垂直居中的方案,這篇文章將會系統(tǒng)地審視它們,從實(shí)用角度進(jìn)行評估。

不羅嗦,先上圖:


考量需求及難度

為避免混淆,本文中所說的父容器子容器都不是相對的,而對應(yīng)著如下文檔結(jié)構(gòu)里面的.outer.inner容器:

<div class="outer"> <!-- 父容器 -->
     <div class="inner"> <!-- 子容器 -->
          ... <!-- 子容器內(nèi)部內(nèi)容 -->
     </div>
     ... <!-- 父容器內(nèi)其他的子元素 -->
</div>

我們從如下角度來評估:

  • 父容器/子容器的高度是否可變
  • 是否需要手工計(jì)算
  • 子元素溢出時(shí)父元素是截?cái)唷⒈粨胃哌€是保留滾動條
  • 當(dāng)然,還有兼容性

高度相關(guān)

代碼 效果
height:100px; 定高
height:auto 不定高,自適應(yīng)于自身的content-box
height:50% 不定高,自適應(yīng)于包含塊

出現(xiàn)了 3(定高/自適應(yīng)于外部/自適應(yīng)于內(nèi)部) ^ 2 (父容器/子容器) =9 種情形,搭配見下:

父容器 子容器 難度 解(tu)說(cao)
定高 定高 簡單 快速開發(fā)時(shí)就是這樣
定高 自適應(yīng)于內(nèi)部 稍難 常見的需求
定高 自適應(yīng)于外部 簡單 手工算一算就好了
自適應(yīng)于內(nèi)部 定高 簡單 變相定高,高度放在內(nèi)層,方便解耦
自適應(yīng)于內(nèi)部 自適應(yīng)于內(nèi)部 稍難 留白固定,罕見的需求
自適應(yīng)于內(nèi)部 自適應(yīng)于外部 WTF 折騰出這種需求,不覺得害臊嗎
自適應(yīng)于外部 定高 困難 適配所有屏幕的slideshow
自適應(yīng)于外部 自適應(yīng)于內(nèi)部 困難 普適性更高的slideshow
自適應(yīng)于外部 自適應(yīng)于外部 稍難 一個(gè)模塊(或大小不定的頭像),出現(xiàn)在大小不定的位置

溢出相關(guān)

子容器溢出代表子容器高度大于父容器高度的情形。

  • 子容器溢出時(shí),被父容器截?cái)?。父容?code>overflow:hidden。
  • 子容器溢出時(shí),把父容器撐高。父容器height:auto;overflow:visibledisplay:table-cell等等。
  • 子容器溢出時(shí),父容器出現(xiàn)滾動條。父容器overflow:scrolloverflow:auto

很顯然,子容器溢出時(shí),被父容器截?cái)嗟那樾螣o法和父容器自適應(yīng)于子容器共存。

兼容性

  1. IE6、IE7:老而不死的瀏覽器,瀏覽器尚未統(tǒng)一、IE一家獨(dú)大之時(shí)的遺毒,一大堆bug等著你。
  2. IE8:IE8起全面支持CSS2.1,剩下一些稍微少坑爹那么一點(diǎn)點(diǎn)的bug。
  3. IE9。尷尬的產(chǎn)物,微軟第一次搭上CSS3的末班車。
  4. IE10+與其他現(xiàn)代瀏覽器(終于可以和其他瀏覽器并列了……IE10淚目)。

4、3、2、1的兼容難度是一步步變難,兼容到4、3、2、1所對應(yīng)的代碼量/工作量是100%、102%、120%、300%的關(guān)系。

在這里僅僅考量IE6/7,IE8的無bug實(shí)現(xiàn)的兼容性。IE9+的兼容性,對于文中提到的所有方案都是可行的。

其他

  1. 是否需要手動計(jì)算/需要calc屬性進(jìn)行輔助計(jì)算

如果需要手動計(jì)算,若界面進(jìn)行重構(gòu),而居中的需求不變,就需要重新計(jì)算。比較費(fèi)時(shí)費(fèi)事。布局也相對不夠靈活。


方案匯總

CSS 版本 布局類型 方案
CSS 2.1 普通流,塊級布局 父容器上下等padding
子容器上下等margin
普通流,行內(nèi)布局 父容器line-height=height
子容器所在的line-box的line-height=父容器的height
普通流,塊級table布局 父容器display:table-cell,子容器vertical-align
子容器被table、tr、td包裹
絕對定位布局 子容器絕對定位,top:50%,負(fù)margin
子容器絕對定位,top:0,bottom:0,margin:auto
普通流,塊級布局 background代圖片background-position
CSS3 絕對定位布局 子容器絕對定位,top:50%,translateY(-50%)
普通流,塊級布局 backgournd代圖片backgournd-size
普通流,flexbox布局 flexbox

方案評估

1. 普通流,塊級布局 (css2.1)

方案 兼容性 父容器 子容器 子容器溢出 其他
IE8 IE6/7 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 撐高 被截?cái)?/td> 不需手工計(jì)算
父容器上下等padding √* × √* × √* ×
子容器上下等margin √* × √* × × ×
background代圖片background-position × × ×

1.1. 父容器上下等padding & 子容器上下等margin

最基礎(chǔ)的方案就是這樣,手工算好每一個(gè)容器的高度和補(bǔ)白/位移需要的內(nèi)容,簡單粗暴:

/*父子均定高,父容器上下等padding*/
.outer{ height: 100px; padding-top: 40px ; }
.inner{ height: 100px; }
/*父子均定高,子容器上下等margin*/
.outer{ height: 180px; overflow: hidden; *zoom: 1; }/*父容器給予BFC以避免子容器margin并到父容器上*/
.inner{ height: 100px; margin-top: 40px ; }

父子都需要自適應(yīng)于內(nèi)部時(shí):

/*父子均自適應(yīng)于內(nèi)部,父容器上下等padding*/
.outer{ height: auto; padding-top: 40px ; padding-bottom: 40px ; }
.inner{ height: auto; }
/*父子均自適應(yīng)于內(nèi)部,子容器上下等margin*/
.outer{ height: auto; overflow: hidden; *zoom: 1; }/*父容器給予BFC和haslayout,以避免子容器margin并到父容器上*/
.inner{ height: auto; margin-top: 40px ; margin-bottom: 40px ; }

說明:

  1. 需求:父子都需要自適應(yīng)于內(nèi)部的解決方案里,是把留白的高度固定,這種需求其實(shí)很少見。
  2. 可缺?。?code>height:auto可以省去,這是默認(rèn)值。
    對于塊級元素,默認(rèn)是height:auto;width:auto;
    width的auto值是自適應(yīng)于這個(gè)元素的包含塊的寬度,而height自適應(yīng)于這個(gè)元素的content-box的高度

  3. 自適應(yīng):父子容器均可以自適應(yīng)于內(nèi)部;也可以父容器自適應(yīng),子容器定高。
    因?yàn)?code>height:auto時(shí),計(jì)算高度值的依賴方向是從外往內(nèi)。

  4. 自適應(yīng):為何在這倆方案里不容許出現(xiàn)父容器或子容器自適應(yīng)于外層呢?
    因?yàn)閷τ趆eight來說,它的百分比值是乘以包含塊的height,但padding-top/padding-bottom/margin-top/margin-bottom的百分比值是乘以包含塊的width,而非我們希望的height。

  5. 溢出:

* 父容器上下等padding時(shí),父容器定高時(shí),子容器溢出padding-edge的部分會被截?cái)唷?br> * 子容器上下等margin時(shí),父容器自適應(yīng)于內(nèi)部,父容器只會被撐高,永遠(yuǎn)無法被截?cái)唷?br> * 其他情形,截?cái)喽紱]有什么意義

1.3. background代圖片background-position

在子容器是<img>標(biāo)簽時(shí),可以直接使用background來替代它。也可以算得上一種方案。

.inner { background-image: url("...");
   background-position: 50% 50%;/*注,火狐不支持background-position-y的屬性設(shè)置*/ }

說明:

  1. 自適應(yīng):無法自適應(yīng)于外部容器,CSS2.1階段,background無法相對于容器伸縮。

  2. 溢出:背景溢出的情形,直接會被截?cái)唷?/p>

  3. 其他:你甚至可以把inner的標(biāo)簽省掉,直接把背景放到outer之上

2. 普通流,行內(nèi)布局 (css2.1)

方案 兼容性 父容器 子容器 子容器溢出 其他
IE8 IE6/7 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 撐高 被截?cái)?/td> 不需手工計(jì)算
父容器line-height=height √* × × × ×
子容器所在的line-box的line-height=父容器的height √* √* × ×

2.1 父容器line-height=height

“父容器line-height=height”,這個(gè)方案在于將子容器當(dāng)做行內(nèi)元素呈遞,并設(shè)置vertical-align,line-box和block-box的高度持平,就完成了垂直居中的的效果。

.outer { line-height: 100px; height: 100px; font-size: 0; }
.inner { display:inline-block; vertical-align:middle; font-size: 16px; }

為何需要font-size:0?因?yàn)関ertical-align:middle的定義是:元素的中垂點(diǎn)與父元素的基線加1/2父元素中字母x的高度對齊。因此在font-size>0時(shí),元素將會在baseline上出現(xiàn)一定的偏移,偏移量跟這個(gè)字號下的x字母的高度有關(guān)。

可以在jsFiddle中看到對比:

不使用font-size:0

http:///humphry/haaaM/

使用font-size:0

http:///humphry/7zCEm/

說明:

  1. 兼容性:沒有涉及relative和absolute定位,布局時(shí)相對無痛。

  2. 兼容性:這個(gè)方案是IE6\7不支持的,原因不詳(只知道inline-blockvertical-align的標(biāo)準(zhǔn)誕生于IE8之后),也沒有時(shí)間研究。2014年了,有點(diǎn)追求好嗎。

  3. 自適應(yīng):子容器可以輕松做到自適應(yīng)于內(nèi)部、外部或者定高,但在這個(gè)方案里,父容器必須定高,因?yàn)?code>line-height的百分比單位是相對font-size來說的。

  4. 溢出:子容器溢出時(shí)會變成頂對齊,這是因?yàn)椋琹ine-box 的高度跟內(nèi)部最高的 inline-box 相等,因而line-box 可以被撐高,從上往下排一個(gè)個(gè)排列下來,從而失去了居中的效果。換句話說,子元素溢出時(shí),父容器可以自適應(yīng)于內(nèi)部。

  5. 其他:line-heightfont-size是一個(gè)可以繼承的屬性,在這種方案里面,必然會導(dǎo)致line-height、font-size被繼承,因此在需要排版子容器時(shí),需要復(fù)寫line-height、font-size

2.2 子容器所在的line-box的line-height=父容器的height

對上面的方法不兼容IE6\7且不能做到父容器自適應(yīng)的方面,可以這樣改進(jìn):

  1. 把子容器當(dāng)成行內(nèi)元素呈遞
  2. 構(gòu)建一個(gè)行內(nèi)級別的鉤子元素,緊挨著子容器,以使用:before/:after偽元素自制一個(gè)文本節(jié)點(diǎn)、或<span>或任意一個(gè)inline級別的標(biāo)簽、或者一個(gè)1*1的圖片。
  3. 讓鉤子元素?fù)螡M容器高度,這意味著它需要成為inline-box元素,然后設(shè)置height:100%即可。
  4. 現(xiàn)在,子容器所在的 line-box 的 line-height = 父容器的 height。
  5. 最后,給子容器和鉤子元素設(shè)置vertical-align:middle,讓它們的中心線對齊于于父容器的middle-line,就能做到垂直居中。

http:///humphry/86dsC/21/

現(xiàn)在這個(gè)布局可以自動生成,詳見@林小志的css小工具:圖片垂直居中span。

(如果需要水平居中,那么這個(gè)額外的節(jié)點(diǎn),需要移去自身所占的距離,一般使用margin-left:-1pxmargin-right:-1px,取決于鉤子在子容器的哪一邊。)

說明:

  1. 兼容性:沒有涉及relative和absolute定位,布局時(shí)相對無痛。

  2. 兼容性:inline-box標(biāo)簽之間的任意數(shù)量的空白符:ASCII 空格 (&#x0020;)、ASCII 制表符 (&#x0009;)、ASCII 換頁符 (&#x000C;)、零寬度空格 (&#x200B;) 會被瀏覽器解析成一個(gè)空格,造成間隙。需要通過改變HTML結(jié)構(gòu)/使用負(fù)margin等來去掉這個(gè)間隙。

  3. 兼容性:這個(gè)方案有一定hack量,去掉inline-box的空格間隙是一部分,display:inline-block的IE6\7 hack是另一部分。

  4. 自適應(yīng):父容器可以自適應(yīng)于外部了,因?yàn)檫@里不需要在任何地方知道父容器的高度。

  5. 溢出:子容器溢出時(shí)會變成頂對齊,原因同上。

3. 普通流,塊級table布局 (css2.1)

方案 兼容性 父容器 子容器 子容器溢出 其他
IE8 IE6/7 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 撐高 被截?cái)?/td> 不需手工計(jì)算
父容器display:table-cell,子容器vertical-align × × × ×
子容器被table、tr、td包裹 √* √* ×

3.1. 父容器display:table-cell,子容器vertical-align

這個(gè)方案依然是用到vertical-align:middle,只不過需要放到作為display:table-cell的元素之上。

http:///humphry/7AMF9/2/

這個(gè)布局也可以自動化生成:見@林小志的css小工具:圖片垂直居中 table cell

說明:

  1. 兼容性:IE6/7不兼容display:table-cell。

  2. 自適應(yīng):子容器無法自適應(yīng)于父容器,高度無法使用百分比單位,因?yàn)楦鶕?jù)渲染規(guī)則,display:table-cell的元素的包含塊是它父級的display:table的元素。

  3. 溢出:父元素就算給定高度,設(shè)置overflow,也不會導(dǎo)致溢出隱藏;在子元素溢出的時(shí)候,父容器不能保有自身設(shè)置的高度,直接會被撐高。

  4. 其他:display:tabel-cell本身讓很多屬性無效。

3.2. 子容器被table、tr、td包裹

為了可以讓子容器有百分比高度,我們可以直接構(gòu)建一個(gè)表結(jié)構(gòu)出來:

http:///humphry/Ns4RK/8/

說明:

  1. 兼容性:這是一個(gè)全兼容的方案。

  2. 自適應(yīng):現(xiàn)在“父級”的自適應(yīng)要求都可以得到滿足,只不過這里的“父級”指的是包在最外層的table。

  3. 溢出:父元素就算給定高度,設(shè)置overflow,也不會導(dǎo)致溢出隱藏。

  4. 其他:文檔結(jié)構(gòu)變復(fù)雜了,語義被拋棄了。

  5. 其他:display:tabel-cell本身讓很多屬性無效。

  6. 其他:可以把這個(gè)方案里的<table>換成display:table的其他元素,tr、td亦然:
    http:///humphry/KxKc8/
    個(gè)人覺得……徒增煩惱爾。

4. 絕對定位布局 (css2.1)

方案 兼容性 父容器 子容器 子容器溢出 其他
IE8 IE6/7 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 撐高 被截?cái)?/td> 不需手工計(jì)算
子容器絕對定位,top:50%,負(fù)margin √* × × × ×
子容器絕對定位,top:0,bottom:0,margin:auto × √* × ×

4.1 子容器絕對定位,top:50%,負(fù)margin

.outer{ position: relative; }
.inner{ position: absolute; top: 50%; height: 20px; margin: -10px; }

這是互聯(lián)網(wǎng)上能找到的最多的關(guān)于垂直居中的方法。我們不相信瀏覽器,使用手算,將子元素挪去自身高度的50%。

說明:

  1. 兼容性:子元素和父元素都需要設(shè)置position,這就意味著IE6\7下面的數(shù)十個(gè)友情附贈的美好bug。

  2. 自適應(yīng):子元素必須定高,不定高算不出來負(fù)margin。不可以是百分比高度單位,因?yàn)?code>margin-top的百分比,是相對其包含塊的寬度而言的。

  3. 自適應(yīng):父容器可以自適應(yīng)于內(nèi)部,只不過不是這個(gè)子元素,而是父容器內(nèi)部其他的元素。子元素對外層高度、寬度塌陷,不能撐寬/撐高父容器了。

  4. 溢出:這個(gè)方案也可以支持子元素高度溢出的情形。

  5. 其他:需要手動計(jì)算子元素1/2的高度是多少。

4.2 子容器絕對定位,top:0,bottom:0,margin:auto

.outer{ position: relative; }
.inner{ position: absolute; margin-top: auto; margin-bottom : auto;
    top: 0; bottom: 0; height: 20px; }

這個(gè)的原理寫在CSS2.1中:

‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ = 包含塊的高度

在其他值不是auto的時(shí)候,margin-topmargin-bottom是可以根據(jù)上式算出的,原理類似于水平居中。

說明:

  1. 兼容性:這個(gè)方案僅僅支持IE8+。IE6和IE7由于對同時(shí)定義top、bottom屬性的樣式解析與 css2.1 不一致,不支持這種定位方式。

  2. 自適應(yīng):父容器可以自適應(yīng)于內(nèi)部,只不過不是這個(gè)子元素,而是父容器內(nèi)部其他的元素。原因同上。

  3. 自適應(yīng):這個(gè)方案需要子容器有一個(gè)固定的高,或百分比自適應(yīng)于外部。它的高度不能是height:auto,因?yàn)檫@樣會使得上面的算式里auto出現(xiàn)在三個(gè)地方,瀏覽器無法計(jì)算出相應(yīng)margin值。

  4. 溢出:這個(gè)方案也可以支持子元素高度溢出的情形。

  5. 其他:完全不用算,耶!

5. css3一系列布局

方案 兼容性 父容器 子容器 子容器溢出 其他
IE8 IE6/7 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 定高 自適應(yīng)于內(nèi)部 自適應(yīng)于外部 撐高 被截?cái)?/td> 不需手工計(jì)算
子容器絕對定位,top:50%,translateY(-50%) × × √* ×
backgournd代圖片backgournd-size × × √* ×
flexbox × ×

5.1 子容器絕對定位,top:50%,translateY(-50%)

.outer{ position: relative; }
.inner{ position: absolute; top: 50%; transform: translateY(-50%);}

原理同上,僅僅是僅僅是用translate替換了負(fù)margin,因?yàn)?code>translate的百分比偏移量是容器本身的。

說明:

  1. 兼容性:ie9+(但,從好處來講,其實(shí)這個(gè)兼容性已經(jīng)完全不需要考慮IE6~8的相對/絕對布局bug了)

  2. 自適應(yīng):子元素可以不指定高度,也可以相對父級高寬做百分比設(shè)置,也包括定寬,非常靈活

  3. 自適應(yīng):父容器可以自適應(yīng)于內(nèi)部,只不過不是這個(gè)子元素,而是父容器內(nèi)部其他的元素。原因同上。

  4. 溢出:支持子元素溢出隱藏,或者溢出顯示。

  5. 其他:你會讓代碼陷入一個(gè)前綴的海洋……

.inner{
    -webkit-transform:translate(-50%, -50%);
    -moz-transform:translate(-50%, -50%);
    -ms-transform:translate(-50%, -50%);
    -o-tranform:translate(-50%, -50%);
    transform:translate(-50%, -50%);
}

5.2 backgournd代圖片,backgournd-size

.inner{ background-image: url("...") ; background-size: cover ; height: 100% ; }

說明:

  1. 兼容性:只能是IE9+和現(xiàn)代瀏覽器

  2. 自適應(yīng):背景可以任意自適應(yīng)于外部容器,或者定高寬。也可以讓子容器自適應(yīng)于內(nèi)部內(nèi)容,背景自適應(yīng)于子容器。

  3. 溢出:支持背景溢出隱藏,但無法溢出顯示。好消息是,可以使用background-clip指定背景從哪里消失。

  4. 其他:你甚至可以把.inner的標(biāo)簽省掉,直接把背景放到.outer之上

5.3 flexbox

// TBD
// 很抱歉,由于對flexbox沒有深入的了解,我還沒有試驗(yàn)出flexbox在子元素溢出時(shí)也能保持居中的解決方案……最好的結(jié)果是子元素被拉伸(= =)。有人有過實(shí)例嗎?

說明:

  1. 兼容性:只能是IE9+和現(xiàn)代瀏覽器

  2. 其他:兼容性是我目前已知的東西……


    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多