This question already has answers here:
Select first Descendant with CSS
(5 answers)
Closed 2 years ago.
I don't have control of the html structure, so for example if I have this structure:
<body>
<div class="red"> <------ style this
<div>content</div>
<div class="red">
<div>
<div class="red">content</div>
</div>
</div>
</div>
</body>
I want to style only the first decendant with the red class..
:not(.red) > * > .red {
background: red;
}
<div class="red">
<div>red</div>
<div class="red">
<div>
<div class="red">red</div>
</div>
</div>
</div>
I have tried following this answer https://stackoverflow.com/a/12922863/2894798 with no results if you inspect the dom in my example you will see that the second decendant with the red class, also has the red style..
Do note that I am trying to select first decendant not first sibling
First you target all elements that have the .red class. Then you unset it from all childs having also this class.
.red {
background: red;
}
.red .red {
background: none;
}
You can use > CSS selector to target only first element without overwriting any properties.
body > .red { border: 1px solid red; }
div { padding: 5px; }
body > .red { border: 1px solid red; }
<body>
<div class="red"> style this
<div>content</div>
<div class="red">
<div>
<div class="red">content</div>
</div>
</div>
</div>
</body>
Related
This question already has answers here:
Is there a "previous sibling" selector?
(30 answers)
CSS: Select element only if a later sibling exists
(9 answers)
Closed 4 days ago.
I have some html like this -
<div class="parentdiv">
<div class="div1"></div>
<div class="div2"></div>
<div>
i want to apply red color to div1 if div2 exists else apply yellow -
.div1 {
color:red;
}
.div1 {
color:yellow;
}
How can i do it via CSS only? I know we have the sibling selectors but there is no previous sibling selector and in my case i'm looking for something similar - :has does not have support for all browsers.
My answer is based on my interpretation of your requirement:
If .div1 is followed by .div2, then .div1 should be red
Otherwise .div1 should be yellow
You can do that with CSS only, but with the pre-requisite that the browser supports the modern :has selector:
.div1 {
color: yellow;
}
/* Style div1 separately if it is followed immediately by .div2 */
.div1:has(+ .div2) {
color: red;
}
This will work for any for the following scenarios:
<div>
<div class="div1"></div><!-- Appears red -->
<div class="div2"></div>
</div>
<div>
<div class="div1"></div><!-- Appears yellow -->
</div>
<div>
<div>Any dummy element before</div>
<div class="div1"></div><!-- Appears red -->
<div class="div2"></div>
<div>Any dummy element after</div>
</div>
<div>
<div>Any dummy element before</div>
<div class="div1"></div><!-- Appears yellow -->
<div>Any dummy element after</div>
</div>
See proof-of-concept below:
.div1 {
color: yellow;
}
.div1:has(+ .div2) {
color: red;
}
/* START: For presentation only */
.parentdiv {
background-color: #333;
color: #fff;
padding: 1rem;
margin: 1rem;
}
/* END: For presentation only */
<div class="parentdiv">
<div class="div1">div1</div><!-- Appears red -->
<div class="div2">div2</div>
</div>
<div class="parentdiv">
<div class="div1">div1</div><!-- Appears yellow -->
</div>
<div class="parentdiv">
<div>Any dummy element before</div>
<div class="div1">div1</div><!-- Appears red -->
<div class="div2">div2</div>
<div>Any dummy element after</div>
</div>
<div class="parentdiv">
<div>Any dummy element before</div>
<div class="div1">div1</div><!-- Appears yellow -->
<div>Any dummy element after</div>
</div>
If you do not want to use :has, you can use the :only-child solution but this only works if .div1 is the ONLY child of the element. This will not work if you have arbitrary DOM elements occurring before .div1 or after .div2:
.div1 {
color: red;
}
.div1:only-child {
color: yellow;
}
/* START: For presentation only */
.parentdiv {
background-color: #333;
color: #fff;
padding: 1rem;
}
/* END: For presentation only */
<div class="parentdiv">
<div class="div1">div1</div>
<div class="div2">div2</div>
</div>
<hr />
<div class="parentdiv">
<div class="div1">div1</div>
</div>
I have layout that is generated dynamically so order of elements could change. Each element that is part of this layout has its own different class. I want to be able to select element of certain class but only if it is last child of its parent to apply styling. If element with different class is last child of its parent, it should not be selected. Is it possible to have this kind of scss selector and achieve this functionality without using javascript?
Example:
<div class="parent">
<div class="child1">Hello!</div>
<div class="child2">Hello!</div>
<div class="child3">Hello!</div>
</div>
I want to select element with class child3 only if it is last child of div with class parent.
So if child2 class element is last child of div class parent it is not selected, for example here:
<div class="parent">
<div class="child1">Hello!</div>
<div class="child3">Hello!</div>
<div class="child2">Hello!</div>
</div>
Yes, and this is the normal CSS behaviour. You can do something like this:
.parent .child3:last-child {}
This is a rule that selects:
a .child3 element inside .parent.
.child3 element comes as the last, there's no other elements after that including text.
For SCSS, you can do something like this:
.parent {
.child3 {
&:last-child {
// Rules.
}
}
}
Example Snippet
.parent .child3:last-child {
background: #ccf;
}
<strong>Trial 1</strong>
<div class="parent">
<div class="child1">Hello!</div>
<div class="child2">Hello!</div>
<div class="child3">Hello!</div>
</div>
<hr />
<strong>Trial 2</strong>
<div class="parent">
<div class="child1">Hello!</div>
<div class="child3">Hello!</div>
<div class="child2">Hello!</div>
</div>
Preview
You can select elements by their attributes, so something like this would achieve your goal.
.parent div {
width: 50px;
height: 50px;
background-color: blue;
border: solid 1px black;
}
.parent div:last-of-type[class="child3"] {
background-color: red;
}
<div class="parent">
<div class="child1">Hello!</div>
<div class="child3">Hello!</div>
<div class="child2">Hello!</div>
</div>
<div class="parent">
<div class="child1">Hello!</div>
<div class="child2">Hello!</div>
<div class="child3">Hello!</div>
</div>
https://www.w3schools.com/cssref/css_selectors.asp
This question already has answers here:
CSS negation pseudo-class :not() for parent/ancestor elements
(2 answers)
Closed 4 years ago.
Check this code below:
.aaa :not(.bbb) .ccc {
font-size: 20px;
color: #FF0000;
}
<div class="aaa">
<div>
<div>
<div class="bbb">
<div>
<div>
<div class="ccc">AQUI</div>
</div>
</div>
</div>
</div>
</div>
</div>
I want to match all .ccc element that are children of .aaa but are not children of .bbb. It means that the code above should NOT make the AQUI word be RED, but it gets RED anyway. What am I doing wrong?
There are actually elements which are not .bbb - the two divs before and after .bbb in this case. For this to work, you'll need to be more specific. You can add another class (zzz in the example), and if this class is not combined with .bbb the rule will be applied.
.aaa .zzz:not(.bbb) .ccc {
font-size: 20px;
color: #FF0000;
}
<div class="aaa">
<div>
<div>
<div class="zzz bbb">
<div>
<div>
<div class="ccc">AQUI</div>
</div>
</div>
</div>
</div>
</div>
</div>
The not(.bbb) will match any div without the class .bbb and you have a lot of them between .aaa and .ccc that why the text is red. To do what you want you need to consider two selectors
.aaa .ccc {
font-size: 20px;
color: #FF0000;
}
/*we reset the style if children of .bbb*/
.bbb .ccc {
color: initial;
font-size:initial;
}
<div class="aaa">
<div>
<div>
<div class="bbb">
<div>
<div>
<div class="ccc">AQUI</div>
</div>
</div>
</div>
</div>
</div>
</div>
You have overlooked that the .ccc is a child of components that match :not(.bbb):
<div class="aaa">
<div class="ccc"></div>
<div class="bbb">
<div> // <-- :not(.bbb)
<div class="ccc"></div>
</div>
</div>
</div>
You need to write two rules:
.aaa .ccc {
color: blue;
}
.aaa .bbb .ccc {
color: red;
}
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>
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>