css多行垂直水平居中--table布局大法

======= SEO專用

  • table-cell
  • 定高水平垂直居中
  • 不定高水平垂直居中
  • 單行定高水平垂直居中
  • 單行不定高水平垂直居中
  • 多行定高水平垂直居中
  • 多行不定高水平垂直居中
  • 多列等高布局
  • 左邊定寬右邊自適應(yīng)布局
  • 左邊右邊定寬中間自適應(yīng)三列布局
    =======

最近開發(fā)遇到一些布局上的問題,由于不確定因素比較多,比如不定寬高、單行多行的情況需要顯示的樣式基本相同。這樣的情況會比較復雜,后來找到display:table-cell這個布局神器,這些問題也就不是問題了。比如以下這種情況:

單行|多行|定寬高|不定寬高水平垂直居中.png

基于這樣的需求,我們通常都是每一種情況需要單獨的寫一份hack樣式,這樣寫起來很麻煩。我們多么希望寫一份樣式,不管你里面的節(jié)點如何變,定不定寬高,多行與否都能表現(xiàn)一致。針對水平|垂直居中的情況,我找到了table-cell布局的方式,基本能解決。下面會總結(jié)一下table-cell的布局原理以及列舉一些日常布局所遇到的情況。

1、table的一些特性與表現(xiàn)形式

雖然table布局因為它的一些非語義化、布局代碼冗余,以及不好維護改版等缺點被趕出了布局界。但是在css不給力時期,table布局也曾風靡一時,就算現(xiàn)在看來table的一些布局的特性也是非常給力的,而幸好css也吸取了table布局一些好的特性為己用。讓我們可以使用更少、更語義化的標簽來模擬table布局,可以跳過table布局的缺點又實現(xiàn)我們想要的效果,所以我們首先需要了解table的一些特性以及對應(yīng)的css屬性。
我們在不居中使用到的也就是table、tr、td的一些特性,所以我們只需要了解這三個標簽的特性就足夠了。

  • table標簽(display:table)
  1. table可設(shè)置寬高、margin、border、padding等屬性。屬性值的單位可以使用px,百分比值。
  2. table的寬度默認由內(nèi)容的寬高撐開,如果table設(shè)置了寬度,寬度默認被它里面的td平均分,如果給某一個td設(shè)置寬度,那么table剩余的寬度會被其他的td平均分(有點類似flex布局)
  3. 給table設(shè)置的高度起到的作用只是min-height的作用,當內(nèi)容的高度高于設(shè)置的高度時,table的高度會被撐高。
  • tr標簽(display:table-row)
  1. 給tr設(shè)置高度只起到min-height的作用,默認會平分table的高度。
  2. tr中的td默認高度會繼承tr的高度,若給任一td設(shè)置了高度,其他td的高度也同樣變高。適合多列等高布局
  3. 設(shè)置寬度、margin、都不起作用
  • td標簽(display:table-cell)
  1. td默認繼承table的高度,且平分table的寬度
  2. 若table(display:table)不存在,給td設(shè)置的寬高不能用百分比只能用準確的數(shù)值
  3. 給td設(shè)置vertical-align: middle; td元素里面(除float、position:absolute)所有的塊級、非塊級元素都會相對于td垂直居中
  4. 給td設(shè)置text-align: center; td元素里面所有非block元素(除float、position:absolute)都會相對于td水平居中,雖然block元素不居中,但其中的文字或inline元素會水平居中

了解了table的一些屬性,當我們遇到一些水平垂直居中的布局時,就會變得so easy了。

2、圖片定高|不定高水平垂直居中

圖片本身就是inline-block元素,那么我們只要給它的父級元素加個display:table-cell就好了

.box{
    height: 200px;
    width: 200px;
    display: table-cell;
    text-align: center;
    border: 1px solid #ccc;
    vertical-align: middle;
}
<div class="box">
    ![](https://ss1.baidu.com/70cFfyinKgQFm2e88IuM_a/forum/pic/item/242dd42a2834349b406751a3ceea15ce36d3beb6.jpg)
</div>

圖片定高|不定高水平垂直居中

就是那么簡單。demo

3、多行定高|不定高|定寬|不定寬水平垂直居中

我們平時常見的就是單行水平垂直居中,其實就是簡單的text-align:center; 然后再是line-height:xx 就搞定了。但是多行的就相對于復雜點。但是使用了table-cell之后,就變得很簡單了

單個標簽多行文字垂直居中

當然,里面也可以是多個標簽形成的多行,然后進行水平垂直居中

多標簽水平垂直居中

demo1 demo2
其實實現(xiàn)的原理還是使用table-cell,先把外層box設(shè)置為table-cell,再把里面的元素設(shè)置為inline|inline-block(不定寬高|元素居中)或者block(寬度100%|文字居中)那么就可以控制里面的元素水平垂直居中了。基于這樣的布局方式,你就可以把什么定高|不定高|定寬|不定寬|多行|單行的水平垂直居中都搞定了。

4、左右浮動元素垂直居中

由于display:table-cell對浮動元素是不起作用的,當我們需要兩個元素一個左浮動一個右浮動,并且這連個元素還居中的時候。上面的方法就不起作用了。那我們可以換個法子,既然display:table-cell;的垂直居中不能直接對浮動元素起作用,那就來個間接的嘛。給兩個浮動的元素外面一個display:inline-block;的元素,并且清除浮動。然后讓display:table-cell的垂直居中對inline-block元素起作用就好了。demo

Paste_Image.png

如果你的需求還需要在兩個浮動的元素中再添加水平垂直居中的話,那么同樣的道理,只需要在這兩個元素中構(gòu)造符合table-cell布局的結(jié)構(gòu)就好了。

5、一行多列水平垂直居中

經(jīng)常會有這樣的需求,一列里面可能會有1、2、3個子元素,不管幾個都是要居中的。有了table-cell就可以輕松解決了。
實現(xiàn)原理也基本是把外層box設(shè)置為display:table-cell;然后設(shè)置居中。里面的元素item設(shè)置成inline或者line-block;就可以了,不管里面的item的個數(shù)多少,都會居中的,包括item是圖片也會這樣。demo

Paste_Image.png
6、多列等高布局

有這樣的需求,一行有三個item,三個item的高度不定,但是這一行的三個item最終的高度以最高的那個為準。按照以前的做法要不就是砍掉需求,必須定高。實在不行就是等加載完之后用js計算三個item的高度,然后把最高的高度給其他item設(shè)置高度。這樣有點惡心,并且會出現(xiàn)抖動。有了table-cell之后,這個就不成問題了,因為在一個tr中,里面的td必須是等高的,而不管里面內(nèi)容的高度。demo

Paste_Image.png
Paste_Image.png

認證看代碼你會發(fā)現(xiàn)跟我們平時的定高布局布局不一樣,每行外面必須得有一個ul來保證里面item的等高,并且里面還需要使用多余的li來控制間距。這樣做的原因是因為tr里面的元素不會自動換行,所以必須手動換行,給外面加個ul,(說好的tr呢?)是這樣的,被設(shè)置為display:table-cell的元素會跟相鄰的兄弟元素共同生成一個虛擬的table、tr把自己包起來,誰叫td只能包在table里面呢。但是你直接寫td標簽是不會產(chǎn)生這樣的效果的。而使用多余的li來控制間距是因為table-cell元素不認識margin,所以只能這樣做了。
在生成機構(gòu)的時候就需要判斷什么時候該換行了,而不是像以前一樣在一個ul里面生成全部的li了

7、左邊定寬右邊自適應(yīng)

demo

Paste_Image.png

8、左邊右邊定寬中間自適應(yīng)三列布局

demo

Paste_Image.png

總結(jié):
使用table-cell還可以實現(xiàn)很多的布局,需要自己去發(fā)揮想象。總結(jié)下來也就需要記住幾點,設(shè)置了display:table-cell的元素具有以下特性。

  1. text-align、vertical-align等對齊屬性起作用,margin不起作用。寬高百分比值不起作用。
  2. 會生成虛擬的table、tr把自己包裹住,如果有相鄰的兄弟元素也被設(shè)置了table-cell,則會跟兄弟元素一起生成虛擬的table、tr把自己包裹住,并一行等高顯示
  3. 多個table-cell元素會占滿被設(shè)置了display: table的元素的寬度,如果一個元素被設(shè)置了寬度,那么其他剩余的table-cell元素會占滿剩下的寬度。當然,如果只有一個table-cell元素,就算設(shè)置了寬度也會占滿table元素的寬度。
  4. 對設(shè)置了float、absolute的元素不起作用。且IE6、7不支持

這就是所謂的table布局大法。

display: inline-block

  • inline-block元素把自己變成特殊的inline元素,對于相鄰的元素來說表現(xiàn)出inline的特點,允許空格。對于內(nèi)部元素來說表現(xiàn)出block元素的特點,可以設(shè)置高度和寬度。
  • 空格是兩個標簽中存在換行符or制表符or空格符(其實就是縮進)的原因生產(chǎn)的,只需要給設(shè)置了inline-block屬性的父元素設(shè)置font-size:0,就可以使標簽中的空格失去寬度
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內(nèi)容