为什么这些 HTML 列标题未对齐?

Wit*_*292 14 html css html-table

经过多次试验,我终于想出了相当简单的 HTML,它以我想要的方式显示表格:6 列具有特定宽度,两列右对齐,在固定标题行下滚动。但是,标题与列不太对齐:

HTML表格

如何使标题与数据列完全对齐? 我的在线搜索发现这是一个常见问题,但没有真正的原因解释或已知的简单修复。

我的 HTML 如下。由于最终将显示的数据,列宽是幻数。使标题文本正常而不是粗体,甚至是空标题,对对齐没有影响。

如果除了解决对齐问题之外,您还有更简单的方法来定义具有相同特征的表格,请告诉我。

编辑: box-sizing: border-box;正如 ProllyGeek 推荐的那样,它似乎很有希望,因为它适用于上面的示例数据,但是使用不同的单元格数据仍然会导致对齐稍微偏离,如下所示(价格/下降、下降/描述和项目#/发布的列边框是即使在使用border-box)时也关闭:

用其他数据重试

有数十个甚至数百个帖子想要在可滚动行上添加粘性标题,但显然所有解决方案都避免动态列,通常使用颜色来隐藏对齐问题,或者必须知道表格宽度的封闭 div 以显示正确放置在旁边的滚动条动态列宽。大多数示例忽略列宽,只使用 100% 宽的带有超大列的表格。

对于具有动态列宽(未声明表格宽度)、在可滚动行上、具有精确的标题和列对齐、仅使用纯 CSS/HTML 的粘性标题,似乎没有已知的自动解决方案。

我只是要使用thead { background-color: black; color: white; }.

<style>

table {
    width: 688px; /* 688 = column widths 80 + 56 + 280 + 120 + 56 + 96 */
    table-layout: fixed;
    font: 12px Courier;
    border-collapse: collapse;
}

table, th, td {
  border: 1px solid black;
  padding: 5px;
}

tbody {
  display: block;
  width: 703px; /* 703 = 688 table width + 15 extra for scrollbar */
  overflow-y: scroll;
  height: 65px;
}

thead tr { display: block; } 

tr:nth-child(even) { background-color: #eee; }

th:nth-child(1), td:nth-child(1) {text-align: right; width:  80px; }
th:nth-child(2), td:nth-child(2) {text-align: left;  width:  56px; }
th:nth-child(3), td:nth-child(3) {text-align: left;  width: 280px; }
th:nth-child(4), td:nth-child(4) {text-align: left;  width: 120px; }
th:nth-child(5), td:nth-child(5) {text-align: right; width:  56px; }
th:nth-child(6), td:nth-child(6) {text-align: left;  width:  96px; }

</style>

<table>
  <thead>
    <tr>
      <th>Price</th>
      <th>Drops</th>
      <th>Description</th>
      <th>Category</th>
      <th>Item #</th>
      <th>Posted</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$5.00<td>Oct 10<td>Valuable item<td>Miscellaneous<td>1234<td>Sep 10 2020</tr>
    <tr>
      <td>$5.00<td>Oct 10<td>Valuable item<td>Miscellaneous<td>1234<td>Sep 10 2020</tr>
    <tr>
      <td>$5.00<td>Oct 10<td>Valuable item<td>Miscellaneous<td>1234<td>Sep 10 2020</tr>
    <tr>
      <td>$5.00<td>Oct 10<td>Valuable item<td>Miscellaneous<td>1234<td>Sep 10 2020</tr>
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

joe*_*der 2

这不是解决固定宽度问题的方法,而是朝着您的愿望迈出的一步

粘性标题,具有动态列宽(未声明表格宽度),可滚动行,具有精确的标题和列对齐,仅使用纯 CSS/HTML。

我相信使用动态列宽渲染大型表格会更快, 然后保证标题/列对齐,而且代码不再混乱于幻数。添加滚动需要使用<div>像下面的代码片段这样的封闭。

更新:根据您的评论请求,这里有一个动态表(没有声明列宽),其中一个滚动 div 可以根据需要自动重新定位滚动条。单击“Refill table”按钮生成测试表。

const SCROLLBARWIDTH = 16;

let maxWidth = 5; // initial max width of our dummy strings

function dummyString() {
  return 'x'.repeat(Math.floor((Math.random() * maxWidth)+1)); // dummy data that will tend to widen with each refill
}

function refill() {
  document.getElementById("theBody").innerHTML = '<tr></tr>'; // remove any previous table body
  let tableRef = document.getElementById("theTable"); // our scrollable HTML table that we'll add rows to
  for (let i = 0; i < 20; i++) { // create 20 rows of dummy data
    let newRow = tableRef.insertRow(-1); // add a new row to the table, then set the 6 <td> cells...
    newRow.insertCell(-1).appendChild(document.createTextNode(dummyString())); // price
    newRow.insertCell(-1).appendChild(document.createTextNode(dummyString())); // drops
    newRow.insertCell(-1).appendChild(document.createTextNode(dummyString())); // description
    newRow.insertCell(-1).appendChild(document.createTextNode(dummyString())); // category
    newRow.insertCell(-1).appendChild(document.createTextNode(dummyString())); // item #
    newRow.insertCell(-1).appendChild(document.createTextNode(dummyString())); // posted
    }
  let tableWidth = window.getComputedStyle(tableRef).getPropertyValue('width'); // get resulting dynamic table width
  document.getElementById("container").style.width = parseInt(tableWidth) + 1 + SCROLLBARWIDTH + 'px'; // make scrolling div wide enough
  maxWidth++; // so our next refill will tend to have wider dummy strings
}

refill();
Run Code Online (Sandbox Code Playgroud)
#container { overflow-y: scroll; height: 200px; } /* width to be determined after table filled */

thead th { position: sticky; top: 0; }

table { font: 12px Courier; border-collapse: collapse; }

th { background: black; color: white; } /* hide scrolling behind the header */

table, th, td { border: 1px solid black; padding: 5px; }
Run Code Online (Sandbox Code Playgroud)
<button onclick="refill()">Refill table</button> <!-- click to generate wider table -->

<div id="container">
<table id="theTable">
  <thead>
    <tr>
      <th>Price</th>
      <th>Drops</th>
      <th>Description</th>
      <th>Category</th>
      <th>Item #</th>
      <th>Posted</th>
    </tr>
  </thead>
  <tbody id="theBody">
    <tr>
    </tr>
  </tbody>
</table>
</div>
Run Code Online (Sandbox Code Playgroud)