# 入力もキーボード操作もできない日付ピッカー

Source: https://easeweb.dev/learn/date-picker
Topics: カスタム入力 > 日付や時刻を直接入力でき、カレンダーもキーボードで操作できる (WCAG 2.1.1, 4.1.2, 3.3.2)
The fix: ラベル付きの標準の日付入力を使うか、テキスト欄のまま形式を見えるテキストで示してaria-describedbyで結び付け、「日付を選択」ボタンからカレンダーのグリッドを持つダイアログを開きます。標準の日付入力は部分ごとに入力でき、ブラウザー自身のカレンダーからも選べます。ダイアログでは、矢印キー、Home、End、Page Up、Page Downで日を移動し、Enterキーで選び、Escapeキーで閉じ、選んだ日と今日にaria-selectedとaria-currentを付けます。
Test with: keyboard, screen reader, zoom, forced colors
References: https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html https://www.w3.org/WAI/WCAG22/Understanding/labels-or-instructions.html https://www.w3.org/WAI/WCAG22/Techniques/general/G89 https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/ https://www.w3.org/TR/wai-aria-1.2/#aria-current https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/date https://design-system.service.gov.uk/components/date-input/

よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。

## 場面

あるショップの購入手続きで、お届け日を指定します。欄には「日付を選択」と表示され、クリックするとその下に2026年11月のカレンダーが開き、今日の2日（月）が太字になっています。12日（木）をクリックすると、欄に「2026/11/12」が入ります。キーボードでは、Tabキーで欄に届いてもそこで止まります。文字を入力しても何も入らず、Enterキーや矢印キーを押しても何も開かず、次のTabキーで次の操作部品へ移ってしまいます。日付を指定する手段がないため、注文できません。スクリーンリーダーは「お届け日」を読み取り専用のテキスト欄として読み上げ、入力できないことは伝えますが、ほかの手段は示しません。マウスでカレンダーを開いても、スクリーンリーダーは各日を「12」のように数字だけで読み、選べることも、どの日が選ばれているかも、どれが今日かも伝えません。

ショップがすぐにできる修正として、欄に入力できるようにします。ショップのコードは、すべての日付を年/月/日として読みます。そのため、日本でよく書かれるように「11/12」と月/日だけを入力した人や、「2026年11月12日」と入力した人の日付は、読み取れません。ラベルは「お届け日」とだけ書かれていて、どの形で書けばよいかを知る手段はありませんでした。カレンダーは変わっていないため、前と同じように使えないままです。

## 確認できる問題

達成基準2.1.1は、マウスでできることをキーボードでもできるよう求めています。欄に `readonly` があるため、ブラウザーはフォーカスは受け取らせますが入力は拒み、欄を埋める手段はカレンダーだけです。カレンダーは `click` イベントで開きますが、テキスト欄はどのキーでもこのイベントを発生させません。日は `div` 要素で、それを囲む箱に付けたクリック処理で選ばれ、divはフォーカスを受け取れません。ブラウザーはこの三つのどれも許し、どれも単独では誤りではありませんが、組み合わさると日付の指定はマウスだけのものになります。

達成基準4.1.2は、操作部品の名前、役割、状態を支援技術が取得できるよう求めています。画面の上では、日は操作部品です。コードでは、ただのdivです。役割がなく、名前は日の数字だけで、選んだ日と今日は、見た目だけを変える `selected` と `today` のクラスで示されています。ブラウザーはマークアップから役割と状態を伝えますが、クラスはどちらも持たないため、スクリーンリーダーには伝えることがありません。

達成基準3.3.2は、入力が必要な場所にラベルや説明を求めていて、その解説ページは、形式をテキストで示した日付の欄を例に挙げています。日付は、年、月、日のどれを先に書くことも、スラッシュ、ハイフン、漢字で区切ることもできますが、二つ目の修正前のコードはそのうち一つしか読めず、それがどれかを示していません。「お届け日」は欄の名前にはなっても書き方は伝えないため、「11/12」や「2026年11月12日」は読み取れず、ページの上ではその理由も分かりません。

## 利用者への影響

お届け日や予約日は、支払いの前に必須であることがよくあります。マウスなしでは埋められない欄は、注文そのものを止めます。スマートフォンではタップでカレンダーが開くため、タッチ操作での確認では問題が見つかりにくく、それがこの欄が長く残る理由の一つです。

## 自動チェックとAIの限界

axeのようなスキャナーはラベル付きのテキスト欄を見つけ、合格にします。`readonly` は正しい属性で、日付を入力できなければならないという規則もありません。カレンダーはクリックするまで表示されず、日は役割もARIAもないdivなので、規則が指摘できるものがありません。「お届け日」が形式について十分に説明しているかは、規則が問わない問題です。日付ピッカーのライブラリーは、初期設定のままで一つ目の修正前のような読み取り専用の欄になることがあります。たとえばflatpickrは、allowInputオプションを設定しない限り、欄を読み取り専用にします。AIに「日付ピッカー」を頼むと、カレンダーをdivで書くか、`role="grid"` を付けても日にはフォーカスも `aria-selected` もないままにすることがあります。使えるかどうかは、入力し、キーボードでカレンダーを開き、読み上げを聞いて初めて分かります。

## 修正前：読み取り専用の欄と、クリックでしか開かないカレンダー

```html
<label for="delivery">お届け日</label>
<input id="delivery" name="delivery" type="text" readonly placeholder="日付を選択">
<div class="calendar" hidden>
  <div class="cal-head">
    <span class="prev">‹</span>
    <span class="cal-month">2026年11月</span>
    <span class="next">›</span>
  </div>
  <div class="cal-week">
    <span>日</span>
    <span>月</span>
    <span>火</span>
    <span>水</span>
    <span>木</span>
    <span>金</span>
    <span>土</span>
  </div>
  <div class="cal-days"></div>
</div>
```

```js
const field = document.getElementById('delivery');
const calendar = document.querySelector('.calendar');
const days = calendar.querySelector('.cal-days');
const today = new Date();
let shown = today;

// このショップは、すべての日付を年/月/日として読みます。
function readDate(text) {
  const [year, month, day] = text.split('/').map(Number);
  return new Date(year, month - 1, day);
}
const same = (a, b) => a.toDateString() === b.toDateString();
const daysIn = (date) => new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();

function draw() {
  calendar.querySelector('.cal-month').textContent =
    shown.toLocaleDateString('ja-JP', { month: 'long', year: 'numeric' });
  const chosen = readDate(field.value);
  days.replaceChildren();
  for (let n = 1; n <= daysIn(shown); n++) {
    const day = new Date(shown.getFullYear(), shown.getMonth(), n);
    const div = document.createElement('div');
    div.className = 'day';
    div.textContent = n;
    if (n === 1) div.style.gridColumnStart = day.getDay() + 1;
    div.classList.toggle('selected', same(day, chosen));
    div.classList.toggle('today', same(day, today));
    days.append(div);
  }
}
field.addEventListener('click', () => {
  draw();
  calendar.hidden = false;
});
for (const [button, step] of [['.prev', -1], ['.next', 1]]) {
  calendar.querySelector(button).addEventListener('click', () => {
    shown = new Date(shown.getFullYear(), shown.getMonth() + step, 1);
    draw();
  });
}
days.addEventListener('click', (event) => {
  const div = event.target.closest('.day');
  if (!div) return;
  const day = new Date(shown.getFullYear(), shown.getMonth(), Number(div.textContent));
  field.value = day.toLocaleDateString('ja-JP');
  calendar.hidden = true;
});
```

```css
.cal-days {
  display: grid;
  grid-template-columns: repeat(7, 2.25rem);
}
.cal-days .today {
  font-weight: bold;
}
.cal-days .selected {
  background: var(--accent);
  color: white;
}
```

欄は入力を拒み、カレンダーはクリックでしか開かず、日はどのキーも届かないdivなので、キーボードではまったく日付を指定できません。日には役割がなく、選んだ日と今日はクラスなので、スクリーンリーダーは数字しか読みません。

## 修正前：入力はできるが、形式を示していない欄

```html
<label for="delivery">お届け日</label>
<input id="delivery" name="delivery" type="text" placeholder="日付を選択">
<div class="calendar" hidden>
  <div class="cal-head">
    <span class="prev">‹</span>
    <span class="cal-month">2026年11月</span>
    <span class="next">›</span>
  </div>
  <div class="cal-week">
    <span>日</span>
    <span>月</span>
    <span>火</span>
    <span>水</span>
    <span>木</span>
    <span>金</span>
    <span>土</span>
  </div>
  <div class="cal-days"></div>
</div>
```

```js
const field = document.getElementById('delivery');
const calendar = document.querySelector('.calendar');
const days = calendar.querySelector('.cal-days');
const today = new Date();
let shown = today;

// このショップは、すべての日付を年/月/日として読みます。
function readDate(text) {
  const [year, month, day] = text.split('/').map(Number);
  return new Date(year, month - 1, day);
}
const same = (a, b) => a.toDateString() === b.toDateString();
const daysIn = (date) => new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();

function draw() {
  calendar.querySelector('.cal-month').textContent =
    shown.toLocaleDateString('ja-JP', { month: 'long', year: 'numeric' });
  const chosen = readDate(field.value);
  days.replaceChildren();
  for (let n = 1; n <= daysIn(shown); n++) {
    const day = new Date(shown.getFullYear(), shown.getMonth(), n);
    const div = document.createElement('div');
    div.className = 'day';
    div.textContent = n;
    if (n === 1) div.style.gridColumnStart = day.getDay() + 1;
    div.classList.toggle('selected', same(day, chosen));
    div.classList.toggle('today', same(day, today));
    days.append(div);
  }
}
field.addEventListener('click', () => {
  draw();
  calendar.hidden = false;
});
for (const [button, step] of [['.prev', -1], ['.next', 1]]) {
  calendar.querySelector(button).addEventListener('click', () => {
    shown = new Date(shown.getFullYear(), shown.getMonth() + step, 1);
    draw();
  });
}
days.addEventListener('click', (event) => {
  const div = event.target.closest('.day');
  if (!div) return;
  const day = new Date(shown.getFullYear(), shown.getMonth(), Number(div.textContent));
  field.value = day.toLocaleDateString('ja-JP');
  calendar.hidden = true;
});
```

```css
.cal-days {
  display: grid;
  grid-template-columns: repeat(7, 2.25rem);
}
.cal-days .today {
  font-weight: bold;
}
.cal-days .selected {
  background: var(--accent);
  color: white;
}
```

同じ欄から `readonly` を外しただけのものです。キーボードで日付を入力できるようになりましたが、ショップが年/月/日の順でしか読まないことはどこにも書かれていないため、「11/12」も「2026年11月12日」も読み取れません。カレンダーはそのままなので、日は一つ目の修正前と同じく2.1.1と4.1.2を満たしません。

## 修正後：標準の日付入力

```html
<label for="delivery">お届け日</label>
<input id="delivery" name="delivery" type="date">
```

ブラウザーは、日付の各部分を順に入力させ、自身のカレンダーから選ばせ、欄の名前と役割と入っている日付をスクリーンリーダーに伝えます。部分の順はブラウザー自身の言語設定から決まり、多くのデスクトップのブラウザーでは空の欄に「年/月/日」のように示されるため、自分で言葉を書かなくても形式が伝わります。送られる値は、画面上の順にかかわらず常に「2026-11-12」です。スマートフォンでは、タップするとシステムの日付の選択画面が開きます。スクリプトとスタイルはなくなり、保守するカレンダーはもう残りません。

ただし、満たせるのは各ブラウザーの部品が正しく動く範囲までです。カレンダーの見た目は変えられません。`min` と `max` で範囲は限れますが、日曜日や売り切れの日のように一日ずつ除くことはできないため、選ばれたあとで断る必要があります。部分の読み上げ方はブラウザーとスクリーンリーダーの組み合わせによって違うため、対応するものすべてで確認してください。順はページではなくブラウザーに従うため、日本語のページでも、米国英語に設定したブラウザーでは月が先に表示されます。標準の日付欄の横に自分で形式を書くと食い違うことがあるため、書かないでください。

## 修正後：形式を示した入力欄と、カレンダーのダイアログ

```html
<label for="delivery">お届け日</label>
<p id="delivery-hint">年/月/日の順。例：2027/03/27</p>
<input id="delivery" name="delivery" type="text" aria-describedby="delivery-hint">
<button type="button" id="delivery-button" aria-haspopup="dialog" aria-label="日付を選択">
  <svg aria-hidden="true">…</svg>
</button>
<dialog class="calendar" aria-label="日付を選択">
  <div class="cal-head">
    <button type="button" class="prev" aria-label="前の月">‹</button>
    <h2 class="cal-month" id="cal-month" aria-live="polite">2026年11月</h2>
    <button type="button" class="next" aria-label="次の月">›</button>
  </div>
  <table role="grid" aria-labelledby="cal-month">
    <thead>
      <tr>
        <th scope="col">日</th>
        <th scope="col">月</th>
        <th scope="col">火</th>
        <th scope="col">水</th>
        <th scope="col">木</th>
        <th scope="col">金</th>
        <th scope="col">土</th>
      </tr>
    </thead>
    <tbody class="cal-days"></tbody>
  </table>
  <button type="button" class="cancel">キャンセル</button>
</dialog>
```

```js
const field = document.getElementById('delivery');
const button = document.getElementById('delivery-button');
const calendar = document.querySelector('.calendar');
const days = calendar.querySelector('.cal-days');
const today = new Date();
let shown = today;

// このショップは、説明のとおり、すべての日付を年/月/日として読みます。
function readDate(text) {
  const [year, month, day] = text.split('/').map(Number);
  return new Date(year, month - 1, day);
}
const same = (a, b) => a.toDateString() === b.toDateString();
const daysIn = (date) => new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
const full = (date) => date.toLocaleDateString('ja-JP', { dateStyle: 'full' });

function draw() {
  calendar.querySelector('.cal-month').textContent =
    shown.toLocaleDateString('ja-JP', { month: 'long', year: 'numeric' });
  const chosen = readDate(field.value);
  days.replaceChildren();
  let row;
  for (let n = 1; n <= daysIn(shown); n++) {
    const day = new Date(shown.getFullYear(), shown.getMonth(), n);
    if (n === 1 || day.getDay() === 0) row = days.insertRow();
    if (n === 1) for (let gap = 0; gap < day.getDay(); gap++) row.insertCell();
    const cell = row.insertCell();
    cell.textContent = n;
    // 各日には日付全体の名前を付け、Tabキーで止まるのは表示中の日だけにします。
    cell.setAttribute('aria-label', full(day));
    cell.tabIndex = same(day, shown) ? 0 : -1;
    if (same(day, chosen)) cell.setAttribute('aria-selected', 'true');
    if (same(day, today)) cell.setAttribute('aria-current', 'date');
  }
}
function moveTo(date) {
  shown = date;
  draw();
  days.querySelector('[tabindex="0"]').focus();
}
function pick(date) {
  field.value = date.toLocaleDateString('ja-JP');
  button.setAttribute('aria-label', `日付を変更、${full(date)}`);
  calendar.close();
}
button.addEventListener('click', () => {
  const chosen = readDate(field.value);
  calendar.showModal();
  moveTo(Number.isNaN(chosen.getTime()) ? today : chosen);
});
// Escape、キャンセル、日の選択のどれでもダイアログが閉じ、フォーカスはボタンに戻ります。
calendar.addEventListener('close', () => button.focus());
calendar.querySelector('.cancel').addEventListener('click', () => calendar.close());
// Tabはカレンダーの中にとどめます。「キャンセル」から「前の月」へ、Shiftを押しながらならその逆へ移ります。
calendar.addEventListener('keydown', (event) => {
  if (event.key !== 'Tab') return;
  const first = calendar.querySelector('.prev');
  const last = calendar.querySelector('.cancel');
  if (event.shiftKey && document.activeElement === first) last.focus();
  else if (!event.shiftKey && document.activeElement === last) first.focus();
  else return;
  event.preventDefault();
});
for (const [name, step] of [['.prev', -1], ['.next', 1]]) {
  calendar.querySelector(name).addEventListener('click', () => {
    shown = new Date(shown.getFullYear(), shown.getMonth() + step, 1);
    draw();
  });
}
days.addEventListener('click', (event) => {
  const cell = event.target.closest('td[aria-label]');
  if (cell) pick(new Date(shown.getFullYear(), shown.getMonth(), Number(cell.textContent)));
});
days.addEventListener('keydown', (event) => {
  const next = new Date(shown);
  if (event.key === 'ArrowRight') next.setDate(next.getDate() + 1);
  else if (event.key === 'ArrowLeft') next.setDate(next.getDate() - 1);
  else if (event.key === 'ArrowDown') next.setDate(next.getDate() + 7);
  else if (event.key === 'ArrowUp') next.setDate(next.getDate() - 7);
  else if (event.key === 'Home') next.setDate(next.getDate() - next.getDay());
  else if (event.key === 'End') next.setDate(next.getDate() + 6 - next.getDay());
  else if (event.key === 'PageDown' || event.key === 'PageUp') {
    // 1か月、Shiftを押していれば1年移り、その月にある限り同じ日にします。
    const months = (event.key === 'PageDown' ? 1 : -1) * (event.shiftKey ? 12 : 1);
    next.setDate(1);
    next.setMonth(next.getMonth() + months);
    next.setDate(Math.min(shown.getDate(), daysIn(next)));
  } else if (event.key === 'Enter' || event.key === ' ') {
    event.preventDefault();
    return pick(shown);
  } else return;
  event.preventDefault();
  moveTo(next);
});
```

```css
.cal-days td {
  width: 2.25rem;
  height: 2.25rem;
  text-align: center;
}
/* 今日と選んだ日は、クラスではなく、スクリーンリーダーが読む状態から描きます。 */
.cal-days [aria-current="date"] {
  font-weight: bold;
}
.cal-days [aria-selected="true"] {
  background: var(--accent);
  color: white;
  outline: 2px solid transparent;
}
.cal-days td:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}
@media (forced-colors: active) {
  .cal-days [aria-selected="true"] {
    outline-color: Highlight;
  }
}
```

欄は再び入力でき、ラベルの下の行が、日付を書く順を例と一緒に示します。`aria-describedby` がその行を欄に結び付けるため、スクリーンリーダーはラベルのあとにそれを読みます。カレンダーは手助けであり、唯一の入り口ではありません。Tabキーで届くボタンから開き、`aria-haspopup="dialog"` が、対応するスクリーンリーダーに、ボタンが何を開くかを伝えます。ダイアログは `showModal()` で開くため、開いている間は後ろのページが操作できない状態になり、Escapeキーで閉じます。Tabキーは「前の月」「次の月」、グリッド、「キャンセル」の順に移ります。モーダルダイアログでは、最後の部品の次にTabキーがアドレスバーなどブラウザー自身の部品へ進み、キーボードの利用者にはフォーカスを失ったように見えます。そのため、APGの日付選択ダイアログと同じく、スクリプトで「キャンセル」から「前の月」へ、Shift + Tabではその逆へ戻します。フォーカスは選んだ日か今日に移り、グリッドはTabキーで止まる場所が一つだけです。矢印キーで1日または1週間、HomeとEndで週の初めと終わり、Page UpとPage Downで1か月、Shiftを押しながらなら1年移ります。各日は日付全体で読まれ、選んだ日は選択中として、今日は `aria-current="date"` で伝わります。Enterキー、Spaceキー、クリックでその日が欄に入り、フォーカスはボタンに戻ります。ボタンの名前は日付を含む「日付を変更」になるため、スクリーンリーダーの利用者に何を選んだかが聞こえます。

ただし、満たせるのはスクリプトが正しく動く範囲までです。上のすべてのキーが動き、Tabキーで止まる場所がフォーカスに付いていき、200%の拡大表示でもスマートフォンでもダイアログが欄のそばに収まる必要があります。この例の元になったAPGの日付ピッカーのダイアログは、ブラウザーと支援技術の組み合わせによっては、特にタッチ操作の端末で、対応に抜けがあるかもしれないと注意しています。対応するすべてのブラウザーとスクリーンリーダーで確認してください。

## どの方法を選ぶか

どちらも2.1.1、4.1.2、3.3.2を満たします。標準の日付入力はスクリプトが要りません。どのブラウザーも自身のキー操作、カレンダー、読み上げを用意し、スマートフォンではシステムの選択画面が開きます。範囲の中ならどの日でもよく、ブラウザーが描くカレンダーの見た目で差し支えない場合に選んでください。日曜日や空きのない日のように除く日がある場合や、料金のように日付以外もカレンダーに出す必要がある場合は、入力欄とダイアログを作り、キー操作、状態、タッチ操作の確認と保守を自分で引き受けてください。どちらでも、日付は入力できます。

## 実装の判断

カレンダーをまったく置かず、形式を示した入力欄だけにしても、それだけで修正になります。カレンダーを足すなら、上のダイアログのように使えるものにします。二つ目の修正前が示すとおり、古いカレンダーを欄の横に残したままでは問題が残るからです。カレンダーのスクリプトが読み込めなくても、欄は使えるようにしておきます。日付ピッカーをライブラリーで描く場合は、flatpickrのallowInputのような入力を許すオプションを有効にし、ドキュメントを信用する前に、下の手順のとおりキーボードとスクリーンリーダーでカレンダーを確認してください。

形式は、入力を始めると消えるプレースホルダーだけでなく、見えるテキストで示します。「[ラベルがない、または表示と食い違うフォームの入力欄](/ja/learn/form-labels)」を参照してください。読み取りも寛容にします。先頭のゼロがあってもなくても、スラッシュの代わりにハイフンやドットで区切っても、示した順なら読み取れます。「2026年11月12日木曜日」のように日付を言葉で欄の横に示し返すと、注文を送る前に読み違いに気づけます。

日曜日のように選べない日も、週の並びをそろえるためにグリッドに残します。`aria-disabled="true"` を付け、矢印キーでは通り過ぎられるようにし、理由を欄の近くにテキストで書きます。標準の日付入力では一日ずつ除くことはできず、`min` と `max` で決められるのは最初と最後の日だけです。

ほかの日付や時刻には、別の欄が合います。

- 生年月日のように本人が知っている日付は、今日の月から開くカレンダーで探すより、入力するほうが速くできます。GOV.UKの日付入力のように、ヒントを添えたfieldsetの中に年、月、日の欄を分けて置くか、形式を示した一つの入力欄にします。
- 時刻には、標準の `<input type="time">` か、「24時間制。例：14:30」のように形式を示した入力欄を使えます。決まった数の配達時間帯なら、ラジオボタンにします。
- divで作った時と分のスクロールする回転式の選択部品は、一つ目の修正前と同じく問題になります。標準の部品と同じキー操作と役割を持たせるか、標準の部品を使ってください。

欄にフォーカスが当たったとたんにカレンダーが開いてフォーカスを奪うのは、別の問題です。「[操作するだけでページが変わるドロップダウンと入力欄](/ja/learn/context-changes)」で扱っています。

## 修正の確認

1. 欄を確認する。ラベル付きの `type="date"` のinputであるか、`readonly` のないテキスト入力欄で、`aria-describedby` が見える形式を指し、`aria-haspopup="dialog"` 付きのボタンが名前のあるダイアログを開き、そのグリッドで `tabindex="0"` を持つセルが一つだけ、選んだ日に `aria-selected="true"`、今日に `aria-current="date"` がある。
2. マウスを使わずにTabキーで欄へ移動し、示された形式で、または標準の欄なら部分ごとに日付を入力して、Tabキーで先へ進む。欄にはその日付が入り、ページはその日付として読み取る。
3. Tabキーで「日付を選択」へ移動してEnterキーを押す。フォーカスは選んだ日か今日にある。矢印キー、Home、End、Page Up、Page Downで移動し、Enterキーで日を選び、もう一度開いて「キャンセル」の先へTab、「前の月」の手前へShift + Tabと押し（フォーカスはカレンダーの中に残る）、Escapeキーを押す。どちらの場合もフォーカスはボタンに戻る。
4. スクリーンリーダーで、Tabキーで欄とカレンダーを移動する。ラベルと形式、届いた日ごとの日付全体、選んだ日の「選択」、今日の「現在の日付」、選んだあとのボタンの名前に含まれる日付が聞こえる。
5. 200%の拡大表示と強制配色で、カレンダーが欄のそばに全体が見える状態で開き、選んだ日、今日、フォーカスの枠がどれも見えることを確認する。

OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。共通の日付欄やカレンダーのコンポーネントを変更した際は、再度確認します。

## 制限

これは日付を一つ選ぶための出発点となる実装例です。チェックインとチェックアウトのような期間の選択、タイムゾーン、和暦のようなグレゴリオ暦以外の暦には当てはまりません。ショップが配達する日かどうかの確認は、コードから省いています。実際の日付を使い、対応するブラウザーと支援技術で、デスクトップだけでなくスマートフォンでも操作全体を確認してください。

---

このガイドをコーディングエージェントで使う: MCP https://easeweb.dev/mcp（設定は https://easeweb.dev/ja/services/developers）
