Calendar month
Category: Data display · Tags: calendar, month, table, dates, schedule
| Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6Today | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |
How to use it
Use to show where a date falls in its month, for example next to an event or a booking summary. It is not a date picker: to let people choose a date use a native date input or a dedicated picker. Generate the cells and caption for the month you show and set data-year and data-month to match; the script then moves the Today marker to the real current date or removes it when today is in another month.
Accessibility
A read-only month is a native <table>: the <caption> names the month, each weekday is a <th scope="col"> whose full name is read while the three-letter form is shown, and the dates are plain cells, so screen readers announce the weekday for every date as they move through the grid. Today's cell has aria-current="date" and the visible word "Today", so it is not marked by colour alone. Dates are #0f172a on white (17.85:1), weekday headings #334155 on #f1f5f9 (9.45:1) and today white on #1d4ed8 (6.70:1). It holds no controls, so it adds nothing to the Tab order.
Source (copy-ready)
<div class="dcl-calendar">
<div class="dcl-calendar__scroll">
<table class="dcl-calendar__table" data-year="2026" data-month="11">
<caption class="dcl-calendar__caption">November 2026</caption>
<thead>
<tr>
<th scope="col" class="dcl-calendar__weekday"><span aria-hidden="true">Mon</span><span class="dcl-calendar__sr">Monday</span></th>
<th scope="col" class="dcl-calendar__weekday"><span aria-hidden="true">Tue</span><span class="dcl-calendar__sr">Tuesday</span></th>
<th scope="col" class="dcl-calendar__weekday"><span aria-hidden="true">Wed</span><span class="dcl-calendar__sr">Wednesday</span></th>
<th scope="col" class="dcl-calendar__weekday"><span aria-hidden="true">Thu</span><span class="dcl-calendar__sr">Thursday</span></th>
<th scope="col" class="dcl-calendar__weekday"><span aria-hidden="true">Fri</span><span class="dcl-calendar__sr">Friday</span></th>
<th scope="col" class="dcl-calendar__weekday"><span aria-hidden="true">Sat</span><span class="dcl-calendar__sr">Saturday</span></th>
<th scope="col" class="dcl-calendar__weekday"><span aria-hidden="true">Sun</span><span class="dcl-calendar__sr">Sunday</span></th>
</tr>
</thead>
<tbody>
<tr><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell" data-day="1"><span class="dcl-calendar__num">1</span></td></tr>
<tr><td class="dcl-calendar__cell" data-day="2"><span class="dcl-calendar__num">2</span></td><td class="dcl-calendar__cell" data-day="3"><span class="dcl-calendar__num">3</span></td><td class="dcl-calendar__cell" data-day="4"><span class="dcl-calendar__num">4</span></td><td class="dcl-calendar__cell" data-day="5"><span class="dcl-calendar__num">5</span></td><td class="dcl-calendar__cell dcl-calendar__cell--today" data-day="6" aria-current="date"><span class="dcl-calendar__num">6</span><span class="dcl-calendar__today">Today</span></td><td class="dcl-calendar__cell" data-day="7"><span class="dcl-calendar__num">7</span></td><td class="dcl-calendar__cell" data-day="8"><span class="dcl-calendar__num">8</span></td></tr>
<tr><td class="dcl-calendar__cell" data-day="9"><span class="dcl-calendar__num">9</span></td><td class="dcl-calendar__cell" data-day="10"><span class="dcl-calendar__num">10</span></td><td class="dcl-calendar__cell" data-day="11"><span class="dcl-calendar__num">11</span></td><td class="dcl-calendar__cell" data-day="12"><span class="dcl-calendar__num">12</span></td><td class="dcl-calendar__cell" data-day="13"><span class="dcl-calendar__num">13</span></td><td class="dcl-calendar__cell" data-day="14"><span class="dcl-calendar__num">14</span></td><td class="dcl-calendar__cell" data-day="15"><span class="dcl-calendar__num">15</span></td></tr>
<tr><td class="dcl-calendar__cell" data-day="16"><span class="dcl-calendar__num">16</span></td><td class="dcl-calendar__cell" data-day="17"><span class="dcl-calendar__num">17</span></td><td class="dcl-calendar__cell" data-day="18"><span class="dcl-calendar__num">18</span></td><td class="dcl-calendar__cell" data-day="19"><span class="dcl-calendar__num">19</span></td><td class="dcl-calendar__cell" data-day="20"><span class="dcl-calendar__num">20</span></td><td class="dcl-calendar__cell" data-day="21"><span class="dcl-calendar__num">21</span></td><td class="dcl-calendar__cell" data-day="22"><span class="dcl-calendar__num">22</span></td></tr>
<tr><td class="dcl-calendar__cell" data-day="23"><span class="dcl-calendar__num">23</span></td><td class="dcl-calendar__cell" data-day="24"><span class="dcl-calendar__num">24</span></td><td class="dcl-calendar__cell" data-day="25"><span class="dcl-calendar__num">25</span></td><td class="dcl-calendar__cell" data-day="26"><span class="dcl-calendar__num">26</span></td><td class="dcl-calendar__cell" data-day="27"><span class="dcl-calendar__num">27</span></td><td class="dcl-calendar__cell" data-day="28"><span class="dcl-calendar__num">28</span></td><td class="dcl-calendar__cell" data-day="29"><span class="dcl-calendar__num">29</span></td></tr>
<tr><td class="dcl-calendar__cell" data-day="30"><span class="dcl-calendar__num">30</span></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td><td class="dcl-calendar__cell"></td></tr>
</tbody>
</table>
</div>
</div>
<style>
.dcl-calendar { max-width: 26rem; font: inherit; color: #0f172a; background-color: #ffffff; }
.dcl-calendar__scroll { max-width: 100%; overflow-x: auto; }
.dcl-calendar__table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.dcl-calendar__caption { padding: 0 0 0.5rem; text-align: left; font-weight: 700; font-size: 1.1rem; color: #0f172a; background-color: #ffffff; }
.dcl-calendar__weekday { padding: 0.4rem 0.1rem; font-size: 0.8rem; font-weight: 600; text-align: center; color: #334155; background-color: #f1f5f9; }
.dcl-calendar__cell { height: 2.75rem; padding: 0.15rem; border: 1px solid #e2e8f0; text-align: center; vertical-align: middle; color: #0f172a; background-color: #ffffff; }
.dcl-calendar__cell--today { font-weight: 700; color: #ffffff; background-color: #1d4ed8; }
.dcl-calendar__num { display: block; }
.dcl-calendar__today { display: block; font-size: 0.65rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em; }
.dcl-calendar__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
</style>
<script>
(function () {
document.querySelectorAll(".dcl-calendar").forEach(function (root) {
if (root.dataset.dclBound) { return; }
root.dataset.dclBound = "true";
var table = root.querySelector(".dcl-calendar__table");
if (!table) { return; }
root.querySelectorAll("[aria-current=\"date\"]").forEach(function (cell) {
cell.removeAttribute("aria-current");
cell.classList.remove("dcl-calendar__cell--today");
var label = cell.querySelector(".dcl-calendar__today");
if (label) { label.remove(); }
});
var now = new Date();
if (Number(table.dataset.year) !== now.getFullYear() || Number(table.dataset.month) !== now.getMonth() + 1) { return; }
var cell = root.querySelector("[data-day=\"" + now.getDate() + "\"]");
if (!cell) { return; }
var marker = document.createElement("span");
marker.className = "dcl-calendar__today";
marker.textContent = "Today";
cell.appendChild(marker);
cell.classList.add("dcl-calendar__cell--today");
cell.setAttribute("aria-current", "date");
});
})();
</script>
Was this useful? Send feedback.