Multiple descendant children selector with css [duplicate] - css

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;
}

Related

Override a CSS Style for previous sibling using CSS only [duplicate]

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>

select first decendant with class [duplicate]

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>

Is there a CSS selector for all grandchildren except first?

In this JSFiddle, how can I style all <a> elements except the first grandchild? (abc) with a single selector? I want to avoid using two rules at all costs.
#outer a:not(:first-child){
color: red;
}
<div id="outer">
<div id="firstParent">
<a>abc</a>
<a>def</a>
<a>hij</a>
</div>
<div id="secondParent">
<a>klm</a>
<a>opq</a>
</div>
</div>
You can do this (not sure if you can avoid more than 1 selector)
#outer >div:first-child a:not(:first-child),
#outer >div:not(:first-child) a{
color: red;
border:1px solid;
}
<div id="outer">
<div id="firstParent">
<a>abc</a>
<a>def</a>
<a>hij</a>
</div>
<div id="secondParent">
<a>klm</a>
<a>opq</a>
</div>
</div>
One rule 2 selectors:
a ~ a The general sibling combinator covers any <a> that follows another <a>. This basically selects all but the first <a> of sibling <a>.
div:nth-of-type(n+2) a This targets all <a> inside the second div and any preceding sibling divs in the future🟊.
Demo
a~a,
div:nth-of-type(n+2) a {
color: red
}
<div id="outer">
<div id="firstParent">
<a>abc</a>
<a>def</a>
<a>hij</a>
</div>
<div id="secondParent">
<a>klm</a>
<a>opq</a>
</div>
</div>
🟊 Props to Temani Afif for suggesting (n+2).
This works, not exactly sure why!
#outer :not(:first-child) {
color: red;
}
<div id="outer">
<div id="firstParent">
<a>abc</a>
<a>def</a>
<a>hij</a>
</div>
<div id="secondParent">
<a>klm</a>
<a>opq</a>
</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>

What is the difference between > and space in css selector [duplicate]

This question already has answers here:
CSS Child vs Descendant selectors
(8 answers)
Closed 9 years ago.
I've seen two example,
.someclass > .inner{...}
and
.someclass .inner{...}
works the same way. Is there are any difference between them which i'm not seeing?
The first applies only to immediate children. The second, to any descendant.
So given this CSS:
.someclass > .inner { color: red }
.someclass .inner { font-weight: bold }
the following applies:
<div class="someclass">
<div class="inner">
Bold and red
</div>
<div>
<div class="inner">
Just bold.
</div>
</div>
</div>
.someclass>.inner {
color: red
}
.someclass .inner {
font-weight: bold
}
<div class="someclass">
<div class="inner">
Bold and red
</div>
<div>
<div class="inner">
Just bold.
</div>
</div>
</div>
.someclass > .inner{...}
- only apply to ".inner" that are direct children to ".someclass".
.someclass .inner{...} - applies to any ".inner" that are inside ".someclass", even if there are elements between them.

Resources