世界を動かす技術を、日本語で。

JavaScriptを単なるHTMLに置き換える

2025年12月28日原文(htmhell.dev)

概要

  • JavaScript の役割が変化し、 HTMLやCSSの進化 による代替が可能に
  • JSの利用を減らし、 パフォーマンス向上ユーザー体験の最適化 を目指す流れ
  • 具体的な代替例として アコーディオン入力補助ドロップダウンモーダル/ポップオーバーオフスクリーンナビ を紹介
  • 各機能の HTML/CSS実装例注意点 を解説
  • リソースリンクブラウザ対応状況 も掲載

JavaScriptの役割再考とHTML/CSS活用のすすめ

  • 長年、 JavaScript はWebの主力技術
  • 近年、 HTMLCSS の標準機能が拡張
  • JSで実装していたUI機能を ネイティブ要素 で代替可能に
  • JSはより重要な処理や高度な機能に集中すべき時代
  • ネイティブ化で ダウンロード量削減パフォーマンス最適化アクセシビリティ向上

アコーディオン/展開式コンテンツパネル

  • detailssummary 要素でJS不要のアコーディオン実装
  • 代表的な用途: コンテンツの開閉セクションの展開
  • 基本構造:
    • <details><summary>タイトル</summary>内容</details>
    • open属性でデフォルト展開状態を設定
  • name属性 でラジオボタンのように 1つだけ展開 も可能
  • CSSJS で見た目や挙動のカスタマイズも柔軟
  • 参考: MDN detailsページ
  • ブラウザ対応 :主要ブラウザで広くサポート

入力補助・オートフィルタドロップダウン

  • inputdatalist 要素で自動候補ドロップダウンを実現
  • 用途例: サイト内検索商品検索リストフィルタ
  • 基本構造:
    • <input type="text" list="候補ID" />
    • <datalist id="候補ID"><option value="候補1"></option>...</datalist>
  • numbertime など他のinput型にも適用可能
  • 制限事項 :Firefoxはテキスト型のみ対応、モバイルやアクセシビリティに課題
  • 参考: MDN datalistページ
  • ブラウザ対応 :一部制限あり

モーダル/ポップオーバー

  • popover属性popovertarget属性 でモーダルやポップオーバーをJSなしで実装
  • 用途例: サイドパネル補足情報の表示
  • 主なタイプ:
    • auto :外部クリックやEscで閉じる
    • hint :複数同時表示可能(Firefox/iOS未対応)
    • manual :手動でのみ開閉
  • 基本構造:
    • <button popovertarget="ID">トグル</button>
    • <dialog popover id="ID">内容</dialog>
  • 詳細: MDN popoverページ
  • アクセシビリティブラウザ対応 に注意

オフスクリーンナビゲーション/コンテンツ

  • popover 機能を応用し、 オフスクリーンメニュー をJS不要で実現
  • 用途例: ナビゲーションメニューの開閉
  • 基本構造:
    • <button popovertarget="menu">メニュー</button>
    • <nav popover id="menu">ナビ内容</nav>
    • CSSでtranslateを利用し、画面外からスライドイン
  • backdrop 疑似要素で背景の装飾も可能
  • manual 指定で明示的な閉じ方も設定可
  • 詳細: MDN popoverページ 参照
  • ブラウザ対応 :主要ブラウザで対応進行中

結論・今後の展望

  • JavaScript のパワーと柔軟性は健在
  • しかし HTML/CSSの進化 を活かし、JSの利用を 本当に必要な場面 に限定することが重要
  • パフォーマンスアクセシビリティ の向上、 メンテナンス性 の強化
  • CSSの新機能も多数登場、さらなるノーJS・ローJS化が可能
  • 詳細・実装例は長文記事を参照

著者情報:Aaron T. Grogg

  • Web Developer/パフォーマンス最適化スペシャリスト
  • Blog: aarontgrogg.com
  • BlueSky: aarontgrogg.bsky.social
  • Mastodon: mastodon.social/@aarontgrogg
  • LinkedIn: linkedin.com/in/aarontgrogg

Hackerたちの意見

オートフィルターの提案ドロップダウンに入力すると、フィールドにタイプミスがあったり、入力した内容の最初に始まらないオプションを表示したいときが大変なんだよね(Google検索のオートコンプリートみたいに)。JavaScriptでフィルタリングして特定のオプションを強制的に表示させる方法がないから、検索提案には別の方法を使ってるよ。

新しいアプリやサイトを作るときは、まずはHTMLだけのオートフィルターみたいなシンプルな解決策から始めて、後で複雑な動作を追加するのがいいよね。こういう選択肢があるって知っておくのは大事だよ。最初から重いReactコンポーネントに手を伸ばす必要はないから。

追加の複雑さを加える前に、プラットフォームがすでに提供しているものを考慮するように促してくれる実用的な例を見るのはいいね。

クライアントから「Edgeで動かない」って言われて、原因が各ブラウザのスタイリングがそれぞれ異なっていて、本当に長いオプションを正しく表示させるのが不可能だってわかると、もうどうしようもないよね。結局、アクセシブルで正しくテーマが設定されたコンボボックスを実装するためのバグ修正の時間が与えられるだけで、最初からそれを使うべきだったって思うよ。先週のネイティブ日付ピッカーの時と同じように。

ページの上部にあるペンタグラムは、JSが有効になってないと読み込まれないよ。

なんか… しっくりくるよね、メタ的で。

詳細/要約の機能が本当に苦手なんだ。基本的にできないことはないから。マーカーを隠したり置き換えたりするのは簡単だし。でも、どのコンポーネントライブラリも存在しないかのように振る舞うんだよね。これらのタグは、すべてのariaコントロールや展開タグを省略できるから、手間が省けるんだ。

詳細は、display: contentsに設定してもちゃんと機能するから、さらに柔軟性があるよ。ただ、オープンからクローズへのアニメーションはまだできないけどね。それが最後のフラストレーションかな。

テキストをプレビューしたいときにはうまく機能する?例えば、段落の最初の100文字を表示して、クリックで展開するみたいな?

実際には、マークアップからオープン状態を適切に制御できないんだよ(open属性はデフォルトの状態を設定するだけだから)、だから俺はこれを使うのを避けてるんだ。

詳細/要約のやつ、ほんとに困る。基本的にできないことはないからね。詳細要素をアニメーションさせるのは難しい。仕様によると、ブラウザはdisplay: noneとdisplay: blockの間のトランジションをネイティブでサポートしてないんだ。

俺が結構期待してるのは、カスタマイズ可能なセレクトボックスだね!今、WHATWGのステージ3にあるらしい。JavaScriptベースのカスタムドロップダウンコンポーネントには、ほんとにひどいのをたくさん見てきたよ。 https://developer.chrome.com/blog/a-customizable-select

Hacker Newsで議論の続きを見る