WWDC Quick Look 💓 By SwiftGGTeam
What's new in CSS

What's new in CSS

元の動画を見る

ハイライト

Safari は今年、Masonry レイアウトプレビュー、margin-trim、OKLCH/LCH/OKLAB/LAB 色関数、color-mix()、relative color 構文、:user-valid/:user-invalid 疑似クラス、font-size-adjust、lh/rlh 単位、@counter-style を追加し、レイアウトを簡潔に、色を豊かに、フォームを使いやすく、タイポグラフィを精密にしました。

主要内容

レイアウト: Masonry と margin-trim

Masonry(瀑布流)レイアウトは Web でよく使われ、高さの異なるカード表示に適しています。以前は CSS Multicolumn(列方向に縦流し)か JavaScript ライブラリでした。Multicolumn は内容順が縦方向で設計意図と合いにくく、JavaScript は CSS より遅く脆弱です。

Safari Technology Preview では Masonry Layout が CSS Grid の拡張としてプレビューされています。grid-template-rows: masonry の 1 行で、列定義を保ちながら行方向に密に配置できます。

01:15

JavaScript ライブラリと異なり、Masonry と Grid の組み合わせで 1 次元は Masonry、もう 1 次元は frminmax()、固定幅列など Grid の全機能を使えます。

margin-trim は別のよくある課題を解決します。コンテナ内子要素の上下 margin が padding と重なり、上下の余白が想定より大きくなります。従来は最初の子の top margin と最後の子の bottom margin を手動削除していましたが、内容変更に弱いです。

margin-trim: block でコンテナ端に接する margin を自動トリム。Safari 16.4 でサポート、margin-trim: inline で水平方向も可能です。

03:58

色: sRGB の壁を超える

sRGB 色域は人間の可視色の一部のみ表現します。Display P3 は 50% 多くの色を表示でき、Apple は 2015 年の iMac から P3 をハード・ソフト両方でサポートしています。

CSS に 4 つの色関数が追加されました:

  • LCHOKLCH:明度(Lightness)、彩度(Chroma)、色相(Hue)
  • LABOKLAB:明度、緑-赤軸(A)、青-黄軸(B)

知覚的に均一で、Display P3 や将来の色域を含む任意の色域を表現できます。Safari 15.0/15.4 でサポート、Chrome/Edge/Firefox も Interop 2023 で対応しました。

06:51

Relative Color Syntax で既存色から新色を派生:

rgb(from blue r g b / 0.7)
lab(from var(--brand-color) calc(l / 2) a b)
oklch(from var(--accent) l calc(c / 3) h)

color-mix() は指定色空間で 2 色を混合、デフォルト 50/50 またはカスタム比率:

color-mix(in oklab, white, blue)
color-mix(in oklch, white 30%, blue 30%)

グラデーションと色アニメーションも色空間を指定可能。同じ白から青へのグラデーションでも、sRGB では紫寄り、OKLAB では青寄り、OKLCH では黄緑シアンを経由します。選択はデザイン効果次第です。

10:23

疑似クラス: より賢いフォーム検証

:valid:invalid は長年の課題があります。ページ読み込み時に空フィールドが invalid となり、入力前からエラーが表示されます。

:user-valid:user-invalid はより賢いアルゴリズムで検証状態の表示タイミングを判断。ユーザーがフィールドを離れた後にエラーを表示し、入力中は邪魔しません。Safari 16.5 以降サポート。

16:55

:has() も今年強化され、:has(:lang()) で特定言語の存在に基づくスタイル、メディア疑似クラスによる再生状態に基づく条件スタイルが可能になりました。

:dir() 疑似クラスは言語方向サポートの空白を埋めます。論理プロパティ(margin-inline-start など)と組み合わせ、LTR と RTL 両対応の CSS を書けます。

18:14

タイポグラフィ: 精密なフォント制御

lh と rlh 単位1lh は現在要素の行高、1rlh はルート要素の行高。レイアウトの間隔を行高の整数倍に保ち、垂直リズムを構築できます。

20:18

font-size-adjust:同じ font-size でもフォントによって見かけの大きさが大きく異なります。font-size-adjust は x-height 比率に基づき視覚サイズを調整し、フォントスタック内の代替フォントを揃えます。

Safari 16.4 は基本用法(font-size-adjust: 0.47)、Safari 17 は from-font(自動計算)と 2 値構文(cap-height、ch-width、ic-width、ic-height を基準に選択)を追加。

22:25

text-box-trim(プレビュー):フォントがテキストボックスに確保する余分な空間をトリムし、垂直中央揃えのずれを修正。進化中で、プロパティ名は leading-trim から text-box-trim に変更され、詳細は変わる可能性があります。

26:42

@counter-style:カスタムカウンタースタイル。セルビア・クロアチア文字、二進、循環 emoji など任意の数え方を定義可能。W3C が数百の既製スタイルを提供しています。

28:53

詳細

Masonry Layout と Grid の組み合わせ

main {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  grid-template-rows: masonry;
  gap: 1rem;
}

main {
  display: grid;
  grid-template-columns: 1fr 2fr 3fr;
  grid-template-rows: masonry;
  gap: 1rem;
}

main {
  display: grid;
  grid-template-columns: 10rem 1fr minmax(100px, 300px);
  grid-template-rows: masonry;
  gap: 1rem;
}

キーポイント:

  • grid-template-rows: masonry で瀑布流モード(行方向配置)
  • grid-template-columns で Grid の全機能を利用
  • 各アイテムは全体高さを最小化する列に配置
  • 現時点 Safari Technology Preview のみ
  • CSS Grid 仕様の一部で独立レイアウト機構ではない

margin-trim で端 margin 重なりを解決

.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

.card {
  background-color: #fcf5e7;
  padding: 2rlh;
  margin-trim: block;
}

.card h2, .card p {
  margin: 1rlh 0;
}

キーポイント:

  • margin-trim: block は垂直(block 軸)の端 margin をトリム
  • margin-trim: inline は水平(inline 軸)
  • 最初/最後の子要素の種類を知る必要なし
  • 内容変更に自動適応
  • Safari 16.4 以降サポート

広色域色の定義

.brand-red {
  color: #ff0000;
  color: rgb(255, 0, 0);
  color: hsl(0, 100%, 50%);
}

.brand-red-p3 {
  color: color(display-p3 1 0 0);
}

.brand-red-oklch {
  color: oklch(62.8% 0.257 29.2);
}

@media (color-gamut: p3) {
  .brand-red {
    color: color(display-p3 1 0 0);
  }
}

キーポイント:

  • color(display-p3 1 0 0) は P3 ディスプレイで sRGB より鮮やかな赤
  • oklch(...) は知覚的に均一なモデル
  • @media (color-gamut: p3) で P3 対応を検出
  • 段階的強化: sRGB 端末は通常色、P3 端末はより豊かな色

Relative Color Syntax

:root {
  --brand-blue: oklch(50% 0.2 250);
}

.brand-blue-light {
  color: oklch(from var(--brand-blue) calc(l + 20%) c h);
}

.brand-blue-dark {
  color: oklch(from var(--brand-blue) calc(l - 15%) c h);
}

.brand-blue-transparent {
  color: oklch(from var(--brand-blue) l c h / 0.5);
}

a:hover {
  color: color-mix(in oklab, currentColor 60%, white);
}

キーポイント:

  • from var(--brand-blue) で基準色を指定
  • calc(l + 20%) で明るい変体を生成
  • ch 不変で彩度・色相を継承
  • / 0.5 で透明度設定
  • color-mix で現在の文字色と白を混合

グラデーション色空間の比較

.gradient-srgb {
  background: linear-gradient(in srgb, white, blue);
}

.gradient-oklab {
  background: linear-gradient(in oklab, white, blue);
}

.gradient-oklch {
  background: linear-gradient(in oklch, white, blue);
}

.gradient-lch {
  background: linear-gradient(in lch, white, blue);
}

キーポイント:

  • in srgb は sRGB 色空間で計算
  • in oklab はより自然な青への遷移
  • 色空間ごとに中間色が異なり、絶対的な正解はない
  • デザイン要件と期待する視覚効果で選択

フォーム検証疑似クラス

.form-group:has(input:invalid) label::before {
  content: "✗ ";
  color: red;
}

.form-group:has(input:user-invalid) label::before {
  content: "✗ ";
  color: red;
}

.form-group:has(input:user-valid) label::before {
  content: "✓ ";
  color: green;
}

input:user-invalid {
  border-color: #dc2626;
  background-color: #fef2f2;
}

input:user-valid {
  border-color: #16a34a;
  background-color: #f0fdf4;
}

キーポイント:

  • :user-invalid はフィールドを離れ内容が無効な時に発火
  • :user-valid は正しく入力後に発火
  • ページ読み込み時や入力中はエラー非表示
  • :has() と組み合わせて親要素をスタイル化
  • Safari 16.5 以降サポート

font-size-adjust で視覚サイズを統一

article {
  font-family: "Iowan Old Style", Georgia, serif;
  font-size-adjust: 0.47;
}

article code {
  font-family: "SF Mono", Courier, monospace;
}

article {
  font-size-adjust: from-font;
}

article {
  font-size-adjust: cap-height from-font;
}

キーポイント:

  • font-size-adjust: 0.47 で全フォントの x-height を font-size の 47% に
  • from-font で主フォントの比率を自動計算
  • 2 値構文で ex-height(デフォルト)、cap-height 等を選択
  • フォントスタック内の視覚サイズ不一致を解消
  • Safari 16.4 は基本、Safari 17 は高度な用法をサポート

@counter-style カスタムカウンター

@counter-style serbo-croatian {
  system: alphabetic;
  symbols: "A" "B" "V" "G" "D" "Đ" "E" "Ž" "Z" "I" "J" "K" "L" "Lj" "M" "N" "Nj" "O" "P" "R" "S" "T" "Ć" "U" "F" "H" "C" "Č" "Dž" "Š";
}

ol.serbian {
  list-style: serbo-croatian;
}

@counter-style binary {
  system: numeric;
  symbols: "0" "1";
  pad: 4 "0";
}

@counter-style emoji-cycle {
  system: cyclic;
  symbols: "🐶" "🐱" "🐰";
}

@counter-style section-number {
  system: numeric;
  symbols: "〇" "一" "二" "三" "四" "五" "六" "七" "八" "九" "十";
}

h2 {
  counter-increment: section;
}
h2::before {
  content: counter(section, section-number) ". ";
}

キーポイント:

  • @counter-style でカスタムカウンターを定義
  • systemalphabeticnumericcyclic 等を指定
  • symbols で記号を列挙
  • pad で最小桁数とパディング文字
  • list-stylecounter() で利用
  • W3C が数百の既製スタイルを提供

重要ポイント

1. 手動端 margin クリーンアップを margin-trim に置き換え

  • やること:カードや記事コンテナで margin-trim: block を使用例
  • 価値:first-child/:last-child 手動ルールの保守負担を削減、内容変更に自動適応
  • 始め方:手動で端 margin を消している CSS を margin-trim: block/inline に置換

2. OKLCH でデザインシステムのパレットを構築

  • やること:HEX/HSL から OKLCH へ移行し、Relative Color Syntax で変体を生成
  • 価値:知覚的に均一で calc(l + 20%) が色相を問わず一貫、ダークモード適応が自然
  • 始め方:基準 OKLCH 色を定義、oklch(from ...) で変体生成、@media (color-gamut: p3) で鮮やかな色

3. :user-invalid でフォーム体験を改善

  • やること:invalid から :user-invalid へフォーム検証スタイルを移行
  • 価値:入力開始前にエラーを表示せず、フィールドを離れた後のみ表示
  • 始め方:invalid を検索しフォーム文脈で :user-invalid に置換、:has(input:user-invalid) で親をスタイル化

4. font-size-adjust でコードブロックの視覚サイズを統一

  • やること:等幅フォント領域に font-size-adjust を追加し本文と視覚サイズを揃える
  • 価値:等幅フォントは本文より小さく見えがちで「凹んだ」印象になる
  • 始め方code/prefont-size-adjust: from-font(Safari 17)を追加

5. @counter-style でローカライズされたリスト番号

  • やること:言語ごとに対応するカウンタースタイルを定義
  • 価値:西洋アラビア数字はすべての言語に適さない
  • 始め方:W3C Ready-made Counter Styles から必要な定義をコピーし適用

関連セッション

コメント

GitHub Issues · utterances