【问题标题】:CSS selector for something not inside something elseCSS 选择器用于不在其他东西中的东西
【发布时间】:2015-07-07 12:18:40
【问题描述】:

我有一些这样的嵌套元素:

<div class="foo">
    <div class="select-inside-this">
        <div class="not-inside-this">
            <div class="one select-this"></div>
        </div>
    </div>
</div>
<div class="select-inside-this">
    <div class="two select-this"></div>
</div>
<div class="three select-this"></div>

我想选择.select-inside-this 中的所有.select-this,但不选择.not-inside-this 中的所有.select-this。所以最后,我应该只能从上面的代码中选择two.select-this。 我尝试过但不起作用的 CSS:

.select-inside-this :not(.not-inside-this) .select-this {
    /* style here /*
}

或:

.select-inside-this *:not(.not-inside-this) .select-this {
    /* style here /*
}

这里有什么解决方法吗?

我不想在这里使用 JavaScript。我需要纯 CSS3 解决方案。

编辑:我不想使用直接子 (&gt;) 选择器。正如我所问的,我想在没有异常包装器的情况下从任何级别选择所有这些元素。

【问题讨论】:

  • 这里不能使用.select-inside-this :not(.not-inside-this) .select-this来选择需要的.two.select-this元素的原因是:not(.not-inside-this)仍然需要匹配一个元素才能让整个选择器匹配(只要any 元素 not 具有某种特征)——但在 .select-inside-this.select-this 之间没有任何元素可以满足这一点,因此整个选择器 不能匹配这个元素。
  • 这是有道理的。但是为什么.select-inside-this *:not(.not-inside-this) .select-this doesn't 工作?
  • 因为基本上是一样的东西。 *:not():not(),没有任何区别,都选择 具有指定特征的 any 元素。

标签: html css css-selectors


【解决方案1】:

:not(.not-inside-this)*:not(.not-inside-this)* 是等价的;在前者的情况下,隐含了通用选择器。请参阅spec

由于以下问题中给出的原因,目前不可能构造一个 CSS 选择器来匹配 不是特定元素的后代的元素:

选择器

.select-inside-this :not(.not-inside-this) .select-this

匹配.select-this元素一些元素的后代不是.not-inside-this,而后者又是.select-inside-this的后代。它确实匹配.select-this元素不是.select-inside-this.not-inside-this的后代

这意味着,首先,您的选择器将错误地匹配以下内容:

<div class="select-inside-this">
    <div class="bar">
        <div class="not-inside-this">
            <div class="select-this"></div>
        </div>
    </div>
</div>

...因为.select-this 的祖先之一.bar:not(.not-inside-this)

此外,这意味着至少有三层嵌套(尽管可能更多)。在您的示例中,.two.select-this 与其包含的.select-inside-this 之间没有其他元素,因此它永远不会匹配该元素。这就是为什么 James Donnelly 建议添加 .select-inside-this &gt; .select-this 来解决这种特殊情况。

但是,仍然不可能使用后代组合器编写单个复杂选择器来匹配没有特定祖先的元素。 唯一的方法是根据需要使用尽可能多的:not(.not-inside-this) 重复子组合器方法,但这需要您考虑所有可能的情况。如果你不能做到这一点,那么你对 CSS 选择器就不走运了。

【讨论】:

  • @Abram:我的回答一开始并没有描述解决方案,所以我不太理解你所说的不起作用。
【解决方案2】:

您可以使用Child Combinator Selector &gt; 指定直接子代:

.select-inside-this :not(.not-inside-this) .select-this,
.select-inside-this > .select-this {
    /* style here /*
}

这会选择不是任何.not-inside-this 元素的后代的任何.select-this 元素,还会选择.select-this 元素,它们是.select-inside-this 元素的直接子元素。

body > .select-inside-this :not(.not-inside-this) .select-this,
body > .select-inside-this > .select-this {
  color: red;
}
<div class="foo">
    <div class="select-inside-this">
        <div class="not-inside-this">
            <div class="one select-this">
                This should not be selected
            </div>
        </div>
    </div>
</div>
<div class="select-inside-this">
    <div class="two select-this">
        This should be selected
    </div>
</div>
<div class="three select-this">
    This should not be selected
</div>

【讨论】:

  • 我知道我可以做到。但我真正需要的是从祖先中选择。这就是我问这个问题的原因;)
【解决方案3】:

聚会晚了一点,它可能与您的用例不匹配,但这是我最终做的:

HTML:

<div class="foo">
    <div class="select-inside-this">
        <div class="not-inside-this">
            <div class="one select-this"></div>
        </div>
    </div>
</div>
<div class="select-inside-this">
    <div class="two select-this"></div>
</div>
<div class="three select-this"></div>

CSS:

.select-inside-this .select-this {
    background: blue;
}
.select-inside-this .not-inside-this .select-this {
    background: none;
}

诀窍是积极选择否定元素并撤消样式。

它至少适用于简单的用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-08
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多