JSFiddle - React, Tailwind, and code Playground

by agib

HTML

<div class="container">
  <div class="timeline-header">
    <div class="timeline-header-slot">14:00</div>
    <div class="timeline-header-slot">15:00</div>
    <div class="timeline-header-slot">16:00</div>
    <div class="timeline-header-slot">17:00</div>
    <div class="timeline-header-slot">18:00</div>
    <div class="timeline-header-slot">19:00</div>
    <div class="timeline-header-slot">20:00</div>
    <div class="timeline-header-slot">21:00</div>
    <div class="timeline-header-slot">22:00</div>
    <div class="timeline-header-slot">23:00</div>
  </div>
 
  <header class="title-wrapper">
    <h2 class="title">Pavilion</h2>
  </header>
  <div class="timeline">
      <div class="timeline-event" data-event-id="2132">Artist 2132</div>
      <div class="timeline-event" data-event-id="1646">Artist 1646</div>
      <div class="timeline-event" data-event-id="2684">Artist 2684</div>
      <div class="timeline-event" data-event-id="703">Artist 703</div>    
  </div>
  <header class="title-wrapper">
    <h2 class="title">Apollo</h2>
  </header>
  <div class="timeline">
      <div class="timeline-event" data-event-id="301">Artist 301</div>
      <div class="timeline-event" data-event-id="1733">Artist 1733</div>
      <div class="timeline-event" data-event-id="1539">Artist 1539</div>
      <div class="timeline-event" data-event-id="1095">Artist 1095</div>    
  </div>
  <header class="title-wrapper">
    <h2 class="title">Orange</h2>
  </header>
  <div class="timeline">
      <div class="timeline-event" data-event-id="1194">Artist 1194</div>
      <div class="timeline-event" data-event-id="3117">Artist 3117</div>
      <div class="timeline-event" data-event-id="3438">Artist 3438</div>
      <div class="timeline-event" data-event-id="4105">Artist 4105</div>    
  </div>
  <header class="title-wrapper">
    <h2 class="title">Avalon</h2>
  </header>
  <div class="timeline">
      <div class="timeline-event" data-event-id="2996">Artist 2996</div>
      <div...

CSS

:root {
  --slot-count: 20;
  --header-slot-count: 10;
  --slot-width: 7rem;
  --slot-gap: .1rem;
}

* {
  box-sizing: border-box;
  font-family: sans-serif;
}

html {
  font-size: 16px;
  padding: 0;
  margin: 0;
  width: 100%;
}

body {
  width: calc((var(--slot-count) + 1) * var(--slot-width) + (var(--slot-count)-1) * var(--slot-gap));
}

.container {
  margin-bottom: var(--slot-width);
}

.timeline {
  display: grid;
  grid-template-columns: [t-1400] 7rem [t-1430] 7rem [t-1500] 7rem [t-1530] 7rem [t-1600] 7rem [t-1630] 7rem [t-1700] 7rem [t-1730] 7rem [t-1800] 7rem [t-1830] 7rem [t-1900] 7rem [t-1930] 7rem [t-2000] 7rem [t-2030] 7rem [t-2100] 7rem [t-2130] 7rem [t-2200] 7rem [t-2230] 7rem [t-2300] 7rem [t-2330] 7rem [t-2400];
  column-gap: var(--slot-gap);
}

.timeline-header {
  display: grid;
  grid-template-columns: repeat(auto-fill, calc(2 * var(--slot-width)));
  column-gap: calc(2 * var(--slot-gap));
  position: sticky;
  top: 0;
  margin-bottom: .5rem;
  z-index: 2;
}

.timeline-header-slot {
  background-color: #1a0600;
  color: white;
  opacity: .85;
  padding: .25rem;
}

.timeline-event {
  background-color: #FFC48C;
  padding: .25rem .25rem .25rem 3rem;
  margin: .5rem 0;
  position: relative;
  color: #801f00;
}

.timeline-event::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  background-color: #801f00;
  opacity: .7;
  width: 2.5rem;
  z-index: 1;
}

.timeline-event::after {
  content: "hh:mm";
  display: block;
  font-size: .85rem;
}

.title {
  display: inline;
  padding: .5rem;
  position: sticky;
  left: 0;
  font-size: 1rem;
  margin: 0;
  z-index: -1;
}

.title-wrapper {
  padding-top: 1rem;
  border-top: 1px solid #ddd;
}

/* PAVILION */

[data-event-id="1646"] {
  grid-row: 1;
  grid-column: t-1400 / t-1530;
}

[data-event-id="2684"] {
  grid-row: 1;
  grid-column: t-1600 / t-1800;
}

[data-event-id="703"] {
  grid-row: 1;
  grid-column: t-1830 / t-2000;
}

[data-event-id="2132"] {
  grid-row: 1;
 ...