JSFiddle - React, Tailwind, and code Playground

by Laura Kishimoto

HTML

<section class="group">
  <ol class="timeline" data-period="4">
    <li class="timeline__range" style="grid-column-end: span 6;">
      <button class="doer doer--add">
        <span class="sr-only">Complete this chore</span>
      </button>
    </li>
    <li class="timeline__range" style="grid-column-end: span 2;">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
  </ol>
  <ol class="timeline" data-period="1">
    <li class="timeline__range" style="grid-column-end: span 3;">
      <button class="doer doer--add">
        <span class="sr-only">Complete this chore</span>
      </button>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range" style="grid-column-end: span 2;">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
    <li class="timeline__range">
      <span class="doer"></span>
    </li>
 ...

SCSS

$grid-size: 6rem;
$border-width: 1px;

$colour-gold: #ffc107;
$colour-dark: #bbb;
$colour-white: #fff;

$colour-success: #92de2d;
$colour-error: #ce1f1f;
$colour-grid: rgba($colour-dark, 0.15);
$colour-shade: rgba(111, 146, 148, 0.20);

html {
  font-size: 62.5%;
}

body {
  font-size: 1.6rem;
  font-family: sans-serif;
  color: $colour-dark;
  padding-right: 10rem;
}

.group {
  padding: 0 0 15px;
  font-size: $grid-size;
  overflow-x: scroll;
  direction: rtl;
  border-top: $border-width solid $colour-dark;
}

.timeline {
  display: grid;
  grid-template: 1em / repeat(60, 1em);
  list-style: none;
  margin: 0;
  padding: 0;
  width: 60em;
  border-bottom: $border-width solid $colour-dark;
  background-image: repeating-linear-gradient(
    to left,
    $colour-grid,
    transparent 0,
    transparent calc(1em - 1px),
    $colour-grid calc(1em - 1px),
    $colour-grid 1em
  );
  
  &:last-of-type {
    border-bottom-width: $border-width;
  }
  
  &__range {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    min-width: 1em; // actual duration
    min-height: 0.9em;
    margin-right: -$border-width;
    padding: 0;
    background-image: linear-gradient(
      to right,
      transparent,
      $colour-shade 1em
    );
    direction: ltr;
    border-left: $border-width solid $colour-grid;
    
    // overdue marker
    &:after {
      content: '';
      position: absolute;
      bottom: -$border-width;
      right: 0;
      left: 1em; // period
      border-bottom: calc(0.05em + #{$border-width}) solid currentColor;
      color: rgba($colour-error, 0.8);
    }
    
    @for $i from 1 through 30 {
      [data-period="#{$i}"] & {
        grid-column-end: span #{$i};
        background-image: linear-gradient(
          to right,
          transparent,
          $colour-shade #{$i}em
        );
        
        &:after {
          left: #{$i}em;
        }
      }
    }
  }
}

.doer {
  $doer-size: 0.5em;
 ...