折叠的 <table /> 列留下了可见的痕迹

Mar*_*tin 5 css visibility html-table col colgroup

根据文档,我们可以visibility: collapse<col />元素上使用来折叠或折叠所有关联的列。

但是(在 Chrome 和 Edge 中)我注意到一些元素仍然可见,漂浮在折叠列将占据的区域的某个位置。我可以将其范围缩小到带有position: absolute或 的元素position: relative。这似乎是 Chrome 和 Edge 中的一个错误(均显示此行为)。在 Firefox 中,不会留下意外可见的痕迹。

const toggle = () => {
  const table = document.querySelector("#my-table");
  table.classList.toggle("collapsed");
};
Run Code Online (Sandbox Code Playgroud)
.table.collapsed .collapsible-column {
  visibility: collapse;
}

.oops {
  position: relative;
}
Run Code Online (Sandbox Code Playgroud)
<table id="my-table" class="table">
  <colgroup>
    <col span="2" class="collapsible-column" />
    <col span="2" class="static-column" />
  </colgroup>
  <thead>
    <tr>
      <th scope="col">col 1<br /><span class="oops">oops</span></th>
      <th scope="col">col 2</th>
      <th scope="col">col 3</th>
      <th scope="col">col 4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>cell 1,1</td><td>cell 2,1</td><td>cell 3,1</td><td>cell 4,1</td>
    </tr>
    <tr>
      <td>cell 1,2</td>
      <td>cell 2,2<br /><span class="oops">oops</span></td>
      <td>cell 3,2</td>
      <td>cell 4,2</td>
    </tr>
  </tbody>
</table>

<button onclick="toggle()">toggle columns</button>
Run Code Online (Sandbox Code Playgroud)

这是已知的错误或限制吗?你知道有什么解决方法吗?如何确保在折叠列时也隐藏这些元素?

附录:迄今为止发现的解决方法

  • 表格单元格中的内容overflow: hidden不会从折叠列中泄漏

    th, td { overflow: hidden; }
    
    Run Code Online (Sandbox Code Playgroud)

    但这只有在所有内容都始终保留在单元格边界内时才可行,并且对于我的用例来说毫无用处,因为我的用例涉及需要在单元格边界之外绘制的绝对定位下拉列表。只要单元格与过孔交互,我们就可以启用可见的溢出:hover:focus-within但这不是一个干净的解决方案,也不是无懈可击的:当焦点位于单元格内时列折叠时,相应的内容仍然会泄漏。

    th:focus-within, th:hover, td:focus-within, td:hover { overflow: visible; }
    
    Run Code Online (Sandbox Code Playgroud)
  • 我们可以.collapsible-cell向属于可折叠栏的所有单元添加类,并相应地显式切换其内容的可见性。但这种方法违背了可见性功能的目的<col />,需要更改标记,并在单元格标记和 colgroup 定义之间创建显式依赖关系。

    .table.collapsed .collapsible-cell > * { display: none; }
    
    Run Code Online (Sandbox Code Playgroud)

jer*_*nis 0

visibility: collapse;只适用于表格元素

在 Firefox 上, td 元素内的元素看起来被隐式地视为 table 元素的一部分

在 Chrome 和 Edge 中,情况并非如此,position: relative“打破”这种考虑并使 .oops 不被视为表格元素

一种解决方法是显式设置 .oops 到位置table-rowtable-cell让此行为在所有浏览器上运行

  .oops {
      position: table-cell;
    }
Run Code Online (Sandbox Code Playgroud)

  .oops {
      position: table-cell;
    }
Run Code Online (Sandbox Code Playgroud)
const toggle = () => {
  const table = document.querySelector("#my-table");
  table.classList.toggle("collapsed");
};
Run Code Online (Sandbox Code Playgroud)
.table.collapsed .collapsible-column {
  visibility: collapse;
}

.oops {
  position: table-cell;
}
Run Code Online (Sandbox Code Playgroud)

如果你想在 chrome 和 Edge 浏览器上保持position:relative,你将不得不使用display: none隐藏非表格元素

<table id="my-table" class="table">
  <colgroup>
    <col span="2" class="collapsible-column" />
    <col span="2" class="static-column" />
  </colgroup>
  <thead>
    <tr>
      <th scope="col">col 1<br /><span class="oops">oops</span></th>
      <th scope="col">col 2</th>
      <th scope="col">col 3</th>
      <th scope="col">col 4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>cell 1,1</td>
      <td>cell 2,1</td>
      <td>cell 3,1</td>
      <td>cell 4,1</td>
    </tr>
    <tr>
      <td>cell 1,2</td>
      <td>cell 2,2<br /><span class="oops">oops</span></td>
      <td>cell 3,2</td>
      <td>cell 4,2</td>
    </tr>
  </tbody>
</table>

<button onclick="toggle()">toggle columns</button>
Run Code Online (Sandbox Code Playgroud)
const toggle = () => {
  const table = document.querySelector("#my-table");
  table.classList.toggle("collapsed");
};
Run Code Online (Sandbox Code Playgroud)
.table.collapsed .collapsible-column {
  visibility: collapse;
}

.oops {
  position: relative;
}

.collapsed .oops {
  display: none;
}
Run Code Online (Sandbox Code Playgroud)