-3

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.

Vishal
  • 12,133
  • 17
  • 82
  • 128
  • If you don't want to use `:has` then your option is limited: either use `:only-child` which means that your use-cases are more limited, or use JS. – Terry Feb 15 '23 at 22:03

1 Answers1

1

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>
Terry
  • 63,248
  • 15
  • 96
  • 118
  • I recommend you migrate your answer to the canonical since it doesn't appear to have a `:has()` solution yet. – TylerH Feb 15 '23 at 22:01
  • @TylerH I don't understand at all: there is a `:has` solution. OP wants to conditionally style an element if it is followed/not-followed by another element. – Terry Feb 15 '23 at 22:02
  • You dont understand what? That the question has been asked before? You have erroneously opened this question, please re-close it as a duplicate of the canonical. – TylerH Feb 15 '23 at 22:03
  • @TylerH It is not a duplicate. – Terry Feb 15 '23 at 22:04
  • Yes it is. It asks how to style an element only if the element has a particular sibling after it. That is exactly what the canonical asks – TylerH Feb 15 '23 at 22:04
  • The question says _previous_ sibling. – Terry Feb 15 '23 at 22:05
  • The question says "i want to apply red color to div1 if div2 exists else apply yellow -" Div2 is after div1 in OP's code. That lines up with the title that says "_override_ the style of the previous sibling", not "_style_ the previous sibling". – TylerH Feb 15 '23 at 22:07
  • "If div2 exists after div1, then style div1 this way". That's the question. That's also what the canonical covers. Your own comment under the OP about :only-child is even the exact solution provided in the canonical by the top answer. – TylerH Feb 15 '23 at 22:08
  • The second solution is an escape hatch is does not fully meet OP's requirements. It seems like we cannot agree on the definition of the question itself: and that is fine, but my answer stands. If you have a solution that works with the `+` selector I'm all ears. – Terry Feb 15 '23 at 22:10
  • my first comment was completely separate from the others, and was based on misreading the question at first (and it's gone now). Your solution literally solves the problem asked in the canonical. I don't know why you would want to preserve this obvious duplicate and have little attention on your answer when you could point OP to the canonical and post your solution there and get more attention, instead. – TylerH Feb 15 '23 at 22:13
  • your first has() solution is over complicated. You can do `.div1:has( + .div2)` (covered in the duplicate) – Temani Afif Feb 15 '23 at 22:14
  • 1
    @TylerH question closed again with the canonical that contain the correct has solution – Temani Afif Feb 15 '23 at 22:15
  • @TemaniAfif Thanks for the constructive suggestion, I've updated the answer now – Terry Feb 15 '23 at 22:19