Whole Web Dev Tips

Contents List

font-weight

Normal (400)

Lorem Ipsum isNormal simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since 1966

Bold (700)

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since 1966

font-size

Change Font Size

Change Font Size

14pxCaution

常用は避けるべき。
狭いスペースや付帯情報など、特定の状況でのみ使用可能。

Under 13pxDon't Use

原則として許容されない。

line-height

line-height: 1

主にボタンなど、コンポーネント内で使用されるワンラインのテキストで上下の余白を持っていない行間。主にボタンなど、コンポーネント内で使用されるワンラインのテキストで上下の余白を持っていない行間

line-height: 1.2default

主に管理画面や業務システムの画面等で、膨大な情報を一覧表示したりなど、限られた画面領域での表示情報量を最優先した行間。主に管理画面や業務システムの画面等で、膨大な情報を一覧表示したりなど、限られた画面領域での表示情報量を最優先した行間

line-height: 1.3

主に管理画面や業務システムの画面等で使用する、表示情報量を優先した行間。主に管理画面や業務システムの画面等で使用する、表示情報量を優先した行間

line-height: 1.4

見出しなど、やや大きな文字に使用される行間。見出しなど、やや大きな文字に使用される行間。見出しなど、やや大きな文字に使用される行間。見出しなど、やや大きな文字に使用される行間。

line-height: 1.5

一般的なウェブサイトの本文や見出しで使用される行間(本文の行間としては最低限度)。一般的なウェブサイトの本文や見出しで使用される行間(本文の行間としては最低限度)

line-height: 1.6

一般的なウェブサイトの本文で使用される行間。一般的なウェブサイトの本文で使用される行間。一般的なウェブサイトの本文で使用される行間。一般的なウェブサイトの本文で使用される行間。

line-height: 1.7Suggested

一般的なウェブサイトの本文で使用する、心理的負荷の軽減を考慮した行間。一般的なウェブサイトの本文で使用する、心理的負荷の軽減を考慮した行間。一般的なウェブサイトの本文で使用する、心理的負荷の軽減を考慮した行間。

line-height: 1.75

一般的なウェブサイトの本文で使用する、心理的負荷の軽減を考慮した行間。採用するグリッド幅やフォントサイズに応じて170%と使い分ける。一般的なウェブサイトの本文で使用する、心理的負荷の軽減を考慮した行間。採用するグリッド幅やフォントサイズに応じて170%と使い分ける

Color Functions

(RGB) RGB

sRGB色空間を基準に指定する。
色空間のデファクトスタンダードであり、色に関するあらゆる環境が対応していると考えてよい。拡張規格としてAdobeRGBなどが存在するものの、モニタ、実印刷共に対応環境が不揃いで汎用性にかけるため「失敗しないカラープロファイル」はsRGB一択となっている。
想定用途としては「正確なRGB指定を行いたい」場合や「既存デザインとの互換性が求められる」ケースなど。

RGBA (0001)

(RGB) HSL

Hue(色相)、彩度(Saturation)、輝度/明度(Lightness)、透明度(Alpha)の4項目で色を指定する方法。
Hueについては360度周期で指定できるため、例えばcalc(360 - 480)と計算したい場合は 120 と丸められる。この特徴を活かして色相を特定間隔で移動させ、要素が連続する場合のグラデーションを簡易に作成することができる。
つまるところRGB()つまり色相をHで固定し、彩度、明度で差分を出していく用途に適切。

background-color:

HSL with Relative Color

大半の色指定関数はベースカラーにrgb()、hwb()、Lab()などを基準として指定可能、相対色の作成を行うことができる。

background-color:

HSL with Conic Gradient

background:

(RGB) HWB

Hue(色相)、Whiteness(白色度)、Blackness(黑色度)、 Alpha(透明度)の4項目で色を指定する方法。
HSLと異なり色の変化を白・黒の差し引きで行う。
こちらも同じくベースカラーを基にした相対色の作成が可能。
用途としては「RGBからの差分を白黒ベースで作成したい場合」か。

background-color:

(Lab) Lab

いわゆるCIELABと呼ばれるプロファイルで、人間の知覚を基準にした色空間。
物体色を表すために用いられる最もポピュラーな表色系とされ、国際規格自体は76年に定められている。
明度を保ったままの色調整に重用され、例えばRGBプロファイルで作成したデータをCMYK出力に変更したい場合のくすみ調整などに用いられる。
こちらも同じくベースカラーを基にした相対色の作成が可能。

  • ・Lightness: 知覚的な明度
  • ・a: 緑から赤の軸。負側が緑、正側が赤
  • ・b: 青から黄色の軸。負側が青、正側が黄色

▼Graph

※bは以下図における“奥行き”である

↑
C
a →
くすんだ(dull)
極薄い(very pale)
薄い(pale)
明るい(light)
灰(grayish)
鮮やかな(vivid)
ごく暗い(very dark)
暗い(dark)
濃い(deep)
H →

background-color:

Lab with Gradient

background-color:

(Lab) LCH
Labをベースに考案された表色系で、Labを円筒形上に表したもの。
それぞれL(明度)、C(彩度)、H(色相角度)を表す。
詳細は以下図を参照。
+b+a外縁ほど +L
030603060

background-color:

(OKLab) OKLab / OKLCH

Lab / LCH がCIEL*A*B*をベースに1976年制定されたものであるのに対し、OKLabおよびOKLCHは2020年にCIE DE2000準拠で策定されたOKLabを基に設計された新興表色系である。
Labに対するOKLabの優位性としては「色ムラの改善」特に青~紫周辺にグラデーションに発生していたムラを改善できる点が上げられる。
人間の知覚的に正しい表色系として策定されたLabであるが、人間には「彩度が高いほど色差を見分けにくくなる」「色により色差を見分ける精度が根本的に異なってしまう」といった傾向があり、知覚ベースで考えた場合上述の通りLabでは青~紫周辺に不備が生ずる状況であった。
具体的にどの色域でどのような不備が発生するかについては以下コニカミノルタ『色色雑学』に詳しい。
▶ 新しい色差式(CIE DE2000)について。

既存Lab/LCHとの使い分けとしては以下2点が挙げられやすい。
・Lab/LCH:印刷物などCIELABを用いる必要のある状況
・OKLab/OKLCH:WebUIの色設計、Web用カラースキームの作成

またOKLabとOKLCHの違いとしては正しくLabとLCHの違いのままで、a軸b軸線上で色を作成したい場合はOKLab、色相や彩度を固定したままサブカラーを作成したい場合はOKLCH、となる。
典型的ユースケースであるWebUI作成やカラースキーム作成においては、サブカラーを破綻無く作成しやすいOKLCHが優先されるだろう。
つまるところ「新規格で用途は限られるがさらに人間の知覚に近づいたLab」といったところか。

background-color:

background-color:

Compare CIELab vs OKLab

上段がLab、下段がOKLab表色系。
全てに視認できる差異がある。赤に関しては左端始点の明度を落とすと差異が確認しづらくなる(明度が高い範囲では大きな差異がある)

↑Lab / ↓OKLab

(Other) Color()

sRGB以外の色区間を指定して色を出力したい場合に用いる。
指定できる色域は以下表参照。

background-color:

srgb
srgb-linear
display-p3
a98-rgb
prophoto-rgb
rec2020
xyz
xyz-d50
xyz-d65
色空間
具体的な特徴
主な用途
srgb
Webの標準的な RGB。白色点は D65。#ff0000 や rgb() と同じ色域。
一般的な Web ページ、画像、UI の色指定。
srgb-linear
色域と白色点は sRGB と同じですが、成分値が光の強さに比例します。
光を混ぜる計算や、color-mix(in srgb-linear, …) のような補間。
display-p3
sRGB より鮮やかな赤・緑などを表せる広色域 RGB。D65、数値の明るさの扱いは sRGB と同じです。
広色域ディスプレイ向けの Web デザインや写真の色。映画用の DCI-P3 とは白色点などが異なります。
a98-rgb
Adobe RGB (1998)。特に緑・シアン方面が sRGB より広く、白色点は D65。
写真編集や印刷を見据えた画像の色を、CSS でも対応する色として指定するとき。CMYK そのものではありません。
prophoto-rgb
非常に広い RGB。白色点は D50。表現範囲の一部には実在しない色も含まれます。
写真の編集・保存で広い色情報を保つ作業用色空間。通常のディスプレイでは全域を表示できません。
rec2020
UHD テレビ向けの非常に広い RGB。白色点は D65。
4K・8K 映像で使われる色域に基づく色指定。ただし CSS で rec2020 と書くだけで HDR 表示になるわけではありません。
xyz
CIE XYZ の D65 版の別名です。RGB ではなく X Y Z の値で指定し、Y は相対的な輝度を表します。
色空間間の変換や測定値の表現。
xyz-d50
白の基準を D50 とした XYZ。
ICC プロファイルや Lab、印刷関連の色変換とのやり取り。
xyz-d65
白の基準を D65 とした XYZ。xyz と同じ意味です。
sRGB や Display P3 など、D65 を基準とする色との変換。

▼白色点とは

色空間の中で「コレを白とする」と定めた色の基準。白がどのような色味の光かを示す。
この基準があるため、RGBの各成分や「色味のないグレー」を一意に解釈することができる。

上記表に出てくるD65およびD50は、どちらも標準的な昼光を基準にした白色点となる。

  • ・D65:約6500Kの昼光に相当する白。sRGB、Display P3、Adobe RGB、Rec.2020などで用いられる。
  • ・D50:5000Kの昼光に相当する白。CSSのlab()、印刷関連の色管理などで用いる。

例えばRGBではcolor(srgb 1 1 1)もcolor(prophoto-rgb 1 1 1)もそれぞれの色空間での「白」だが、ただし前者の基準はD65、後者はD50となる。
一方XYZ系では白の座標そのものが以下のように異なる。


    color(xyz-d65 0.9505 1 1.089)
    color(xyz-d50 0.9643 1 0.8251)
      

いずれもYは1、つまり基準となる白の相対的な輝度は同一だが、白の色味の基準が異なる。
色管理に対応したブラウザはこの違いを考慮してモニタ向けに変換する。そのためCSSでD50を用いるたびモニタのプロファイルをD50へ切り替える必要はない。

@media color-gamut

    /* 指定可能な色空間は srgb / p3 / rec2020 の3つ */
    @media (color-gamut: rec2020) {
      background-image: radial-gradient(in oklab, oklch(0.6 0 0), transparent 72%);
    }

    @media (color-gamut: p3) {
      background-color: color(display-p3 1 1 0);
    }
        

「クライアント(ブラウザ)が指定した色域に対応しているか」によって適用するスタイルを変更するためのメディア特性。
・srgb:ユーザエージェントと出力機器がsRGBに対応しているか否か。大概のモニタが対応。
・p3:Display P3またはそれ以上の色域に対応しているか。sRGBが含まれる。
・rec2020:ITU-R 勧告 BT.2020またはそれ以上に対応しているか。P3を含む。

device-cmyk

Images

Explanation

sizes属性の登場により画像の実装は実に面倒なことになっている。

原則picture要素で拡張子フォールバックを担保し、各クエリごとに表示幅が固定(画面幅に追従しない)の場合は、「DPIに沿う画像密度」のみ考慮すればよいので密度記述子 1x、
画面幅の拡大に合わせグングン画像が拡大していく場合は幅記述子 sizes + wが妥当となる。

sizes 属性内で幅記述子と密度記述子は併記不可能なため一見同属性では高 DPI 環境へ対応できないように思えるが、大方の場合ブラウザ側が CSS 表示幅と DPI を掛けた横幅から要求する画像を判断するため、幅記述子でも@3xまでをざっくり用意すれば高 DPI への対応は可能。

具体的なパターンに基づいた事例は以下 Sample Code を参照。

              
    表示する画像がガチンコで1枚だけ?
      ├─ はい → srcsetもsizesも不要(img srcだけ)
      └─ いいえ
          └─ CSS 上の表示幅は画面幅に応じて変わる?
              ├─ いいえ 各クエリごとに幅が固定 >> サイズ記述子のみでOK
              └─ はい width: 100%などで流動的に変わる >> picture + sizes + 幅記述子
              
            

▼共通ルール

  • ・sizes属性は"レンダリング時の画面幅"を基に最適な画像サイズを選択する。
  • ・sizes属性は"画面幅拡大に合わせ大サイズの画像へ自動で切り替える"が、縮小時は元に戻さない(※ブラウザの挙動に依存する)
  • ・フォールバックが発生する可能性の高い拡張子から上行に記述する
  • ・PCに対しSPを上行に記載する
  • ・拡張子ごとにPCとSPをまとめる
  • ・全img, sourceにwidth, heightを指定する(省略可能パターンもあるが考えるだけ無駄)
  • ・密度記述子のみの場合sizes属性は不要
Sample Code - with Different Aspects


    各クエリごとに画像の表示幅が固定で、DPIにのみ注意すればよい場合は、
    密度記述子 Nx を用いてDPIに比例した倍数の解像度を持つ画像セットを用意する

    <!-- 密度記述子 -->
    <picture>
      <source
        media="(max-width: 767px)"
        type="image/avif"
        srcset="img_01_sp.avif 1x, img_01_sp@2x.avif 2x, img_01_sp@3x.avif 3x"
        width="300"
        height="400"
      >
      <source
        media="(max-width: 1200px)"
        type="image/avif"
        srcset="img_01_tb.avif 1x, img_01_tb@2x.avif 2x, img_01_tb@3x.avif 3x"
        width="1000"
        height="1000"
      >
      <source
        type="image/avif"
        srcset="img_01.avif 1x, img_01@2x.avif 2x, img_01@3x.avif 3x"
        width="1200"
        height="900"
      />
      <source
        media="(max-width: 767px)"
        type="image/webp"
        srcset="img_01_sp.webp 1x, img_01_sp@2x.webp 2x, img_01_sp@3x.webp 3x"
        width="300"
        height="400"
      >
      <source
        media="(max-width: 1200px)"
        type="image/webp"
        srcset="img_01_tb.webp 1x, img_01_tb@2x.webp 2x, img_01_tb@3x.webp 3x"
        width="1000"
        height="1000"
      >
      <source 
        type="image/webp"
        srcset="img_01.webp 1x, img_01@2x.webp 2x, img_01@3x.webp 3x"
        width="1200"
        height="900"
      />
      <source
        media="(max-width: 767px)"
        srcset="img_01_sp.jpg 1x, img_01_sp@2x.jpg 2x, img_01_sp@3x.jpg 3x"
        width="300"
        height="400"
      >
      <source
        media="(max-width: 1200px)"
        srcset="img_01_tb.jpg 1x, img_01_tb@2x.jpg 2x, img_01_tb@3x.jpg 3x"
        width="1000"
        height="1000"
      >
      <img
        srcset="img_01.jpg 1x, img_01@2x.jpg 2x, img_01@3x.jpg 3x"
        src="img_01.jpg"
        width="1200"
        height="900"
        alt="test image"
        loading="lazy"
      >
    </picture>
        
Sample Code - with Different Aspects / Responsive Size


    ・クエリごとに画像のアスペクト比が変化する
    ・inline-size: 100% など画面幅に合わせ表示サイズ横幅が可変する
    場合は
    ・アスペクト比変化への対応:picture タグ
    ・画面幅に合わせた表示サイズの変化 sizes 属性
    で対応する

    <!-- クエリごとにアスペクト比が異なる且つ横幅が可変する画像に対する picture + 幅記述子 -->
    <picture>
      <source
        media="(max-width: 767px)"
        type="image/avif"
        srcset="img_01_sp.avif 300w, img_01_sp@2x.avif 600w, img_01_sp@3x.avif 900w"
        sizes="100dvw"
        width="300"
        height="400"
      >
      <source
        media="(max-width: 1200px)"
        type="image/avif"
        srcset="img_01_tb.avif 1000w, img_01_tb@2x.avif 2000w, img_01_tb@3x.avif 3000w"
        sizes="100dvw"
        width="1000"
        height="1000"
      >
      <source
        type="image/avif"
        srcset="img_01.avif 1200w, img_01@2x.avif 2400w, img_01@3x.avif 3600w"
        sizes="1200px"
        width="1200"
        height="900"
      />
      <source
        media="(max-width: 767px)"
        type="image/webp"
        srcset="img_01_sp.webp 300w, img_01_sp@2x.webp 600w, img_01_sp@3x.webp 900w"
        sizes="100dvw"
        width="300"
        height="400"
      >
      <source
        media="(max-width: 1200px)"
        type="image/webp"
        srcset="img_01_tb.webp 1000w, img_01_tb@2x.webp 2000w, img_01_tb@3x.webp 3000w"
        sizes="100dvw"
        width="1000"
        height="1000"
      >
      <source 
        type="image/webp"
        srcset="img_01.webp 1200w, img_01@2x.webp 2400w, img_01@3x.webp 3600w"
        sizes="1200px"
        width="1200"
        height="900"
      />
      <source
        media="(max-width: 767px)"
        srcset="img_01_sp.jpg 300w, img_01_sp@2x.jpg 600w, img_01_sp@3x.jpg 900w"
        sizes="100dvw"
        width="300"
        height="400"
      >
      <source
        media="(max-width: 1200px)"
        srcset="img_01_tb.jpg 1000w, img_01_tb@2x.jpg 2000w, img_01_tb@3x.jpg 3000w"
        sizes="100dvw"
        width="1000"
        height="1000"
      >
      <img
        srcset="img_01.jpg 1200w, img_01@2x.jpg 2400w, img_01@3x.jpg 3600w"
        src="img_01.jpg"
        width="1200"
        height="900"
        sizes="(max-width: 1200px) 100dvw, 1200px"
        alt="test image"
        loading="lazy"
      >
    </picture>
        
Sample Code - with Same Aspects / Different Extension

    ・画像のアスペクト比がクエリ間で共通
    ・画面横幅に合わせ画像表示サイズも拡縮する
    場合は sizes 属性のみの対応で問題ない。
    複数拡張子に対応するため picture 要素は使用することになるが、記述量は例2より大幅に削減される。

    <!-- 画像のアスペクト比がクエリで変わらない且つ画面幅に画像サイズが追従する場合 -->
    <picture>
      <source
        type="image/avif"
        srcset="img_01_sp.avif 300w, img_01_sp@2x.avif 600w, img_01_sp@3x.avif 900w, img_01_tb.avif 1000w, img_01.avif 1200w, img_01_tb@2x.avif 2000w, img_01@2x.avif 2400w, img_01_tb@3x.avif 3000w, img_01@3x.avif 3600w"
        sizes="(max-width: 1200px) 100dvw, 1200px"
      >
      <source
        type="image/webp"
        srcset="img_01_sp.webp 300w, img_01_sp@2x.webp 600w, img_01_sp@3x.webp 900w, img_01_tb.webp 1000w, img_01.webp 1200w, img_01_tb@2x.webp 2000w, img_01@2x.webp 2400w, img_01_tb@3x.webp 3000w, img_01@3x.webp 3600w"
        sizes="(max-width: 1200px) 100dvw, 1200px"
      >
      <img
        srcset="img_01_sp.jpg 300w, img_01_sp@2x.jpg 600w, img_01_sp@3x.jpg 900w, img_01_tb.jpg 1000w, img_01.jpg 1200w, img_01_tb@2x.jpg 2000w, img_01@2x.jpg 2400w, img_01_tb@3x.jpg 3000w, img_01@3x.jpg 3600w"
        src="img_01.jpg"
        width="1200"
        height="900"
        sizes="(max-width: 1200px) 100dvw, 1200px"
        alt="test image"
        loading="lazy"
      >
    </picture>
        
Templates

    上から
    ・picture + x / Aspects Difference in Each Query  / Fixed Image Size 
    ・picture + w + size / Aspects Difference in Each Query / Adjastable Image Size
    ・picture + w + size / No Aspects Difference in Any Query / Adjastable Image Size

  ==================================

    <picture>
      <source
        media="(max-width: 767px)"
        type="image/avif"
        srcset=".avif 1x, .avif 2x, .avif 3x"
        width=""
        height=""
      >
      <source
        type="image/avif"
        srcset=".avif 1x, .avif 2x, .avif 3x"
        width=""
        height=""
      />
      <source
        media="(max-width: 767px)"
        type="image/webp"
        srcset=".webp 1x, .webp 2x, .webp 3x"
        width=""
        height=""
      >
      <source 
        type="image/webp"
        srcset=".webp 1x, .webp 2x, .webp 3x"
        width=""
        height=""
      />
      <source
        media="(max-width: 767px)"
        srcset=".jpg 1x, .jpg 2x, .jpg 3x"
        width=""
        height=""
      >
      <img
        srcset=".jpg 1x, .jpg 2x, .jpg 3x"
        src=".jpg"
        width=""
        height=""
        alt=""
      >
    </picture>

  ==================================

    <picture>
      <source
        media="(max-width: 767px)"
        type="image/avif"
        srcset=".avif 300w, .avif 600w, .avif 900w"
        sizes="100dvw"
        width=""
        height=""
      >
      <source
        type="image/avif"
        srcset=".avif 1200w, .avif 2400w, .avif 3600w"
        sizes="1200px"
        width="1200"
        height="900"
      />
      <source
        media="(max-width: 767px)"
        type="image/webp"
        srcset=".webp 300w, .webp 600w, .webp 900w"
        sizes="100dvw"
        width=""
        height=""
      >
      <source 
        type="image/webp"
        srcset=".webp 1200w, .webp 2400w, .webp 3600w"
        sizes="1200px"
        width=""
        height=""
      />
      <source
        media="(max-width: 767px)"
        srcset=".jpg 300w, .jpg 600w, .jpg 900w"
        sizes="100dvw"
        width=""
        height=""
      >
      <img
        srcset=".jpg 1200w, .jpg 2400w, .jpg 3600w"
        src=".jpg"
        width=""
        height=""
        sizes="(max-width: 1200px) 100dvw, 1200px"
        alt=""
      >
    </picture>

  ==================================

    <picture>
      <source
        type="image/avif"
        srcset=".avif 300w, .avif 600w, .avif 900w, .avif 1000w, .avif 1200w, .avif 2000w, .avif 2400w, .avif 3000w, .avif 3600w"
        sizes="(max-width: 1200px) 100dvw, 1200px"
      >
      <source
        type="image/webp"
        srcset=".webp 300w, .webp 600w, .webp 900w, .webp 1000w, .webp 1200w, .webp 2000w, .webp 2400w, .webp 3000w, .webp 3600w"
        sizes="(max-width: 1200px) 100dvw, 1200px"
      >
      <img
        srcset=".jpg 300w, .jpg 600w, .jpg 900w, .jpg 1000w, .jpg 1200w, .jpg 2000w, .jpg 2400w, .jpg 3000w, .jpg 3600w"
        src=".jpg"
        width=""
        height=""
        sizes="(max-width: 1200px) 100dvw, 1200px"
        alt=""
      >
    </picture>
        

Elevation

filter: drop-shadow()によるエレベーションを用いる場合は、エフェクトの大きさを8段階程度に分類する。
また高さを持った要素と背景要素の間でコントラスト比を保つ場合は、事前に要素へ持たせたborderと背景の間で3:1のコントラスト比を確保する。
つまりborderを持たない要素に高さをもたせてはいけない。

「高さを持った要素」の上に「高さを持った要素」を配置する場合は、原則上側の要素は二段階高く設置すること。

drop shadow 1

drop shadow 2

drop shadow 3

drop shadow 4

drop shadow 5

drop shadow 6

drop shadow 7

drop shadow 8

no blur 1

no blur 2

no blur 3

no blur 4

no blur 5

no blur 6

no blur 7

no blur 8

F
X
X
K
O
F
F
B
U
L
L
S
H
I
T
A
S
S
H
O
L
E

font-famliy
(for Windows CJK)

組織はA新しAい技術Aを見てAいます。彼はB丁寧Bにこの問B題をB改善しBていBます。
あなたはやや過去を学んでいます。チームは実績を見ています。システムは継続的に現在を信じています。これはデータを実施しています。彼らは機会を評価しています。企業はとても実績を見ています。あなたは過去を思っています。誰もが情報を試しています。プロジェクトはわずかにデータを感じています。彼女は目標を提案しています。彼らは新しい技術を期待しています。多くの人々が継続的に情報を知っています。
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since 1966, when designers at Letraset and James Mosley, the librarian at St Bride Printing Library in London, took a 1914 Cicero translation and scrambled it to make dummy text for Letraset's Body Type sheets.

Most Stable Font Settings in 2026

    html {
      font-family: 
        "Helvetica Neue",
        "zenkaku-gothic-new",
        "Hiragino Sans",
        Arial,
        "Noto Sans JP", // or BIZ UDPGothic or Meiryo,
        sans-serif;
    }

    or

    html {
      font-family: 
        sans-serif,
        system-ui;
    } 
              
Explanation

▼ sans-serif 対応表

This is a text written with sans-serif.
Check the acctual font with devtool.
sans-serif を使用したテキストです。
検証ツールを用いて実際に用いられているフォントを確認してください。

Windows CJK Chromium
JA
Noto Sans JP
※ブラウザ指定のsans-serifフォントに依存
EN
Noto Sans JP
※ブラウザ指定のsans-serifフォントに依存
Windows CJK Firefox
JA
Meiryo
※ブラウザ指定のデフォルトフォントに依存
EN
Meiryo
※ブラウザ指定のデフォルトフォントに依存
Windows EN Chromium
JA
Noto Sans JP
EN
Arial
Windows EN Firefox
JA
Meiryo
EN
Arial
macOS CJK Chromium
JA
Hiragino Kakugo ProN
EN
Hiragino Kakugo ProN
macOS CJK Firefox
JA
Hiragino Kakugo ProN
EN
Hiragino Kakugo ProN
macOS CJK Safari
JA
Hiragino Kakugo
EN
Hiragino Kakugo
macOS EN Chromium
JA
Hiragino Kakugo
EN
Helvetica
macOS EN Firefox
JA
Hiragino Kakugo ProN
EN
Helvetica
macOS EN Safari
JA
Hiragino Kakugo ProN
※検証ツール上ではHelvetica
EN
Helvetica
iOS(systemlang: JA)
JA
Hiragino Kakugo
EN
Hiragino Kakugo
iOS(systemlang: EN)
JA
Hiragino Kakugo ProN
EN
Helvetica
Android
JA
Noto Sans CJK JP
EN
Roboto
和文
英文
Windows CJK Chromium
Noto Sans JP
※ブラウザ指定のsans-serifフォントに依存
Noto Sans JP
※ブラウザ指定のsans-serifフォントに依存
Windows CJK Firefox
Meiryo
※ブラウザ指定のデフォルトフォントに依存
Meiryo
※ブラウザ指定のデフォルトフォントに依存
Windows EN Chromium
Noto Sans JP
Arial
Windows EN Firefox
Meiryo
Arial
macOS CJK Chromium
Hiragino Kakugo ProN
Hiragino Kakugo ProN
macOS CJK Firefox
Hiragino Kakugo ProN
Hiragino Kakugo ProN
macOS CJK Safari
Hiragino Kakugo
Hiragino Kakugo
macOS EN Chromium
Hiragino Kakugo
Helvetica
macOS EN Firefox
Hiragino Kakugo ProN
Helvetica
macOS EN Safari
Hiragino Kakugo ProN
※検証ツール上ではHelvetica
Helvetica
iOS(systemlang: JA)
Hiragino Kakugo
Hiragino Kakugo
iOS(systemlang: EN)
Hiragino Kakugo ProN
Helvetica
Android
Noto Sans CJK JP
Roboto

▼ system-ui 対応表

This is a text written with system-ui.
Check the acctual font with devtool.
system-ui を使用したテキストです。
検証ツールを用いて実際に用いられているフォントを確認してください。

Windows Chromium
JA
Yu Gothic UI
EN
Yu Gothic UI
Windows Firefox
JA
Yu Gothic UI
EN
Yu Gothic UI
macOS Chromium
systemlang: JA
JA
Hiragino Kakugo ProN
EN
San Francisco
※検証ツール上では .SF NS
macOS Chromium
systemlang: EN
JA
.Hiragino Kaku Gothic Interface
EN
San Francisco
※同上
macOS Firefox
JA
Hiragino Kakugo ProN
EN
San Francisco
※同上
macOS Safari
JA
.Hiragino Kaku Gothic Interface
※検証ツール上では AppleSystemUIFont
EN
San Francisco
※同上
iOS
JA
.Hiragino Kaku Gothic Interface
EN
San Francisco
Android
JA
Noto Sans CJK JP
EN
Roboto
和文
英文
Windows Chromium
Yu Gothic UI
Yu Gothic UI
Windows Firefox
Yu Gothic UI
Yu Gothic UI
macOS Chromium
systemlang: JA
Hiragino Kakugo ProN
San Francisco
※検証ツール上では .SF NS
macOS Chromium
systemlang: EN
.Hiragino Kaku Gothic Interface
San Francisco
※同上
macOS Firefox
Hiragino Kakugo ProN
San Francisco
※同上
macOS Safari
.Hiragino Kaku Gothic Interface
※検証ツール上では AppleSystemUIFont
San Francisco
※同上
iOS
.Hiragino Kaku Gothic Interface
San Francisco
Android
Noto Sans CJK JP
Roboto

▼sans-serif とは

その環境が使用可能なデバイスフォント(デフォルトでOSにインストールされているもの)を指定する値。
実際にどのフォントが用いられるかはデバイス規定フォントに依存する。

▼system-ui とは

その環境が使用可能なデバイスフォント(デフォルトでOSにインストールされているもの)を指定する値。
実際にどのフォントが用いられるかはデバイス規定フォントに依存する。

▼sans-serif と system-ui の違い

上記表の通り、指定されるフォントが異なるのみ。
ブラウザによってはsans-serif用の設定項目が個別に設けられている場合がある。

▼結局どうすればよいのか

現状適切なデフォルト値が指定されているため、system-uiまたはsans-serifの指定で問題ない。
が、常にブラウザ自体の挙動に依存する形となるため、意図しない挙動の発生リスクが常に付きまとう。
デザインデータが厳密に存在する場合、または段落ちなどレイアウトに気を配る必要のあるページの場合は、やはり引き続き明確にフォントを指定し挙動を管理すべきである。

Accordion

Accordion Sample

CSSのみで実装、かつiOS18.4以降のSafariに対応するアコーディオン。

各アコーディオンにnameを付与することで、最大展開個数を1とする排他的な実装が可能。

iOS18.4から疑似要素::details-contentが指定可能となったため、非展開時の ::details-content を grid-template-rows: 0frに、展開時は1frに設定のうえtransition-property: grid-template-rows;を指定することでCSSのみの展開アニメーションが可能となる。
ただしそのままでは格納時に内容コンテンツがアコーディオンから逸脱してしまうため、コンテンツのdivラップの上にさらにoverflow: hidden用の追加divラップが必要となること、
併せてgrid-template-columnsは相対値プロパティのため、transition-behavior: allow-discreteにより相対値プロパティへのtransition適用許可が必要となる。

Accordion Sample

CSSのみで実装、かつiOS18.4以降のSafariに対応するアコーディオン。

各アコーディオンにnameを付与することで、最大展開個数を1とする排他的な実装が可能。

iOS18.4から疑似要素::details-contentが指定可能となったため、非展開時の ::details-content を grid-template-rows: 0frに、展開時は1frに設定のうえtransition-property: grid-template-rows;を指定することでCSSのみの展開アニメーションが可能となる。
ただしそのままでは格納時に内容コンテンツがアコーディオンから逸脱してしまうため、コンテンツのdivラップの上にさらにoverflow: hidden用の追加divラップが必要となること、
併せてgrid-template-columnsは相対値プロパティのため、transition-behavior: allow-discreteにより相対値プロパティへのtransition適用許可が必要となる。

Accordion Sample

CSSのみで実装、かつiOS18.4以降のSafariに対応するアコーディオン。

各アコーディオンにnameを付与することで、最大展開個数を1とする排他的な実装が可能。

iOS18.4から疑似要素::details-contentが指定可能となったため、非展開時の ::details-content を grid-template-rows: 0frに、展開時は1frに設定のうえtransition-property: grid-template-rows;を指定することでCSSのみの展開アニメーションが可能となる。
ただしそのままでは格納時に内容コンテンツがアコーディオンから逸脱してしまうため、コンテンツのdivラップの上にさらにoverflow: hidden用の追加divラップが必要となること、
併せてgrid-template-columnsは相対値プロパティのため、transition-behavior: allow-discreteにより相対値プロパティへのtransition適用許可が必要となる。

Sample Code

    <details name='accordion__sample' class='accordion__sample__1' open=true>
      <summary>Accordion Sample<span class='twister'></span></summary>
      <div class="accordion__overflow__hidden">
        <div class="accordion__content">
          content...
        </div>
      </div>
    </details>
        

    /* 許可されていない場合は相対値への transition 適用を許可する */
    html {
      transition-behavior: allow-discrete; 
    }

    details {
      &::details-content {
        content-visibility: unset; /* Safari固有不具合への対策 */
        display: block grid;
        line-height: 1.7;
          
        @media(prefers-reduced-motion: no-preference) {
          transition-duration: 300ms;
          transition-property: grid-template-rows;
        }
      }
          
      &:not([open])::details-content {
        grid-template-rows: 0fr;
      }
          
      &[open]::details-content {
        grid-template-rows: 1fr;
      }
    }

    summary {
      display: grid;
      grid-template-columns: 1fr 30px;
      align-items: center;
      padding: 1rem 1.5rem;
      font-size: calc(24 / 16 * 1rem);
      color: var(--paper);
      background-color: var(--blue-400);

      &:not(:last-child) {
        border-bottom: 1px solid var(--paper);
      }
    }

    .accordion__overflow__hidden {
      overflow: hidden;
    }

    .accordion__content {
      padding: 1rem 1.5rem;
      background-color: var(--base-50);
    }
        

Popover Menu

Sample Code

    <button
      type="button"
      class="popovermenu__btn item__hover" 
      popovertarget='popovermenu-dialog'
    >
    </button>
    <dialog
      id="popovermenu-dialog"
      class="popovermenu__dialog"
      closedby="any"
      aria-labelledby="dialog-title"
      autofocus
      popover
    >
      <div class="popovermenu__content__wrap">
        <h2 id="popovermenu-heading" class="popovermenu__heading">MENU</h2>
        <nav class="linkitem__wrap popovermenu__linkitem__wrap">
          {
            popovermenuList.map((item) => (
              <a href={item.path} class="linkitem__link link__twister">
                {item.name}
              </a>
            ))
          }
        </nav>
      </div>
      <button 
        type="button"  
        class="popovermenu__close__btn item__hover"
        popovertarget="popovermenu-dialog"
        popovertargetaction="hide"
      >
        Close
      </button>
    </dialog>
              

    dialog[popover] {
      position: fixed; /* Safariで表示に不具合が出るので明示する必要がある */
      inset-block-start: 50%;
      inset-inline-start: auto;
      inset-inline-end: calc(60 / 16 * 1rem); /* PCレイアウトのgutter片側分 */
      margin: 0; /* ブラウザデフォルトのmarginをリセット */
      block-size: 80dvh;
      inline-size: 50dvw;
      max-inline-size: calc((700 / 16) * 1rem); /* PCコンテンツサイズ / 2 */ 
      color: var(--paper);
      background-color: var(--base-950);
      transform: translateY(-50%);
      transition-duration: 0.2s;
      transition-property: display, overlay, opacity, transform;
      transition-timing-function: ease-out;
      transition-behavior: allow-discrete;
      overscroll-behavior-block: contain;
      overflow: auto;

      h2 {
        color: var(--paper);
        border-bottom: none;
      }

      @media screen and (min-width: 1400px) {
        inset-inline-end: calc(50vw - calc(640 / 16 * 1rem));
      }
    }

    .popovermenu__content__wrap {
      padding: 2rem;
    }

    .popovermenu__linkitem__wrap {
      padding-inline-start: 2rem;
      margin-block-start: 3rem;
    }

    .popovermenu__close__btn {
      position: fixed;
      inset-block-start: 6rem;
      inset-inline-end: calc(60 / 16 * 1rem);
      font-size: calc(20 / 16 * 1rem);
      font-weight: bold;
      background-color: var(--base-950);
      border-block-start: none;
      border-inline-end: none;
      opacity: 0.8;

      @media screen and (min-width: 1560px) {
        inset-inline-end: calc(50vw - calc(760 / 16 * 1rem));
      }
    }

    @starting-style {
      dialog[popover] {
        opacity: 0;
        transform: translate(-50%, -50%) scale(0.95);
      }
    }

    [popover]:not(:popover-open) {
      opacity: 0;
    }
              
Explanation

ブロック要素(dialog / divなど)にpopover属性を付与することで、非モーダルとなるshow()にて同要素を展開する。
command属性で展開する

▼ popover 属性

  • ・popover: “popover”のみ指定した場合、デフォルト値autoが適用される。
  • ・popover="auto": 閉じるボタンのほか、ポップオーバー領域の外側を押下することでも閉じることが可能。
  • ・popover="manual": 閉じるボタンなど、ユーザ側が明示的に閉じる操作を行わないとモーダルが閉じない。

▼ popovertargetaction 属性

  • ・show: popovertarget属性で指定した id を持つ要素をポップオーバーとして表示する。
  • ・hide: 同様にポップオーバーを非表示にする。
  • ・toggle: こちらは単独で表示 / 非表示を切り替える。

:where() :is() :has() :not()

Sample Code

    /* 引数に当てはまる要素全て(継承度最低) */
    :where(h1, h2, p:not(first-child)) {
      color: blue;
    }

    /* 引数に当てはまる要素全て(継承度 = 引数のうち最も高い継承度) */
    :is(h1, h2, p:not(first-child)) {
      color: blue;
    }

    /* :modal 要素を持った場合の :root */
    :root:has(:modal) {
      overflow: hidden;
    }

    /* 子要素に p を持つ div */
    div:has(> p) {
      border: 1px solid var(--base-950);
    }

    /* h2 を兄弟に持つ h1 */
    h1:has(+ h2) {
      margin-block-end: 1rem;
    }

    /* h2, h3, h4 のいずれかを兄弟要素に持つ h1, h2, h3 のいずれかまたは全て */
    :is(h1, h2, h3):has(:is(+ h2, h3, h4)) {
      margin-block-end: 1rem;
    }

    /* 非展開時の details 要素に含まれる ::details-content */
    details:not([open])::details-content {
      grid-template-rows: 0fr;
    }
                
Explanation

▼ :where()

引数として指定された全てのセレクタを対象にスタイルを適用させる疑似クラス。
特有の点としてあらゆる他セレクタより継承度が低くなる仕様があり、例えば以下の形で:where()を用いてのh2スタイルの上書きは出来ない。


    h1 {
      color: red;
    }

    :where(h1, h2, p:not(first-child)) {
      color: blue;
    }
                

▼ :is()

記述方法は:where()と同様だが特性は真逆であり指定した引数の中で最も高い継承度を継承する。
以下例で:where()が最大の継承度を保持しているとした場合、指定した引数全てがh1と同様の強い継承度を持つ。
伴って後述の:is()にて指定のcolor: blue;はh1に適用される。


    html body main section h1 {
      color: red;
    }

    :is(h1, h2, p:not(first-child)) {
      color: blue;
    }
                

▼ :has()

引数として取った要素が、:has()の指定元要素から相対位置(相対セレクターリスト)として存在する場合にスタイルを適用する。伴って基準セレクタの親要素や兄弟要素を指定することが可能。具体的な使用例は上記サンプルソースを参照。
なお複数の独特な仕様や注意点が存在するため、使用は慎重に行う必要がある。

  • ・DOMが更新されるたびブラウザが:has()を再評価するため、実装方法次第では甚大なパフォーマンス低下を発生させる
  • ・:has() の中に:has()を入れ子することは出来ない
  • ・:has()の引数に疑似要素を指定することは出来ない(循環クエリ発生の危険性があるため)

    div:has(p:has(> span)) {
      /* 入れ子の :has() は不可 */
    }

    details:has(::details-content) {
      /* 疑似要素の引数への指定は不可 */
    }
                

▼ :has() と論理演算

:has()はその用法によって「引数のいずれか一つを持つか」または「引数全てを持つか」の識別に用いることができる。
「引数のすべてを持つ場合」を指定したい場合は:has()を連結する。


    /* video、または audio を持つ場合 */
    .content__wrap:has(video, audio) {
      ...
    }

    /* video または audio を持つ場合 */
    .content__wrap:has(video):has(audio) {
      ...
    }
                

▼ :has() と正規表現

:has()はその用法によって「先読みアサーション」的な使用が可能となる。


    /* 肯定先読み abc(?=xyz) */
    .abc:has(+ .xyz) {
      ...
    }

    /* 否定先読み abc(?!xyz) */
    .abc:has(+ :not(.xyz)) {
      ...
    }
                

▼ :has() とパフォーマンス懸念

・広範な規模となる引数の指定を避ける
アンカーセレクタA:has(B)のAは、bodyや:root、全称セレクタのように子要素が大量となるものを指定してはいけない。
上述の通り:has()は DOM が更新されるたび都度再評価されるため、そのような指定は膨大な数の子要素が精査されるため。

・引数は結合子を用いて可能な限り対象を絞る
同様の理由で、.A:has(> .B)や .A:has(+ .B)のように予め可能な限り走査の対象となる要素を絞ることで、パフォーマンス負荷を抑えることができる。


    /* 実はよろしくない */
    :root:has(:modal) {
      ...
    }            

    .content__wrap:has(> .astro-code) {
      ...
    }
                

▼ :not()

基本的な考え方は:has()と同様だが、独自の注意すべき挙動がいくつか存在する。

  • ・無意味なセレクターを作成可能。:not(*)など
  • ・無理やり詳細度を上げることが可能。#foo:has(#bar)など
  • ・:not(.foo)のような指定にはbodyやhtmlも含まれる
  • ・例えばbody:not(table) aはtable内の 子孫aを含んでしまう。tableが包括する全てのaを指定したい場合はbody:not(table a) とする
  • ・複数のセレクタを同時に否定可能。例えばbody:not(.foo, .bar)は body:not(.foo):not(.bar)と同等
  • ・:has()と異なり、:not()単独では指定した引数のうちいずれかが無効の場合そのほかの引数も全て無効となる。回避する場合は:not(:is(.foo, .bar))とする

▼ 寛容な解釈

CSSの仕様としてwhere / is / not / hasは「寛容なセレクター解釈」を行う。
通常、引数を伴うセレクタはひとつでもその引数の解釈に失敗すると、単独であっても複数であっても全ての引数(セレクターリスト)を無効とするが、
これらは解釈に失敗した引数のみ無視し、そのほかの正常なセレクタは引き続き扱い続ける。

HTML: Do's Dont's from MWG

Fundamental Semantics
All Do's and Don'ts
  • ・イカれたレンダリング結果にならないよう、HTML5 doctype !DOCTYPE htmlを使おう
  • ・スクリーンリーダと翻訳ツールを補助するために、html要素にはlang=''属性を付与しよう
  • ・headにmeta name='viewport'を付与しよう。値はwidth=device-width, initial-scale=1.0尼設定しよう
  • ・.showModal()で表示されるダイアログ要素を除いて、ページ全体でh1は一つにしよう。
  • ・見出しh◯要素の順番は番号をスキップせずに用いよう
  • ・divの乱用は避け、役割ごとにheadernavasidemainなどセマンティックな要素を使おう
  • ・検索用要素にはrole='search'ではなくsearch要素を使おう
  • ・buttonはボタン、aはリンク、役割を混濁させないようにしよう
  • ・buttonにはtype=''属性を必ず付与しよう。デフォルトはsubmitなので、意図せぬ通信が発生するぞ
  • ・リストにはuloldl要素を使おう
  • ・リンクやボタンなどのユーザインタラクティブな要素には必ずアクセシブルな名称や補足を入れよう
  • ・装飾用要素や画像にはaria-hidden='true'を使い、アシストツール群からの補足を回避させよう
  • ・装飾用要素や画像はaltを空にし、aria-hidden と併せて装飾用であることをDOMに伝えよう
  • ・逆にロゴ、ボタン、データ表示など意味を持つ画像群には必ずアクセシブルな名称を付与しよう
  • ・boolである属性、例えばdisabledをdisabled='disabled'と記載してはいけない
  • ・専用の要素があるにも関わらず、aria-roleで無理やり意味を変えて別要素で代替してはいけない
  • ・特別な理由無く、要素本来の意味をaria-role=''で書き換えてはいけない
  • ・フォーカス可能な要素、またはその親祖先にrole='presentation'やaria-hidden='true'
  • を付与してはいけない
  • ・ページのズーム機能を排除してはいけない
Correct HTML Template

    <!-- HTML5 doctype を用いること -->
    <!DOCTYPE html>
    
    <!-- スクリーンリーダー補助のためhtmlタグには lang 属性を付与すること -->
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <!-- meta name viewport は以下設定で必ず実装すること -->
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
                
h tag

    <!-- モーダルダイアログ要素を除き、h1 タグは一ページに一つとすること -->
    <h1 class="main__ttl">Main Title</h1>

    <!-- h タグの順序はスキップしてはいけない -->
    <h2>...</h2>
      ...
      <h3>...</h3>
        ...             
                
Use Semantic Tags

    <!-- divを乱用するのではなく、header, nav, aside, main, footer などセマンティックなタグでマークアップすること -->
    <nav class="navigation">
      <ul>
        <li class="link__item">
          <a href="#">TOP</a>
        </li>
        <li class="link__item">
          <a href="#">About</a>
        </li>
        <li class="link__item">
          <a href="#">Content</a>
        </li>
      </ul>
    </nav>

    <!-- 悪例 -->
    <div class="navigation">
      ...
    </div>
                
Use Search Tag

    <!-- 検索絞り込み機能は role="search" ではなく search 要素で実装すること -->
    <search>
      <form action="/search" method="get">
        <label for="keyword">Keyword</label>
        <input type="search" id="keyword" name="q">
        <button type="submit">Search</button>
      </form>
    </search>

    <!-- 悪例 -->
    <div role="search">
      ...
    </div>
                
Separate Depending on Button and Link

    <!-- 機能の起動はbutton、リンクは a と混同しないこと -->
    <nav>
      <ul>
        <li><a href="#">Link_1</a></li>
        <li><a href="#">Link_2</a></li>
      </ul>
    </nav>

    <!-- type は省略すると自動で submit になる -->
    <!-- 意図せぬ送信を防ぐため type は必ず明示すること -->
    <button type="button" commandfor="my-dialog" command="show-modal">Open Modal</button>
    <button type="submit">Send</button>

    <!-- 悪例 -->
    <nav>
      <ul>
        <li><button type="button"></button></li>
        <li><button type="button"></button></li>
      </ul>
    </nav>

    <button>Vote Up the Function</button>
                
Elements For Listing

    <!-- リストには ul ol dl タグを使用すること -->
    <ul>
      <li><a href="#"></a>Link_1</li>
      <li><a href="#"></a>Link_2</li>
    </ul>

    <dl>
      <dt>Content A</dt>
      <dd>Desc A</dd>
      <dt>Content B</dt>
      <dd>Desc B</dd>
    </dl>

    <!-- Don'ts -->
    <div>
      <div>Content A</div>
      <div>Desc A</div>
      <div>Content B</div>
      <div>Desc B</div>
    </div>
                
Give aria-hidden='true' and Blank alt for Purely Decorative Images

    完全に修飾目的の画像には、
    ・SVG画像であれば aria-hidden="true" 
    ・img画像であれば alt=""
    を設定し、各種アクセシビリティ判定から排除させる。

    それぞれにはDOMに「コレは修飾用要素である」と伝える機能があり、
    例えば inert もユーザのインタラクトを完全に排除できるため代替可能と考えられるかもしれないが、
    inert にそのような伝達機能は無い。

    <span class="twister" aria-hidden="true"></span>

    <img src="#" alt="">
                
Give a Accessible Name

    <!-- リンクやボタンなどユーザーがインタラクトできる要素には必ずアクセシブルな記述を含ませる -->
    <button type="button">Start Animation</button>

    <!-- アイコンだけの場合 -->
    <button type="button" aria-label="Start Animation">
      <svg> ... </svg>
    </button>

    <!-- 画像リンクの場合は alt -->
    <a href="#">
      <img src="#" alt="Start Animation">
    </a>
                
Don't use Boolean Attributes with Redundant Values

    <!-- disalbled など boolean 系の属性に対し boolean 系の値を渡してはいけない -->
    <details open="open">
      ...
    </details>
    
    <!-- 単独でOK -->
    <details open>
      ...
    </details>
                
Don't Change the Native Role of Each Elements

    <!-- 特段の理由無く、各要素の既存ロールを上書きしてはいけない -->
    <a href="#" role="button">Submit</a>
    
    <!-- ネイティブロールだけでは対応できないものを aria で補う(ただし用法はかなり難しい) -->
    <button
      type="button"
      aria-expanded="false"
      aria-control="menu"
    >Menu
    </button>
                
Don't Use Attributes about Hidden contents for Focusable Elements

    <!-- aria-hidden='true' や role='presentation' をフォーカス可能な要素に付与してはいけない -->
    <img 
      src="#"
      alt="Link for Menu"
      aria-control="menu"
      role="presentation"  
    >
    
    <!-- 同様にそれらはフォーカス可能な要素の親要素や祖先に付与してもいけない -->
    <div class="img__wrapper">
      <img 
        src="#"
        alt="Link for Menu"
        aria-control="menu"
        role="presentation"  
      >
    </div>
                
Use Viewport Meta Correctry

    <!-- 以下を推奨 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0 ">

    <!-- 以下のような meta viewport 設定はアクセシビリティを著しく低下させる -->
    <!-- ユーザによるズームの禁止 -->
    <meta name="viewport" content="user-scalable=no">
    <!-- ユーザによるズームの禁止 -->
    <meta name="viewport" content="initlal-scale=1.0, maximum-scale=1.0">
    <!-- 画面幅の固定 -->
    <meta name="viewport" content="width=1000">
    <!-- width の未指定によるクライアント画面幅への最適化不足 -->
    <meta name="viewport" content="initial-scale=1.0, ...">
                
Content Grouping and Attributtion
ALL Do's and Don'ts
  • ・引用文はblockquote要素で囲み、cite属性で引用元を渡すことで、引用としてセマンティックな実装をしよう
  • ・自己完結している要素(本文から外したところで本文mその要素共に意味が変わらない要素)はfigureで囲もう
  • ・figure の最初か最後の子要素としてfigcaptionを記述しよう
  • ・コードはcodeで囲もう
  • ・code はpreで囲もう
  • ・スクロールが発生する可能性のある pre にはtabindex=0を付与しよう。キーボードでアクセスできない可能性があるぞ
  • ・ 間違っても純なる修飾要素に blockquote を用いてはいけない
  • ・全てのイメージを figure で囲ってはいけない
  • ・コードを書いてるのに code 抜きで pre 囲いしてはいけない
Use Blockquote Element for extended quotations

    <!-- 一定量以上の引用には blockquote 要素を用いセマンティックに示す -->
    <!-- blockquote の cite 属性を用い、機械的に参照元を示す -->
    <blockquote cite='httpS://www.hogehogecom/fuga'>
      <p>piyopiyo...</p>
    </blockquote>
    
    <!-- ただし cite 属性で指定したURLはページ上に表示されないため、必要な場合リンクは別途記述する -->
    <blockquote cite='httpS://www.hogehogecom/fuga'>
      <p>piyopiyo...</p>
      <a href="httpS://www.hogehogecom/fuga">Link: httpS://www.hogehogecom/fuga</a>
    </blockquote>
                
Use Figure Element to Group Self-Contained Content

    <!-- 画像、図表、引用、コード例など、本文から独立しても意味が変化しないと判断できる要素は figure 要素で囲む -->
    <!-- 同様に“本文から欠落しても本文自体の意味が変わらない”ものである必要がある -->
    <!-- figcaption は figure 要素内の最初または最後に配置する -->
    <p>以下は昨年の売上推移となる。</p>
    <figure>
      <img src="#" alt="2025年の売上推移図。期末の12億円まで毎月1億円のリニアな線を描いている">
      <figcaption>図1:2025年の売上推移図</figcaption>
    </figure>
    
    <figure>
      <pre><code>print('hello world!')</code></pre>
      <figcaption>Pythonにおける print 関数</figcaption>
    </figure>
    
    <figure>
      <blockquote cite="hogehoge.jp">
        <p>hogehoge...</p>
        <a href="hogehoge.jp">Link: hogehoge.jp</a>
      </blockquote>
      <figcaption>出典:記事タイトル</figcaption>
    </figure>
    
    <!-- このページのコードスニペットは? -->
    アコーディオン開閉により本文からの隔離が可能となっているため、問題ないらしい。
    また文脈的に必要な場合も囲む必要がない。
                
Add tabindex=0 to Pre Element

    <!-- スクロールが発生した際にユーザがキーボードからアクセスできるよう、pre には tabindex=0 を付与する -->
    <pre tabindex="0">
      <code>print('hello world!')</code>
    </pre>
                
Don't Use Figure Element for Each Imgs

    <!-- 画像に対する figure の使用は「キャプションが必要な場合」および「要素として独立している場合」に限る -->
    <!-- 例えば装飾画像など -->
    <img src="img/line.svg" alt="">
                
Resouce Priorization and Performance
All Do's and Don'ts
  • ・KVなどLCPとして扱われる要素についてはfetchpriority='high'を付与し読み込み優先度を引き上げよう
  • ・もしLCPに背景画像が存在する場合は、link rel='preload' as='image'をhead内に実装し、CSS側で指定の背景画像を優先的に読み込もう
  • ・遷移時点で画面外の画像、およびiframe要素にはloading='lazy'属性を付与し遅延読込みさせよう
  • ・レイアウトシフト(CLS)を防ぐため、全ての画像にwidth / height属性を付与しよう。srcset / sourceを組んでいる場合はそれぞれに必要だが、全セットでアスペクト比が共通の場合は大元のimg要素への指定のみでOK
  • ・picture sizes srcsetを適切に使い分けよう。詳細はImages項目を参照
  • ・間違ってもKVなどヒロイックなイメージに loading=lazy を付与してはいけない
  • ・fetchpriority='high' を乱用してはいけない。読み込み優先度はゼロサムのため、優先度の低い画像にはfetchpriority='low'を明示し、高低の差を大きくすべき。
Use fetchpriority='high' for LCP Content

    <!-- KVなど最もサイズの大きな要素に対しては fetchpriority='high' 属性を付与する -->
    <!-- iOS 17.2 から対応 -->
    <h1>Page Title</h1>
    <div class="hero">
      <img src="#" alt="key visual" class="img__kv" fetchpriority="high">
    </div>
                
High vs Async vs Eager

    KV = LCPと仮定して考える。

    LCPに対し問答無用で付与すべきは fetchpriority = high であり、特に懸念はない。

    loading = eager は「遅延させるな」という指示だが、要素に対するデフォルトの loading は eager であるため、明示的に指定する必要はない。

    decoding = async はデコードに対する指示のため、優先度とは異なる指標を指示する。
    ブラウザごとに恩恵が異なる可能性が高いため、付与を切り替えて実測するのが最も確実である。
                
Use rel='preload' as='image' for background KV

    KV画像が背景画像として実装されるのはよくあるパターンだが、
    その場合 img に対する直接の fetchpriority='high' 指定が不可能となる。
    
    この場合は head 要素内に 画像をリンクとした link 要素を配置し、優先して背景画像を読み込むよう指定する。
    この用法では link に対し fetchpriority が使用可能となる。
    
    <head>
      <link 
        rel="preload" 
        as="image"
        href="./img/KV.webp"
        fetchpriority="high"
      >
    </head>
    
    なお imagesrcset を用いる場合でも同様に指定が可能。
    <head>
      <link 
        rel="preload" 
        as="image"
        href="./img/KV.webp"
        imagesrcset="./img/KV.webp 1x, ./img/KV@2x.webp 2x"
        fetchpriority="high"
      >
    </head>
                
Add loading='lazy' Attr for Secondory Contents

    初期遷移時点でビューポートから外れる画像および iframe 要素については、
    loading='lazy' を付与することでビューポートに近づくまたは含まれるまで読み込みを開始しないようにする。
    
    <body>
      <hgroup>
        <h1>Page Title</h1>
        <p>subttl</p>
        <img 
          src="./img/kv.webp"
          alt="key visual"
          fetchpriority="high"
        >
      </hgroup>
    
      ...
    
      <img 
        src="./img/aftercontent.webp"
        alt="after content"
        loading="lazy" 
      >
    </body>
                
Specify Width and Height Attr for ALL Images

    レイアウトシフト(CLS)を防ぐため、全ての img タグに対し width と height の指定が求められる。
    
    両属性は主にアスペクト比に基づいて描画領域をあらかじめ確保するために参照されるが、
    その値は「基準画像」を基に指定するのがよい。
    例えば基準画像がPCレイアウトの巨大なものであっても、
    CSS側で予め画像幅が制限されていれば(SPレイアウト時に inline-size=100% など)、
    その制限に基づいた横幅から属性を参照して割り出したアスペクト比を参考に必要な縦領域を確保する。
    
    アスペクト比の算出が目的であればCSS側で aspect-ratio を指定してやれば問題なさそうだが、
    ブラウザがDOMを構成する時点で描画領域を確保できるメリットが大きく、
    逆に「適切なサイズ属性が指定されていれば img に対してCSS側で aspect-ratio を指定する必要はない」と言える。
    
    <img 
      src="./img/img_01.web"
      alt="test image"
      width="640"
      height="400"
    >
                
Use Picture tag and Srcset Attr for Responsive Image Sets

詳細は上述の Image カテゴリにて。

Don't Apply Loading Lazy for Heroic Image

その通り。

Don't Overuse fetchpriority='high'

    Heroicでない画像については fetchpriority="low" の使用も検討する。
    fetchpriority は最終的にゼロサムのため、
    例えばカルーセル内など優先順位が明確に低い画像は low の付与を行うべき。

    <img src="#" alt="test" fetchpriority="low">
                
Native Overlays: Dialogs and Popovers
Foundations
  • ・DOMの最頂点にオーバーレイし、背景要素へのアクセスを制限するモーダルダイアログに対してはdialog要素を使おう
  • ・背景要素へのアクセスを制限しないモーダルダイアログに対してはpopover API(popover属性)を使おう
  • ・モーダルダイアログの背景レイヤを就職するには::backdropセレクタを使おう
  • ・キーボードでフォーカスを行うことが想定されるモーダルダイアログには.show()メソッドを使わないこと(キーボードでフォーカスできない可能性がある)
  • ・popover 属性の付与された要素を.showModal()メソッドで呼び出してはいけない
Use Dialog Els for Modal Overlays

※ 詳細は Modal with Dialog Element を参照のこと。


    全てのDOM要素の頂点に新たなレイヤをオーバーレイする(画面スクロールを抑制させる)形で
    モーダル ※1 を実装する場合、<dialog> 要素を使用すること。
    理由としては以下。
    ・自動的なトラップフォーカス(モーダルへのフォーカス誘導) ※2
    ・モーダル背景の調整 >> ::backdrop 要素へのスタイル適用
    ・Escキーによるモーダルからの離脱機能 ※3

    ※1:モーダルの定義 = .showModal() を用いた、スクロールを抑制するタイプの要素展開
    ※2:dialog 要素への autofocus 属性は付与するべきである
    ※3:dialog 要素への closedby='any' 属性付与により light-dismiss = 
        モーダル以外の要素をクリックでモーダル閉じ を実装可能

    <button
      type="button"
      command="show-modal"
      commandfor="my__dialog">
      Open
    </button>

    <dialog
      id="my__dialog"
      class="my__dialog"
      closedby="any"
      autofocus>
        ...content 

      <button
        type="button"
        command="close"
        commandfor="my__dialog">
        Close
      </button>
    </dialog>        
                
Use Popover API for Non-Modal UI

※ 詳細は Popover API を参照のこと。


    背景スクロールの抑制を伴わないモーダル要素に対しては popover 属性 ※1 を用いる。

    ※1:popoverの定義 = .show() を用いた、背景スクロール抑制を伴わないモーダル要素

    <button
      type="button"
      popovertarget="popover__dialog"
    >
      Open Popover
    </button>
    
    <dialog
      id="popover__dialog"
      closedby="any"
      aria-labelledby="dialog-title"
      autofocus
      popover
    >
      ...contents
    
      <button
        type='button'
        popovertarget="popover__dialog"
        popovertargetaction="hide"
      ></button>
    </dialog>
                
Use ::backdrop Selector for styling of Dialog's BG

※ 詳細は Modal with Dialog Element を参照のこと。


    dialog {
      position: fixed; /* Safariで表示に不具合が出るので明示する必要がある */
      /* 中央寄せ */
      inset-block-start: 50%;
      inset-inline-start: 50%;
      transform: translate(-50%, -50%);
      /* inset: 0 を削除して、幅・高さを明示的に設定 */
      inline-size: min(90vw, calc((600/16) * 1rem)); /* 最大幅を設定 */
      max-block-size: 40vh;
      margin: 0; /* ブラウザデフォルトのmarginをリセット */
      overscroll-behavior-block: contain;
      transition-duration: 0.2s;
      transition-property: display, overlay, opacity, transform;
      transition-timing-function: ease-out;
      transition-behavior: allow-discrete;
      overflow: auto;
    }

    dialog::backdrop {
      background-color: oklch(from var(--black) l c h / 50%);
      backdrop-filter: blur(4px);
      -webkit-backdrop-filter: blur(4px);
      transition-duration: inherit;
      transition-property: opacity;
      transition-timing-function: inherit;
    }
                
Don't Use show() for modals where keyboard traps are expected

こちらも表題の通りだが、
キーボードでの操作が想定されるモーダル要素については.showModal()メソッドを用いること。
モーダルがDOMレイヤの頂点に位置し、他要素へのアクセスが遮断された状態でなければ、キーボードによるフォーカスが適切に動作しない。

The Method to Balance Dialog Semantic between Popover API

上記例にも有るとおりだが、
・ダイアログ(モーダル)としてのセマンティックな実装
・popover としての挙動
を両立させたい場合は、シンプルにdialog要素へpopover属性を付与する。


    <dialog
      id="popover__dialog"
      closedby="any"
      aria-labelledby="dialog-title"
      autofocus
      popover
    >
      ...contents
    </dialog>
                
DisClousures: Details and Summary
All Dos and Don'ts

※ 詳細は Accordion を参照のこと。

  • ・ブラウザネイティブなアコーディオン実装のためdetails要素とsummary要素を使おう
  • ・summary は details の最初の子要素にしよう
  • ・summary を見出し要素として使わなければならない場合は、より堅牢な実装方法を検討しよう(後述)
  • ・展開中 details のスタイリングにはdetails[open]セレクタを使おう
  • ・details が内包するコンテンツのスタイリングには::details-contentセレクタを使おう
  • ・複数アコーディオンのうち展開動作を排他的にしたい場合はname属性を使おう
  • ・summary 内に他のインタラクティブな要素を直接含めてはいけない(a, linkなど)
  • ・開閉状態が分かる装飾無しに、summary にデフォルトの三角形を消すのはやめよう
  • ・summary に対しtitle属性でツールチップを設けるのはやめよう
If You Hafta Combine Headings and Summary

    以下の場合、h2 の意味は summary に上書きされ機能を果たさない。
    
    <details>
      <summary><h2>Category Title</h2></summary>
      <div>
        <div>
          contents...
        </div>
      </div>
    </details>
    
    
    summary に見出しとしての意味を持たせなければならない場合は、以下のような例を検討する。
    
    <h2>
      <button
        type="button"
        aria-expanded="false"
        aria-controls="significant-section-content"
      >
        Siginificant Section
      </button>
    </h2>
    <div id="significant-section-content" hidden>
      contents...
    </div>
                
Focus Boundaries and Visibility
All Do's Don'ts
  • ・その時点で画面に展開されていないメニューなど、総体として"隠された"セクションにはinert属性を付与しよう。タブアクセスおよびアクセシビリティツリーからの排除が可能となる。
  • ・showModal()メソッドで開かれるモーダルダイアログ要素については、デフォルトでbody全体(たぶん)に inert が付与された場合の挙動を取る(タブ以外にフォーカスが当たらない)ため、特段対応の必要はない。
  • ・inert を付与した要素にはペアとしてCSSでopacity: 0.5;を付与し、視覚的にも非活性であることを伝えよう
  • ・タブフォーカス順はDOMの並び順に沿うため、特に項目が連続するnavなどにおいて、orderやflex-flow: row-reverseなどで"DOMの変更を伴わない"見た目だけの並び順変更はタブフォーカスを混乱させる
  • ・tabindex=''に正の数(1,2,3...)を当ててはいけない。タブフォーカスさせたい場合は='0'、JSにフォーカスさせたい場合は='-1'を用いる
  • ・element.focus({ preventScroll: true })はユーザビリティテストなしに用いてはならない。画面外またはオフスクリーンの要素に対してフォーカスが当たったままフォーカスを見失う可能性がある
Do Use the Global inert Attr for Entire Hidden Sections

    非展開中のメニューなど"隠された"セクションに対しては inert を当て、
    アクセシビリティツリーからの参照や不要なタブフォーカスを排除する。

    const dialogItems = document.querySelectorAll<HTMLDialogElement>
    
    dialogItems.forEach((dialog) => {
      const syncInert = () => {
        dialog.toggleAttribute('inert', !dialog.open)
      }
    
      syncInert()
    
      const observer = new MutationObserver(syncInert)
      observer.observe(dialog, {
        attributes: true,
        attributeFilter: ['open']
      })
    })
                
HTML APIs and Forms Grouping
All Do's Dont's
  • ・
  • ・
  • ・
  • ・
  • ・
  • ・
  • ・
  • ・
  • ・
  • ・
Utilize the form='form-id' attribute to decouple input and tree

CSS Tips from Modern Web Guidance

Foundatsions
  • ・情報の重複にはくれぐれも注意する。以下のような例外を除き、原則として情報の重複より変数の使用を優先する
  • ・要素の色指定を単に「文字色と同一にしたい」場合は冗長化を防ぐためCSS変数ではなくcurrentColorの値を用いること。currentColor は現要素で指定または継承した文字色をそのまま指定する
  • ・「親要素と同一のプロパティ:値」を子要素にも指定したい場合はinherit値を指定し記述の重複を避ける
  • ・font-size: var(--size)を用いるくらいならemで指定すること
  • ・メディアクエリごとに何度もpaddingやmarginを指定するくらいならコンテナクエリ+cqi / cqbを用いて一回の指定としてしまおう
  • ・「コードの重複」は「情報の重複」とは限らない。あくまで目的は保守性、堅牢性の向上であり、文字数の削減ではないことを理解しよう
  • ・論理プロパティを使用すること。たとえページ制作者がローカライズを意図していなくとも、ユーザが使用する翻訳ツールによってはその真価を発揮する
  • ・だからといって野放図に論理プロパティを用いないこと。例えばdrop-shadowなど、言語によって反転してしまっては困る装飾に対し論理プロパティを用いるのは悪手
  • ・異なる表示モード(ダークモード、ハイコントラストモードなど)、異なる画面幅、異なる入力形式(キーボード、タッチ、ポインタなど)に対し常に意識を巡らせること
List of @media with various situations

    OS・ブラウザのカラースキーム対応
    @media (prefers-color-scheme: dark) {}
    @media (prefers-color-scheme: light) {}

    Windowsのハイコントラストモードなど、強制カラーモード
    @media (forced-colors: active) {}
    @media (forced-colors: none) {}

    高(低)コントラスト設定
    @media (prefers-contrast: none) {}
    @media (prefers-contrast: less) {}
    @media (prefers-contrast: custom) {}

    色反転設定
    @media (inverted-colors: inverted) {}
    @media (inverted-colors: none) {}





    ポインティングデバイスの精度別
    @media (pointer: fine) {} // マウスなど
    @media (pointer: none) {} // ポインタ入力なし
    @media (pointer: coarse) {} // タッチなど
    ※pointer = 画面を操作する主デバイスを判定

    利用可能なポインティングデバイスのうち、最も適合するもの
    @media (any-pointer: fine) {}
    @media (any-pointer: none) {}
    @media (any-pointer: coarse) {}
    ※any-pointer = 端末に接続されている全てのデバイスを判定

    ホバー可能なデバイスが接続されている場合
    @media (hover: hover) {}
    @media (hover: none) {}
    ※hover = 画面を操作する主デバイスを判定

    何かしらホバー可能なデバイスが接続されている場合
    @media (any-hover: hover) {}
    @media (any-hover: none) {}
    ※any-hover = 端末に接続されている全てのデバイスを判定





    アニメーションやモーションを減らす
    @media (prefers-reduced-motion: reduce) {
      * {
        animation-duration: .01ms;
        transition-duration: .01ms;
      }
    }

    透過効果を減らす
    @media (prefers-reduced-transparency: reduce) {}





    縦向き・横向き
    @media (orientation: portrait) {}
    @media (orientation: landscape) {}

    縦横比
    @media (aspect-ratio > 16 / 9) {}

    画面解像度・DPI
    @media (min-resolution: 2dppx) {}





    色を表示できるビット深度
    @media (color) {}
    @media (min-color: 8) {}

    表示可能な色域
    @media (color-gamut: srgb) {}
    @media (color-gamut: p3) {}
    @media (color-gamut: rec2020) {}

    HDRなどのダイナミックレンジ
    @media (dynamic-range: high) {}

    画面の更新頻度
    @media (update: fast) {}
    @media (update: slow) {}
    @media (update: none) {}





    Webアプリの表示モード。PWAなどで使用
    @media (display-mode: standalone) {}
    @media (display-mode: fullscreen) {}
    @media (display-mode: browser) {}

    Javascriptが使用可能か
    @media (scripting: enabled) {}
    @media (scripting: none) {}

    ブロック方向・インライン方向へのオーバーフロー方法
    @media (overflow-block: scroll) {}
    @media (overflow-inline: scroll) {}






    データ通信量を減らしたい設定
    @media (prefers-reduced-data: reduce) {}





    印刷時
    @media print {
      nav {
        display: none;
      }
    }

    画面表示時
    @media screen {}





    折りたたみ端末など分割されたビューポートのセグメント数
    @media (horizontal-viewport-segments: 2) {}



    一覧を調べる場合は以下を参照するとわかりやすい
    ・Media features
    ・User preferences media features
    ・Display quality media features
    ・Interaction media features
    ・Video-related media features
    ・Scripting media features
    ・Experimental media features
                
Inheritance and The Cascade

BEMなどの命名則を用いて構造を示すことは避ける。
代替としてCascade Layersや:where()を用いて制作者が自然に意図を反映できるようなしくみを構築する。

Cascade Layers(@layer)を用いて明示的なスタイル階層を定義しておき、且つ階層の優先度を定義する(例:reset > base > theme > components > utilities ...)。
併せて :where() を用いて妥当な、明確な意味合いを持つ競合でのみ継承度の比較が行われるようにすることで、スタイルのオーバーライドを簡易にする。
なお:not()や遠い祖先からの継承など特殊ケースにおいては :where() の使用を控えること。

明示的な値の代わりにinherit, initial, unset, revertなどの共通キーワードを積極的に使用することで、スタイルの流れや意味合いをより明快にするとともに保守性を向上させる。

▼各値の詳細

  • ・initial:「W3C」が定義する各プロパティの初期値を値とする。ユーザエージェントやリセットCSSの初期値ではないことに注意
  • ・inherit:該当プロパティを持つ最も近い親または祖先要素の値を継承する。いずれの祖先も該当プロパティを保持していない場合はinitialと同じ挙動を取る。注意点として"例えそのプロパティが非継承プロパティであったとしても強制的に継承する"点がunsetと異なる
  • ・unset:親または祖先が該当のプロパティを保持しており且つそのプロパティが"継承プロパティである場合"はその値を継承する。該当プロパティが非継承プロパティの場合、およびいずれの親または祖先要素も該当プロパティを保持敷いていない場合はinitialと同一の挙動を取る
  • ・revert:その環境のスタイルオリジンまでロールバックする。例えばStylus拡張などでブラウザ上に閲覧者が独自のスタイルを当てている場合はページ自体のスタイルを破棄して閲覧者作成のスタイルへ、特に閲覧者側指定のスタイルが無ければユーザエージェントの初期値に戻す

▼代表的な継承プロパティ

  • color
  • font
  • font-family
  • font-size
  • font-stretch
  • font-style
  • font-variant
  • font-weight
  • font-feature-settings
  • font-kerning
  • font-language-override
  • font-optical-sizing
  • font-variation-settings
  • line-height
  • letter-spacing
  • word-spacing
  • text-align
  • text-indent
  • text-transform
  • white-space
  • word-break
  • overflow-wrap
  • direction
  • writing-mode
  • visibility
  • cursor
  • list-style
  • list-style-image
  • list-style-position
  • list-style-type
  • quotes
  • tab-size
  • orphans
  • widows
  • border-collapse
  • border-spacing
  • caption-side
  • empty-cells
  • text-rendering
  • text-justify

▼代表的な非継承プロパティ

  • margin
  • margin-top
  • margin-right
  • margin-bottom
  • margin-left
  • padding
  • padding-top
  • padding-right
  • padding-bottom
  • padding-left
  • width
  • height
  • min-width
  • max-width
  • min-height
  • max-height
  • display
  • position
  • top
  • right
  • bottom
  • left
  • z-index
  • float
  • clear
  • overflow
  • overflow-x
  • overflow-y
  • box-sizing
  • box-shadow
  • opacity
  • transform
  • transform-origin
  • transition
  • animation
  • background
  • background-color
  • background-image
  • background-position
  • background-size
  • background-repeat
  • border
  • border-width
  • border-style
  • border-color
  • border-radius
  • outline
  • outline-width
  • outline-style
  • outline-color
  • flex
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex-direction
  • flex-wrap
  • justify-content
  • align-items
  • align-content
  • align-self
  • order
  • gap
  • row-gap
  • column-gap
  • grid
  • grid-template
  • grid-template-columns
  • grid-template-rows
  • grid-column
  • grid-row
  • grid-area
  • grid-gap
  • content
  • counter-reset
  • counter-increment
  • object-fit
  • object-position
  • resize
  • pointer-events
  • user-select