DEV Community

Cover image for Curriculum Timeline – Stylus (CSS) Tutorial
Honza
Honza

Posted on

Curriculum Timeline – Stylus (CSS) Tutorial

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)