Reputation: 43589
I have a generic layout component that needs to lay out its children with a vertical space between them:
.container > * + * {
margin-top: 1rem;
}
For reasons I won't go into, I can't guarantee the order the component styles are loaded in.
If a child component has had a reset to its margins applied, for example …
.child {
margin: 0
}
… and it is loaded after the .container
css, its styled will win out because a wildcard selector has no specificity, meaning both declarations are of equal weight (so the last declaration will win).
I don't want the container to know or care about what its children are (and I don't want to add a specific class to all the children).
Is there any way to increase the specificity of the first selector while leaving it generic (so it applies to any children).
Upvotes: 2
Views: 180
Reputation: 723448
A more elegant alternative (i.e. one that comes with the additional specificity you need without requiring specificity hacks) is
.container > :not(:first-child)
which is functionally equivalent to your original selector, with a specificity of (0, 2, 0) over the original's (0, 1, 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>
Upvotes: 2
Reputation: 28722
By adding the selector
.container > * + [class]
You can get a more specific selector it seems for the margin rule.
You can also use the :not() rule as suggested by Temani Afif
.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>
Upvotes: 1