Universal Selector with Descendent Selector Specificity - css

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).

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>

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>

Related

select the last two rows in container [duplicate]

This question already has answers here:
What does the ">" (greater-than sign) CSS selector mean?
(8 answers)
Closed 3 years ago.
Im trying to select the last two div's with class row in my container div
I have tried this code
.child1 {
padding: 5px;
background-color: red;
margin: 5px;
width: 30%;
}
.parent .child :nth-last-child(-n+2) {
background-color: green;
}
<div class="parent">
<div class="child">
<div class="child1">test1</div>
<div class="child1">test2</div>
<div class="child1">test3</div>
<div class="child1">
test4
<div class="child2">test42</div>
</div>
<div class="child1">test5</div>
<div class="child1">test6</div>
</div>
</div>
Im expecting that the backgrounds of test5 and test6 is going to be green.
The problem is the background of test42 is also comming green.
Use the child combinator > to only target direct children:
.child1 {
padding: 5px;
background-color: red;
margin: 5px;
width: 30%;
}
.parent .child>:nth-last-child(-n+2) {
background-color: green;
}
<div class="parent">
<div class="child">
<div class="child1">test1</div>
<div class="child1">test2</div>
<div class="child1">test3</div>
<div class="child1">
test4
<div class="child2">test42</div>
</div>
<div class="child1">test5</div>
<div class="child1">test6</div>
</div>
</div>

Create a different background colour for each flex box item

My site uses wordpress and toolset, basically, the below code returns a flexbox that has three items within it. Each of those items background colour needs to be different.
I'm unsure on the approach, but research points to something like using, but localizing it to just the flex box, not site wide. Could I request some direction ideas?
div:nth-child(1) {
background: gray;
}
div:nth-child(2) {
background: red;
}
div:nth-child(3) {
background: cyan;
}
CODE BLOCK
[wpv-layout-start]
[wpv-items-found]
<div class="row flexbox-wrap">
<!-- wpv-loop-start -->
<wpv-loop>
<div class="col-md-4 flexbox-equalise">
<article class="well well-equal">
<h4>[wpv-post-title]</h4>
<p>[wpv-post-excerpt output="raw"]</p>
<p class="lead">[wpv-woo-product-price]</p>
<div class="well-actions">
[wpv-woo-buy-or-select add_to_cart_text="Join now!" class="btn-block"]
</div>
</article>
</div>
</wpv-loop>
<!-- wpv-loop-end -->
</div>
[/wpv-items-found]
[wpv-no-items-found]
<strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong>
[/wpv-no-items-found]
[wpv-layout-end]
CSS
.flexbox-equalise .well { position: relative; padding-bottom: 76px; }
.flexbox-equalise .well .well-actions { position: absolute; bottom: 0; left: 0; right: 0; padding: 16px; }
Based on the assumption that the loop creates 3 <div class="col-md-4 flexbox-equalise"> siblings, you can use the nth-child selector like this:
.flexbox-equalise:nth-child(1) { background: red; }
.flexbox-equalise:nth-child(2) { background: yellow; }
.flexbox-equalise:nth-child(3) { background: green; }
This selector will target any element having the class flexbox-equalise and being sibling nr 1-3
You can narrow this down further by e.g. adding .flexbox-wrap class to the selector, like this:
.flexbox-wrap > .flexbox-equalise:nth-child(n) { ... }
This selector will target any element having the class flexbox-equalise, being a child of flexbox-wrap and sibling nr 1-3.
Stack snippet
.flexbox-equalise:nth-child(1) {
background: red;
}
.flexbox-equalise:nth-child(2) {
background: yellow;
}
.flexbox-equalise:nth-child(3) {
background: green;
}
<div class="row flexbox-wrap">
<div class="col-md-4 flexbox-equalise">
<article class="well well-equal">
<h4>[wpv-post-title]</h4>
<p>[wpv-post-excerpt output="raw"]</p>
<p class="lead">[wpv-woo-product-price]</p>
<div class="well-actions">
"Join now!"
</div>
</article>
</div>
<div class="col-md-4 flexbox-equalise">
<article class="well well-equal">
<h4>[wpv-post-title]</h4>
<p>[wpv-post-excerpt output="raw"]</p>
<p class="lead">[wpv-woo-product-price]</p>
<div class="well-actions">
"Join now!"
</div>
</article>
</div>
<div class="col-md-4 flexbox-equalise">
<article class="well well-equal">
<h4>[wpv-post-title]</h4>
<p>[wpv-post-excerpt output="raw"]</p>
<p class="lead">[wpv-woo-product-price]</p>
<div class="well-actions">
"Join now!"
</div>
</article>
</div>
</div>

CSS and first-child

In CSS, I select "first-child". I want only <div class="b">1</div> on red background. I don't understand
div {
height: 50px;
margin-bottom: 10px
}
.a .b:first-child {
background: red
}
<div class="a">
<div class="b">1</div>
<div class="c">
<div class="b">2</div>
<div class="b">3</div>
<div class="b">4</div>
</div>
</div>
.a .b:first-child means any .b:first-child that is a descendant of .a. Space is the descendant combinator; it doesn't link :first-child to .a in any way.
You want a direct child of .a, using the child combinator: .a > .b.
I think you want your first-child pseudo-class on .a, not .b.
div {
height: 50px;
margin-bottom: 10px
}
.a:first-child {
background: red
}
<div class="a">
<div class="b">1</div>
<div class="c">
<div class="b">2</div>
<div class="b">3</div>
<div class="b">4</div>
</div>
</div>

css find closest item

I have a nested structure that contains the same elements. To only target the elements within the current set I do something like this:
.set1 > .content > .trigger {
background: red;
}
In real life this selector has much more elements. While it works, if I change the name or depth on one of the elements it will no longer work.
Is there a way to just find the .trigger (in this case) of the current set?
<div class="set set1">
<div class="content">
<div class="trigger"></div>
<div class="set set2">
<div class="content">
<div class="trigger"></div>
</div>
<div>
</div>
<div>
You can apply a style on all triggers inside the current set and then remove the style for the other triggers that comes after the first trigger.
div {
padding: 5px;
border: 1px solid;
}
.set1 .trigger {
background: red;
}
.set1 .trigger ~ .set .trigger {
background: none;
}
<div class="set set1">
<div class="content">
<div class="trigger"></div>
<div class="set set2">
<div class="content">
<div class="trigger"></div>
</div>
</div>
</div>
</div>

Target element if it is the first element inside a div

Given the following, is there a way to target an element ONLY if it is an h3 AND it is positioned immediately inside the parent?
<style>
h3:first-of-type { color: #f00; }
</style>
Example a)
<div class="mydiv">
<h3 class="tobetargeted"></h3>
</div>
Example b)
<div class="mydiv">
<p></p>
<h3 class="nottobetargeted"></h3>
</div>
Neither first-of-type or first-child will work because in both cases, the h3 element evaluates to true. What I want is for Example a) to be true but Example b) to be false.
So... IF the element is an H3 AND it is the first element immediately inside the parent.
Any ideas?
:first-child should definitely work out for you.
.test {
border: 1px solid black;
margin: 0 0 10px;
}
.test h3:first-child {
color: red;
}
<div class="test">
<h3>H3 - should be red</h3>
</div>
<div class="test">
<p>p</p>
<h3>H3 - should be black</h3>
</div>
Use this
h3:nth-child(1) { color: #f00; }
h3:nth-child(1) { color: #f00; }
<div class="mydiv">
<h3 class="tobetargeted">Hello</h3>
</div>
<div class="mydiv">
<p></p>
<h3 class="nottobetargeted">Hello</h3>
</div>

Resources