冷門佈局方法 tabel-cell 的可行性研究

display:table-cell 屬性簡介

display:table-cell;會使元素表現的類似一個表格中的單元格 td,利用這個特性可以實現文字的垂直居中效果。同時它也會破壞一些 CSS 屬性,使用 table-cell 時最好不要與 float 以及 position: absolute 一起使用,設置了 table-cell 的元素對高度和寬度高度敏感,對 margin 值無反應,可以響應 padding 的設置,表現幾乎類似一個 td 元素。

小結:

  1. 不要與 float:left; position:absolute; 一起使用。

  2. 可以實現大小不固定元素的垂直居中。

  3. **margin** 設置無效,響應 **padding** 設置。

  4. 對高度和寬度高度敏感。

  5. 不要對 display:table-cell 使用百分比設置寬度和高度。

下面介紹幾個 table-cell 的應用:

1. 高度不固定內容水平垂直居中

關鍵在於設置了 display:cell; 後,vertical-align:middle 使文字內容垂直居中。

<style>
.outer{display: table;width: 100%;}
.table-wrap{
    display: table-cell;
    height: 200px;            
    padding: 20px;
    vertical-align: middle;
    text-align: center;
    border: 1px solid red;
    }
</style>
<div>
    <div  class="table-wrap">
        <img src="http://jsfiddle.net/img/logo@2x.png" alt="logo" />
    </div>
</div>

中間的圖片會隨着外層容器的大小而自動水平垂直居中,其實原理和文字水平垂直居中一模一樣。

2. 多列布局實現文字水平方向對齊

<style>
    *{margin: 0;padding: 0;}
    .outer{display: table;width: 90%;margin: 10px  auto;
        padding: 10px; border: 1px solid green;}
    .table-left,.table-right{
        display: table-cell;            
        width: 20%;
        border: 1px solid red;
    }
    .table-center{
        height: 100px;
        background-color: green;
    }
</style>
<div>
    <div>
        <p>我是左邊</p>
    </div>
    <div  class="table-center">
        我是中間
    </div>
    <div>
        <p>我是右邊</p>
    </div>
</div>

可以看到左右兩邊以及中間部分的文字,雖然它們在不同的容器中,且不用管當前列容器設置的 padding 是多少,它們在水平方向上是絕對對齊的。

3. 等高佈局

<style>
        *{margin: 0;padding: 0;}
        .outer{display: table;width: 90%;margin: 10px  auto;
            padding: 10px; border: 1px solid green;}
        .table-left{
            display: table-cell;            
            width: 150px;
            padding-top: 20px;
            border: 1px solid red;
            vertical-align: top;
            text-align: center;
        }

        .table-right{            
            border: 1px solid yellow;
            background-color: green;
            margin-left: 20px;
            padding: 10px;
        }
    </style>
    <div>
        <div>
            <img src="http://jsfiddle.net/img/logo@2x.png" alt="logo" />
        </div>
        <div>
            <span>這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字。。。。。</span>
        </div>
    </div>

拉伸寬度,會發現左右兩側始終保持高度一致。

4. 均分列表佈局

<style>
    *{margin: 0;padding: 0;}
    .table-wrap{
        display: table;
        width: 80%;
        margin: 20px auto;
        border: 1px solid red;
        padding: 20px;
    }
    .table-wrap li{
        display: table-cell;
        padding: 20px;
        border: 1px solid green;
        border-right: none;
        text-align: center;
        vertical-align: middle;
    }
    .table-wrap li:last-child{
        border-right: 1px solid green;
    }
</style>
<ul>
    <li>001</li>
    <li>002</li>
    <li>003</li>
    <li>004</li>
    <li>005</li>
</ul>

以前進行類似的佈局我都會使用 display:inline-block; 的方式,需要在 ul 上設置 font-size: 0; 來清除每一個小塊之間的間隙,還需要爲每一個項寫一個百分比寬度。使用 table-cell 後,不需要寫百分比寬度,也不需要清除小塊間的間隙。而且添加額外項時,會自動平均分配寬度。

5. 兩欄自適應佈局

即左側寬度固定,右側自動分配剩餘空間:

<style>
        * {
            box-sizing: border-box;
        }
        .content {
            display: table;
            border: 1px solid #06c;
            padding: 15px 5px;
            max-width: 1000px;
            margin: 10px auto;
            min-width: 320px;
            width: 100%;
        }
        .left-box{
            float: left;            
            background-color: green;
            margin-right: 10px;
            padding-top:5px;            
        }
        .right-box{
            display: table-cell;
            border: 1px solid red;
            padding: 10px;
            vertical-align: top;
        }
    </style>
    <div>
        <div>
             <img src="http://jsfiddle.net/img/logo@2x.png" alt="logo" />
        </div>
        <div>
            <span>這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字這是很多文字。。。。。</span>
        </div>
    </div>

左側寬度固定,右側寬度自適應。佈局原理也可以用 BFC 來解釋,左側和右側都是 BFC 塊,BFC 塊是不會和 float 塊發生重疊的。

6. 詭異的百分比寬高

使用 table-cell 有一個讓人很抓狂的地方,那就是他的寬高是不能使用百分比設置的,具體的原因我一直沒有找到,只能理解爲這是這個屬性的特性。希望有知道的老鐵告知一聲。下面說一說關於百分比寬高的結論:1. 高度設置百分比無效,只與內容的實際高度有關 2. 寬度設置百分比分兩種情況, * 一種是父容器設置 display:table;,這種情況下分兩種情況 1. 沒有其他元素 table-cell 的容器會獲得它前面的元素在水平方向分配完的全部寬度。2. 在其前面有其他元素時,其寬度可以按照 display:inline-block 的元素來計算,也就是寬度會小於等於其百分比計算值的寬度的 * 在父容器未設置 table時width 的百分比值可以理解爲內容區寬度加上 border-box 左右兩邊到父容器邊框的距離,也就是 width 的百分比值越小,其所佔據的寬度越大 如果你對這個問題比較感興趣,可以看看這個問答。真的是匪夷所思啊。

小結:所有的 display:table-cell; 佈局中,vertical-align 屬性對於文字對齊都是很關鍵的。

Q&A

Q: 有兼容性的坑麼,生產環境使用的如何?

A: 對於兼容性,只是在新版的 chrome 中測試過,生產環境中還是不建議用這種小衆的方案,畢竟出了問題也不好找解決方案。

Q: 相對其他對齊或者佈局方式的優勢是?

A: 相對其他佈局方式,其實並沒啥優勢,而且還是屬於比較小衆的佈局方式。但是針對一些特殊的場景,使用起來還是很方便的。比如對於列子一,使用 table-cell 的方式就要比其他佈局方式簡單。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/a3HFIv74PH6LWgHnVRsfKg