Calendar Component
Readonly Calendar
A readonly calendar has cells containing static text or hypertext.
The current date is conveyed using calendar__cell--current and clipped text.
<div class="calendar">
<div class="calendar__body">
<div class="calendar__month">
<table>
<caption>
August 2019
</caption>
<thead>
<tr>
<th>Su</th>
<th>Mo</th>
<th>Tu</th>
<th>We</th>
<th>Th</th>
<th>Fr</th>
<th>Sa</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" />
<td>
<span> 1 </span>
</td>
<td>
<span> 2 </span>
</td>
<td>
<span> 3 </span>
</td>
<td>
<span> 4 </span>
</td>
<td>
<span> 5 </span>
</td>
</tr>
<tr>
<td>
<span> 6 </span>
</td>
<td>
<span> 7 </span>
</td>
<td>
<span> 8 </span>
</td>
<td>
<span> 9 </span>
</td>
<td>
<span> 10 </span>
</td>
<td>
<span> 11 </span>
</td>
<td>
<span> 12 </span>
</td>
</tr>
<tr>
<td>
<span> 13 </span>
</td>
<td>
<span class="calendar__cell--current">
14
<span class="clipped"> - today </span>
</span>
</td>
<td>
<span> 15 </span>
</td>
<td>
<span> 16 </span>
</td>
<td>
<span> 17 </span>
</td>
<td>
<span> 18 </span>
</td>
<td>
<span> 19 </span>
</td>
</tr>
<tr>
<td>
<a href="https://www.ebay.com"> 20 </a>
</td>
<td>
<span> 21 </span>
</td>
<td>
<span> 22 </span>
</td>
<td>
<span> 23 </span>
</td>
<td>
<span> 24 </span>
</td>
<td>
<span> 25 </span>
</td>
<td>
<span> 26 </span>
</td>
</tr>
<tr>
<td>
<a href="https://www.ebay.com"> 27 </a>
</td>
<td>
<span> 28 </span>
</td>
<td>
<a href="https://www.ebay.com"> 29 </a>
</td>
<td>
<span> 30 </span>
</td>
<td>
<span> 31 </span>
</td>
<td colspan="2" />
</tr>
</tbody>
</table>
</div>
</div>
</div>
NOTE: for the eagle-eyed BEM afionados, we are saying each span has an implicit class of calendar__cell .
Read-Only Calendar with Inactive Dates
Inactive/unavailable dates are conveyed using calendar__cell--disabled and offscreen text.
<div class="calendar">
<div class="calendar__body">
<div class="calendar__month">
<table>
<caption>
August 2023
</caption>
<thead>
<tr>
<th>Su</th>
<th>Mo</th>
<th>Tu</th>
<th>We</th>
<th>Th</th>
<th>Fr</th>
<th>Sa</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" />
<td>
<span class="calendar__cell--disabled">
1
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
2
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
3
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
4
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
5
<span class="clipped"> - inactive </span>
</span>
</td>
</tr>
<tr>
<td>
<span class="calendar__cell--disabled">
6
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
7
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
8
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
9
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
10
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
11
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
12
<span class="clipped"> - inactive </span>
</span>
</td>
</tr>
<tr>
<td>
<span class="calendar__cell--disabled">
13
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--current">
14
<span class="clipped"> - today </span>
</span>
</td>
<td>
<span> 15 </span>
</td>
<td>
<span> 16 </span>
</td>
<td>
<span> 17 </span>
</td>
<td>
<span> 18 </span>
</td>
<td>
<span> 19 </span>
</td>
</tr>
<tr>
<td>
<a href="https://www.ebay.com"> 20 </a>
</td>
<td>
<span> 21 </span>
</td>
<td>
<span> 22 </span>
</td>
<td>
<span> 23 </span>
</td>
<td>
<span> 24 </span>
</td>
<td>
<span> 25 </span>
</td>
<td>
<span> 26 </span>
</td>
</tr>
<tr>
<td>
<a href="https://www.ebay.com"> 27 </a>
</td>
<td>
<span> 28 </span>
</td>
<td>
<a href="https://www.ebay.com"> 29 </a>
</td>
<td>
<span> 30 </span>
</td>
<td>
<span> 31 </span>
</td>
<td colspan="2" />
</tr>
</tbody>
</table>
</div>
</div>
</div>
Read-Only Calendar with Date Range
Date ranges are conveyed using calendar__cell--selected , calendar__range , calendar__range--start , calendar__range-end and clipped text.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| 1 - inactive | 2 - inactive | 3 - inactive | 4 - inactive | 5 - inactive | ||
| 6 - inactive | 7 - inactive | 8 - inactive | 9 - inactive | 10 - inactive | 11 - inactive | 12 - inactive |
| 13 - inactive | 14 - today | 15 | 16 | 17 - start of range | 18 - in range | 19 - in range |
| 20 - in range | 21 - in range | 22 - in range | 23 - in range | 24 - in range | 25 - end of range | 26 |
| 27 | 28 | 29 | 30 | 31 | ||
<div class="calendar">
<div class="calendar__body">
<div class="calendar__month">
<table>
<caption>
August 2023
</caption>
<thead>
<tr>
<th>Su</th>
<th>Mo</th>
<th>Tu</th>
<th>We</th>
<th>Th</th>
<th>Fr</th>
<th>Sa</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" />
<td>
<span class="calendar__cell--disabled">
1
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
2
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
3
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
4
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
5
<span class="clipped"> - inactive </span>
</span>
</td>
</tr>
<tr>
<td>
<span class="calendar__cell--disabled">
6
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
7
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
8
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
9
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
10
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
11
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--disabled">
12
<span class="clipped"> - inactive </span>
</span>
</td>
</tr>
<tr>
<td>
<span class="calendar__cell--disabled">
13
<span class="clipped"> - inactive </span>
</span>
</td>
<td>
<span class="calendar__cell--current">
14
<span class="clipped"> - today </span>
</span>
</td>
<td>
<span> 15 </span>
</td>
<td>
<span> 16 </span>
</td>
<td
class="calendar__cell--selected calendar__range calendar__range--start"
>
<span>
17
<span class="clipped"> - selected - start of range </span>
</span>
</td>
<td class="calendar__range">
<span>
18
<span class="clipped"> - in range </span>
</span>
</td>
<td class="calendar__range">
<span>
19
<span class="clipped"> - in range </span>
</span>
</td>
</tr>
<tr>
<td class="calendar__range">
<a href="#">
20
<span class="clipped"> - in range </span>
</a>
</td>
<td class="calendar__range">
<span>
21
<span class="clipped"> - in range </span>
</span>
</td>
<td class="calendar__range">
<span>
22
<span class="clipped"> - in range </span>
</span>
</td>
<td class="calendar__range">
<span>
23
<span class="clipped"> - in range </span>
</span>
</td>
<td class="calendar__range">
<span>
24
<span class="clipped"> - in range </span>
</span>
</td>
<td
class="calendar__cell--selected calendar__range calendar__range--end"
>
<span>
25
<span class="clipped"> - selected - end of range </span>
</span>
</td>
<td>
<span> 26 </span>
</td>
</tr>
<tr>
<td>
<a href="https://www.ebay.com"> 27 </a>
</td>
<td>
<span> 28 </span>
</td>
<td>
<a href="https://www.ebay.com"> 29 </a>
</td>
<td>
<span> 30 </span>
</td>
<td>
<span> 31 </span>
</td>
<td colspan="2" />
</tr>
</tbody>
</table>
</div>
</div>
</div>
Interactive Calendar
An interactive calendar uses toggle buttons to allow the input of single dates or date ranges.
NOTE: a fully functional and accessible interactive calendar requires JavaScript and is outside the scope of a CSS library such as eBay Skin. The examples below are NOT fully functional and serve to demonstrate the necessary HTML semantics and styling hooks only.
Interactive Calendar With Single Date Selection
A single date selection is conveyed using aria-pressed .
NOTE: in comparison to the readonly calendar, with buttons we can now leverage the disabled property and aria-current instead of clipped text.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
<div class="calendar">
<div class="calendar__body">
<div class="calendar__month">
<table>
<caption>
August 2023
</caption>
<thead>
<tr>
<th>Su</th>
<th>Mo</th>
<th>Tu</th>
<th>We</th>
<th>Th</th>
<th>Fr</th>
<th>Sa</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" />
<td>
<button disabled>1</button>
</td>
<td>
<button disabled>2</button>
</td>
<td>
<button disabled>3</button>
</td>
<td>
<button disabled>4</button>
</td>
<td>
<button disabled>5</button>
</td>
</tr>
<tr>
<td>
<button disabled>6</button>
</td>
<td>
<button disabled>7</button>
</td>
<td>
<button disabled>8</button>
</td>
<td>
<button disabled>9</button>
</td>
<td>
<button disabled>10</button>
</td>
<td>
<button disabled>11</button>
</td>
<td>
<button disabled>12</button>
</td>
</tr>
<tr>
<td>
<button disabled>13</button>
</td>
<td>
<button aria-current="date">14</button>
</td>
<td>
<button>15</button>
</td>
<td>
<button>16</button>
</td>
<td class="calendar__cell--selected">
<button aria-pressed="true">17</button>
</td>
<td>
<button>18</button>
</td>
<td>
<button>19</button>
</td>
</tr>
<tr>
<td>
<button>20</button>
</td>
<td>
<button>21</button>
</td>
<td>
<button>22</button>
</td>
<td>
<button>23</button>
</td>
<td>
<button>24</button>
</td>
<td>
<button>25</button>
</td>
<td>
<button>26</button>
</td>
</tr>
<tr>
<td>
<button>27</button>
</td>
<td>
<button>28</button>
</td>
<td>
<button>29</button>
</td>
<td>
<button>30</button>
</td>
<td>
<button>31</button>
</td>
<td colspan="2" />
</tr>
</tbody>
</table>
</div>
</div>
</div>
Interactive Calendar With Date Range Selection
Date ranges are bookended by two buttons with the aria-pressed property. All buttons in between these dates leverage clipped text for assistive technology.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
<div class="calendar">
<div class="calendar__body">
<div class="calendar__month">
<table>
<caption>
August 2023
</caption>
<thead>
<tr>
<th>Su</th>
<th>Mo</th>
<th>Tu</th>
<th>We</th>
<th>Th</th>
<th>Fr</th>
<th>Sa</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" />
<td>
<button disabled>1</button>
</td>
<td>
<button disabled>2</button>
</td>
<td>
<button disabled>3</button>
</td>
<td>
<button disabled>4</button>
</td>
<td>
<button disabled>5</button>
</td>
</tr>
<tr>
<td>
<button disabled>6</button>
</td>
<td>
<button disabled>7</button>
</td>
<td>
<button disabled>8</button>
</td>
<td>
<button disabled>9</button>
</td>
<td>
<button disabled>10</button>
</td>
<td>
<button disabled>11</button>
</td>
<td>
<button disabled>12</button>
</td>
</tr>
<tr>
<td>
<button disabled>13</button>
</td>
<td>
<button aria-current="date">14</button>
</td>
<td>
<button>15</button>
</td>
<td>
<button>16</button>
</td>
<td
class="calendar__cell--selected calendar__range calendar__range--start"
>
<button aria-label="17 - start of range" aria-pressed="true">
17
</button>
</td>
<td class="calendar__range">
<button aria-label="18 - in range">18</button>
</td>
<td class="calendar__range">
<button aria-label="19 - in range">19</button>
</td>
</tr>
<tr>
<td class="calendar__range">
<button aria-label="20 - in range">20</button>
</td>
<td class="calendar__range">
<button aria-label="21 - in range">21</button>
</td>
<td class="calendar__range">
<button aria-label="22 - in range">22</button>
</td>
<td class="calendar__range">
<button aria-label="23 - in range">23</button>
</td>
<td class="calendar__range">
<button aria-label="24 - in range">24</button>
</td>
<td
class="calendar__cell--selected calendar__range calendar__range--end"
>
<button aria-label="25 - end of range" aria-pressed="true">
25
</button>
</td>
<td>
<button>26</button>
</td>
</tr>
<tr>
<td>
<button>27</button>
</td>
<td>
<button>28</button>
</td>
<td>
<button>29</button>
</td>
<td>
<button>30</button>
</td>
<td>
<button>31</button>
</td>
<td colspan="2" />
</tr>
</tbody>
</table>
</div>
</div>
</div>
Calendar With Header Pagination
The calendar module allows an optional header section for pagination between months.
<div class="calendar">
<div class="calendar__header">
<div class="calendar__header--inner">
<button
class="icon-btn icon-btn--small icon-btn--transparent"
aria-label="Previous Month - July 2023"
>
<svg aria-hidden="true" class="icon icon--24">
<use href="#icon-chevron-left-24" />
</svg>
</button>
<h3>August 2023</h3>
<button
class="icon-btn icon-btn--small icon-btn--transparent"
aria-label="Next Month - September 2023"
>
<svg aria-hidden="true" class="icon icon--24">
<use href="#icon-chevron-right-24" />
</svg>
</button>
</div>
</div>
<div class="calendar__body">
<div class="calendar__month">
<!-- readonly or interactive table goes here -->
</div>
</div>
</div>
Multi-month Calendar with Header Pagination
Multiple instances of calendar__month can be rendered inside of the calendar__body .
July 2023
August 2023
September 2023
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 | |||||
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 - today | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 | 31 | ||
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
<div class="calendar">
<div class="calendar__header">
<div class="calendar__header--inner">
<button
class="icon-btn icon-btn--small icon-btn--transparent"
aria-label="Previous Month - July 2019"
>
<svg aria-hidden="true" class="icon icon--24">
<use href="#icon-chevron-left-24" />
</svg>
</button>
<h3>July 2023</h3>
<h3>August 2023</h3>
<h3>September 2023</h3>
<button
class="icon-btn icon-btn--small icon-btn--transparent"
aria-label="Next Month - November 2019"
>
<svg aria-hidden="true" class="icon icon--24">
<use href="#icon-chevron-right-24" />
</svg>
</button>
</div>
</div>
<div class="calendar__body">
<div class="calendar__month">
<!-- readonly or interactive table goes here -->
</div>
<div class="calendar__month">
<!-- readonly or interactive table goes here -->
</div>
<div class="calendar__month">
<!-- readonly or interactive table goes here -->
</div>
</div>
</div>