Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript なしで動作するモダンなコードの書き方

azukiazusa
November 17, 2023

JavaScript なしで動作するモダンなコードの書き方

Next.js、Remix、SvelteKit といった近年のフレームワークは、JavaScript がなくても動作することを一つの価値として提供しています。

例えばSvelteKit のフォームではプログレッシブエンハンスメントとして、JavaScript が利用できる環境ではリッチなユーザー体験を提供しつつ、JavaScript が使えない環境においては HTML のフォームとして振る舞うことでアプリケーションの機能を変わらず提供できます。 React Server Component はサーバー側で HTML に変換されるため、クライアントに JavaScript のコードが配信されることはありません。React Server Component では useState() を使用できないといった制約がありますので、我々開発者は React Server Component の利点を十分に発揮するために、JavaScript を用いた状態管理を行う範囲を狭めることが求められています。

このトークでは、CSS の :has() セレクターや、Popover API といった、従来は JavaScript を用いなければ提供できなかった機能を代替する方法を紹介します。

azukiazusa

November 17, 2023
Tweet

More Decks by azukiazusa

Other Decks in Programming

Transcript

  1. JavaScript なしで動作する
    モダンなコードの書き方
    azukiazusa / JSConf JP 2023

    View full-size slide

  2. アジェンダ
    ● 昨今のフレームワークの動向
    ○ 開発者に求められていること
    ● JavaScript を使わないで動くコードの紹介
    ● まとめ

    View full-size slide

  3. アジェンダ
    ● 昨今のフレームワークの動向
    ○ 開発者に求められていること
    ● JavaScript を使わないで動くコードの紹介
    ● まとめ

    View full-size slide

  4. Progressive Enhancement
    プログレッシブエンハンスメント

    View full-size slide

  5. プログレッシブエンハンスメントな
    フォーム
    ● 可能な限り多くのユーザーに対して機能を提供する
    ○ クライアントの JavaScript が動作しない環境でも、
    必要不可欠な機能を提供する
    ● JavaScript が動作するユーザーに対しては、リッチな体
    験を提供する

    View full-size slide

  6. ハイドレーション前でも操作が
    可能
    FID/INP に有利

    View full-size slide

  7. SvelteKit のフォーム
    ● 古典的な HTML のフォーム
    ● JavaScript が有効な環境であれ
    ば、フルページリロードを取り
    除くなど、ユーザーの体験を強
    化する

    View full-size slide

  8. Remix のフォーム

    View full-size slide

  9. Next.js Server Actions

    View full-size slide

  10. フォームの UI が JavaScript
    なしで動作することが必要

    View full-size slide

  11. React Server Components

    View full-size slide

  12. Server Components がデフォルトとい
    うメンタルモデル
    ● 従来はひとまず useState() から考えていた
    ● useState() を使うには、"use client" を宣言するという
    ステップが追加される
    ○ useState() を使うかわりにパフォーマンスの悪化を受
    け入れますよ、という宣言のようなもの
    ● 先に別の手段を取れないか?を考えるように

    View full-size slide

  13. 開発者に求められていること
    JavaScript で実現していた機能を HTML や CSS など他の
    技術に置き換えつつ、ユーザーの体験を損なわないようにす
    る。

    View full-size slide

  14. HTML や CSS の仕様は進化
    しつつあり、Web の表現力が
    上がっている

    View full-size slide

  15. JavaScript を使わないで動く
    コードの紹介
    https://github.com/azukiazusa1/jsconfjp-2023-demo

    View full-size slide

  16. CSS の :has() 擬似クラス
    ● 引数で渡した要素が存在する場合にスタイルを適用する
    ○ CSS 条件式のようなもの使用できる

    View full-size slide

  17. CSS の :has() 擬似クラス
    .form-group 要素の中に
    検証に失敗した要素
    (:invalid 擬似クラス)があ
    れば、エラーメッセージ
    を表示する

    View full-size slide

  18. :user-invalid 擬似クラス
    ● :invalid 擬似クラスはページをロー
    ドした直後や入力中に評価されると
    いう問題がある
    ○ 今までは JavaScript を使用し
    て任意のタイミングでフィード
    バックを返していた
    ● :user-invalid はユーザーが操作した
    後に検証される

    View full-size slide

  19. field-sizing: content
    入力量に応じて高さが可変する
    textarea を CSS のみで実現

    View full-size slide

  20. ポップオーバー API
    JavaScript を使わずにポップアップを表示する。
    ● ポップオーバーの開閉状態を切り替える要素に popovertarget 属性を指定
    ● ポップオーバーのコンテンツとなる要素に popover を指定

    View full-size slide

  21. アクセシビリティ上必要な機能を備えている
    ● ポップアップの外側をクリックするとポップアップが閉じる
    ● Escape キーを押すとポップアップが閉じる
    ● ポップアップが非表示になったときに、ポップアップ内にフォーカスがある
    場合前にフォーカスしていた要素にフォーカスが戻る
    ● 1 度に 1 つのポップアップしか表示できない
    ● ポップオーバーの表示・非表示を切り替える要素に expanded ステートがア
    クセシビリティツリーに公開される(aria-expanded 属性と同等)

    View full-size slide

  22. 要素
    ● カスタマイズ可能なセレクトボックス
    ● が提供する擬似クラスを
    通じてスタイリングを行う
    ● スロットによりカスタマイズする
    ○ スロットは Web Components の
    と同じ、独自の拡張を入れ
    ることができるプレースホルダー

    View full-size slide


  23. はリストボックスを開閉する要
    素として振る舞う
    ● 要素には、
    現在選択されているオプション
    のテキストを表示する
    ● 内に 要素を
    含めるなど、従来の
    では不可能なパターンの実装も
    可能
    スロットで拡張する例

    View full-size slide

  24. Invokers
    JavaScript を使わずにインタラクションを追加する
    ● 要素に invoketarget 属性を指定する
    ○ invoketarget の値は対象の要素の ID
    ● invokeaction 属性でインタラクションの動作を指定できる

    View full-size slide

  25. 様々な要素が対象となる
    ● popover:ポップオーバーの開閉
    ● ダイアログの開閉
    ● :クロージャーの開閉
    ● , :ピッカーの表示(showPicker())
    ● :再生、停止、ミュート
    ● :再生、停止、ミュート
    ● 任意の要素:fullscreen
    Invokers

    View full-size slide

  26. OpenUI コミュニティグループ
    https://open-ui.org/

    View full-size slide

  27. まとめ
    ● フレームワークの機能を最大限発揮するために、
    JavaScript に頼らないで機能を実現することが求められ
    ている
    ● HTML や CSS の仕様は進化しつつあり、従来は
    JavaScript を使わなければ実現できなかった機能を置き
    換えられるようになってきている

    View full-size slide