在鼠标悬停时给HTML表格边框着色

3

当我悬停在上时,我希望它的顶部和底部边框改变颜色。 我遇到的问题是,在悬停的上方的覆盖了悬停样式(至少我认为是这样)。

在我的示例中,第一个项目正确地悬停,但在第二个和第三个项目中,只有底部边框突出显示:

table {
  border-collapse: collapse;
}

th {
  background-color: rgb(231, 231, 231);
}

td {
  border-bottom: 2px solid rgb(214, 214, 214);
  border-top: 2px solid rgb(214, 214, 214);
}

table tr:hover td {
  border-bottom: 2px solid red;
  border-top: 2px solid red;
}
<table>
  <tr>
    <th>COMPANY</th>
    <th>CONTACT</th>
    <th>COUNTRY</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
</table>


5
你在打破边界,但仍希望看到它们? - mplungjan
border-collapse: collapse有一个复杂的算法来决定显示哪个边框。详情请参阅官方文档 - AlexP
1
合并边框具有规则来确定哪个边框是显示的边框。尝试使用 border-spacing:0 而不是 border-collapse,看看是否更好。 - Niet the Dark Absol
好的,我明白。border-spacing: 0让表格看起来相当丑陋,这仍然很糟糕。 - Frank
4个回答

7
如果您想保留 2 像素边框,您需要取消合并并删除边框填充。然后,您可以使用兄弟选择器在悬停时更改正确的边框。在下面的代码中,我只是添加了 thead 和 tbody 元素到您的表格中,以便我们知道仅当鼠标悬停在其上时,body 元素将会发生变化。

table {
 border-spacing:0;
}

th {
  background-color: rgb(231, 231, 231);
}

td {
  border-top: 2px solid rgb(214, 214, 214); /* make all cells have a top border */
}

tbody tr:last-child td {
  border-bottom: 2px solid rgb(214, 214, 214);  /* make the last row also have a bottom border */ 
}

tbody tr:hover td {
  border-color: red;    /* change all borders to red on hover (mainly because of the last child bottom border */
}

tbody tr:hover + tr td {
  border-top-color: red;  /* change any cells without a bottom border - make the next row have top border go red (so it looks like current row bottom border) */
}
<table>
<thead>
  <tr>
    <th>COMPANY</th>
    <th>CONTACT</th>
    <th>COUNTRY</th>
  </tr>
</thead>
<tbody>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
</tbody>
</table>


太牛了!做得好,谢谢你!请问您能否解释一下最后那个类 tbody tr:hover + tr td 是什么意思呢?我不是很明白这个 CSS 如何改变其他东西。 - Frank
我认为你不需要在这里使用tbody和thead。 - Frank
嗨@Frank,tbody并不是必需的,但它只是为了确保如果您在标题中有任何普通的td单元格,它们不会被样式化。选择器基本上是选择直接下一个兄弟tr的任何td(加号表示下一个兄弟)的td。 - Pete
我明白了!好的,感谢你的回答和教我新东西 :) - Frank

3

如果不使用折叠,这是我能得到的最接近的结果,而您的问题正是这个。

  • 边框间距:0;
  • 上下边框:1像素而不是2像素;

table {
   border-spacing:0;
}

th {
  background-color: rgb(231, 231, 231);
}

td {
  border-bottom: 1px solid rgb(214, 214, 214);
  border-top: 1px solid rgb(214, 214, 214);
}

table tr:hover td {
  border-bottom: 1px solid red;
  border-top: 1px solid red;
}
<table>
  <tr>
    <th>COMPANY</th>
    <th>CONTACT</th>
    <th>COUNTRY</th>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
</table>


我理解为什么这个有效,但我希望有一个不同的答案。 - Frank

0

另一个选择“可能”是使用:before或:after!

其中一个主要好处是它不像边框那样改变盒子的大小。

这里是一个例子:

table tr {
    position: relative;
}

table tr:before {
    position: absolute;
    top: 0;
    left: 0;
    content: "";
    width: 100%;
    height: 2px;
    background: red;
}

“content”属性是必须的,以便能够生成元素,但字符串可以为空(特别是当您想将此元素用作图形hack时)。

编辑-我忘记明确悬停状态:

table tr:hover:before {
    background: blue;
}

注意::before 会自动放置在父元素内容的最前面,而 :after 则会放置在父元素标签关闭之前。


0

只需删除 border-collapse: collapse;,然后添加 border-spacing:0


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接