根据悬停的子元素设置不同的父元素样式 | CSS

Posted

技术标签:

【中文标题】根据悬停的子元素设置不同的父元素样式 | CSS【英文标题】:Style parent element differently depending on which child element is hovered | CSS 【发布时间】:2021-03-02 09:06:00 【问题描述】:

我正在部分使用解决方案来解决不久前提出的this 问题。

我说 部分 因为这个解决方案似乎只有在你想基于 one 子元素设置父元素 one 的样式时才有效.当您有两个或多个子元素(元素)时,如下所示,并且您希望第一个子元素为父元素设置一种颜色,而第二个子元素为父元素设置另一种颜色;使用pointer-events 似乎失败了。

在下面的 gif 中,head 很好地悬停,因为子元素选择了它后面的 table 父元素并为背景的一部分着色以匹配它的颜色。然而,所有其他元素( bodyfoot )在悬停时看起来都不一致。什么是唯一的 CSS 解决方案?

注意 bodyfoot 元素如何无法更改 table 背景以匹配其颜色。期望的行为是悬停在顶部的 head 元素的行为。

悬停在孩子们身上:

thead th:first-child, tbody td:first-child 
  border-top-left-radius: 1rem;

thead th:last-child, tbody td:last-child 
  border-top-right-radius: 1rem;

tbody td:first-child, tfoot td:first-child 
  border-bottom-left-radius: 1rem;

tbody td:last-child, tfoot td:last-child 
  border-bottom-right-radius: 1rem;

thead th 
  background-color: #666;

tbody td 
  background-color: #aaa;

tfoot td 
  background-color: #eee;

thead th:hover 
  background-color: #333;

tbody td:hover 
  background-color: #888;

tfoot td:hover 
  background-color: #ccc;
<style>
  html, body 
    margin: 0;
    padding: 0;
    font-family: Arial;
    font-size: 1.22rem;
    text-align: center;
  
  table, th, td 
    padding: 1rem;
    border-spacing: 0;
    pointer-events: auto;
  
  table 
    width: 10rem;
    margin: auto;
    padding: 0;
    background-image: linear-gradient( 
      transparent 20%, #666 20% 46.5%, #eee 46.5% 70%, transparent 70% 100%
    );  
    pointer-events: none;
    
  table:hover 
    background-image: linear-gradient( 
      transparent 20%, #333 20% 46.5%, #eee 46.5% 70%, transparent 70% 100%
    );  
    
</style>
<table>
  <thead> <tr> <th>head</th> </tr> </thead>
  <tbody> <tr> <td>body</td> </tr> </tbody>
  <tfoot> <tr> <td>foot</td> </tr> </tfoot>
</table>

编辑:我保持代码简短,以便更容易看到发生了什么。如果我以错误的方式解决这个问题并且他们是一种更简单的方法(比如重新排列我的 HTML 并更改我的所有 CSS)以获得所需的结果;我也对此持开放态度。

【问题讨论】:

【参考方案1】:

提供父表overflow: hidden,删除所有pointer-event 样式并在悬停时在表格单元格本身上使用box-shadow 似乎可以解决所有问题。

thead th:first-child, tbody td:first-child 
  border-top-left-radius: 1rem;

thead th:last-child, tbody td:last-child 
  border-top-right-radius: 1rem;

tbody td:first-child, tfoot td:first-child 
  border-bottom-left-radius: 1rem;

tbody td:last-child, tfoot td:last-child 
  border-bottom-right-radius: 1rem;

thead th 
  background-color: #666;
  position: relative;

tbody td 
  background-color: #aaa;
  position: relative;

tfoot td 
  background-color: #eee;

thead th:hover 
  background-color: #333;

tbody td:hover 
  background-color: #888;

tfoot td:hover 
  background-color: #ccc;
<style>
  html, body 
    margin: 0; padding: 0;
    font-family: Arial; font-size: 1.22rem;
    text-align: center;
  
  table, th, td 
    padding: 1rem;
    border-spacing: 0;
  
  table 
    overflow: hidden;
    width: 10rem;
    margin: auto;
    padding: 0;
    background-image: linear-gradient( 
      transparent 20%, #666 20% 46.5%, #eee 46.5% 70%, transparent 70% 100%
    );  
    
  table:hover 
    background-image: linear-gradient( 
      transparent 20%, #666 20% 46.5%, #eee 46.5% 70%, transparent 70% 100%
    );  
    
  thead th:hover  box-shadow: #333 0 0.75rem 0 0.25rem;   
  tbody td:hover  box-shadow: #666 0 -0.75rem 0 0.25rem; 
  tfoot td:hover  box-shadow: #ccc 0 -0.75rem 0 0.25rem;   
</style>
<table>
  <thead> <tr> <th>head</th> </tr> </thead>
  <tbody> <tr> <td>body</td> </tr> </tbody>
  <tfoot> <tr> <td>foot</td> </tr> </tfoot>
</table>

【讨论】:

以上是关于根据悬停的子元素设置不同的父元素样式 | CSS的主要内容,如果未能解决你的问题,请参考以下文章

如何将鼠标悬停在子元素上而不悬停在 CSS 中的父元素上?

根据子元素将CSS样式应用于元素[重复]

CSS父元素的子元素样式控制另一子元素怎么实现?

css里怎么去掉从父级元素继承下来的 css 样式吗

CSS减轻父鼠标悬停的子元素

不能为 Label 元素的子元素设置样式