Sample of generated calendar

As part of the relaunch of this website, I wanted an archive page that would display thumbnails of articles for each month in a calendar format. I will explain the construction of this calendar backwards: in this entry, I’ll talk about the final markup and CSS produced, with a calendar showing a single month; in future articles, I’ll show the , and code used to set the calendar to any month.

The calendar I envisioned for the site had a few particular features:

  • first, it would use pure HTML markup. While there are many calendar web page creation tools out there, most of them produce calendars using tables. While this isn’t wrong – a calendar is tabular data, after all – I wanted to see if it was possible to create a calendar using the minimum markup possible while retaining semantic richness.
  • Any month displayed would show the days of the previous month, along with the days of the following month. For example, if the month was June 2011, with the 1st of June falling on a Wednesday, the first line of the calendar would include May the 29th, 30th, and 31st (the Sunday, Monday and Tuesday beforehand) and the final line the 1st and 2nd of June (Friday and Saturday at the end of the month).
  • Days with a single digit, like the 1st, would have a leading 0 (so January 1 would become 01).
  • The calendar should show all dates when the viewport was wide enough, but should collapse down to show only those dates with associated entries at smaller sizes.

Calendar Markup

The construction of the calendar is based on the <time> element. <time> has one required attribute, datetime, the value for which must appear in a particular format (yyyy-mm-dd) with an optional timezone offset. So the elements for a June 2011 calendar would look something like this:

<time datetime="2011-06-01">01</time>
<time datetime="2011-06-02">02</time>

I also wanted each date to be a link, so the final markup would be something like this:

<section id="calendar">
	<h1>June 2011</h1>
	<time datetime="2011-05-29">
		<a href="#">29</a>
	</time>
	<time datetime="2011-05-30">
		<a href="#">30</a>
	</time>
	<time datetime="2011-05-31">
		<a href="#">31</a>
	</time>
	<time datetime="2011-06-01">
		<a href="#">01</a>
	</time>
…
</section>

Calendar CSS

Each date on the calendar had to be a square of the same dimension, and seven squares had to fall on a single line. Rather than using the extra markup of a table, I used to achieve the same effect:

* {
	box-sizing: border-box;
}
section {
	display: -webkit-box;
	display: -webkit-flex;
	display: -ms-flexbox;
	display: flex;
	-webkit-flex-flow: wrap;
      -ms-flex-flow: wrap;
	flex-flow: wrap;
	font-size: 0;
}

section time {
	-webkit-box-flex: 1;
	-webkit-flex: 1;
	-webkit-flex: 1 1 14.2857%;
      -ms-flex: 1;
	flex: 1;
	min-width: 14.2857%;
	max-width: 14.2857vw;
	position: relative;
	font-size: 1.8vw;
	line-height: 0;
	-webkit-transition: .35s opacity;
	transition: .35s opacity;
}
section time.blank {
	min-height: 14vw; 
}
section time a { 
	display: inline-block; 
	width: 100%; height: 100%; 
	position: inherit;
	border-bottom: none;
	outline: none;
 }

Dates displayed outside the current month receive a class of blank, completing the calendar. At smaller screen sizes, those dates are hidden, and the days with articles expanded to fill in the space:

@media all and (max-width: 950px) {
    section time.blank { display: none; }
    section time { 
        min-width: 20%;
        max-height: 20vw;
        max-width: 20vw;
        font-size: 3vw;
    }
}
@media all and (max-width: 750px) {
    section time { 
        min-width: 33%;
        max-height: 33vw;
        font-size: 5vw;
    }
}
@media all and (max-width: 450px) {
    section time { 
        min-width: 50%;
        max-height: 50vw;
        font-size: 5vw;
    }
}

This markup creates a static calendar for a specific month; the next step is to generate the appropriate <time> markup for any calendar month, which I will discuss in an upcoming article.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/MagNaY