css table佈局大法,解決你大部分居中、多列等高、左右佈局的問題

看了這篇文章,你能夠了解到如下佈局方法:css

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

最近開發遇到一些佈局上的問題,因爲不肯定因素比較多,好比不定寬高、單行多行的狀況須要顯示的樣式基本相同。這樣的狀況會比較複雜,後來找到display:table-cell這個佈局神器,這些問題也就不是問題了。好比如下這種狀況:佈局

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

基於這樣的需求,咱們一般都是每一種狀況須要單獨的寫一份hack樣式,這樣寫起來很麻煩。咱們多麼但願寫一份樣式,無論你裏面的節點如何變,定不定寬高,多行與否都能表現一致。針對水平|垂直居中的狀況,我找到了table-cell佈局的方式,基本能解決。下面會總結一下table-cell的佈局原理以及列舉一些平常佈局所遇到的狀況。flex

一、table的一些特性與表現形式

雖然table佈局由於它的一些非語義化、佈局代碼冗餘,以及很差維護改版等缺點被趕出了佈局界。可是在css不給力時期,table佈局也曾風靡一時,就算如今看來table的一些佈局的特性也是很是給力的,而幸虧css也吸收了table佈局一些好的特性爲己用。讓咱們可使用更少、更語義化的標籤來模擬table佈局,能夠跳過table佈局的缺點又實現咱們想要的效果,因此咱們首先須要瞭解table的一些特性以及對應的css屬性。
咱們在不居中使用到的也就是table、tr、td的一些特性,因此咱們只須要了解這三個標籤的特性就足夠了。spa

table標籤(display:table)

1) table可設置寬高、margin、border、padding等屬性。屬性值的單位可使用px,百分比值。
2) table的寬度默認由內容的寬高撐開,若是table設置了寬度,寬度默認被它裏面的td平均分,若是給某一個td設置寬度,那麼table剩餘的寬度會被其餘的td平均分(有點相似flex佈局)
3) 給table設置的高度起到的做用只是min-height的做用,當內容的高度高於設置的高度時,table的高度會被撐高。code

tr標籤(display:table-row)

1) 給tr設置高度只起到min-height的做用,默認會平分table的高度。
2) tr中的td默認高度會繼承tr的高度,若給任一td設置了高度,其餘td的高度也一樣變高。適合多列等高佈局
3) 設置寬度、margin、都不起做用繼承

td標籤(display:table-cell)

1) td默認繼承tr的高度,且平分table的寬度
2) 若table(display:table)不存在,給td設置的寬高不能用百分比只能用準確的數值
3) 給td設置vertical-align: middle; td元素裏面(除float、position:absolute)全部的塊級、非塊級元素都會相對於td垂直居中
4) 給td設置text-align: center; td元素裏面全部非block元素(除float、position:absolute)都會相對於td水平居中,雖然block元素不居中,但其中的文字或inline元素會水平居中圖片

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

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

圖片自己就是inline-block元素,那麼咱們只要給它的父級元素加個display:table-cell就行了rem

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

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

就是那麼簡單。demoget

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

咱們平時常見的就是單行水平垂直居中,其實就是簡單的text-align:center; 而後再是line-height:xx 就搞定了。可是多行的就相對於複雜點。可是使用了table-cell以後,就變得很簡單了

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

固然,裏面也能夠是多個標籤造成的多行,而後進行水平垂直居中

多標籤水平垂直居中
demo1 demo2
其實實現的原理仍是使用table-cell,先把外層box設置爲table-cell,再把裏面的元素設置爲inline|inline-block(不定寬高|元素居中)或者block(寬度100%|文字居中)那麼就能夠控制裏面的元素水平垂直居中了。基於這樣的佈局方式,你就能夠把什麼定高|不定高|定寬|不定寬|多行|單行的水平垂直居中都搞定了。

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

因爲display:table-cell對浮動元素是不起做用的,當咱們須要兩個元素一個左浮動一個右浮動,而且這連個元素還居中的時候。上面的方法就不起做用了。那咱們能夠換個法子,既然display:table-cell;的垂直居中不能直接對浮動元素起做用,那就來個間接的嘛。給兩個浮動的元素外面一個display:inline-block;的元素,而且清除浮動。而後讓display:table-cell的垂直居中對inline-block元素起做用就行了。demo

Paste_Image.png

若是你的需求還須要在兩個浮動的元素中再添加水平垂直居中的話,那麼一樣的道理,只須要在這兩個元素中構造符合table-cell佈局的結構就行了。

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

常常會有這樣的需求,一列裏面可能會有一、二、3個子元素,無論幾個都是要居中的。有了table-cell就能夠輕鬆解決了。
實現原理也基本是把外層box設置爲display:table-cell;而後設置居中。裏面的元素item設置成inline或者line-block;就能夠了,無論裏面的item的個數多少,都會居中的,包括item是圖片也會這樣。[demo]()

Paste_Image.png

六、多列等高佈局

有這樣的需求,一行有三個item,三個item的高度不定,可是這一行的三個item最終的高度以最高的那個爲準。按照之前的作法要不就是砍掉需求,必須定高。實在不行就是等加載完以後用js計算三個item的高度,而後把最高的高度給其餘item設置高度。這樣有點噁心,而且會出現抖動。有了table-cell以後,這個就不成問題了,由於在一個tr中,裏面的td必須是等高的,而無論裏面內容的高度。demo

Paste_Image.png

Paste_Image.png

認證看代碼你會發現跟咱們平時的定高佈局佈局不同,每行外面必須得有一個ul來保證裏面item的等高,而且裏面還須要使用多餘的li來控制間距。這樣作的緣由是由於tr裏面的元素不會自動換行,因此必須手動換行,給外面加個ul,(說好的tr呢?)是這樣的,被設置爲display:table-cell的元素會跟相鄰的兄弟元素共同生成一個虛擬的table、tr把本身包起來,誰叫td只能包在table裏面呢。可是你直接寫td標籤是不會產生這樣的效果的。而使用多餘的li來控制間距是由於table-cell元素不認識margin,因此只能這樣作了。
在生成機構的時候就須要判斷何時該換行了,而不是像之前同樣在一個ul裏面生成所有的li了

七、左邊定寬右邊自適應

demo
Paste_Image.png

八、左邊右邊定寬中間自適應三列布局

demo
Paste_Image.png

總結:

使用table-cell還能夠實現不少的佈局,須要本身去發揮想象。總結下來也就須要記住幾點,設置了display:table-cell的元素具備如下特性。

  1. text-align、vertical-align等對齊屬性起做用,margin不起做用。寬高百分比值不起做用。
  2. 會生成虛擬的table、tr把本身包裹住,若是有相鄰的兄弟元素也被設置了table-cell,則會跟兄弟元素一塊兒生成虛擬的table、tr把本身包裹住,並一行等高顯示
  3. 多個table-cell元素會佔滿被設置了display: table的元素的寬度,若是一個元素被設置了寬度,那麼其餘剩餘的table-cell元素會佔滿剩下的寬度。固然,若是隻有一個table-cell元素,就算設置了寬度也會佔滿table元素的寬度。
  4. 對設置了float、absolute的元素不起做用。且IE六、7不支持

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

display: inline-block

  • inline-block元素把本身變成特殊的inline元素,對於相鄰的元素來講表現出inline的特色,容許空格。對於內部元素來講表現出block元素的特色,能夠設置高度和寬度。
  • 空格是兩個標籤中存在換行符or製表符or空格符(其實就是縮進)的緣由生產的,只須要給設置了inline-block屬性的父元素設置font-size:0,就可使標籤中的空格失去寬度
相關文章
相關標籤/搜索