【问题标题】:Any way to synchronize table column widths with HTML + CSS?有什么方法可以将表格列宽与 HTML + CSS 同步?
【发布时间】:2010-10-02 04:39:49
【问题描述】:

我有许多具有相同列的表,如果它们共享相同的列宽会更好看。这样的事情可能吗?将它们放在同一张表中,其中一些行之间没有边框。

编辑: 是的,我知道我可以自己修复宽度,但我希望有一些可以与浏览器的列宽算法相关联的东西,但只需将两个或多个表绑定在一起即可做那个布局。

我不认为这样的事情是可能的,但我想我会检查一下以防万一。

【问题讨论】:

    标签: html css


    【解决方案1】:

    您可以通过组合表格来同步列宽(如@Stefanvds 建议的那样),但每个表格都使用tbody + th

    table {
      border-collapse: collapse;
    }
    
    table thead,
    table tbody {
      border-bottom: solid;
    }
    
    table tbody th {
      text-align: left;
    }
    <table>
      <thead>
        <tr> <th> ID <th> Measurement <th> Average <th> Maximum
      <tbody>
        <tr> <td> <th scope=rowgroup> Cats <td> <td>
        <tr> <td> 93 <th scope=row> Legs <td> 3.5 <td> 4
        <tr> <td> 10 <th scope=row> Tails <td> 1 <td> 1
      <tbody>
        <tr> <td> <th scope=rowgroup> English speakers <td> <td>
        <tr> <td> 32 <th scope=row> Legs <td> 2.67 <td> 4
        <tr> <td> 35 <th scope=row> Tails <td> 0.33 <td> 1
    </table>

    来源:Example in the HTML spec itself

    【讨论】:

      【解决方案2】:

      最简单的方法是一种“肮脏”的方法,但效果最好。 它完全符合要求:

      只需将您的两张表合并为一张表即可。 就我而言,两张表之间唯一的东西是h3

      所以我的桌子

      <table>
      <tr></tr>
      <table>
      
      <h3>Title<h3>
      
      <table>
      <tr></tr>
      <table>
      

      变成了这样:

      <table>
      <tr></tr>
      
      <tr><td colspan="6">
      <h3>Title<h3>
      </td></tr>
      
      <tr></tr>
      <table>
      

      这样您的表将“同步”它的大小。 当然,这仅在两张表之间没有太多复杂的东西时才有效,但我猜在大多数情况下并非如此。如果是,那么一开始就不需要同步。

      【讨论】:

      • 这是我在少数情况下想出的唯一解决方案。虽然它非常乏味,并且可能会产生一些令人不快的 colspans 以及遇到各种怪癖(也有地狱的边界)。我建议您还添加以使用 tbody、thead、caption 等来改进将表格分解为具有适当样式的替代表格类型。
      • 另外,它还禁止您轻易使用 thead 或 tfoot。此外,这意味着您无法分离内容大小。如果表类型 a 的第一列很长,b 的第一列很短,那么表 b 会很长。这可能会成为另一个 colspan 的噩梦。
      【解决方案3】:

      每对表都将其列的大小调整为相同的宽度
      类似于 Ole J. Helgesen,但使用 jquery 和一个参数来选择哪些表进行均衡。
      (我不能投票,但它本质上是你的解决方案)

      <table data-ss="1" border="1">
        <tr><td>asdf<td>129292<td>text
      </table>
      <table data-ss="1" border=1>
        <tr><td>a<td>1<td>each column here has the same size than the table above
      </table>
      <table data-ss="2" border=1>
        <tr><td>asdf<td>129292<td>text
      </table>
      <table data-ss="2" border=1>
        <tr><td>each column here has the same size than the table above<td>a<td>1
      </table>
      

      并使用这个脚本

      $(function(){
        resizeTables('1');
        resizeTables('2');
      });
      
      //please set table html attribute `data-ss="something"` to properly call this js
      // ss is short for SharedSize
      function resizeTables(sharedSize){
        var tableArr = $('table[data-ss='+sharedSize+']');
        var cellWidths = new Array();
        $(tableArr).each(function() {
          for(j = 0; j < $(this)[0].rows[0].cells.length; j++){
             var cell = $(this)[0].rows[0].cells[j];
             if(!cellWidths[j] || cellWidths[j] < cell.clientWidth) cellWidths[j] = cell.clientWidth;
          }
        });
        $(tableArr).each(function() {
          for(j = 0; j < $(this)[0].rows[0].cells.length; j++){
              $(this)[0].rows[0].cells[j].style.width = cellWidths[j]+'px';
          }
        });
      }
      

      【讨论】:

        【解决方案4】:

        Luis Siquot 的答案是我使用的答案。但是,您应该使用 jquery width() 函数来规范浏览器之间的宽度,而不是使用 clientWidth,而不是计算填充。由于填充(如果在 TD 中使用填充),使用 clientWidth 会导致表格单元格在 ajaxpostbacks 上扩展。 因此,使用 Luis Siquot 答案的正确代码是替换

        var cell = $(this)[0].rows[0].cells[j];
               if(!cellWidths[j] || cellWidths[j] < cell.clientWidth) cellWidths[j] = cell.clientWidth;
        

        var cell = $($(this)[0].rows[0].cells[j]);
                    if (!cellWidths[j] || cellWidths[j] < cell.width()) cellWidths[j] = cell.width();   
        

        【讨论】:

          【解决方案5】:

          只有在您可以固定列宽的情况下才有可能。如果你可以设置一个固定的宽度,那么像这样的一些 css 应该可以工作:

          td {
              width: 25%;
          }
          

          您可以像这样自定义每个列的宽度:

          <table>
            <tr>
              <td class="col1">...</td>
              <td class="col2">...</td>
            </tr>
          </table>
          ...
          <table>
            <tr>
              <td class="col1">...</td>
              <td class="col2">...</td>
            </tr>
          </table>
          

          然后像这样指定宽度:

          .col1 {
             width: 25%;
          }
          .col2 {
             width: 75%;
          }
          

          【讨论】:

          • 错误,不,这不是唯一的方法。请看我的回答!
          【解决方案6】:

          如果您对浏览器提供的列宽不太挑剔,只要它们在不同的表格中相同,您可以结合使用 CSS table-layout 属性(所有主流浏览器都支持)表格宽度:

          table {
              table-layout: fixed;
              width: 100%;
          }
          

          这会导致所有列(没有指定宽度)具有相同的宽度,而与表格内容无关。

          【讨论】:

          • ...代价是使列太窄,以至于当视口的宽度很窄或有足够的列需要水平滚动时,甚至一个单词都不能在单元格中呈现而不会溢出对吧?
          • 这取决于你表的内容,不是吗?如果这就是你得到的,那么这显然不是最好的解决方案。但是您也可以将此解决方案与其他一些解决方案结合使用。 IE。使用table-layout: fixed 并在某些列/单元格上设置固定宽度。
          【解决方案7】:

          我几乎惊呆了,没有人建议column groups!使用它,您可以为列指定特定的类、宽度和其他有用的属性。由于它是 HTML 4.01,所有支持该文档类型的浏览器都支持它。

          【讨论】:

          • 我相信 IE 不支持 colgroups,不是吗?
          • 也许我遗漏了一些东西,但是 colgroups 如何真正帮助解决这个问题?
          • 据我所知,IE 支持 colgroups。作为标准的一部分,它们应该是……但 IE 团队认为它们很特别。
          • Cletus:如果有统一的列数,则可以将 colgroup 应用于所有相关表。如果您愿意,甚至可以使用 javascript。
          • 但这只是固定所有表格/列的宽度的另一种变体,是吗?
          【解决方案8】:

          这是我制作的一个小 JavaScript,用于调整单元格的大小以使它们在页面上的所有表格中的宽度相等。

          function resizeTables()
          {
              var tableArr = document.getElementsByTagName('table');
              var cellWidths = new Array();
          
              // get widest
              for(i = 0; i < tableArr.length; i++)
              {
                  for(j = 0; j < tableArr[i].rows[0].cells.length; j++)
                  {
                     var cell = tableArr[i].rows[0].cells[j];
          
                     if(!cellWidths[j] || cellWidths[j] < cell.clientWidth)
                          cellWidths[j] = cell.clientWidth;
                  }
              }
          
              // set all columns to the widest width found
              for(i = 0; i < tableArr.length; i++)
              {
                  for(j = 0; j < tableArr[i].rows[0].cells.length; j++)
                  {
                      tableArr[i].rows[0].cells[j].style.width = cellWidths[j]+'px';
                  }
              }
          }
          
          window.onload = resizeTables;
          

          【讨论】:

            【解决方案9】:

            要扩展 Ken 的答案,您还可以指定确切的宽度(以像素为单位):

            td { width: 250px }
            

            或ems(字母m的宽度):

            td { width: 32em }
            

            或 ex 或 pt 或其他任何东西(嗯...实际上 %, pt, px, em, ex 可能是它)。如果你需要你的列是不同的宽度,那么简单的方法是给表格单元格类:

            <table><tr>
                <td class="col1">...</td><td class="col2">...</td>...
            </tr></table>
            

            并为类分配列宽:

            td.col1 { width: 48em }
            td.col2 { width: 200px }
            ...
            

            将列宽分配给每个表格的第一行就足够了。 [编辑:看起来我在写作的时候已经被人发现了]

            你也可以对 CSS 2 同级选择器发疯,写出类似的东西

            tr > td:first-child { width:48em } /* first column */
            tr > td:first-child + td { width: 200px } /* second column */
            tr > td:first-child + td + td { width: 5% } /* third column  */
            ...
            

            但如果您有多个列,那可能会变得很难看。如果您使用某种模板系统或脚本来生成这些表格,我相信只需将 class="col#" 属性放在模板中的每个单元格上一次会更容易/更清晰。

            【讨论】:

            • 我认为一些浏览器不支持同级选择器。可能不支持 IE6,甚至 IE7。
            • 是的,它适用于遵循 W3C CSS 标准的浏览器。 IE6 和 7 一般不遵循标准,但 IE8 可能。 (当然,Firefox 和大多数小型浏览器都会这样做。)
            • 相邻兄弟选择器和 :first-child 伪类在 IE7 中有效;不在IE6中。但我认为这是您可以放弃 IE6 的主要示例,除非您特别需要支持 IE6(例如在 Intranet 上)。没有它,什么都不会破裂。它只是看起来不太好。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-14
            • 2011-10-05
            • 1970-01-01
            • 2012-09-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多