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;
...