All the Time in the World

Who's Got the Time for Yet Another Timeline?

(Now with new mobile love!) Right - nobody! So why do it? I ask myself the same thing all the time.   You know what else I ask myself? I ask: What would a static, horizontal timeline look like, if all you had was CSS?   Well, if you are a grandmaster, maybe this   Hint: scroll up/down over the timeline to move left/right  
55 AR - Book of Baby Names 5 AR - King Bob complains 56 AR - Book of Lost Causes 23 AR - John the Brain 80 AR - Battle of Vermin Ridge 110 AR - Scrolls of Fatigue 112 AR - Scrolls of Fatigue Vol II 115 AR - Seer Pinsky born 120 AR - Treaty of Pah! 133 AR - Postcard from The Edge 145 AR - Bill the Donkey 177 AR - Parliament Passes Tax Rebate 189 AR - Manuscript of Four Pages 201 AR - John the Leprechaun dies 201 AR - End of an Era 220 AR - Two Tickets to The Boss 235 AR - Yando the Brave Flees 415 AR - New Dawn
0 AR
100 AR
200 AR
300 AR
400 AR
500 AR
600 AR
700 AR
800 AR
900 910 920 930 940 950 960 970 980 990
900 AR
  There are only sample events to 400 AR. I just made a lot of epochs so you can see the potential. Making up all that sample data is teeeeedious.  

Wait, why would you do this?!

That's what they asked Sir Edmund Hillary. And do you know what he said? "Because it is there." Actually, what he really said was, "We've knocked the bastard off," but that does not serve my purposes as well. It's a mood.  

Maybe you are as crazy as I

In that case, you'll need some BBCode:
[section:ptevent t55 the-arts][section:far fa-book][/section][b]55 AR[/b] - [tooltip:This ancient grimoire was written a long time ago indeed.]Book of Baby Names[/tooltip][/section]
[section:ptevent t5 politics][section:far fa-crown][/section][b]5 AR[/b] - [tooltip:King Bob is a whiner. He learned how when he was a little tyke.]King Bob complains [/tooltip][/section]
[section:ptevent t56 the-arts L2][section:far fa-book][/section][b]56 AR[/b] - [tooltip:Better get Geico, this is gonna leave a scratch.]Book of Lost Causes[/tooltip][/section]
...etc., list all other events here like the two above, then finish with the following:
 [container:epoch][container:yr-line] [/container][section:yr] 0 AR[/section][/container] 
 [container:epoch][container:yr-line] [/container][section:yr]100 AR[/section][/container]
 [container:epoch][container:yr-line] [/container][section:yr]200 AR[/section][/container]
 [container:epoch][container:yr-line] [/container][section:yr]300 AR[/section][/container]
 [container:epoch][container:yr-line] [/container][section:yr]400 AR[/section][/container]
 [container:epoch][container:yr-line] [/container][section:yr]500 AR[/section][/container]
 [container:epoch][container:yr-line] [/container][section:yr]600 AR[/section][/container]
 [container:epoch][container:yr-line] [/container][section:yr]700 AR[/section][/container]
 [container:epoch][container:yr-line] [/container][section:yr]800 AR[/section][/container]
 [container:epoch][container:yr-line]10 20 30 40 50 60 70 80 90[/container][section:yr]900 AR[/section][/container]
  Let's unpack this a bit. The two outside containers, plancktimeframe and plancktime, hold the timeline. Plancktimeframe needs to be the height of the timeline to preserve the vertical space in the page.   The last block of "epoch" containers is what sets the background. Keep these as squares for easiest calculation. The big dates at the bottom are just text in each container; update them to whatever you want. If you want "BC" times, just list them as such: 300 BC, 200 BC, 100 BC, 0 AD, 100 AD, 200 AD, etc. The offsets for each event must be calculated from the actual negative years, though. That's because if you start your timeline at 300 BC and something happens at 250 BC, you want it 50 years to the right from the left edge of the timeline.   This brings us to the events. These are one line each, and they have several key elements:  
  • A class for the left edge of the event (e.g., t55, t23)
  • A "stream" - I used the-arts, politics, and biography, but you can use anything you like. It is used for both css color and font styling and to set the offset from the top of the timeline. E.g., the-arts are all near the top and in red on this example.
  • A "level" - This helps to keep overlapping events from obscuring each other. Use no class, or L2 - L5 to slightly offset within a stream.
  • A Font Awesome icon; this can be anything you like. I stuck to some boring stuff.
  • Finally, there is the event and the tooltip (description), which are just text with the usual permitted BBCode

Of course, without styles, it's all a big list

So you'll need the following styles:  
Base code: all the timelines need this
.user-css .plancktimeframe {
 position: relative;
 border: none;
 height: 420px;
.user-css .plancktime {
 position: absolute;
 display: block;
 top: 0;
 left: 0;
 max-height: 1100px;
 margin: 0;
 background: #ccc;
 overflow-y: auto;
 overflow-x: hidden;
 transform: rotate(-90deg) translateY(-420px) ;
 transform-origin: right top;
 padding: 60px 0 0 0;
 color: #522;
 .user-css div.plancktime::-webkit-scrollbar {
 -webkit-appearance: none;
 .user-css div.plancktime::-webkit-scrollbar-track {
 background-color: rgba(55,0,55,0.5) ;
 .user-css div.plancktime::-webkit-scrollbar-thumb {
 background-color: rgba(55,0,55,1) ;
  .user-css div.plancktime::-webkit-scrollbar-button {
 background-color: rgba(120,0,120,1) ;
 width: 25px;
 height: 25px;
@media (max-width: 1200px) {
 .user-css .plancktime {
  max-height: 900px;
@media (max-width: 992px) {
 .user-css .plancktime {
  max-height: 700px;
@media (max-width: 679px) {
 .user-css .plancktime {
  max-height: 350px;
.user-css .plancktime div.epoch {
 display: block;
 padding: 5px;
 background: rgba(50,50,150, 0.35) ;
 transform: rotate(90deg) translateX(340px) ;
 transform-origin: right top;
 overflow-x: hidden;
 overflow-y: hidden;
.user-css .plancktime span.ptevent {
 transform: rotate(90deg)
 translateY(-400px) translateZ( 0) ;
 transform-origin: left top;
 display: block !important;
 position: absolute;
 left: 0px;
 z-index: 10;
 border-left: 1px dashed #939; 
 padding-left: 5px;
.user-css .plancktime .yr-line {
 translateY(-400px) translatez ;
 transform-origin: left top;
 position: absolute;
 bottom: 50px;
 left: -1px;
 z-index: 10;
 width: 100%;
 height: 20px;
 background: repeating-linear-gradient(
  to right,
  rgba(255, 0, 0, 1),
  rgba(255, 0, 0, 1) 1px,
  rgba(150, 150, 185, 1) 1px,
  rgba(150, 150, 185, 1) 4px,
  rgba(255, 255, 255, .5) 4px,
  rgba(255, 255, 255, .5) 5px,
  rgba(150, 150, 185, 1) 5px,
  rgba(150, 150, 185, 1) 8px,
  rgba(255, 255, 255, .5) 8px,
  rgba(255, 255, 255, .5) 9px,
  rgba(150, 150, 185, 1) 9px,
  rgba(150, 150, 185, 1) 12px,
  rgba(255, 255, 255, .5) 12px,
  rgba(255, 255, 255, .5) 13px,
  rgba(150, 150, 185, 1) 13px,
  rgba(150, 150, 185, 1) 16px,
  rgba(255, 255, 255, .5) 16px,
  rgba(255, 255, 255, .5) 17px,
  rgba(150, 150, 185, 1) 17px,
  rgba(150, 150, 185, 1) 20px,
  rgba(255, 255, 255, .5) 20px,
  rgba(255, 255, 255, .5) 21px,
  rgba(150, 150, 185, 1) 21px,
  rgba(150, 150, 185, 1) 24px,
  rgba(255, 255, 255, .5) 24px,
  rgba(255, 255, 255, .5) 25px,
  rgba(150, 150, 185, 1) 25px,
  rgba(150, 150, 185, 1) 28px,
  rgba(255, 255, 255, .5) 28px,
  rgba(255, 255, 255, .5) 29px,
  rgba(150, 150, 185, 1) 29px,
  rgba(150, 150, 185, 1) 32px,
  rgba(255, 255, 255, .5) 32px,
  rgba(255, 255, 255, .5) 33px,
  rgba(150, 150, 185, 1) 33px,
  rgba(150, 150, 185, 1) 36px,
  rgba(255, 255, 255, .5) 36px,
  rgba(255, 255, 255, .5) 37px,
  rgba(150, 150, 185, 1) 37px,
  rgba(150, 150, 185, 1) 40px
 ) ; 
.user-css .plancktime span.ptevent .text-abbreviation {
 background-color: rgba(150,150,185, 1) ;
.user-css .plancktime span.ptevent .far {
 margin-right: 0.25em;
.user-css .plancktime .epoch span.yr {
 margin: 0px;
 position: absolute;
 color: rgba(200, 200, 200, 0.5) ;
 bottom: 0px;
 left: 0;
 z-index: 1;
 font-size: 4em;
 font-weight: bold;
 background: rgba(150,150,185,1) !important;
 display: block !important;
 width: 100%;
 height: 1em;
 padding-top: 0.40em;
  Some notes:
  • You have to style the scrollbars so that they appear on mobile (tested on Android). Mobile chrome doesn't let you grab the scrubber, you just have to tap in the scrollbar track.
  • The media queries resize the timeline as you change your browser size
  • The yr-line is the little bar of vertical lines that mark out the years. This is pretty idiosyncratic, and works in this instance because I have set my epochs to 100 years. You have to play with the linear gradients to get the pattern you want if you change from 100 year epochs.
The rest depends on your choices
What streams do you want? What colors and positions? Use "em" as your measure to make it easy to count vertical lines. If you use pixels, you'll have to play with the numbers a lot more.  
.user-css span.the-arts .far, .user-css span.the-arts b {
 color: #a00;
.user-css span.politics .far, .user-css span.politics b {
 color: #090;
.user-css span.biography .far, .user-css span.biography b {
 color: #00a;
.user-css span.ptevent.the-arts {margin-left: -1em; z-index: 11; height: 20em;}
.user-css span.ptevent.the-arts.L2 {margin-left: -2.2em; z-index: 12; height: 18.8em;}
.user-css span.ptevent.the-arts.L3 {margin-left: -3.4em; z-index: 13; height: 17.6em;}
.user-css span.ptevent.the-arts.L4 {margin-left: -4.6em; z-index: 14; height: 16.4em;}
.user-css span.ptevent.the-arts.L5 {margin-left: -5.8em; z-index: 15; height: 15.2em;}
.user-css span.ptevent.politics {margin-left: -8em; height: 12.8em;}
.user-css span.ptevent.politics.L2 {margin-left: -9.2em; z-index: 16; height: 11.6em;}
.user-css span.ptevent.politics.L3 {margin-left: -10.4em; z-index: 17; height: 10.4em;}
.user-css span.ptevent.politics.L4 {margin-left: -11.6em; z-index: 18; height: 9.2em;}
.user-css span.ptevent.politics.L5 {margin-left: -12.8em; z-index: 19; height: 8em;}
.user-css span.ptevent.biography {margin-left: -14em; z-index: 20; height: 7em;}
.user-css span.ptevent.biography.L2 {margin-left: -15.2em; z-index: 21; height: 5.8em;}
.user-css span.ptevent.biography.L3 {margin-left: -16.4em; height: 4.6em;}
.user-css span.ptevent.biography.L4 {margin-left: -17.6em; z-index: 22; height: 3.4em;}
.user-css span.ptevent.biography.L5 {margin-left: -18.8em; z-index: 23; height: 2.2em;}
  Huh, that's weird - why are all these setting left margin when they are supposed to be line heights? GOOD QUESTION! Becaue we're rotating everything 90-degrees. That's what makes this little solution a total mind bender. Next you're going to have to think about where your origin of rotation is, and how much you need to translate left to compensate. Yoiks.   The drop line from the event to the year line at the bottom is a left border. Each of those events therefore overlaps the one above it. In order to allow you to hover, the z-index has to be set in increasing order the further down the timeline you go. Also, I have tried to get their "heights" more or less the same so that they all end right above the year line.  
Last little bit: the year offsets
Every event has to be pushed right the correct number of years from the beginning of the timeline. That means that if you are starting "BC," we actually need to subtract those years from the offset. This timeline begins with the year 0 to make life easier for me.   Here's a little sample of the offsets:
.user-css .plancktime span.t5 {margin-top: 20px;}
.user-css .plancktime span.t55 {margin-top: 220px;}
.user-css .plancktime span.t56 {margin-top:224px;}
.user-css .plancktime span.t23 {margin-top:92px;}
.user-css .plancktime span.t80 {margin-top:320px;}
.user-css .plancktime span.t110 {margin-top:440px;}
  I draw your attention to the pixel offsets. If you have epochs of 100 years that are 400 pixels wide, you have 4 pixels per year. If you need an offset of 10 years, you need to shift right by 40 pixels.  

Maybe it's Cool, but...

Heh, yep, it's a lot of work to build out a timeline like this. You almost need a tool, something to help you quickly generate all that BBCode and CSS. Oh, wait...   What about this Google sheet?   Just save it to your own Drive (You'll need a free Google account OR you can save as Excel if you own that product) and fill in the columns A-F with your events. Order doesn't matter, except for your own sanity.   First, fill in:
  • The number of pixels per year
  • The calendar "abbreviation" you want. This is just text, so if you want, you can change it manually after you generate the BBCode, like if you have to go from BC to AD.
  • The timeline start year, using negative for BC dates. So, if you start at 350 BC, then the timeline start is -350. The reason is just that we need positive pixel offsets.
  Now you can fill stuff out and then copy all the BBCode cells and paste them into your plancktime container. Then copy all the CSS cells and paste them into the article CSS (I suggest there instead of the main CSS to keep it slim, but it's up to you. This example actually uses the global CSS, but there you have it. I don't always practice what I preach.)   U51

Cover image: Behind a Clock by Murray Campbell


Please Login in order to comment!
24 Aug, 2021 02:15

This is beautifully done. I already found a good use for it...   Though, there is only one problem I have found. When I copy-pasted the CSS and BBcode, everything looked fine, except for the "the-arts" portion. It seems that when either I add !important to "the-arts .far" or "the-arts b" or not, the color doesn't change. It stays the same color as the text, even though the text color is connected to my .user-css, .user-css-extended, .user-css .article-content. The reason I'm pointing this out is that I changed a few colors around, but I haven't messed with it too much.

Feel free to check out my WIP novel, His Mate!