Is there a selector (or any way around) for "Adjacent Until..." in CSS?

Viewed 127

I am trying to create a html layout that will be based of many adjacent sections. I want to have, somewhere between them, some divs that would control their appearance.

My html would be something like this:

<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>
<div class="color-scheme--clear"></div>
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>

And I would want that every section that came AFTER a color-scheme div had a background defined by it, as I was trying with this scss:

$white: #fefefe;
$red: #c54839;
$violet: #6c195e;

.section {
    height: 15em;
    background: $white;
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    color: $red;
}


.color-scheme--violet-red ~ .section {
    background-image: linear-gradient(to right, darken($violet, 10%) 0%, darken($red, 10%) 100%);
    color: $white;
}

.color-scheme--clear ~ .section {
    background: $white;
    color: $red;
}

Here's a Fiddle with an working example: https://jsfiddle.net/raphaelaleixo/4featqrg/ (The last two sections are white, but they should be colored)

The thing is, as the last sections are both adjacent to the color-scheme--clear div AND to the color-scheme--violet-red, the one that is below in the css file gains priority, and overwrite the other.

My question is: Is there anyway to - using only html/css - to select every element that is the CLOSEST adjacent to another?

For this html, I can't nest this sections inside the "color controller" divs, neither I will be sure of how many divs will be until the next "controller" div (If this was know, I could nest multiple "next siblings" selectors and call it a day).

I am very opened to any css hacks that could achieve this layout :-)

Thanks!

2 Answers

One hacky idea is to increase the specifity of each selector consider the previous color-sheme before it. So the more color-sheme we have before the more the selector will be specific thus it will win the one before it.

Of course, you will need to write many CSS rules depending on how many section you will have. You can consider SASS/LESS to easily generate the code:

.section {
    height: 15em;
    background: white;
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    color: red;
}


.color-scheme--violet-red ~ .section,
[class*="color-scheme" ] ~ .color-scheme--violet-red ~ .section,
[class*="color-scheme" ] ~ [class*="color-scheme" ]  ~ .color-scheme--violet-red ~ .section,
[class*="color-scheme" ] ~ [class*="color-scheme" ] ~ [class*="color-scheme" ]  ~ .color-scheme--violet-red ~ .section,
[class*="color-scheme" ] ~ [class*="color-scheme" ] ~ [class*="color-scheme" ] ~ [class*="color-scheme" ]  ~ .color-scheme--violet-red ~ .section{
    background-image: linear-gradient(to right, purple 0%, red 100%);
    color: white;
}

.color-scheme--clear ~ .section,
[class*="color-scheme" ] ~ .color-scheme--clear ~ .section,
[class*="color-scheme" ] ~ [class*="color-scheme" ] ~.color-scheme--clear ~ .section,
[class*="color-scheme" ] ~ [class*="color-scheme" ] ~ [class*="color-scheme" ] ~.color-scheme--clear ~ .section,
[class*="color-scheme" ] ~ [class*="color-scheme" ] ~ [class*="color-scheme" ] ~ [class*="color-scheme" ] ~.color-scheme--clear ~ .section{
    background: white;
    color: red;
}
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>
<div class="color-scheme--clear"></div>
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>
<div class="color-scheme--clear"></div>
<section class="section">White</section>
<section class="section">White</section>
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">White</section>
<section class="section">White</section>

This would be another hacky solution. Adding a + selector for each .section.

Assuming there is a max number of .sections in each 'colour' - you could do something like below (see demo)

The difficulty is (obviously) that you would need to write as many + .section as there are possible siblings of the same colour in a given section

Of course, you could use SASS/LESS to generate the code for you but you still would need to find out how many to generate.

.section {
    height: 5em;
    background: white;
    font-family: sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    color: red;
}

/* up to 4 coloured sections  */
.color-scheme--violet-red + .section,
.color-scheme--violet-red + .section + .section,
.color-scheme--violet-red + .section + .section + .section,
.color-scheme--violet-red + .section + .section + .section + .section
{
    background-image: linear-gradient(to right, purple 0%, red 100%);
    color: white;
}

.color-scheme--clear + .section
{
    background: white;
    color: red;
}
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>
<div class="color-scheme--clear"></div>
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>
<section class="section">Colored</section>
<div class="color-scheme--clear"></div>
<section class="section">White</section>
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>
<section class="section">Colored</section>
<section class="section">Colored</section>
<div class="color-scheme--clear"></div>
<section class="section">White</section>
<section class="section">White</section>
<section class="section">White</section>
<section class="section">White</section>
<section class="section">White</section>
<section class="section">White</section>
<div class="color-scheme--violet-red"></div>
<section class="section">Colored</section>
<section class="section">Colored</section>

Related