CSS 父级选择器的最新信息

Latest on CSS parent selector

我能找到的关于此的最新信息是 W3C Selectors Level 4 Editor’s Draft,但据我所知,它不再提及父选择器。

我知道有一个Google survey about this,但现在已经结束了。

父选择器怎么了?它会被引入,还是已经被删除?

根据Wikipedia

Selectors are unable to ascend

CSS currently offers no way to select a parent or ancestor of an element that satisfies certain criteria. CSS Selectors Level 4, which is still in Working Draft status, proposes such a selector, but only as part of the “complete” selector profile, not the “fast” profile used in dynamic CSS styling. A more advanced selector scheme (such as XPath) would enable more sophisticated style sheets. The major reasons for the CSS Working Group previously rejecting proposals for parent selectors are related to browser performance and incremental rendering issues.

至于什么时候 Selectors Level 4 会被引入,虽然...好吧,这取决于主要浏览器何时实现对它的支持。当足够多的用户升级到这些浏览器版本时。

编辑:有关详细信息,请参阅this answer

调查最终导致主题选择器(所谓的“父选择器”的专有名称)被更通用的 :has() 伪 class 取代,记录在案 here(有一个有趣的锚名称,#relational,我想知道它是否会坚持下去)。

可能只有当此功能的规范更加稳定时才会实现。目前,随着诸如用伪 class 完全替换主题选择器这样的破坏性变化,我不指望它很快就会发生。也就是说,:has() 伪 class 很可能会坚持下去,但由于其性质,它是否可以在 CSS 中实施还有待观察。请参阅 this section of the same draft 了解实施配置文件。


:has() 更通用的原因是,对于主题选择器,在任何草案中都没有明确说明单个复杂选择器是否可以有多个主题选择器(因为单个复杂选择器可以只有一个主题)and/or 如果 :matches() 等功能性伪 class 接受了主题选择器。但是因为伪 class 是一个简单的选择器,它适合现有的选择器语法,并且您可以可靠地假设 :has() 将在任何接受伪 class 的地方被接受。

例如,这使得如下选择器在理论上完全可行:

/* 
 * Select any p
 * that is a sibling of a ul
 * that has more than one li child.
 */
ul:has(> li:nth-of-type(2)) ~ p,     /* p follows ul */
p:has(~ ul:has(> li:nth-of-type(2))) /* p precedes ul */

然而,使用主题选择器,这只有在 :matches() 接受主题选择器的情况下才有可能,这从未在规范中直接说明:

ul:matches(! > li:nth-of-type(2)) ~ p, /* p follows ul */
!p ~ ul:matches(! > li:nth-of-type(2)) /* p precedes ul */

您还可以在这里看到为什么我不喜欢任何一种选择器形式的名称“父选择器”——它可以用于更多

好吧,在 css 中没有父选择器。但是由于一个小技巧,我可以使用 .childinternal :parent { 背景色:黄色 } 在我的本地 CSS 文件中,无需深入 jquery 或 javascript.

这个技巧有点脏,因为它改变了父元素的样式(这不是 CSS 所做的)并且不是真正的伪 class。 但是在您的 css 样式表中,您可以照原样使用它。

有两种实现方式(均已显示) 第一个是伪 class :parent 这只能在本地样式表上完成,因为某些浏览器的 'dont allow bad psuedos'。

另一个是遍历所有样式表以检查 'GetParent class reference'。

对我来说很管用。我一般拿第一个,这个最快。

解决方案:

$(function() {

  //First possibility when using local css file (=faster)//

  $.when($.get("your local filename.css")).done(function(response) {
    var spl = response.split(":parent");
    if (spl.length > 1) {
      var clas = $.trim((spl[0].split("}")[spl[0].split("}").length - 1]).replace(String.fromCharCode(10), '').replace(String.fromCharCode(13), ''));
      var cs = $.trim((spl[1].split("}")[0].split("{")[1]).replace(String.fromCharCode(10), '').replace(String.fromCharCode(13), ''));
      var eClas = $(clas).parent().attr('style');
      eClas = eClas == undefined ? '' : (eClas + '').toString;
      $(clas).parent().attr('style', eClas + ';' + cs);
    }
  });
});

// second possibility looping all used css files

for (var s = document.styleSheets.length - 1; s >= 0; s--) {
  var cssRules = document.styleSheets[s].cssRules || document.styleSheets[s].rules || []; // IE support
  for (var c = 0; c < cssRules.length; c++) {
    if (cssRules[c].selectorText) {
      if (cssRules[c].selectorText.indexOf('.GetParent') > -1) {
        var spl = cssRules[c].cssText.split(".GetParent");
        if (spl.length > 1) {
          var clas = $.trim((spl[0].split("}")[spl[0].split("}").length - 1]).replace(String.fromCharCode(10), '').replace(String.fromCharCode(13), ''));
          var cs = $.trim((spl[1].split("}")[0].split("{")[1]).replace(String.fromCharCode(10), '').replace(String.fromCharCode(13), ''));
          var eClas = $(clas).parent().attr('style');
          eClas = eClas == undefined ? '' : (eClas + '').toString;
          $(clas).parent().attr('style', eClas + ';' + cs);
        }
      }
    }
  }
}
.childinternal :parent {
  background-color: yellow
}

.childexternal .GetParent {
  Background-color: green
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  Not affected Main parent
  <div class="childinternal">
    <p>Not affected parent (no parent selector)</p>
  </div>
  <div class="childinternal:parent">
    <p>local css file used (:parent selector)
      <span style='color:grey;font-size:0.6em'>Only works on local files so not possible to show in this snippet
      </span>
    </p>
  </div>
</div>

<div>
  <div class="childexternal .GetParent">
    <p>external css file used (.GetParent class selector)</p>
    <div class="x"></div>
  </div>
</div>