【问题标题】:Latest on CSS parent selector [duplicate]最新的 CSS 父选择器 [重复]
【发布时间】:2015-03-14 23:55:10
【问题描述】:

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

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

父选择器发生了什么?它会被引入,还是被移除?

【问题讨论】:

  • 我只是在需要选择器的少数情况下使用 jQuery。 $(this).parent().addClass('parent');我知道在 css-tricks 上,他们说 css 父选择器存在巨大的性能问题。
  • 我不确定这是怎么重复的,但是除了浏览器供应商之外,任何人都无法客观地回答这个问题的“有人知道是否以及何时”部分,这导致了一个问题潜在的权威答案,或者一个非常脆弱的答案。也就是说,我发布了针对第一部分的答案。
  • @chipChocolate.py 没问怎么伪造效果,所以看不出这是怎么复制的。
  • @BoltClock 公平点,我希望得到权威的答案。
  • 我试图让您的问题更接地气,更适合该网站。至少可以说,这个特定功能的开发历史很有趣,我很高兴有人实际上发布了与调查相关的问题。

标签: css css-selectors


【解决方案1】:

根据Wikipedia

选择器无法上升

CSS 目前无法选择满足特定条件的元素的父级或祖先。 CSS Selectors Level 4 仍处于工作草案状态,提出了这样一个选择器,但只是作为“完整”选择器配置文件的一部分,而不是动态 CSS 样式中使用的“快速”配置文件。更高级的选择器方案(例如 XPath)将支持更复杂的样式表。 CSS 工作组之前拒绝父选择器提案的主要原因与浏览器性能和增量渲染问题有关。

至于 when 选择器级别 4 将被引入,不过……嗯,这取决于主要浏览器何时实现对它的支持。当足够多的用户升级到这些浏览器版本时。

编辑:更多信息请参见this answer

【讨论】:

    【解决方案2】:

    调查的高潮是主题选择器(所谓的“父选择器”的专有名称)被更通用的:has() 伪类所取代,该伪类被记录在here 中(带有一个有趣的锚名称,#relational,我想知道这是否会坚持)。

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


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

    作为一个例子,这使得如下的选择器在理论上是可能的:

    /* 
     * 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 */
    

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

    【讨论】:

    • 应该叫三角形选择器
    【解决方案3】:

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

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

    有两种实现方式(均显示) 第一个是伪类 :parent 这只能在本地样式表上完成,因为某些浏览器的“不允许错误的伪类”。

    另一个是遍历所有样式表检查“GetParent 类引用”。

    对我来说它有效。我一般拿第一个,这是最快的。

    解决方案:

    $(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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-18
      • 2012-04-05
      • 2011-10-15
      • 1970-01-01
      • 2014-10-15
      • 2016-11-10
      • 1970-01-01
      相关资源
      最近更新 更多