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

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>

Related

CSS : modifying the style of a div if it his parent has a specific class

I've am stuck on this css issue. Here is a simplified code :
<div class="parent type1">
<div class="child">
red
</div>
</div>
<div class="parent type2">
<div class="child">
blue
</div>
<div>
I don't know how to code this (or if I can code this) but I need something like :
"If class is "child" and parent's class is "type2", put the div in blue (without changing the red div)".
Knowing that in my specific situation, I can't change the html, so I can't add some ids.
Thank you in advance and have a great day ! :-)
Chained CSS could do the trick:
.type2 .child {
color: blue;
}
/* OR combined classes + child */
.parent.type2 .child {
color: blue;
}
/* OR direct child of type2 */
.type2 > .child {
color: blue;
}
.type2 div{
color : blue;
}
.type2 .child{
color : blue;
}
<div class="parent type1">
<div class="child">
red
</div>
</div>
<div class="parent type2">
<div class="child">
blue
</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

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>

How do I access the value of a data-attribute and use it in a CSS declaration

Q: How can I access the value of a data-attribute and use it inside the declaration?
Edit: I'm expanding the scope to include Sass.
For example, assume I have the following HTML:
<div class="black box">
<div data-color="green">
This text should be green
</div>
<div data-color="red">
This text should be red
</div>
<div data-color="white">
This text should be white
</div>
</div>
That renders to this:
using the following CSS:
/* Ignore this */
.black.box {
background-color: black;
}
/* Refactor the three rules below into a single rule */
div[data-color="green"] {
color: green;
}
div[data-color="red"] {
color: red;
}
div[data-color="white"] {
color: white;
}
How can I refactor the three repetitive CSS rules into something like this pseudocode:
div[data-color=VALUE] {
color: VALUE;
}
Here's fiddle to help: https://jsfiddle.net/gilani/54de0zn6/7/
In this particular case using inline style is one solution since the values are already added inline:
.black {
background:black;
font-size:30px;
}
<div class="black box">
<div style="color:green">
This text should be green
</div>
<div style="color:red">
This text should be red
</div>
<div style="color:white">
This text should be white
</div>
</div>
You can also consider the use of CSS variable for more complex situations (also relying on inline style)
.black {
background:black;
font-size:30px;
}
.black > div {
color:var(--c);
border:5px solid var(--c);
}
<div class="black box">
<div style="--c:green">
This text should be green
</div>
<div style="--c:red">
This text should be red
</div>
<div style="--c:white">
This text should be white
</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>

Resources