Recently, I came across a need to display a list of artist's exhibitions in a sidebar on a webpage. I wasn't quite satisfied with the styling of the presentation I had at hand at the time. That lead me to write a snippet of code you'll find in this tutorial. I wrote it in Stylus and HTML. Click on the View Compiled button to see the compiled CSS.
The Curriculum Timeline – grab the code
For those of you, who just wanna see it in action or just get the final code, here it is…
Default settings and variables
$bgColor   ?= #ffffff
$txtColor  ?= #444444
$linkColor ?= #ec008c
The basic structure
AS you can see, in the code above, the actual timeline HTML is made of the following parts:
<!-- The actual timeline HTML starts here -->
<div class="timeline tm">
  <!-- listing of the individual years -->
  <div class="tm__year"> … </div>
  <div class="tm__year"> … </div>
  <div class="tm__year"> … </div>
  <div class="tm__year"> … </div>
  <!-- the actual vertical line representing the timeline -->
  <div class="tm__line"></div>
</div>
This is pretty straight forward. The idea is an encapsulating block .tm that has its property position: relative to provide a point of reference for the vertical line .tm__line which is positioned absolutely. The .tm block also displays all the .tm__year elements. I shall mention these in more detail later.
.tm
  min-height: 100vh
  position: relative
  /* The vertical line symbolizing the timeline */
  &__line
    position: absolute
    /* defines the width of the vertical line */
    width: 2px
    top: 0
    bottom: 0
    left: 100%
    transform: translateX(-5rem)
    background-color: lighten($txtColor, 80%)
    z-index: -1
The structure of the individual year elements and their labels
Each of the .tm__year elements is made of an unordered list of the exhibitions that the artist participated in that year and a label for the particular year.
<div class="tm__year">
  <div class="tm__label">2018</div>
  <ul class="tm__events">
    <li class="tm__event"> … </li>
    <li class="tm__event"> … </li>
    <li class="tm__event"> … </li>
  </ul>
</div>
The formatting of the .tm__year makes each one of them position: relative; to set a reference point for the .tm__label element that is positioned absolutely. The label uses a set of text-shadow properties to create the illusion of the text outline.
  /* Definition of the year elements */
  &__year
    position: relative
    min-height: 10rem
    margin-top: 3rem
    &:first-child
      /* making sure the first year sticks to the top */
      margin-top: 0
  &__label
    color: rgba($txtColor, 0.3)
    color: $bgColor
    font-family: 'PT Serif', serif;
    font-weight: bold
    font-size: 4rem
    line-height: 1
    transform: rotate(-90deg)
    transform-origin: 100% 0
    position: absolute
    top: 0
    right: 4.75rem
    max-width: 16rem
    text-align: right
    text-shadow: -1px -1px 0 rgba($linkColor, 0.6),
                  1px -1px 0 rgba($linkColor, 0.6),
                 -1px  1px 0 rgba($linkColor, 0.6), 
                  1px  1px 0 rgba($linkColor, 0.6)
The actual list of exhibitions
There is nothing really special about the unordered list of exhibitions for each year. Each exhibition element consists of its heading and description.
<ul>
  <li class="tm__event">
    <h2 class="tm__event__heading">Ceramiq, Órgiva, Spain</h2>
    A cyanotype exhibition.
  </li>
  …
</ul>
The actual styling of the list, its items and their headings
  &__events
    /* Sets the right edge of the list in line with the vertical line */
    width: calc(100% - 5rem)
    /* Aligns the text of exhibitions to the right edge */
    text-align: right
  &__event
    padding: 1rem 0
    padding-right: 2rem
    /* set the reference point for the timeline bullet points */
    position: relative
    …
    &__heading
      font-size: 1.5rem
      line-height: 1.2
      margin-bottom: 0.5rem
      color: $linkColor
The timeline bullet points
Each event on the timeline is highlighted by a bullet point. These are made by the CSS ::after pseudo-element thus they don't require any additional HTML markup. As an icing on the cake, I've added a gentle micro-animation. I'm animating the bullet point's box-shadow property and offsetting the odd and even bullet points by half of the animation period, thus creating an alternating effect.
  &__event
    …
    &::after
      content: ''
      width: 1rem
      height: 1rem
      background-color: $linkColor
      position: absolute
      top: 1.5rem
      right: calc(-0.5rem - 1px)
      transform: rotate(45deg)
      animation-duration: 1.5s
      animation-name: microEvent
      animation-iteration-count: infinite
      animation-delay: 0
    &:nth-child(odd)
      &::after
        animation-delay: 0.75s
    @keyframes microEvent
      from
        box-shadow: 0 0 0 rgba($linkColor, 0.5)
      to
        box-shadow: 0 0 1rem 0.5rem rgba($linkColor, 0.1)
Special thanks go to my wife for letting me use some of her artist's CV records to make the example a bit more natural and for the cover image. Please, reward her goodwill, visit her website Emma Plunkett Art and perhaps even buy a piece of her artwork.

