Calendar view

캘린더 뷰

A grid laying out a full month of dates, with dots or labels marking which days have events.

Also known as: Month viewEvent calendarDate grid
···
html
<div class="cvw">
  <div class="cvhead"><button aria-label="이전 달" tabindex="-1">‹</button><b>2026년 9월</b><button aria-label="다음 달" tabindex="-1">›</button></div>
  <div class="cvgrid" role="grid" aria-label="9월 일정" id="cvgrid">
    <span class="dow">일</span><span class="dow">월</span><span class="dow">화</span><span class="dow">수</span><span class="dow">목</span><span class="dow">금</span><span class="dow">토</span>
  </div>
</div>
css
.cvw{position:absolute;inset:10px;display:flex;flex-direction:column;gap:6px}
.cvhead{display:flex;align-items:center;justify-content:space-between;font-size:12px;font-weight:700;color:var(--fg)}
.cvhead button{border:0;background:none;color:var(--muted);font-size:15px;cursor:default;width:20px}
.cvgrid{display:grid;grid-template-columns:repeat(7,1fr);gap:3px;flex:1}
.dow{text-align:center;color:var(--muted);font-size:9px;padding:2px 0}
.ccell{position:relative;border:1px solid transparent;border-radius:7px;color:var(--fg);font-size:10px;display:flex;flex-direction:column;align-items:center;padding-top:2px;gap:2px}
.ccell.today{color:var(--accent);font-weight:700}
.ccell[data-focus]{border-color:var(--accent)}
.evt{width:4px;height:4px;border-radius:50%;background:var(--accent-2)}
js
const grid = document.getElementById('cvgrid');
const FIRST_DOW = 2, DAYS = 30, EVENTS = [3, 10, 10, 18, 26];
for (let i = 0; i < FIRST_DOW; i++) grid.appendChild(document.createElement('span'));
const cells = [];
for (let d = 1; d <= DAYS; d++) {
  const c = document.createElement('div');
  c.className = 'ccell'; c.setAttribute('role', 'gridcell'); c.tabIndex = -1;
  if (d === 26) c.classList.add('today');
  const n = document.createElement('span');
  n.textContent = String(d);
  c.appendChild(n);
  const dots = EVENTS.filter((e) => e === d).length;
  for (let k = 0; k < dots; k++) { const e = document.createElement('i'); e.className = 'evt'; c.appendChild(e); }
  grid.appendChild(c);
  cells.push(c);
}
let i = 25;
cells[i].tabIndex = 0;
cells[i].setAttribute('data-focus', '');
setInterval(() => {
  cells[i].removeAttribute('data-focus'); cells[i].tabIndex = -1;
  i = (i + 1) % cells.length;
  cells[i].setAttribute('data-focus', ''); cells[i].tabIndex = 0;
}, 700);

Date cells form a role="grid" of role="gridcell" entries, with only one cell holding tabindex="0" at a time — a roving tabindex that lets arrow keys move by a day left/right and by a week (7 days) up/down, with PageUp/PageDown jumping a month.

It shares the same grid structure as a date picker (see that entry) but serves a different purpose. A date picker is a popup that opens briefly to fill one form field and closes the moment a date is picked, while a calendar view is the main content of the screen, staying open, and a single day can carry several stacked events (multiple dots, or a "+3 more").

Today's date should be marked by shape as well as color (a border, extra weight) — and a day's events shouldn't rely on dot color alone to distinguish kinds; hovering or clicking should reveal the actual text so colorblind users can tell what's there.