
寫前端這么多年table標簽是我見過被吐槽最多、但根本繞不開的一個標簽。早年被拿來做整頁布局后來被 Flexbox、Grid 按在地上摩擦現在大家提到 table十有八九是 antd、element-plus 里的 Table 組件。可不管上層封裝成什么樣瀏覽器最終渲染出來的還是table那幾個字母。這個標簽的屬性看著不多實際用起來卻容易踩坑尤其是很多屬性在 HTML5 里已經不推薦了但老代碼、郵件模板、舊系統里還到處都是。這篇文章就把table標簽的常見屬性徹底講明白哪些能用、哪些該用 CSS 替代、怎么排查“屬性明明寫了卻沒效果”這種問題。不管是剛學 HTML 的新人還是要維護老項目的朋友讀這一篇基本夠了。1. table 標簽的基本結構和屬性到底在哪一層想搞清楚 table 的屬性得先知道一個表格是由哪些標簽“拼”出來的。一個完整的表格不是只有table它只是最外層的容器里面還有thead、tbody、tfoot、tr、th、td這些標簽。平時我們說的“table 標簽的常見屬性”其實分成兩層看第一層是寫在table自己身上的屬性比如border、cellpadding、cellspacing、align、bgcolor、background、width、frame、rules、summary這些它們控制的是整個表格的外框、間距、背景、寬度和對齊方式。第二層是寫在td、th身上的單元格屬性比如colspan、rowspan、scope、headers這些控制的是單個單元格的跨行跨列和語義關系。很多人一搜“table 屬性”把 colspan 也當成 table 的屬性嚴格講不對但它確實是表格體系里的核心屬性后面我會單獨講。先看一個最基礎的結構代碼table border1 cellpadding6 cellspacing0 width100% thead tr th產品/th th單價/th /tr /thead tbody tr td拿鐵/td td32/td /tr /tbody /table這里border給表格加了邊框cellpadding控制單元格內邊距cellspacing控制單元格之間的間隙width讓表格撐滿容器。老式寫法能讓表格在沒有任何 CSS 的情況下也能“長得像個表格”代價是樣式全寫在 HTML 里后期改起來非常痛苦。這就是我為什么建議你先認識這些屬性但不要急著在生產項目里亂堆。2. 常見屬性逐項拆解這些屬性分別控制什么我把table上真正出現過的常見屬性整理成了一張表逐項說清楚它的作用、狀態和替代方案。這里的“狀態”指的是在 HTML5 里還正不正規很多屬性雖然瀏覽器還認但官方已經判定為“過時屬性”。屬性作用HTML5 狀態現代替代方案border設置表格和單元格邊框寬度不推薦使用CSSborderborder-collapsecellpadding設置單元格內容與邊框之間的內邊距已過時CSSpaddingcellspacing設置單元格之間的間距已過時CSSborder-spacingalign設置表格水平對齊方式已過時CSSmargin: autobgcolor設置表格背景色已過時CSSbackground-colorbackground設置表格背景圖片已過時CSSbackground-imagewidth設置表格寬度已過時CSSwidthheight設置表格高度已過時CSSheight不推薦直接寫在 table 上frame控制表格外邊框顯示哪些邊已過時CSS 邊框選擇器rules控制表格內部行和列的分隔線已過時CSS 邊框選擇器summary為表格提供無障礙摘要已過時caption和th的scopeid/class/style/title/>table { border-collapse: collapse; } th, td { border: 1px solid #333; padding: 8px; }border屬性在 HTML5 里不是完全不能寫很多郵件模板和低代碼平臺還在用它做降級兜底。我的建議是日常網頁里不要用寫郵件模板時為了兼容老 Outlook可以保留border0或border1做基礎樣式核心樣式再用內聯 CSS 補上。2.2 cellpadding 和 cellspacing一個管“家里空間”一個管“鄰居距離”cellpadding是單元格內容到單元格邊框的距離相當于給每個單元格“家里”留出呼吸空間。加了cellpadding10之后文本不會緊貼 cell 邊緣視覺效果會舒服很多?,F代 CSS 里對應的是th, td { padding: 10px; }。cellspacing是單元格與單元格之間的距離相當于“鄰居與鄰居之間的間隔線”默認不是 0不同瀏覽器默認值不太一樣。如果你發現 table 的 cell 之間總有一條縫尤其是用 border 的時候出現雙線多半是 cellspacing 沒清零。CSS 里對應的是border-spacing但要注意它只在border-collapse: separate模式下生效。如果你用了border-collapse: collapseborder-spacing會被忽略。這里有個很經典的坑很多人看到 cellspacing 以為是“單元格之間的邊框距離”就給它設成 0結果發現本來的雙線邊框也沒了其實是 cellspacing 為 0 后兩條邊疊在一起視覺上看起來像是“邊框變細了”。這不是 bug是表格邊框機制的問題。2.3 align、bgcolor、background舊時代的樣式三兄弟aligncenter寫在table上是讓整個表格居中。但 HTML5 以后align對 table 已經過時推薦用margin-left: auto; margin-right: auto;。為什么不是text-align: center因為text-align管的是文本和內聯元素table默認是塊級盒子塊級盒子要居中得靠水平方向的 margin 自適應。你寫margin: 0 auto;才是真正的“表格居中”。如果你把text-align: center寫在 table 上可能只會讓里頭的文字居中表格本身沒動。bgcolor和background就更好理解了一個是背景色一個是背景圖現在全部交給 CSS。需要注意bgcolor是寫在 table 上的背景色它會被單元格自身的背景覆蓋。如果只想讓某一行變色不要寫table的 bgcolor應該寫在tr或td上但現代項目里還是建議用 class 控制。2.4 frame 和 rules最容易被忽略的兩個“外行”屬性frame和rules是老版本 HTML 里控制表格邊框顯示規則的屬性現在基本沒人用但老系統里偶爾能看到。frame控制的是表格最外邊這一圈該顯示哪幾條邊取值有void、above、below、hsides、vsides、lhs、rhs、box、border。聽名字就知道它是來描述邊框的“殘缺美”。比如framebelow只顯示表格底邊framevsides只顯示左右兩條豎邊。想用 CSS 實現通常用border-top/bottom/left/right分別控制四條邊或者用偽元素。rules控制的是表格內部的行列分隔線取值有none、groups、rows、cols、all。rulesrows的效果就是只在行與行之間畫線類似常見的數據報表樣式rulescols只在列與列之間畫豎線。現在想實現這個效果用 CSS 給指定的tr或td加border-top或border-left即可可控性高得多。2.5 width 和 height不是不能寫是很容易寫出“迷之行為”width100%寫在 table 上在只有簡單結構的表格里很直觀就是撐滿容器。但 table 的實際寬度由內容、table-layout、單元格寬度共同決定一旦單元格內容過長或過少width不一定是最終結果。CSS 里width也一樣但搭配table-layout使用更可控。height寫在 table 上更不靠譜。table 的高度是自動計算的強行給 table 設定 height未必能讓所有行跟著變高反而可能出現“上下留白”或者“內容頂到最上面”的怪異效果。真需要定高建議把樣式寫在tbody或具體行上或者用 CSS 的min-height做兜底。3. 現代寫法怎么用 CSS 替代 table 的舊屬性我知道很多人不是要考古是真要在項目里寫一個表格。所以這一節直接給“新舊對照方案”把最常用的幾個舊屬性換成現代 CSS。3.1 最常用的屬性替換對照舊屬性老寫法新寫法外框線border1table { border: 1px solid #ccc; }單元格邊框自動由 border 生成th, td { border: 1px solid #ccc; }單元格內邊距cellpadding8th, td { padding: 8px; }單元格間距cellspacing0table { border-collapse: collapse; }表格居中aligncentertable { margin: 0 auto; }表格背景色bgcolor#f5f5f5table { background: #f5f5f5; }表格寬度width100%table { width: 100%; }這里很多人會把padding記成內邊距但寫著寫著就寫到了td上。注意table上的 padding 只對“表格容器”生效不會給每個單元格加內邊距。給單元格加內邊距必須寫在th, td上。cellspacing0對應的新寫法并不是把 padding 設為 0而是用border-collapse: collapse。這個屬性是很多新手第一次做表格時的救星寫完邊框后發現兩條線變粗、中間有縫只要加上這一行瞬間清爽。3.2 一個完整的花式表格示例下面是一個現代寫法的表格包含斑馬紋、懸浮高亮、表頭背景和響應式處理div classtable-wrap table classdemo-table caption2024 年 Q4 銷售統計/caption thead tr th scopecol季度/th th scopecol訂單數/th th scopecol銷售額/th /tr /thead tbody tr tdQ4-10/td td1280/td td586,200/td /tr tr tdQ4-11/td td1420/td td653,300/td /tr tr tdQ4-12/td td1660/td td782,400/td /tr /tbody /table /div.table-wrap { overflow-x: auto; } .demo-table { width: 100%; border-collapse: collapse; background: #fff; } .demo-table caption { text-align: left; padding: 8px; font-weight: bold; } .demo-table th, .demo-table td { border: 1px solid #e0e0e0; padding: 10px 12px; } .demo-table thead th { background: #f2f2f2; } .demo-table tbody tr:hover { background: #fafafa; }這個寫法里沒有border1沒有cellpadding沒有align但效果比老屬性精確得多。border-collapse: collapse讓邊框合攏padding控制內邊距caption替代了summary做表格標題scopecol讓屏幕閱讀器知道表頭是縱向一列還是橫向一行。3.3 響應式表格移動端不要把 table 硬塞進小屏幕移動端最常遇到的場景是一個表格有七八列手機屏幕一窄內容全部擠在一起字都看不清。老屬性里沒有專門解決這個問題的方案現代做法是把 table 放進一個overflow-x: auto的容器里允許橫向滾動而不是強行壓縮列寬。如果數據量不大還可以考慮在窄屏時把每行變成一張“卡片”用 CSSdisplay: block重新組織單元格布局。但這種做法只適合簡單的兩列、三列表格復雜表格還是老老實實橫向滾動。4. 別漏了單元格上的屬性colspan、rowspan、scope 這些怎么用表格體系里光會寫table是不夠的表頭、單元格上的屬性同樣得掌握。colspan和rowspan是高頻考點也是很多人問“table 屬性”時真正想問的東西。colspan寫在td或th上表示這個單元格橫跨幾列。比如商品表里想做一個合并單元格展示“促銷價格”就讓它橫跨兩列table border1 styleborder-collapse: collapse; tr th名稱/th th原價/th th促銷價/th /tr tr td美式咖啡/td td colspan2第二杯半價/td /tr /tablerowspan則表示一個單元格跨幾行常用于合并左側分類欄table border1 styleborder-collapse: collapse; tr td rowspan2咖啡/td td拿鐵/td /tr tr td美式/td /tr /tablescope是給屏幕閱讀器用的寫在th上取值為col、row、colgroup、rowgroup。它告訴讀屏軟件這個表頭是作用于整列還是整行。視覺上無差別但對無障礙體驗非常重要。headers屬性則更進階它通過 id 把單元格和表頭顯式關聯起來適合復雜表頭場景。這些屬性雖然不在table標簽上但只要你寫表格百分之百會用到。不要以為“table 的常見屬性”就只是border和cellpadding真正的實戰里colspan、rowspan才是處理復雜表格的關鍵。5. 常見坑和排查經驗屬性明明寫了卻沒效果這部分是我實際維護老項目時踩過最多的坑。整理成一張速查表遇到問題直接對著查?,F象原因排查方向寫了aligncenter表格沒居中瀏覽器不支持或 CSS 優先級覆蓋了改用 CSSmargin: 0 auto檢查父容器寬度cellspacing0寫了單元格之間還有縫瀏覽器默認邊距或 CSS 里設置了border-spacing檢查border-collapse和border-spacingtable 上下出現一條多余白線table 默認border-collapse: separate加上 border 后會有外框間隙加border-collapse: collapse背景色bgcolor在某個瀏覽器里失效現代瀏覽器對過時屬性兼容性參差不齊換成 CSSbackground-colorwidth100%但表格沒有撐滿table-layout: fixed或單元格內容撐破了檢查table-layout給 td 設置合理寬度屏幕閱讀器讀表格很亂缺少caption、scope或用了過時的summary加caption給th加scope兩個 td 之間的邊框變成 2px默認 border 疊加用 CSSborder-collapse: collapse單獨說兩個高頻問題。5.1 border 寫成 1結果出現“雙倍邊框”這個我真的見太多次了。新手寫border1然后發現單元格之間的線特別粗其實是兩個單元格各自畫了一條 1px 邊框緊挨在一起就變成 2px。解決辦法有兩個老寫法是cellspacing0把單元格間距設為 0新寫法是border-collapse: collapse讓相鄰邊框合并。二選一不要同時糾結。5.2 table 里的圖片或內容把表格撐破有一種情況單元格里放了一張大圖比如img src...圖片寬度 800px父容器只有 600pxtable 直接撐破頁面。這個跟 table 屬性關系不大但會影響你所有的 width 設置。解決辦法是給img設置max-width: 100%或者給table外層加overflow-x: auto。還有一類老代碼喜歡用tableimg srca2 height50 width50/table這種拼接字符串的方式輸出圖片和表格好處是靈活壞處是很容易混入奇怪的屬性、缺少引號久而久之頁面結構就亂了。碰到這種情況優先清理生成邏輯別在屬性堆里打補丁。6. 一個完整的實操案例從“屬性堆疊”改成“現代可維護寫法”最后給一個看得見摸得著的改造案例你可以拿它當模板。老代碼可能是這樣的table width100% border1 cellpadding8 cellspacing0 bgcolor#ffffff aligncenter tr bgcolor#f0f0f0 td姓名/td td部門/td td入職時間/td /tr tr td張三/td td研發/td td2022-03-15/td /tr /table這段代碼不是不能用但 bgcolor、align、cellpadding 全堆在標簽上別人接手根本分不清哪些是業務屬性、哪些是布局屬性?,F代排版方式是拆開HTML 只負責語義CSS 負責樣式。改造后table classstaff-table caption員工列表/caption thead tr th scopecol姓名/th th scopecol部門/th th scopecol入職時間/th /tr /thead tbody tr td張三/td td研發/td td2022-03-15/td /tr /tbody /table.staff-table { width: 100%; border-collapse: collapse; background: #fff; } .staff-table th, .staff-table td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; } .staff-table thead th { background: #f0f0f0; }改造之后功能完全一致但你可以很清楚地給表頭加懸浮效果、給特定列加寬、給特定行高亮不會因為 HTML 里的 bgcolor 和 CSS 背景色互相打架。真要說現代 CSS 比老屬性強在哪就是“職責分離”四個字CSS 可以精確命中任何一行、一列、一個單元格而舊屬性只能做全局粗粒度控制。我個人在實際項目里的經驗是兩類場景會保留舊屬性一類是郵件模板因為 Outlook 這類客戶端的 CSS 支持很玄幻另一類是低代碼平臺導出代碼不得不兼容老引擎。普通網頁項目里凡是遇到bgcolor、cellpadding、align這類屬性直接改成 CSS 是最省心的選擇。如果你還在維護一個 table 鋪滿全站的老系統也不用一夜之間全改掉可以先把新增頁面改成現代寫法老頁面等有 bug 時順手清理。至少下次再看到table border1 cellpadding8 cellspacing0 aligncenter你能一眼看出它在干嘛也知道該往哪個方向改。