我有一个通用的布局组件,该组件需要对其子级进行布局,并在它们之间设置垂直空间:
.container > * + * {
margin-top: 1rem;
}
出于我不愿讨论的原因,我不能保证组件样式的加载顺序。
如果子组件已重置为应用其边距,例如……
.child {
margin: 0
}
…并且它在.container
CSS之后加载,其样式将获胜,因为通配符选择器没有特异性,这意味着两个声明的权重相等(因此最后一个声明将获胜)。
我不想让容器知道或关心它的子代是什么(并且我不想为所有子代添加特定的类)。
有什么方法可以提高第一个选择器的特异性,同时保持其通用性(因此适用于所有子代)。
答案 0 :(得分:2)
一种更优雅的替代方法(即,无需特定的hack即可带来所需的附加特异性)
.container > :not(:first-child)
在功能上等同于原始选择器,与原始选择器的(0,1,0)相比具有(0,2,0)的特异性。
.container {
margin: 1rem 0;
border-style: solid;
}
/* 1 class, 1 pseudo-class -> specificity = (0, 2, 0) */
.container > :not(:first-child) {
margin-top: 1rem;
}
/* 1 class -> specificity = (0, 1, 0) */
.child {
margin: 0;
}
<div class="container">
<div class="child">Child</div>
<div class="child">Child</div>
<div class="child">Child</div>
</div>
<div class="container">
<div class="child">Child</div>
<div class="child">Child</div>
<div class="child">Child</div>
</div>
答案 1 :(得分:1)
通过添加选择器
.container > * + [class]
您可以为边距规则找到一个更具体的选择器。
您还可以按照Temani Afif
的建议使用:not()规则。
.container, .container2, .container3 {
background-color: goldenrod;
border: 1px solid black;
display: block;
margin-bottom:50px;
}
.container > * + * {
margin-top: 1rem;
}
.container2 > * + *,
.container2 > * + [class] {
margin-top: 1rem;
}
.container3:not(#doyoudreamofelectricsheep) > * + * {
margin-top: 1rem;
}
.child {
margin: 0;
height: 20px;
background-color:red;
color: black;
}
.foobar {
height: 20px;
background-color:black;
color: white;
}
Without the "fix"
<section class="container2">
<div class="foobar">
foobar
</div>
<div class="child">
child
</div>
<div class="foobar">
foobar
</div>
<div class="child">
child
</div>
<div class="foobar">
foobar
</div>
<div class>
just class
</div>
</section>
With the [class] "fix"
<section class="container2">
<div class="foobar">
foobar
</div>
<div class="child">
child
</div>
<div class="foobar">
foobar
</div>
<div class="child">
child
</div>
<div class="foobar">
foobar
</div>
<div class>
just class
</div>
</section>
With the :not(#doyoudreamofelectricsheep) "fix"
<section class="container3">
<div class="foobar">
foobar
</div>
<div class="child">
child
</div>
<div class="foobar">
foobar
</div>
<div class="child">
child
</div>
<div class="foobar">
foobar
</div>
<div class>
just class
</div>
</section>