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.
For those of you, who just wanna see it in action or just get the final code, here it is…
$bgColor ?= #ffffff $txtColor ?= #444444 $linkColor ?= #ec008c
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
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)
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
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.