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

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

概要

  • 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

HTMLとJavaScriptはそれぞれ異なる目的があるから、比較するのは論理的におかしいよね。複雑でインタラクティブなウェブアプリには、JavaScriptが必須なんだ。HTMLだけで高度なアプリを作ろうとすると(お前のことを見てるぞ、HTMLX)、最終的には機能的な限界にぶつかるんだよ。

でも、こんな風にしなくてもいいはずだよ。HTMLが完全なアプリを作るために必要なことをできない理由はないし。JavaScriptなしで新しいタイプのHTMLマークアップを使えるように、合理的なデフォルトを使うことができるはず。HTTPの動詞も全部。まともなHTML入力コントロール、他には何がある?

おそらくhtmxのことを言ってるんだよね。どちらか一方だけじゃなくて、htmxをJavaScriptで補完することもできるよ。htmxの核心的なアイデアは、単なるJSONの塊じゃなくて、コントロールと構造が組み込まれたハイパーテキストを転送することなんだ。ちょっとしたJavaScriptを使って、htmxだけで驚くほど早く、非常に便利でインタラクティブなアプリを顧客のために作ったばかりなんだ。

これのほとんどは素晴らしいけど、入力やデータリストの部分は、実際のシナリオで使うには機能が不十分だよね。ユーザーは、これらのインターフェースが誤字に寛容で、各オプションの下にオプショナルなサブテキストがあって、モバイルUXの細かい配慮があることを期待してるから、みんなJavaScriptでこれを作るんだよね…

データリストに対する俺の主な不満は、テキスト(例えばビバリーヒルズ)だけを表示して選ばせる簡単な方法がないのに、実際に選ばれる値が数字(例えば90210)であることなんだ。つまり、ビバリーヒルズに対するアナロジーがないってこと。

他の人も、ページに直接載せるんじゃなくてCodepenにリンクしてるのが気になる?ブログシステムだってのはわかるけど、特に「このプレーンHTMLを使って」っていうスタイルの投稿にしては変な感じがするなぁ。

それほど気にはならないかな。著者のCodepenにリンクしてるみたいだし。Codepenを使えばスニペットをブックマークできるし、HTMLやCSSを色付けしてくれる。でも、リンクロットって問題があるから、サードパーティのURLに依存するのは理想的じゃないこともあるよね。

SVGにどれだけのものが入るか、誰にも教えないでほしい。HTMLのソースコードの中にインラインで入れることもできるからね。

プレーンHTMLはすごく居心地がいいんだよね。あの時代に育ったから。マルキータグは永遠に!でも、認めたくはないけど、今の時代にプレーンHTMLとほとんどJSなしで機能するものを作るのはすごく難しい。たとえば、子要素を管理するモデルフォームが欲しいなら、2003年頃のASPっぽいアプリになっちゃう(今の会社のHRシステムみたいに)、ビューやフォームが多すぎるし。HTMXを使うと…結局同じくらい(部分的な)ビューができるけど、今度は暗黙の状態が多すぎて、書き込み専用のコードに近づいちゃう。現代のJSが嫌いなあまり、JSに触れずにインタラクティブなものを実現するためにPhoenix LiveViewを選んだんだけど、実際には包括的な解決策じゃない。ウェブワーカーや通知を扱うためのブリッジも書かなきゃいけなかったし。さらに、Phoenixの未来の方向性、AIに全振りしてるのが心配。正直、嫌悪感を飲み込んで現代のJSを学んで使うべきなんだろうな、どんなに痛くても。クールなものを書いてリリースしたいのに、言語戦争に巻き込まれたくないんだよね。

自分ではあまり使ってないけど、ElixirとPhoenixを知ってるなら、JavaScriptにコンパイルされるGleamが好きかもしれないよ。