Is there a CSS selector for all grandchildren except first? - css

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>

Related

Select a div that contains a div having specific attribute value or class [duplicate]

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 2 months ago.
I want to select a div that contains another div with specific class or specific attribute value. I have tried these: (but it selects the child not the parent/container)
div div[data-value="hi"]
div>div[data-value="hi"]
div div.any
div>div.any
(example) the one with attribute value:
<div>
<div data-value="hi">example</div>
</div>
(example) or the one below with class:
<div>
<div class="any">example</div>
</div>
Please do not suggest nth-child as their will be couple of div and div position is random as the below example:
<div>
<div class="other">example</div>
</div>
<div>
<div class="any">example</div>
</div>
<div>
<div class="other">example</div>
</div>
<div>
<div class="other">example</div>
</div>
Please let me know if it even possible with only CSS, Thank you for your help.
If I've understood correctly and you want to target the PARENT should it contain a child with a given class or attribute, then you want the :has pseudo-selector. Note, that it isn't available in all browsers/versions yet but has good availability see: Can I Use :has selector
div {
height: 50px;
width: 100%;
}
div:has(div.other) {
background: red;
}
div:has(div[data-value="hi"]) {
background: orange;
}
<div>
<div class="other">example</div>
</div>
<div>
<div class="any">example</div>
</div>
<div>
<div class="other">example</div>
</div>
<div>
<div data-value="hi">example</div>
</div>
just directly select its class or data-value
div > .any {
background: red;
}
div > [data-value="other"] {
background: blue;
}
<div>
<div data-value="other">example</div>
</div>
<div>
<div class="any">example</div>
</div>
<div>
<div class="other">example</div>
</div>
<div>
<div class="other">example</div>
</div>

Is it possible to have scss selector that selects class only if it is last child of other element?

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

can not exclude class from css * selector

I want to apply a style on all children of a class except .fixedsize children:
.inner *:not(.fixedsize){
max-width:100%
}
.fixedsize > *{
max-width:none
}
<div class="inner">
<div>
<div id="map" class="fixedsize">
inspect the map here
<div id="childOfMap">inspect the child of map here</div>
</div>
</div>
</div>
It seems not working. How can I exclude it and all of its children from * selector?
Edit:
When I inspect the main element (map) in stackoverflow snippet it has no max-width:100% and this is ok. But in runtime and perhaps a more complex codes when I inspect the map, It has max-width:100% calculated from this * selector.
The issue is that the :not() selector is more specific, so you need to increase the specifity of the other selector or use !important
.inner *:not(.fixedsize) {
border:1px solid red;
}
/*Adding not() will make the specifity of this one higher*/
.fixedsize *:not(#randomId) {
border:none;
}
<div class="inner">
<div>
<div id="map" class="fixedsize">
no border
<div id="childOfMap">no border <span>here also</span></div>
</div>
<div>Content</div>
</div>
<div>some other content<span>here</span></div>
</div>
With !important:
.inner *:not(.fixedsize) {
border:1px solid red;
}
.fixedsize * {
border:none!important;
}
<div class="inner">
<div>
<div id="map" class="fixedsize">
no border
<div id="childOfMap">no border <span>here also</span></div>
</div>
<div>Content</div>
</div>
<div>some other content<span>here</span></div>
</div>

How to select an element when a sibling is not present?

I have a structure like this:
<div class="parent">
<div class="child-1"></div>
<div class="child-2"></div>
<div class="child-3"></div>
<div class="child-4"></div>
<div class="child-5"></div>
</div>
I want to target .child-4 only when .child-2 is not a child of the same parent, without knowing the order of children, but the .child-2 would never come after .child-4.
The classic CSS approach to such problems is to write a general case, then a more specialized case, where in this situation you would override the general case:
/* case where there may or may not be a preceding child-2 */
.child-4 { color: red; }
/* case where there IS a preceding child-2 */
.child-2 ~ .child-4 { color: inherit; }
<div class="parent">
<div class="child-1">child1</div>
<div class="child-2">child2</div>
<div class="child-3">child3</div>
<div class="child-4">child4</div>
<div class="child-5">child5</div>
</div>
<br/>
<div class="parent">
<div class="child-1">child1</div>
<div class="child-3">child3</div>
<div class="child-4">child4</div>
<div class="child-5">child5</div>
</div>
This uses the general sibling combinator, represented by a tilde (~).

Complex css to only select first instance of an element

I need to be able to apply a width to a div but only if any of it's parents have a class of grid.
Obviously the child selector allows me to select an element if it's a direct child of the grid div:
.grid > .test {
width: 300px;
}
<div class="grid">
<div class="test"></div>
</div>
I need a selector that allows me to select the .test div even if its not the direct child of grid:
<div class="grid">
<div class="another">
<div class="test"></div>
</div>
</div>
You'd imagine that I could just use a bog-standard selector like:
.grid .test
Problem with this is that I only want to match the first instance of the .test div. The above selector matches all instances even if they're nested. Any subsequent div's with a class of test should be ignored.
<div class="grid">
<div class="another">
<div class="test">
<div class="test"></div> <!-- this should be ignored somehow -->
</div>
</div>
</div>
http://jsfiddle.net/hs3G9/1/
Is there any way to do this with css or do I need to resort to JS?
There isn’t a way of excluding that inner .test element without JavaScript. If the two had been siblings, you could do something like:
.grid .test:first-of-type {}
edit: Right you are; you can cook something up with the :not selector.
Using the :first-child selector in css should work.
So for you case:
<style>
.grid .test:first-child {
background-color: rgba(0,0,0,.2);
}
</style>
<div class="grid">
<div class="another">
<div class="test">
<div class="test"></div> <!-- this should be ignored somehow -->
</div>
</div>
</div>

Resources