社内LT会 / Frontend Conference Nagoya 2026 前夜祭!


autofocusの正しい用法を
知っていますか?


ぶりお @burio_16

ぶりおの写真

自己紹介

  • ぶりお @burio_16
  • タコスとTottenham Hotspur FCが大好き
  • 最近食品衛生責任者の資格講習を受けたので
    みんなにタコスを振る舞うことができるようになりました🌮

フロントエンドカンファレンスで
プロポーザル通らなかったので
ここで発散します!

autofocusってなーに?

autofocus属性

  • HTMLのグローバル属性で、ページ読み込み時に要素にフォーカスを当てる
  • どの要素にも付与できる(フォーカス可能な要素でのみ効果あり)
  • 複数の要素に付与することができるが、フォーカスは最初のものに当たる
<input type="text" autofocus />

なんで遭遇したんだ?

ESLint jsx-a11yの導入

  • SonarQubeでa11yの指摘を受けたPRがきっかけ
  • 「そもそもa11yのLintルール入ってなくない?」と気づいた
  • eslint-plugin-jsx-a11yを自分で導入
  • するとjsx-a11y/no-autofocusの警告が発生
  • そこで初めてautofocusという属性の存在を知った
a11y周り修正 PR #532

最初の選択肢

  • ESLintのエラーなので、単純にautofocusを消すこともできた
  • でも知らなかった属性だったので、ちゃんと調べてみた

なんでエラーなるん?

jsx-a11y/no-autofocusの理由

  • autofocusはページ読み込み時にフォーカスを強制的に移動させる
  • スクリーンリーダーユーザーにとって混乱の原因になる
    • ページの先頭から読み上げが始まらない
    • フォーカスが突然移動し、現在位置を見失う
oxlint jsx-a11y/no-autofocus の警告出力

Demo: よくないautofocusの使い方

ページ読み込み時に意図しない場所へフォーカスが飛ぶ

↓ 本来はここから順番に読んでほしい

1. まずはこの説明を読んでください

2. 次にこちらの内容を確認してください

3. でもこのdivにautofocusが付いているので、ここに飛ばされる

正しい使い方も知りたい!!

ドキュメント読んだ感じ
こう使うのが良さそう!

W3Cの推奨

  • autofocusはユーザーの操作に応じて表示される要素で使うべき
    • ダイアログ / モーダル
    • ポップオーバー
    • ドロワー
  • ページの初期読み込み時には使わない
  • 「ユーザーがアクションを起こした結果、フォーカスが移る」のが正しい

なぜダイアログでは正しいのか

  • ユーザーが能動的にダイアログを開いている
  • フォーカスがダイアログ内に移ることは期待される動作
  • スクリーンリーダーでも自然な流れになる
  • フォーカストラップと組み合わせるとさらに良い

Demo: 正しい用法 — ダイアログ内のautofocus

ユーザーの操作でダイアログが開き、入力欄にフォーカス

ログイン

Demo: W3C APG推奨 — キャンセルにautofocus

不可逆な操作ではキャンセルにフォーカスを置き、誤操作を防ぐ

⚠️ アカウント削除

この操作は取り消せません。

すべてのデータが完全に削除されます。本当に削除しますか?

デザインシステムとDialog

  • 最近チームでデザインシステムを構築中
  • チームメンバーがDialogコンポーネントを実装
  • レビュー時に「フォーカス制御あるかな?」と確認したら…あった!

Radix UI Dialog の onOpenAutoFocus

  • Dialog.ContentonOpenAutoFocus propがある
  • HTML autofocus を使わずにフォーカス制御ができる → Linterにも怒られない
<Dialog.Content
  onOpenAutoFocus={(event) => {
    event.preventDefault();
    cancelButtonRef.current?.focus();
  }}
>
  ...
</Dialog.Content>
  • onCloseAutoFocus で閉じた後のフォーカス先も制御できる

Demo: onOpenAutoFocus でキャンセルにフォーカス

HTML autofocusなしで、Linterにも怒られない

Base UIにも同様の仕組みがある

  • Base UIのDialogには initialFocus propがある
  • Radix UI: onOpenAutoFocus / Base UI: initialFocus — アプローチは違うが同じことができる
  • shadcn/uiはどちらのプリミティブにも対応しているので、いい感じにフォーカス制御できる
Radix UIBase UI
開いた時onOpenAutoFocusinitialFocus
閉じた時onCloseAutoFocusfinalFocus

まとめ

まとめ

  • autofocusはどの要素にも付けられるグローバル属性
  • Linterが警告するのはa11y的にユーザーを混乱させる可能性がある
  • ダイアログやモーダル内での使用が正しいパターン
  • UIライブラリにもフォーカス制御の仕組みが用意されている
  • ESLintのエラーを「消す」のではなく「調べた」ことで正しい知識を得られた

次は絶対にプロポーザル通すぞ!!!!
目指せカンファレンス登壇!!

【宣伝】Frontend Conference Nagoya 2026 前夜祭!

Frontend Conference Nagoya 2026 前夜祭 - 2026.05.08(Fri) 19:00 株式会社スタメン 名古屋オフィス
  • 2026.05.08(Fri) 19:00
  • 株式会社スタメン 名古屋オフィス
  • プロポーザルの供養がてら登壇してきます!!
  • stmn.connpass.com/event/390165