JSFiddle - React, Tailwind, and code Playground

Twelve month calendar of holidays

by Jennifer Perrin

HTML

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<div class="container">
  <h1 class="year">&mdash; 2015 &mdash;</h1>
  <h2 class="description">Twelve Month Calendar of Holidays &amp; Birthdays</h2>
  <ul>
    <li>
      <article tabindex="0">
        <div class="outline"></div>
        <div class="dismiss"></div>
        <div class="binding"></div>
        <h1>January</h1>
        <table>
          <thead>
            <tr>
              <th>Sun</th>
              <th>Mon</th>
              <th>Tue</th>
              <th>Wed</th>
              <th>Thu</th>
              <th>Fri</th>
              <th>Sat</th>
            </tr>
          </thead>
          <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td class="is-holiday">
              <div class="day">1</div>
              <div class="holiday">New Year's Day</div>
            </td>
            <td><div class="day">2</div></td>
            <td><div class="day">3</div></td>
          </tr>
          <tr>
            <td><div class="day">4</div></td>
            <td><div class="day">5</div></td>
            <td><div class="day">6</div></td>
            <td><div class="day">7</div></td>
            <td><div class="day">8</div></td>
            <td><div class="day">9</div></td>
            <td><div class="day">10</div></td>
          </tr>
          <tr>
            <td><div class="day">11</div></td>
            <td><div class="day">12</div></td>
            <td><div class="day">13</div></td>
            <td><div class="day">14</div></td>
            <td><div class="day">15</div></td>
            <td><div class="day">16</div></td>
            <td><div class="day">17</div></td>
          </tr>
          <tr>
            <td class="is-birthday">
              <div class="day">18</div>
              <div class="birthday">Dad's Birthday</div>
            </td>
            <td class="is-holiday">
             ...

CSS

@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,700);

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  color: #666;
  background-color: #f6f6f6;
  font: 1em/1 'Open Sans', sans-serif;
}

a {
  text-decoration: none;
}

.container {
  position: absolute;
  left: calc(50% - 400px);
  width: 800px;
  margin: 60px auto;
}

.year {
  margin: 0 0 8px;
  color: #548383;
  text-align: center;
  font-size: 4em;
}

.description {
  margin: 0 0 64px;
  color: #acc2c2;
  text-align: center;
  font-size: 2em;
}

ul {
  display: flex;
  flex-wrap: wrap;
  width: 740px;
  margin: -14px auto -14px;
  padding: 0;
  list-style: none;
}

/* Safari/iOS fix: Adjusting both z-index and transform on <article>
   causes text anti-aliasing to die within subsequent <article>
   elements during the transition. Moving z-index to the parent <li>
   fixes this. */
li {
  position: relative;
  z-index: 1;
  width: 25%;
  height: 160px;
  transition: z-index;
  transition-delay: .4s;
}

article {
  position: absolute;
  top: 50%;
  left: 50%;
  border-bottom: 8px solid #dfe7e7;
  background-color: #fff;
  cursor: pointer;
  transform: translate(-50%, -50%) scale(.25);
  transition: transform .4s;
}

/* Firefox fix: The outline style stretches to include absolutely
   positioned child elements (in this case, the offset dismiss
   button). This looks weird. The fix is to have a <div> with no
   child elements, position it to have the same edges as <article>,
   and apply the outline style there. */
.outline {
  position: absolute;
  z-index: -1;
  top: 0;
  bottom: -8px;
  left: 0;
  right: 0;
}

article:focus {
  outline: none;
}

article:focus .outline {
  outline: 4px solid #dab08c;
}

.dismiss {
  display: block;
  opacity: 0;
  position: absolute;
  top: -28px;
  right: -28px;
  width: 48px;
  height: 48px;
  border: 4px solid #fff;
  border-radius: 50%;
  color: #fff;
  background-color: #666;
  cursor: pointer;
  transition: opacity...

JavaScript

function activate(e) {
  var $wrapper = $(e.currentTarget).parent();
  $wrapper
    .addClass('active')
    .siblings().addClass('inactive');
}

function dismiss(e) {
  var $wrapper = $(e.currentTarget).closest('li');
  $wrapper
    .removeClass('active')
    .siblings().removeClass('inactive');
  e.stopPropagation();
}

function checkKey(e) {
  var $wrapper = $(e.currentTarget).parent();
  var isActive = $wrapper.hasClass('active');
  if (isActive && (e.keyCode === 13 || e.keyCode === 27)) {
    // active and hit enter or escape
    dismiss(e);
  } else if (!isActive && e.keyCode === 13) {
    // not active and hit enter
    activate(e);
  }
}

$('article').on({
  'click': activate,
  'blur': dismiss,
  'keyup': checkKey
});
$('.dismiss').on('click', dismiss);