CSS有父级选择器吗?

4116

如何选择作为锚点元素的直接父级的 <li> 元素?

例如,我的 CSS 如下:

li < a.active {
    property: value;
}

很明显可以用JavaScript做到这一点,但我希望存在CSS Level 2本身的解决方法。

我正在尝试样式化的菜单是由CMS生成的,所以我不能将活动元素移动到<li>元素中...(除非我主题化菜单创建模块,但我宁愿不这样做)。


9
今天发布的 Safari Tech Preview 137 首次引入了 :has() 选择器的实现。 - TylerH
希望有一种与JavaScript el.parenteElement.parenteElement... 一致的工作方式,比如 a:active:parent:parent 或者甚至是 a::active::parent::parent,用两个分号。这不仅更符合现有伪类的逻辑,而且更易于使用和链接,以便在需要时向上多级。我真的希望有这种实现,因为我真的很讨厌使用 :has(something):它既没有逻辑性,也没有直观性和人体工程学可用性。JavaScript 的方式更好,远胜于 :has()。 - willy wonka
截至今天,大多数现代浏览器都支持最新版本,例如:Chrome / Android 浏览器 / Chrome for Android 105+、Edge 105+、Safari / Safari iOS 15.4+ 和 Opera 91+。只有 Firefox 103 至 106 不支持默认功能,您需要启用它。对于移动设备:(Opera mini、Samsung internet 和 Firefox mobile 尚不支持该功能)。 - Abzoozy
1
@Abzoozy 感谢您的更新。为了使您的有用评论更加完善,您能否定义“它”,并说明哪个 Firefox 首选项启用此功能,直到它正式推出? - RockPaperLz- Mask it or Casket
2
现在在Chrome 105中 https://developer.chrome.com/blog/has-m105/ - northamerican
显示剩余6条评论
33个回答

2

没有CSS(也就是CSS预处理器)的父选择器,这是因为“CSS工作组以前拒绝父选择器提案的主要原因与浏览器性能和增量渲染问题有关。”


1
我会雇用一些 JavaScript 代码来实现这个功能。例如,在 React 中,当您遍历一个数组时,可以向父组件添加另一个类,该类表示它包含您的子项:
<div className={`parent ${hasKiddos ? 'has-kiddos' : ''}`}>
    {kiddos.map(kid => <div key={kid.id} />)}
</div>

然后简单地:

.parent {
    color: #000;
}

.parent.has-kiddos {
    color: red;
}

1
这是对一个类似问题的回答(尽管我感觉不完全相同),该问题已被关闭,转而支持此问题,因此我在此处回答如何在输入被选中时更改边框颜色
由于无法使用纯CSS样式化父元素以依赖于其子元素的状态,因此此代码段修改了HTML,使得在输入元素之后紧接着有一个空的span元素。除非输入被悬停,否则此span元素不起作用,此时它会显示自身并扩展到与设置了位置的祖先元素相同大小。这是标签本身,而不是输入。因此,边框(阴影)显示为在标签上。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.OuterField {
  display: flex;
}

.listLabel {
  padding: 8px 5px;
  border: 2px solid black;
  width: 32%;
  margin: 1%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-flow: row;
  position: relative;
}

input[type="radio"]~span {
  display: none;
}

input[type="radio"]:checked~span {
  display: inline-block;
  width: 100%;
  height: 100%;
  border: 2px solid red;
  box-shadow: 0 0 0 3px orange;
  position: absolute;
  top: 0;
  left: 0;
}
<div class="OuterField">
  <label for="List1" class="listLabel">List 1
        <input type="radio" id="List1" name="list" value="List1">
        <span></span>
     </label>
  <label for="List2" class="listLabel">List 2
         <input type="radio" id="List2" name="list" value="List2">
         <span></span>
     </label>
</div>


非常感谢(+1),但如果只有border没有box-shadow,该怎么居中呢?尝试在span标签上更改top: -2pxleft: -2pxwidth: 102%height: 112%。它可以在某些屏幕尺寸上工作,但不会在所有屏幕尺寸上重叠黑色边框。我必须给出绝对值吗?还是有其他方法解决这个问题?再次感谢您的帮助,非常感激。 - Rana
找到了一个解决方法,可能使用 width: calc(100% + 4px); height: calc(100% + 4px);top: -2px left: -2px - Rana
1
很高兴你有一个可行的解决方案。是的,要让一个绝对定位的元素与另一个元素完全重合并得到像细边框这样的精确对齐是很困难的——即使在CSS上完全一致的情况下,底层的屏幕像素可能会显示出来(因为一个CSS像素可能对应几个屏幕像素),所以你的解决方案是实用的。 - A Haworth

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