带有边框半径和粘性标题的 HTML 表格

问题描述 投票:0回答:5

我有一个带有

<table>
的 HTML
border-radius
和使用
position: sticky
的粘性标题,如下所示:

https://codepen.io/muhammadrehansaeed/pen/OJpeeKP

但是,当使用粘性标题滚动时,表格行会伸出粘性标题的圆角所在的位置。请参阅此图片的左上角:

有没有办法可以在使用粘性标题向下滚动时保持圆角,或者在标题变得粘性并从原始位置向下移动时删除粘性标题?理想情况下,我想要一个CSS解决方案。

html css html-table css-position sticky
5个回答
5
投票

您可以使用伪元素隐藏边框的某些部分:

table thead th:first-child::before, 
table thead th:last-child::after {
    width: 1px;
    height: 5px;
    background: white;
    content: "";
    display: block;
    position: absolute;
    top: 0px;
}
table thead th:first-child::before {
    left: -1px;
}
table thead th:last-child::after {
    right: -1px;
}

3
投票

正如Ivan建议的那样,似乎使用伪元素来覆盖标题下方不需要的边框是(令人惊讶的)唯一可行的选择。我建议使用伪不仅用于覆盖“外部”区域,而且还用于绘制弧线和填充“内部”区域。可以使用堆叠背景来做到这一点。应用于原始代码:

/* 
§ Additions / Changes
*/
table thead th {
  position: relative;
}

/* Pseudos exceeding header boundary by border width; with rectangle covering half circle and rest of height */

table thead th:last-child::after,
table thead th:first-child::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-1 * var(--global-border-width-1));
  width: var(--global-border-radius);
  background-image:
    linear-gradient(to bottom, 
      transparent var(--global-border-radius),
      var(--global-title-color) 0),
    radial-gradient(circle at var(--global-border-radius) var(--global-border-radius),
      var(--global-title-color) var(--global-border-radius),
      var(--global-content-background-color) 0);
  background-position: top left;
  background-size:
    var(--global-border-diameter) 100%,
    var(--global-border-diameter) var(--global-border-diameter);
  background-repeat: no-repeat;
}

table thead th:last-child::after {
  left: auto;
  right: calc(-1 * var(--global-border-width-1));
  background-position: top right;
}

/*
§ Declarations and original style
*/

html {
  --global-content-background-color: white;
  --global-title-color: black;
  --global-background-color: lightblue;
  --global-border-color: black;
  --global-border-radius: 20px;
  --global-border-width-1: 10px;
  --global-space-fixed-2: 10px;
  --global-space-fixed-3: 15px;
  --global-border-diameter: calc(2 * var(--global-border-radius));
  background-color: var(--global-content-background-color);
}

table {
  color: var(--global-title-color);
  background-color: var(--global-content-background-color);
  border-collapse: separate;
  border-color: var(--global-title-color);
  border-style: solid;
  border-radius: var(--global-border-radius);
  border-width: 0 var(--global-border-width-1) var(--global-border-width-1) var(--global-border-width-1);
  border-spacing: 0;
  width: 100%;
}

table thead {
  position: sticky;
  top: 0;
  z-index: 10;
}

table thead th {
  color: var(--global-background-color);
  background-color: var(--global-title-color);
  padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
  vertical-align: bottom;
}

table tbody td {
  border-top: var(--global-border-width-1) solid var(--global-border-color);
  padding: var(--global-space-fixed-2) var(--global-space-fixed-3);
  vertical-align: top;
}

table tbody tr:last-child td:first-child {
  border-bottom-left-radius: var(--global-border-radius);
}

table tbody tr:last-child td:last-child {
  border-bottom-right-radius: var(--global-border-radius);
}

/*
§ Unrelated / demo
*/

* {
  scroll-margin-top: calc(var(--global-space-fixed-2) * 4 + 1rem);
  /* = height of sticky thead + top padding of cell, provided text in thead does not wrap */
  scroll-margin-bottom: 1em;
}

td {
  height: 60vh;
}

td a {
  float: right
}

tr:last-child td {
  vertical-align: bottom;
}

a[name]:empty::before {
  content: attr(name);
}

th:not(#\0):hover::before {
  background-image: linear-gradient(to bottom, transparent var(--global-border-radius), #0F08 0), radial-gradient(circle at center, #00F8 var(--global-border-radius), #F2F4 0);
  background-position: top left;
  background-size: var(--global-border-diameter) 100%, var(--global-border-diameter) var(--global-border-diameter);
}
<table>
  <thead>
    <tr>
      <th>Fake non-transparent "border-radius"</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <a href="#⬆️" name="⬇️"></a> For fixed header</td>
    </tr>
    <tr>
      <td>
        <a href="#⬇️" name="⬆️"></a> Using CSS stacked background images in pseudo elements</td>
    </tr>
  </tbody>
</table>


0
投票

只需从表格中删除边框,并为表格主体中的第一个和最后一个表格单元格添加左右边框:

tbody td:first-child {
  border-left: 1px solid black;
}
tbody td:last-child {
  border-right: 1px solid black;
}
tbody tr:last-child td{
  border-bottom: 1px solid black;
}
tbody tr:last-child td:first-child {
  border-bottom-left-radius: 2px;
}
tbody tr:last-child td:last-child {
  border-bottom-right-radius: 2px;
}

当然是使用适当的缩进、嵌套和变量!

使用许多伪选择器看起来样式相当丑陋,但似乎可以解决您的问题。


0
投票

有一个更紧凑的解决方案。只需将具有背景颜色的框阴影添加到第一个 < th > 和最后一个 < th > 即可隐藏元素。

在此示例中,在右侧,您可以看到表格行由于边框半径而可见。在左边,我应用了盒子阴影。

盒子阴影:0 -2.1rem 0 .6rem #E5E7EB;

在这里,它是灰色的,以便您可以看到它的工作原理,但您只需使用与背景相同的颜色即可使其完全不可见。

这是最终结果以及我正在使用的代码:

th:第一个孩子 { 边界半径:0.75rem 0 0 0; 左边框:.1rem 实心 $color-gray-200; 框阴影:0 -2.1rem 0 .6rem $color-gray-200; }

th:最后一个孩子{ 边界半径:0 0.75rem 0 0; 右边框:.1rem 实心 $color-gray-200; 盒子阴影:1rem -2.1rem 0 .6rem $颜色白色; }

可能需要调整框阴影以隐藏基于所选边框半径的行。


-1
投票

不确定你是否熟悉jquery,如果熟悉的话你可以在滚动内容时动态更改 border-top-left-radius: 等于粘性标题的半径,但这对于新手来说有点棘手jquery/JS。

其次,您可以将粘性标题封闭到父级(例如

class="parent")
),并将父级背景设置为白色,没有边框。并保持粘性标题的边框半径不变。因此,当您滚动内容时将位于该父级下方(例如
class="parent"
)。为了确保父级出现在该行上方,您可以给出
z-index: 10

© www.soinside.com 2019 - 2024. All rights reserved.