1

I am looking for a CSS solution on applying a background color to a vertical timeline axis on the previous event from the current

.timeline {
    position: relative;
    display: flex;
    margin: 10px;
    flex-direction: column;
}

.timeline .event {
    position: relative;
    display: flex;
    flex-direction: row;
    padding-left: 15px;
}

.timeline .event::before {
    content: '';
    position: absolute;
    top: 0px;
    left: 2px;
    bottom: 0px;
    width: 2px;
    background: #d9d9d9;
}

.timeline.descending .event.open + .event:nth-child(3n-1)::before {
    background: #555555;
} 
<div class="timeline descending">
    <div class="event">
        Event 1
    </div>
    <div class="event">
        Event 2
    </div>
    <div class="event open">
        Event 3
    </div>
    <div class="event">
        Event 4
    </div>
    <div class="event">
        Event 5
    </div>
    <div class="event">
        Event 6
    </div>
</div>

In the above example, I have class open for Event 3, I am trying to change the color of Event 2 axis with #555555, I wrote code like -

.timeline.descending .event.open + .event:nth-child(3n-1)::before {
    background: #555555;
}

Which didn't work!

But, when I modified the code to

.timeline.descending .event + .event:nth-child(3n-1)::before {
    background: #555555;
}

.timeline {
    position: relative;
    display: flex;
    margin: 10px;
    flex-direction: column;
}

.timeline .event {
    position: relative;
    display: flex;
    flex-direction: row;
    padding-left: 15px;
}

.timeline .event::before {
    content: '';
    position: absolute;
    top: 0px;
    left: 2px;
    bottom: 0px;
    width: 2px;
    background: #d9d9d9;
}

/* .timeline .event:nth-child(1)::before {
    background: #000000;
} */

.timeline.descending .event + .event:nth-child(3n-1)::before {
    background: #555555;
}
<div class="timeline descending">
    <div class="event">
        Event 1
    </div>
    <div class="event">
        Event 2
    </div>
    <div class="event open">
        Event 3
    </div>
    <div class="event">
        Event 4
    </div>
    <div class="event">
        Event 5
    </div>
    <div class="event">
        Event 6
    </div>
</div>

I am able to run it, and it gives me partial result. I have limited understanding of nth-child and nth-last-child working, any help here would be appreciated.

cs1193
  • 1,090
  • 1
  • 16
  • 28
  • Well `.event.open` doesn't have the same sibling as `.event` – Mukyuu Apr 04 '19 at 06:27
  • You can not select a previous sibling with CSS. nth-child/nth-last-child won’t help you here, unless you’d want to use them with fixed numbers that are specifically tailored towards the current data set. Giving that latest previous event its own class when the HTML is generated is probably the easiest solution. – 04FS Apr 04 '19 at 06:53

1 Answers1

0

In case you just want to change the (n)th index (you can just change n incrementally and you can select starting from second index; for first sibling you can use .timeline.descending .event:first-child::before):

.timeline.descending .event:nth-child(1) + .event::before {
    background: #555555;
}

which in this example you can also swap :nth-child(1) with :first-child.

Note that there is no previous sibling selector in CSS.

.timeline {
    position: relative;
    display: flex;
    margin: 10px;
    flex-direction: column;
}

.timeline .event {
    position: relative;
    display: flex;
    flex-direction: row;
    padding-left: 15px;
}

.timeline .event::before {
    content: '';
    position: absolute;
    top: 0px;
    left: 2px;
    bottom: 0px;
    width: 2px;
    background: #d9d9d9;
}


.timeline.descending .event:nth-child(1) + .event::before {
    background: #555555;
}
<div class="timeline descending">
    <div class="event">
        Event 1
    </div>
    <div class="event">
        Event 2
    </div>
    <div class="event open">
        Event 3
    </div>
    <div class="event">
        Event 4
    </div>
    <div class="event">
        Event 5
    </div>
    <div class="event">
        Event 6
    </div>
</div>

Alternatively, if you're fine using JavaScript you can use:

const evt = document.querySelectorAll('.event');
for(let i = 0; i < evt.length ; i++) {
    if(((i+1) != evt.length) && evt[i+1].classList.contains('open')){
      var styleElem = document.head.appendChild(document.createElement("style"));   
      styleElem.innerHTML = ".timeline.descending .event:nth-child("+ (i+1) + ")::before {background: #555555;}";
    }
}

const evt = document.querySelectorAll('.event');
for(let i = 0; i < evt.length ; i++) {
    if(((i+1) != evt.length) && evt[i+1].classList.contains('open')){
      var styleElem = document.head.appendChild(document.createElement("style"));
      styleElem.innerHTML = ".timeline.descending .event:nth-child("+ (i+1) + ")::before {background: #555555;}";
    }
}
.timeline {
    position: relative;
    display: flex;
    margin: 10px;
    flex-direction: column;
}

.timeline .event {
    position: relative;
    display: flex;
    flex-direction: row;
    padding-left: 15px;
}

.timeline .event::before {
    content: '';
    position: absolute;
    top: 0px;
    left: 2px;
    bottom: 0px;
    width: 2px;
    background: #d9d9d9;
}
<div class="timeline descending">
    <div class="event">
        Event 1
    </div>
    <div class="event">
        Event 2
    </div>
    <div class="event open">
        Event 3
    </div>
    <div class="event">
        Event 4
    </div>
    <div class="event">
        Event 5
    </div>
    <div class="event">
        Event 6
    </div>
</div>
Mukyuu
  • 6,436
  • 8
  • 40
  • 59