表格行與列邊框樣式處理的原理分析及實戰應用

QcloudCommunity發表於2017-11-07

歡迎大家前往騰訊雲社群,獲取更多騰訊海量技術實踐乾貨哦~

作者:韓宇波

導語:table之間的邊框存在共用問題,自然而然就存在衝突。既然存在衝突,那麼就勢必涉及到最後渲染哪一個樣式的問題。本文就主要研究當衝突產生時,如何讓瀏覽器按照自己意願渲染衝突邊框。在這篇文章中都有介紹,以及對錶格的邊框渲染原理進行了深度的剖析。

最近需求中有用到table,並在做需求的過程中遇到table border的問題,在空餘的時間把遇到的問題進行探索一番,收穫頗多,特此分享;

廢話不多說,直接上乾貨!

表格行與列邊框樣式處理的原理分析

1、border-style:none優先順序最低 demo

結論

a)當且僅當兩個相鄰產生衝突的邊框的border-style為none時,衝突邊框才不會顯示

2、border-style:hidden優先順序高於border-style:solid demo

結論

a)border-style:hidden;邊框的優先順序高於solid樣式的邊框

3、border-style優先順序 demo

結論

a)hidden > double > solid > dashed > dotted > none(預設值)

4、邊框的溢位與style屬性有關 demo

結論
a)上面兩個角中水平方向緊貼著table邊框的邊很重要,如若border-style為hidden,則邊框會溢位
b)垂直方向上不會發生溢位情況
c)溢位的邊框不會佔用文字流的空間

理由
具體例項可以檢視border-style優先順序

5、border-width較大者優先渲染 demo

結論
a)border-width較大者邊框樣式將被渲染

理由
命名為“中”的單元格邊框比其他邊框都要大,因此渲染的是“中”單元格的邊框,因而得出較大邊框樣式將被渲染,也符合W3C裡面對哪條邊渲染的解釋:“The rule of thumb is that at each edge the most "eye catching" border style is chosen”

6、table-border優先順序 demo

結論
a)優先順序如下:'table-cell','table-row','table-row-group','table-col','table-col-group', 'table'

理由
可以到Demo7啟用審查工具逐層去掉'table-cell','table-row','table-row-group','table-col','table-col-group', 'table'邊框,即可看到效果
7、左上優先渲染原則 demo

結論
a)水平方向上:當兩個單元格只存在顏色不一致的情況下,發生衝突的單元格相對較左側單元格的樣式
b)垂直方向上:當兩個單元格只存在顏色不一致的情況下,發生衝突的單元格相對較頂部單元格的樣式

8、border-style:double四個角的渲染方式 demo

chorme

FF

IE

結論
a)四個角重合之處採用組合層疊的方式進行渲染,而不是單一的選擇某一種樣式,而四條邊框則非重合(單一選擇某一條邊進行渲染)(chrome與IE,FF四個角重合之處不會採用組合層疊的方式進行渲染)
b)可以看出在FF下,四個角重合之處渲染優先順序是,垂直方向上的兩個相鄰單元格,相對偏下的單元格的衝突邊進行渲染

理由
從“中”這個單元格的四個角可以看出,四個角除了會的底邊是有其他叫層疊而來,而不是單一的去選擇某種邊框去渲染

9、border-style:double表現形式 demo

結論
a)border-style:double;寬度需要大於等於3px才能體現,否則,樣式與solid無異
b)border-style:double;會發生溢位,並且左右溢位值不一致

10、border-style:ridge與border-style:groove的表現形式 demo

結論
a)table2 ~ table5發生衝突邊渲染情況可以得出 ridge > groove
b)當ridge 與 groove衝突並且在表格 非 第一行發生衝突時,兩個衝突單元格的左上角和右上角以及衝突邊的上角都存在問題
c)從table2、table3、table4中可以看出,當outset 與 inset衝突且在表格 非 第一行發生衝突時,groove ==> outset, ridge ==> inset

理由
例10~例14可以到線上例子詳細檢視

11、border-style:outset與border-style:inset的表現形式 demo

結論
a)從table2~table5發生衝突邊渲染情況可以得出 outset > inset
b)從table2、table4、table5中可以看出,當outset 與 inset衝突且在表格第一行發生衝突時,兩個衝突單元格的左上角和右上角以及衝突邊的上角都存在問題
c)從table2、table4、table5中可以看出,當outset 與 inset衝突且在表格第一行發生衝突時,outset ==> groove, inset ==> ridge

理由
例10~例14可以到線上例子詳細檢視

12、border-style:outset與border-style:ridge的表現形式 demo

結論
a)table2~table5發生衝突邊渲染情況可以得出 ridge > outset
b)兩個單元格發生衝突以後,左上角都存在渲染問題
c)當outset 與 inset衝突且在表格第一行發生衝突時,兩個衝突單元格的左上角和右上角以及衝突邊的上角都存在問題
d)綜合上部表現可以看出,當兩個單元格發生衝突以後,處於表格的最後一行時,衝突邊的上部(角)存在渲染問題
e)綜合上部表現可以看出,outset未發生衝突的邊框的上部角會出現渲染問題

理由
例10~例14可以到線上例子詳細檢視

13、border-style:groove與border-style:inset的表現形式 demo

結論
a)table2~table5發生衝突邊渲染情況可以得出 groove > inset
b)groove與outset可以相互轉化,ridge與inset可以相互轉化

理由
例10~例14可以到線上例子詳細檢視

14、border-style:groove與border-style:outset的表現形式 demo

結論
a)table2~table5發生衝突邊渲染情況可以得出 outset > groove

理由
例10~例14可以到線上例子詳細檢視

15、direction屬性對table-border的影響 demo

結論
a)tr上使用direction: rtl;屬性,單元格(只是邊框,內容不變)並不會左右調換,而是邊框向後推了(最後一個邊框使用了渲染成第二個邊框,倒數第二個邊框渲染成倒數第三個邊框,依此列推)
b)table上使用direction: rtl;屬性,會使單元格左右調換,並且發生衝突的單元格相對較右側單元格的樣式

備註
在tr上使用direction: rtl;屬性,僅在google下生效,其他瀏覽器下不會生效

結論:

  • border-collapse: collapse;存在衝突情況,border-collapse: separate;不存在衝突情況(理所當然);
  • border-style: hidden;邊框優先順序最高,hidden屬性優先於所有其他邊界的衝突;
  • border-style: none;是邊框樣式的預設值,其優先順序最低,只有當發生衝突的所有元素的邊框屬性都為"none"時,邊框才會被省略;
  • border-width的值不相同時,窄邊界將會被捨棄,較寬的邊界會被顯示;
  • border-width的值相同時,border-style樣式優先順序順序為'double','solid'','dotted','ridge','outset',' 'inset';
  • border-color的值不相同時,border-color最終顯示的顏色優先順序如下為'table-cell','table-row','table-row-group','table-col','table-col-group','table';
  • border-color的值不相同時,但都是同一型別(如:table-cell),水平方向由direction屬性決定,若direction:ltr屬則採用相對較左側的元素樣式,若direction:rtl屬則採用相對較右側的元素樣式;垂直方向上則採用相對較靠近頂部的元素樣式;
  • border-collapse: collapse;相鄰的邊框存在衝突,但兩對角的兩個單元格是不存在衝突現象;
  • border-style:double;寬度渲染與設定值不一致;
  • border-style:double;寬度需要大於3px才能體現,否則,樣式與solid無異;
  • 水平方向上:當兩個單元格只存在顏色不一致的情況下,衝突邊界渲染的樣式與direction(table上設定該屬性)有關。若direction:ltr屬則採用相對較左側的元素樣式,若direction:rtl屬則採用相對較右側的元素樣式;垂直方向上:當兩個單元格只存在顏色不一致的情況下,較靠近頂部的邊框樣式將被渲染;
  • 四個角重合之處採用組合層疊的方式進行渲染,而不是單一的選擇某一種樣式,而四條邊框則非重合(單一選擇某一條邊進行渲染)
  • 上面兩個角中水平方向緊貼著table邊框的邊很重要,如若border-style為hidden,則邊框會,溢位垂直方向上不會發生溢位情況,溢位的邊框不會佔用文字流的空間

另外發現一些相容性問題:

  • 水平方向上:當兩個單元格只存在顏色不一致的情況下,衝突邊界渲染的樣式與direction(tr上設定該屬性在chrome有效,在其他瀏覽器上設定無任何效果)有關。若direction:ltr屬則採用相對較左側的元素樣式,若direction:rtl屬則導致渲染失常(無法解釋)
  • 四個角重合之處採用組合層疊的方式進行渲染,而不是單一的選擇某一種樣式,而四條邊框則非重合(單一選擇某一條邊進行渲染)(chrome與IE)
  • 在FF下,FF四個角重合之處不會採用組合層疊的方式進行渲染,四個角重合之處渲染規則是採用垂直方向上的兩個相鄰單元格,相對偏下的單元格的衝突邊進行渲染
  • a)在FF和IE下,ridge和inset渲染是一樣的,groove和outset渲染是一樣的;

    b)在chrome下,當outset 與 inset衝突且在表格第一行發生衝突時,outset ==> groove, inset ==> ridge,當outset 與 inset衝突且在表格 非 第一行發生衝突時,groove ==> outset,ridge ==> inset

表格行與列邊框樣式處理的實戰應用

上面分享了一些實用表格時,常遇到的一些衝突;

下面內容是對上述文章中提到的一些知識點加以運用,用到具體的例子上。

採用表格佈局最遠可以追溯到上個世紀90年代,當時使用table進行佈局是沒有辦法的辦法。從css2.0以後以table為主的網頁佈局慢慢的退出歷史舞臺,而採用現在為大家所熟悉的div + css的佈局方式。

table網頁佈局方式退出歷史舞臺並不等於table也退出舞臺,table有它自身的好處。目前大家使用table多數用於資料展示,資料展示必然會涉及到資料的對比,突出重點資料的需求。因此則產生了類似下圖的展示樣式。

看到這個視覺稿,想必大家第一反應是高亮列的實現方式應該是在td上面新增高亮邊框即可,沒什麼難度的。如果你這樣認為那就錯了。

在td上面直接新增border,會在造成左側邊缺失,具體原因可以參考(demo),如果要在高亮列的單元格直接實現缺失的左邊框(採用行內樣式或者加權重的方法,也是實現不了的),暫時是沒有什麼辦法的。如果有請聯絡筆者。

如果你查閱了上面推薦的文章,那麼你就知道產生這種現象的原因。

解決方法是在高亮列的前一列的右邊框新增高亮邊框。

看到解決方法有沒有一種很蛋疼的感覺,高亮列產生的問題,要跑到高亮列的前一列去解決。

今天我就針對這一類的問題進行研究並提供相關解決方法

解決上面的問題很簡單

style.css

/*公共 start*/
*{margin: 0;padding: 0;}
table{
    border-collapse: collapse;
    font-size: 14px;
    width: 30%;
    margin-top: 200px;
    margin-left: auto;
    margin-right: auto;
}
table tr td:first-child{
    font-weight: bold;
}
th{
    background-color: #f3f3f3;
}
/*公共 end*/
.comparison-table{
    width: 30%;
    border: 1px solid;
    border-color: #e6ebf2;
    color: #333;
    text-align: left;
    font-size: 14px;
    border-collapse: collapse;
}
.comparison-table th,
.comparison-table td{
    vertical-align: top;
    line-height: 1.7;
    padding: 0;
    border: 1px solid #d7e7f3;
}
.comparison-table thead th{
    background-color: #f6f8fa;
    line-height: 1;
}
.comparison-table .comparison-table-inner{
    padding: 15px 40px;
    color: inherit;
}
.comparison-table tbody tr td:first-child{
    font-weight: bold;
}

.comparison-table tr td:nth-child(2),
.comparison-table tr th:nth-child(2){
    border: 1px double #22d1b4;
}
.comparison-table colgroup col:nth-child(2){
    border: 1px double #22d1b4;
}

.comparison-table tr th:nth-child(2){
    background-color: #ccf0ec;
    color: #22d1b4;
}複製程式碼

demo.html

<table class="comparison-table">
    <colgroup>
        <col style="width:22%;">
        <col style="">
        <col style="">
    </colgroup>
    <thead>
        <tr>
            <th>
                <div class="comparison-table-inner">
                    <p>優勢</p>
                </div>
            </th>
            <th>
                <div class="comparison-table-inner">
                    <p>雲伺服器</p>
                </div>
            </th>
            <th>
                <div class="comparison-table-inner">
                    <p>傳統伺服器</p>
                </div>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <div class="comparison-table-inner">彈性</div>
            </td>
            <td>
                <div class="comparison-table-inner">彈性擴充套件,靈活配置</div>
            </td>
            <td>
                <div class="comparison-table-inner">運維困難</div>
            </td>
        </tr>
        <tr>
            <td>
                <div class="comparison-table-inner">可靠</div>
            </td>
            <td>
                <div class="comparison-table-inner">穩定可靠,資料放心</div>
            </td>
            <td>
                <div class="comparison-table-inner">系統脆弱,資料丟失</div>
            </td>
        </tr>
        <tr>
            <td>
                <div class="comparison-table-inner">易用</div>
            </td>
            <td>
                <div class="comparison-table-inner">即買即用,快速部署</div>
            </td>
            <td>
                <div class="comparison-table-inner">費心麻煩</div>
            </td>
        </tr>
        <tr>
            <td>
                <div class="comparison-table-inner">安全</div>
            </td>
            <td>
                <div class="comparison-table-inner">立體防護,專業支援</div>
            </td>
            <td>
                <div class="comparison-table-inner">黑客入侵</div>
            </td>
        </tr>
</table>複製程式碼

主要知識點

  1. 利用:nth-child(n)選擇器選擇高亮列/行
  2. 當邊框樣式為實線時,運用double優先順序比solid高的特點,覆蓋solid樣式
  3. 運用1px或2px的double視覺上與solid一樣的特點
  4. 運用'table-cell','table-row','table-row-group','table-col','table-col-group', 'table'之間渲染優先順序的關係

solid實現是如此,那dashed實現又如何呢

dashed.css

/*公共 start*/
*{margin: 0;padding: 0;}
a{color: #2277da;}
table{
    border-collapse: collapse;
    font-size: 14px;
    width: 30%;
    margin-top: 200px;
    margin-left: auto;
    margin-right: auto;
}
table tr td:first-child{
    font-weight: bold;
}
th{
    background-color: #f3f3f3;
}
/*公共 end*/
.method-4 th,
.method-4 td{
    padding: 20px;
    text-align: center;
}
.method-4 tr{
    border-top: 1px dashed #d3d3d3;
    border-bottom: 1px dashed #d3d3d3;
}
.method-4 thead tr{
    border-top-width: 0;
}
.method-4 tr:last-child{
    border-bottom-width: 0;
}
.method-4 colgroup{
    border: 1px dashed #d3d3d3;
}
.method-4 tr td:nth-child(3),
.method-4 tr th:nth-child(3),
.method-4 colgroup:nth-child(3){
    border: 1px dashed #22d1b4;
}
.method-4 tr td:nth-child(1),
.method-4 tr th:nth-child(1){
    border-left: 1px dashed #22d1b4;
}
.method-4 colgroup:nth-child(1){
    border: 1px dashed #22d1b4;
}複製程式碼

dashed.html

<div class="method-4">
    <table>
        <colgroup></colgroup>
        <colgroup class="highlight"></colgroup>
        <colgroup></colgroup>
        <thead>
            <tr>
                <th>優勢</th>
                <th>雲伺服器</th>
                <th>傳統伺服器</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>彈性</td>
                <td>彈性擴充套件,靈活配置</td>
                <td>運維困難</td>
            </tr>
            <tr>
                <td>可靠</td>
                <td>穩定可靠,資料放心</td>
                <td>系統脆弱,資料丟失</td>
            </tr>
            <tr>
                <td>易用</td>
                <td>即買即用,快速部署</td>
                <td>費心麻煩</td>
            </tr>
            <tr>
                <td>安全</td>
                <td>立體防護,專業支援</td>
                <td>黑客入侵</td>
            </tr>
        </tbody>
    </table>
</div>複製程式碼

而在這個demo中最核心的知識點就是利用colgroup上設定的border優先順序較低的特點。

閱讀推薦

一站式滿足電商節雲端計算需求的祕訣
Web 前端效能優化 : 如何有效提升靜態檔案的載入速度
白夜追凶 :手 Q 圖片的顯示和傳送邏輯

此文已由作者授權騰訊雲技術社群釋出,轉載請註明文章出處
原文連結:
cloud.tencent.com/community/a…

相關文章