想象一下下面的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>
显然不是这样,因为我没有正确选择:
不是[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;
}
从好的方面来说,这确实有效。(所以,比我以前拥有的任何东西都要好得多(。
在减号方面:
- 很啰嗦
- 它不优雅
- 它仅适用于元素嵌套的第四级
- 我当然可以继续添加关卡,但这只会使它更冗长和不优雅
这是一项教育活动。
它教会我的最重要的事情是,鉴于: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
,它的直系父母也没有......这足以满足 CSS 规则中p
之前的任何后代选择器(即[SPACE]
(:
: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>
看:
.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
得出以下结论:
我们只能在CSS 中显式描述HTML 结构时使用
:not()
来排除后代。
我现在更清楚地理解@G-Cyrillus
的意思:
您还需要注意结构
后续步骤:
在我的 CSS 中描述无限数量的潜在后代结构显然是不切实际的,所以我:
1(重新配置了我的架构,以允许在其他地方描述更复杂的后代关系
和
2( 优化了我的排除查询,以:
body > :not([id^="filter-"]):not([class^="filter-"])
再次非常感谢,@G-Cyrillus
- 由于您在评论部分的大量帮助,我只做到了这一点。