首頁  >  文章  >  web前端  >  深入解析HTML的table表格標籤與相關的換行問題

深入解析HTML的table表格標籤與相關的換行問題

高洛峰
高洛峰原創
2017-02-24 10:17:501906瀏覽

何為table:

table者Html表格也,資料之載體。
以下是一個比較標準的table程式碼寫法:

<table border="0" cellspacing="0" cellpadding="0" width="100%">
  <tr>
    <th>Month</th>
    <th>Date</th>
  </tr>
  <tr>
    <td>AUG</td>
    <td>18</td>
  </tr>
</table>

簡單的HTML表格由table元素以及一個或多個tr、th或td元素組成。 tr元素定義表格行,th元素定義表頭的單元格,td元素定義表格單元格。 border屬性規定表格邊框的寬度,cellpadding規定單元邊緣與其內容之間的空白,cellspacing規定單元格之間的空白,這三個屬性我們一般手動設定為0避免瀏覽器差異。 width屬性規定表格的寬度,因為table寬度是隨內部元素的寬度撐起多少而變化,而常用情況下我們希望table是同外部容器等寬,所以常常默認設置100%寬度使之撐滿容器。


不得不說的table-layout:fixed屬性
table-layout: auto(預設)|fixed。
參數:
auto:預設的自動演算法。佈局將基於各單元格的內容。表格在每一單元格讀取計算之後才會顯示出來,速度很慢。
fixed:固定佈局的演算法。在這個演算法中,水平佈局是僅基於表格的寬度,表格邊框的寬度,單元格間距,列的寬度,而和表格內容無關。 解析速度快。
fixed佈局模型的工作步驟:
1.width屬性值不是auto的所有列元素會根據width值設定該列的寬度。
2.表首行中位於該列的單元格width,根據該單元格寬度設定此列的寬度。如果這個儲存格跨多個列,則寬度在這些列上平均分配。
3.在以上兩步驟之後,若列的寬度仍為auto,會自動確定其大小,使其寬度盡可能相等。此時,表的寬度設定為表的width值或列寬度總和(取其中較大者)。如果表度度大於其列寬總和,將二者差除以列數,再把得到的這個寬度增加到每一列上。
這種方法的速度很快,因為所有列寬都由表格的第一行定義。首行後所有行中的儲存格都根據首行所定義的列寬來決定大小。後面這些行中的儲存格不會改變列寬。這意味著為這些單元格指定的width值都會被忽略。
通常在做複雜表格html的時候,有時候你會發現,無論怎麼調整第一行每列的width,列寬還是會發生出乎於你意料之外的變動(例如一長串英文文本,並且中間無空格分隔的情況你要這列限定寬度,使得過長文字強制換行且不撐破表格,而往往結果是怎麼也調整不到合適的寬度),這個時候在萬般無奈之下,你可以使用table-layout:fixed。

常見而又生疏的幾個table標籤
thead、tfoot以及tbody
這三個標籤是所謂xhtml的產物,主要是讓您有能力對錶格中的行進行分組。當您建立某個表格時,您也許希望擁有一個標題行,一些帶有資料的行,以及位於底部的一個總計行。這種劃分使瀏覽器有能力支援獨立於表格標題和頁腳的表格正文滾動。當長的表格被列印時,表格的表頭和頁腳可列印在包含表格資料的每張頁面上。個人認為其主要用途適用於超長表格的顯示優化。
thead標籤表示HTML表頭
表格的頭部thead,可以使用單獨的樣式定義表頭,並且在列印時可以在分頁的上部列印表頭。
thead標籤表示HTML頁腳
表格的頁腳tfoot,可以使用單獨的樣式定義頁腳(腳註或表註),並且在列印時可以在分頁的下部列印頁腳。
tbody標籤表示HTML表體
瀏覽器顯示表格時,通常是完全下載表格後,再全部顯示,所以當表格很長時,可以使用tbody分段顯示。
註解:如果您使用 thead、tfoot以及tbody元素,您就必須使用全部的元素。它們的出現次序是:thead、tfoot、tbody,這樣瀏覽器就可以在收到所有資料前就可呈現表頭和頁腳了。您必須在table元素內部使用這些標籤,且thead內部必須擁有tr標籤。所以書寫較為標準的table方式即如下程式碼:

<table border="0" cellspacing="0" cellpadding="0" width="100%">
  <thead>
    <tr>
      <th>Month</th>
      <th>Date</th>
    </tr>
  </thead>
  <tfoot>
    <tr>
      <th>Month Lists</th>
      <th>Date Lists</th>
    </tr>
  </tfoot>
  <tbody>
    <tr>
      <td>AUG</td>
      <td>18</td>
    </tr>
  </tbody>
</table>

個人認為這個東西挺雞肋,取之無用,棄之可惜。小專案可以增加些語意化,但因為曾經遇到有多個不同表頭在同一表格顯示的窘境,限制了日後的開發,所以正式專案從可擴展的角度來說情慎用這些標籤。

col和colgroup
這兩個標籤也是xhtml的產物,功能強大,相容於奇差。
col標籤為表格中一個或多個欄位定義屬性值。
colgroup標籤用於對表格中的列進行組合,以便對其進行格式化。
它們的作用主要就是來控制單元格的寬度了,這樣省去單獨定義每個單元格的麻煩,過去我們往往是在第一行中的th或者td上定義寬度來規定每列的寬度,而col不但可以定義寬度還能同時定義其他的屬性,例如可以透過col來控制幾列寬度的總和,還可以控制這列的背景色。但理想是豐滿的,現實是骨幹的,正如前面所說,功能越大不代表其兼容性也越強,根據現有的測試下來,col和colgroup能發揮作用還能保證兼容的應用就只有倆:width和background。對於width,個人寧願使用常規方式,第一行設定寬度,保證列寬。對於bacground,一般實際中表格大面積使用不同背景的情況也很少見。故個人認為:能不用盡量不用。

何處用table
個人認為,在一個放置資料非常密集且又非常序列化的一個容器裡,用table準沒錯。最常見的例子就是我們常見的購物訂單結算頁面,上面列有你訂單詳情:商品名稱、單價、購買數量、金額小計、運費等等,最後最下方還會有一個最終訂單金額的結果,table這裡可謂如魚得水,達到了數據之載體的神效。


table疑難雜症之換行
用table顯示資料有時候會有一個頭痛的地方,即不換行顯示某段文字,尤其在表頭th中用到地方最多。其實你所頭痛的並非換行,而是其背後的瀏覽器相容加性使得換行的困難程度大大增加。
整體來說在table中換行個人比較推薦的方式為:先為table設定table-layout:fixed,基本上設定完這個屬性後基本的換行問題都能夠解決而不會出現table中td ,th因為裡面各個內容的多寡發生搶奪其他td,th寬度的情形發生。這時如果你依舊有強制換行問題,那麼在此td中內部加一層p,再利用word-wrap:break-word; word-break:break-all;這兩個CSS方法可以解決換行的問題。

攻略強制換行與強制不換行
強制換行與強制不換行問題曾經一度困擾著我,每當遇到換行問題時候那就是痛苦回憶的開始,現在終於痛定思痛,一鼓作氣把這個長期頑固問題給解決。
強制換行與強制不換行用到的屬性
我們一般控制換行所用到的CSS屬性一共有三個:word-wrap; word-break; white-space。這三個屬性可以說是專門為了文字斷行而創造出來的。首先我們得知道這三個屬性到底是做什麼用地:


word-wrap語法
word-wrap: normal(預設) | break-word
各個瀏覽器都能辨識
參數:
normal: 允許內容頂開指定的容器邊界。
break-word: 內容將在邊界內換行。必要時會觸發word-break(注意:請分辨清楚word-break和break-word這兩個是不同的東西,一為屬性另為參數)。
說明:
word-wrap是控制是否「斷行字」的,設定或檢索目前行超過指定容器的邊界時是否斷開轉行。中文沒有任何問題,英文語句也沒問題。但是長串的英文,就不行。
範例:
congratulation這個單字屬於長串英文,word-wrap:break-word整個單字看成一個整體,如果該行末端寬度不夠顯示整個單詞,它會自動把整個單字放到下一行,而不會把單字截斷,這就是對於長串文字不起作用的解釋。 word-wrap:normal是預設情況,英文單字不被拆開。
結論:
作用範圍僅為p這類標準塊級元素,th,td這類table元素雖然識別但是沒有效果(如果為td,th加上寬度word-wrap在IE下是能夠發揮效果的,但根據完全相容性方便記憶角度上來說還是以前面的結論為準)。


word-break語法
word-break: normal(預設) | break-all | keep-all
參數:
normal: 依照亞洲語言和非亞洲語言的文本規則,允許在字內換行。
break-all: 該行為與亞洲語言的normal相同。也允許非亞洲語言文本行的任意字內斷開。該值適合包含一些非亞洲文本的亞洲文本。
keep-all: 與所有非亞洲語言的normal相同。對於中文,韓文,日文,不允許字斷開。適合包含少量亞洲文本的非亞洲文本。
說明:
word-break:break-all,是斷開單字。當單字到邊界時,下個字母自動到下一行。主要解決了長串英文的問題(只是彌補了上面word-wrap:break-word對於長串文字不起作用的缺陷)。
範例:
繼續以上面congratulation這個字屬於長串英文,word-break:break-all它會把字截斷,該行末端就會變成類似conra(congratulation的前端部分),下一行為tulation(conguatulation)的後端部分了。
word-break:keep-all,是指Chinese, Japanese, and Korean不斷詞。即只用此時,不用word-wrap,中文就不會換行了。 (英文語句正常。)
結論:
作用範圍僅為p這類標準塊級元素,th,td這類table元素雖然識別但是沒有效果(經測試Chrome下word-break:break-all是有效果的,但根據完全相容性方便記憶角度上還是以前面的結論為準)。 Firefox,Opera是無法辨識word-break的,更不用提Firefox下的th,td中使用word-break的效果了。

white-space語法
white-space: normal(預設) | pre | nowrap
參數:
normal: 預設。空白會被瀏覽器忽略。
pre: 空白會被瀏覽器保留。其行為方式類似HTML中的pre標籤。
nowrap: 文字不會換行,文字會在同一行上繼續,直到遇到br標籤為止。
說明:
對於pre屬性,其實就是HTML中連續的多個空白符會被合併,然後為了不讓他合併(最常用的場合就是表示程式碼文字縮排)讓其中的空白符繼續保留而不需要我們增加額外的樣式和標籤來控制它的縮排和換行。 pre標籤的原理也是一樣的內部預設有了個white-space:pre。
對於nowrap屬性,這個是強制不換行核心,一般強制不換行就是利用這個屬性。 Firefox的p和td中,以及IE的p中,都沒有問題。唯一的瑕疵就是在IE的td中會有一個問題,如果td沒有指定寬度,則nowrap仍然有效,如果td有寬度,並且文字中無標點、無空格(例如中文長串文字),nowrap則不再有效。解決方式就是可以加word-break:keep-all;可以解決此問題。
 

總結強制換行:
如果在p這類標準區塊層級元素中需要強制換行,最普遍的方案就是word-wrap:break-word; word-break:break-all;此方式的缺點就是會導致如果恰巧該行末端寬為一個長串英文單詞,那麼該單字會被撕開的尷尬樣式(而且FF不識別word-break,反而不會撕開這個單字)。個人認為如果你這個p裡面放的類似於URL這個長串地址,那麼用此方案是非常不錯的選擇(注意:由於FF不識別word-break,所以無法保證每行末端會整齊的斷開URL單詞,但這也是無奈的選擇)。如果不是放置URL這類可以斷開的長串英文,而是英文句子的話,那麼使用word-wrap:break-word;即可。至於網路上看到有word-wrap:break-word; overflow:hidden;這麼個寫法,據說可以兼容IE和FF,但經過親自測試似乎沒有什麼特別效果。

總結強制不換行:
強制不換行的問題到是比較容易分析的,就如上面所討論的那樣使用white-space:nowrap,Firefox的p和td中,以及IE的p中,都沒有問題。唯一的瑕疵就是在IE的td中會有一個問題,如果td沒有指定寬度,則nowrap仍然有效,如果td有寬度,並且文字中無標點、無空格(例如中文長串文字),nowrap則不再有效。解決方式就是可以加word-break:keep-all;可以解決此問題。綜合下來,比較穩健的方式是在文字與td之間再套一層p,然後使用nowrap,那就是強制不換行。注意這時候很有可能文字會過多導致溢出容器,所以你還要加一個overflow:hidden,防止溢出容器,這樣子就可以相容於各個瀏覽器了。
總結了那麼多,發覺似乎也就那幾個屬性在瀏覽器裡面的各種兼容性的平衡,現在似乎尚未有一個完美的方案可以全部兼容各個瀏覽器,我們所能做的最多的就是盡可能的保持個瀏覽器顯示一致。如果你還是覺得一定要相容於所有的瀏覽器,那麼最後的方案那麼就是動用JS了,以後的文章中我會考慮從以最小的JS代價來滿足此要求,但這暫不在本文所討論的範圍內。


更多深入解析HTML的table表格標籤與相關的換行問題相關文章請關注PHP中文網!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn