10 ポイント 投稿者 GN⁺ 10 일 전 | 1件のコメント | WhatsAppで共有
  • ブラウザーの基本機能から JavaScript メディアクエリ まで、ダークモード実装の範囲を段階的に広げていく 8段階の区分 を整理
  • 最も単純な方法は <meta name="color-scheme" content="light dark"> または color-scheme: light dark の宣言だけで、ユーザーのカラースキーム設定 に従う構成
  • より高い段階では light-dark() 関数、@media (prefers-color-scheme: dark)、スキーム別の 分離スタイルシート により、色だけでなく画像や影まで幅広く調整可能
  • ユーザーのシステム設定に従うだけでなく、Automatic・light・dark の3つの選択肢を提供するスイッチャーを構成でき、:has() と実際の meta 要素 を基準にテーマを判定可能
  • Safari の アクセシビリティ上の限界 や、印刷時の prefers-color-scheme の動作観察まで含まれており、最近の CSS 機能だけでもライト・ダークモードの内蔵が容易になったことが分かる

ダークモードの段階別実装

  • Level 1: Barebone

    • CSS を1行も書かなくても light/dark の区別 を有効化でき、文書の head に <meta name="color-scheme" content="light dark"> を追加するだけでブラウザーがユーザーの カラースキーム設定 に従い始める
    • content 属性の項目順には理論上意味があり、カラースキーム設定を明示していないユーザーには、空白区切りの一覧の先頭の値が適用される
    • 現在の OS 設定にはカラースキームを選択しないオプションがないため、実際には OS 設定と一致するスキームに落ち着く
    • content に単一の値だけを指定することもでき、この場合はユーザー設定を考慮せずそのスキームを強制適用する
    • この meta タグは、ある程度は次の段階の CSS 方式に対応する HTML 側の方法 として機能する
  • Level 2: Basic

    • CSS では html { color-scheme: light dark; } の宣言で ライト/ダークモードの区別 を適用できる
    • すでに DOM に meta タグがあるならこの宣言は不要で、HTML を制御できるならブラウザーが CSS を解析する前から指示を把握できる meta タグの使用が推奨される
    • どちらの方法でも、ユーザーエージェントのデフォルトスタイルと、そこに含まれる ライト/ダークモード を利用できるようになる
    • ここに CSS を追加しつつ、主に CSS system colors の使用に絞れば、かなり整ったデザインを実現できる
    • meta タグが常に文書全体に適用されるのに対し、CSS の color-scheme 宣言はルート要素以外の場所にも設定でき、この違いにより追加の活用余地がある
  • Level 3: Benign

    • 比較的新しく追加された CSS の light-dark() 色関数 により、単純なライト/ダークモード調整が可能
    • 例では background-color: light-dark(black, white);color: light-dark(white, black); のように使い、最初の引数はライトモードに、2番目の引数はダークモードに適用される
    • 引数には実際の色を直接入れることもできるし、色として解釈される custom properties を入れることもできる
    • この記事全体の中では、この段階だけが執筆時点では ブラウザー対応 がまだ十分ではない
  • Level 4: Bold

    • 従来の @media (prefers-color-scheme: dark) メディアクエリ でダークモード切り替えを実装できる
    • lightdark のどちらを問い合わせても、単なる色変更にとどまらない 最大レベルのカスタマイズ が可能
    • ダークモードで画像をフィルターで低彩度にしたり、ボックスシャドウをアウトラインに置き換えたりする調整もすべて可能
  • Level 5: Bisectional

    • メディアクエリは HTML でも使え、link 要素の media 属性に入れて スキーム別スタイルシート を分離できる
    • 例として light.cssdark.css をそれぞれ prefers-color-scheme: lightprefers-color-scheme: dark に結びつける方法が示されている
    • カスタマイズ範囲が大きい場合は専用ファイル構成が適しており、ブラウザーはクエリに一致しない CSS ファイルを無視できるため、ダウンロード対象を1つ減らせる可能性がある
  • Level 6: Ballistic

    • JavaScript では window.matchMedia('(prefers-color-scheme:dark)')カラースキームのメディアクエリ を使える
    • 他のメディアクエリと同じ方法でライトまたはダークスキームかどうかを問い合わせ、その結果に基づいて任意の処理を行える
    • 実際の実装では、前段までの手法を1つだけに固定せず 組み合わせて適用 できる

ユーザースイッチャーと高度なパターン

  • Level 7: Beyond

    • ユーザーのシステム設定だけに依存せず、color scheme switcher を構築できる
    • このスイッチャーは単純な真偽値ではなく、初期デフォルトとして prefers-color-scheme に従う Automatic モードが必要
    • その上にスイッチャーを載せると、ユーザーは Automatic、light、dark の 3つのモード から1つを選べる
  • Level 8: Beguiling

    • Level 7 のスイッチャー実装では、一般に HTML 要素へ .dark クラスや data-theme="dark" のような属性を追加する方式がよく使われる
    • その代わりに :has() を使って、実際の <meta name="color-scheme" content="dark"> の有無を直接問い合わせることができる
    • 例では html:has(meta[name="color-scheme"][content="dark"]) セレクターの下で、--color-bg--color-text のような CSS 変数 をダークモード用の値に設定している
    • 別途クラスやデータ属性がなくても、実際の meta 要素 を基準にテーマを判定できる

追加の議論と観察

  • CSS Naked Day での観察

    • スタイルを外して訪れたほぼすべてのサイトで ダークモード不在 が目立ち、これがダークモードの段階分けにつながった
    • 新しいサイトを最初から構築して新しいスタイルを書く場合、最近の CSS 機能により ライト/ダークモードの内蔵 が非常に容易になったとの言及を含む
  • Safari のアクセシビリティ問題

    • 比較的最近まで Safari はダークモードで アクセシブルなリンク色 を提供していなかったという指摘を含む
    • 以前の CSS Naked Day ではこの問題を見つけ、meta タグを削除してライトカラースキームだけを使った経験にも触れている
    • その後 meta タグを再び追加したが、旧バージョンの Safari 利用者には アクセシビリティ低下 が生じうることを認識している
    • Safari のダークモードではテキストボックスに 見える境界線がない ことも確認された
    • ユーザーエージェントのスタイルだけでは、正しいセマンティック HTML を使っていても完全なアクセシビリティは保証できず、今後の CSS Naked Day でも十分なスタイルを維持する方法を考えている
  • 印刷と screen and 条件

    • Bisectional の例で screen and ... を使った理由として、プリンター向けの除外 を意図したことに触れている
    • テーマ非依存のコアスタイルシートや専用の印刷スタイルシートが別にあると仮定し、プリンターでダークモードがインクを多く使う可能性があるため、安全のため分離しようという判断が示されている
    • 実際のテストでは、システムのダークモードを有効にした状態で印刷しても黒い文字と白い紙だけが出力され、ブラウザーは印刷時にそのダークモードスタイルを適用していないようだと観察された
    • 追加テストでは、印刷プレビューでは prefers-color-scheme が常に light と報告され、Firefox と Chromium で確認された
    • 黒い紙と白いインクを使うプリンターがあれば残念だ、という冗談めいた言及も含まれる

1件のコメント

 
GN⁺ 10 일 전
Hacker Newsのコメント
  • カスタムを多用するなら専用ファイルという発想自体は分かるが、メディアクエリに一致しないCSSはそもそもダウンロードすらされないという説明は、実際のブラウザ挙動とは違うと思う。私の経験では、ブラウザは結局全部ダウンロードして、優先度を変えるだけだ
  • サーバーから初期コンテンツが返ってくるのを待つ間に起きるフラッシュバンのようなまぶしい点滅を防ぐ方法が、いまだにないのか気になった
    • 私はFirefoxのuserContent.cssbackground-colorを指定するやり方が悪くないと思う
    • 私は単に画面の明るさを下げてダークモードを切ったら、フラッシュバンがなくなった。おまけにバッテリーも長持ちする
  • 私はこの記事が、ダークモード背景の黒の濃さの好みについての話だと思っていた。純粋な黒のほうがOLEDでバッテリー効率が良いとも聞くし、完全な黒よりインクの少ないグレーを好む人も知っている。ただ、わざわざ6段階も必要かはよく分からず、体感できるのは多くても3〜4段階くらいだと感じた
    • 私はもっと一般的な解決策はReader Mode互換性の標準化だと思っていた。各サイトがあらゆるユーザーの好みに一つひとつ対応するn x m問題にするより、サイトは1つのシンプルなコンテンツビューだけを提供し、その上でブラウザがユーザーごとの設定を引き受ける構造のほうが良いと思う
    • 私はOLEDでは純粋な黒を好むほうだ。点灯するピクセルが少ないほど焼き付きの負担が減ると感じるし、どうせ寿命には限りがあるのだから、長期的にはモニターを2〜3年ではなく5年以上使いたいという考えだ
  • 私の基準での最高レベルは9、さもなければ0で、つまりコンピューターを切ってそのまま寝ること
  • 私はOPが3状態トグルをきちんと実装していたのがうれしかった
  • スクロールしていくにつれて段階が動的に適用されたら、もっと面白かったと思う
    • あるいは、ページ内の適切な位置ごとに読者が自分で段階選択できてもよかったと思う
  • 私には8段階ではないかと思えた
  • 今が2024年なのだと感じた
  • この状況で思い浮かぶのはやはりxkcd 3227だった