在CSS中,我如何可以选择那些不是*容器元素的后裔的元素,这些元素的类符合一个可识别的模式?

问题描述 投票:1回答:1

想象一下,下面的HTML和CSS已经设置好了。

我可以在已经写好的CSS下面添加什么CSS规则来使红色段落显示为红色?

body,
div {
  display: flex;
  flex-wrap: wrap;
}

p {
  margin: 6px;
}

.one-filter-one p,
p[class^="one-filter-one"] {
  color: blue;
}

.two-filter-two p,
p[class^="two-filter-two"] {
  color: green;
}

.four-filter-four p,
p[class^="four-filter-four"] {
  color: orange;
}
<p class="another-class">This is red.</p>
<p>This is red.</p>

<div class="one-filter-one">
  <p>This is blue.</p>
  <p class="one-filter-one--paragraph">This is blue.</p>
</div>

<p class="two-filter-two">This is green.</p> 

<p>This is red.</p> 
<p class="another-class-two">This is red.</p>

<div class="three-filter-three">
  <p>This is unstyled (black).</p>
  <div><p>This is unstyled (black) too.</p></div> 
</div>

<div class="four-filter-four">
  <p class="four-filter-four--sentence">This is orange.</p>
</div>
  
<p class="five-filter-five">This is also unstyled (black).</p>

<div class="another-class-three">
  <p>This is red.</p>
  <p class="another-class-four">This is red.</p>
</div>

我最好的猜测是使用 :not() 伪类。

但我并不完全相信这是个正确的方法,主要是因为我不确定 :not() 可以处理这种情况。

我的解决方案的尝试,使用 :not():

body,
div {
  display: flex;
  flex-wrap: wrap;
}

p {
  margin: 6px;
}

.one-filter-one p,
p[class^="one-filter-one"] {
  color: blue;
}

.two-filter-two p,
p[class^="two-filter-two"] {
  color: green;
}

.four-filter-four p,
p[class^="four-filter-four"] {
  color: orange;
}

p:not([class*="-filter-"]) {
  color: red;
}
<p class="another-class">This is red.</p>
<p>This is red.</p>

<div class="one-filter-one">
  <p>This is blue.</p>
  <p class="one-filter-one--paragraph">This is blue.</p>
</div>

<p class="two-filter-two">This is green.</p> 

<p>This is red.</p> 
<p class="another-class-two">This is red.</p>

<div class="three-filter-three">
  <p>This is unstyled (black).</p>
  <div><p>This is unstyled (black) too.</p></div> 
</div>

<div class="four-filter-four">
  <p class="four-filter-four--sentence">This is orange.</p> </div>
  
<p class="five-filter-five">This is also unstyled (black).</p>

<div class="another-class-three">
  <p>This is red.</p>
  <p class="another-class-four">This is red.</p>
</div>

显然不是这样的,因为我没有正确选择。

NOT 子孙 的元素 [class*="-filter-"].

但我根本不清楚如何做到这一点。

有没有什么方法可以做到这一点,还是说以CSS的当代能力,我想在2020年实现不可能的事情?


笔记。

虽然,在2020年,伪类... ... :not() 已经存在了十年之久,我总是倾向于避免使用它。我唯一知道的是 :not() 伪类函数只能接受简单的(即不是复合)选择器。


新增。

基于 @G-Cyrillus的绝妙建议(在下面的评论中),我提出了以下建议。

body > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > :not([class*="-filter-"]) > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]),
body > :not([class*="-filter-"]) > :not([class*="-filter-"]) > :not([class*="-filter-"]) > :not([class*="-filter-"]) > p:not([id*="-filter-"]):not([class*="-filter-"]) {
  color: red;
}

从好的方面来说 是否 工作。所以,比我之前的任何东西都要无限好)。

在不利的一面。

  • 它的啰嗦
  • 拗口
  • 它只适用于第四级元素嵌套。
  • 当然,我可以继续增加等级,但这只会让它变得更啰嗦,更不容易。
css css-selectors pseudo-class
1个回答
1
投票

这是一次教育活动。

它给我的最重要的启示是,鉴于 :not() 不能接受 复合选择器但要想处理好后续的工作,却远非易事。嵌套式标注 申请后 :not().

鉴于以下情况:

.filter-1 {
  color: red;
}

:not([class^="filter-"]) p {
  color: blue;
}
<div>
  <div>
    <p>Test.</p>
  </div>
</div>

<div class="filter-1">
  <div>
    <p>Test.</p>
  </div>
</div>

第二个 <p> 出现 blue.

为什么呢?因为即使它的祖父母有类。.filter-1其直系亲属 ......这就足够满足了。任何后代选择器 (即 [SPACE])前面的 p 在CSS规则中。

:not([class^="filter-"]) p

唯一的办法就是把这条规则替换成:

:not([class^="filter-"]) > * > p

这样就可以了

.filter-1 {
  color: red;
}

:not([class^="filter-"]) > * > p {
  color: blue;
}
<div>
  <div>
    <p>Test.</p>
  </div>
</div>

<div class="filter-1">
  <div>
    <p>Test.</p>
  </div>
</div>

但是...

CSS规则现在是 严丝合缝 的HTML结构,上述修改后的CSS规则现在将不适用于。

<div class="filter-2">
  <p>Test.</p>
</div>

See:

.filter-1 {
  color: red;
}

:not([class^="filter-"]) > * > p {
  color: blue;
}
<div>
  <div>
    <p>Test.</p>
  </div>
</div>

<div class="filter-1">
  <div>
    <p>Test.</p>
  </div>
</div>

<div class="filter-2">
  <p>Test.</p>
</div>

相反,我们现在需要使用 两则:

:not([class^="filter-"]) > p,
:not([class^="filter-"]) > * > p

得出以下结论。

我们可以 只是 使用 :not() 排除后代,当我们还 明确 描写 HTML结构 在CSS中。

我现在更清楚地明白了什么是 @G-Cyrillus 的意思。

你也要注意结构


接下来的步骤。

在我的CSS中描述无限数量的潜在子代结构显然是不切实际的,所以我已经:

1) 重新配置我的架构,允许更复杂的... 世系 另文所述

2)将我的排除查询优化为。

body > :not([id^="filter-"]):not([class^="filter-"])

再次感谢你 @G-Cyrillus - 由于你在评论区的大力协助,我才走到这一步。

© www.soinside.com 2019 - 2024. All rights reserved.