Slide 1

Slide 1 text

CSSレイアウト再入門: 完全に理解して CSSを記述するために berlysia / フロントエンドカンファレンス北海道2024

Slide 2

Slide 2 text

お品書き 1. はじめに:このトークについて 2. 整形コンテキスト / Formatting context a. ボックスモデル b. 通常フロー、またはフローレイアウト c. displayプロパティ d. その他のレイアウトモデル 3. ほかのやつ

Slide 3

Slide 3 text

このトークで想定するレベル感 ● それっぽいプロパティを書いてランダムウォークしている ● 他人の実装をコピペしている ● いつもMDNとにらめっこして時間がかかる ● 経験則的にはわかる(つもりだ)が論理的に説明することが難しい CSSを使ったレイアウト実装がなんとなくできる人 後から自分で検索して 理解を深めていくための足がかりをつくります

Slide 4

Slide 4 text

このトークの前提となること ● 「計算値 / Computed value」が定まっているところからスタートします ○ カスケーディング、継承、詳細度の話をしません ● どんな道具を使ってもCSSを扱う人間が決して逃げられない話をします ○ CSSを管理する道具、周辺のツールの話をしません ○ 全部自前でCanvasにレンダリングしたら逃げられるかもしれない ● 最低限言及に必要な範囲にとどめ、メンタルモデルの再構築に努めます ○ CSSの特定モジュールの詳細には必要以上に分け入りません ● 一般的な「Webブラウザ」上での視覚的なレイアウトの話をします ○ 「視覚整形モデル」のもと、特に「連続メディア」について扱います ○ 印刷用のような「ページメディア」の場合でもほとんど共通しています

Slide 5

Slide 5 text

このトークが主に参照する文書 ● CSS Snapshot 2023 ○ https://www.w3.org/TR/css-2023/ ○ 仕様の言葉はこの文書の索引から追いかけたものを示します ● CSS: カスケーディングスタイルシート | MDN ○ https://developer.mozilla.org/ja/docs/Web/CSS ○ 訳語はMDNに(あれば)合わせるようにしています このトークでよくわからなかったら MDNなどにもだいたい書いてあります! ゆっくり自分のペースで咀嚼してみてください

Slide 6

Slide 6 text

Original image from Understanding the critical path | web.dev by Google / CC-BY 4.0 このあたりの話をします このトークはだいたい

Slide 7

Slide 7 text

整形コンテキスト Formatting context CSS Display Module Level 3 整形コンテキストの紹介 - CSS: カスケーディングスタイルシート | MDN これがわかるとレイアウトはたちどころにわかる

Slide 8

Slide 8 text

こういうタスクをしたい header article article footer h2 p computed style span lorem…

Slide 9

Slide 9 text

CSSのボックスモデル margin border padding content 文書のある要素につき、ゼロ個以上の「ボックス」を生成する 文書の要素のツリーに対応するボックスのツリーを得る ※1 だいたい0個か1個と思ってよい 複数の場合は「主ボックス」を代表として 1個と同様に考えられる ※2 要素に対応しない「無名ボックス」が必要に応じて生成されることがある
...

Slide 10

Slide 10 text

フローレイアウト ボックスを並べる基本の仕組みで、何も指定しない場合の動作のこと。 文書を記述するためのレイアウトモデル。 テキストを与えると行が伸びていく。特定の要素を使って一部をマークアップでき、端ま でいけば折り返したりする。 段落を新たに作ると、行の伸びる方向とは直交する方向に並ぶ。 段落の並ぶ方向 ブロックフロー方向 Block flow direction 行の伸びる方向 インラインベース方向 Inline base direction

Slide 11

Slide 11 text

ブロックとインライン フローレイアウトにおけるボックスは大別して2種類 ● ブロックレベルのボックス、ブロックレベルボックス ○ フローレイアウトにおいて、段落のような振る舞いをする ○ ブロックレベルボックスは「ブロック 整形コンテキスト 」に参加する ● インラインレベルのボックス、インラインレベルボックス ○ フローレイアウトにおいて、行の中に現れる振る舞いをするボックス ○ インラインレベルボックスは「インライン 整形コンテキスト 」に参加する 各「整形コンテキスト」がボックスの並びを制御する

Slide 12

Slide 12 text

ボックスを並べる基本の仕組みで、何も指定しない場合の動作のこと。 文書を記述するためのレイアウトモデル。 テキストを与えると行が伸びていく。特定の要素を使って一部をマークアップでき、端ま でいけば折り返したりする。 段落を新たに作ると、行の伸びる方向とは直交する方向に並ぶ。 「インライン整形コンテキスト」が引き起こすこと 「ブロック整形コンテキスト」が引き起こすこと フローレイアウト

Slide 13

Slide 13 text

ブロック整形コンテキスト 前提 ● ページのルート要素の主ボックスはブロック整形コンテキストをなす ○ ページのルート要素の主ボックスはブロックレベルボックスである ○ ブロックレベルボックスは通常フローではほとんどの場合ブロックコンテナボックスでもある ○ ブロックコンテナボックスは自分がブロック整形コンテキストにいないとき、新たに生成する ● 参加するボックスはすべてブロックレベルボックスである ○ インラインレベルボックスが現れた場合は無名ブロックレベルボックスで囲むことで達成 次のようにレイアウトする ● 「包含ブロック」の中に、ブロックフロー方向の順にボックスを並べる ○ 包含ブロックは後述。初期値ではブロック整形コンテキストをなすブロックと一致する ● ボックス間の距離はブロックフロー方向のmarginによって定める ○ このときmarginの相殺が起きる。相殺の挙動はブロック整形コンテキストの仕業である ● 包含ブロックのインラインベース方向の始点側の辺に接するように配置する ○ ブロックフロー方向の寸法の初期値は autoなので、何もしなければ終点側までを占める

Slide 14

Slide 14 text

インライン整形コンテキスト 前提 ● 参加するボックスはすべてインラインレベルボックスである ○ テキストノードは無名インラインレベルボックスで囲まれる ○ ブロックコンテナボックスがインラインレベルボックスのみを含むとき生成される 次のようにレイアウトする ● 「包含ブロック」の中に、インラインベース方向の順にボックスを並べる ○ 行に対応する「行ボックス」が生成され、その中にボックスが並べられていく ○ 複数行に渡る場合は行ボックスも複数生成される ○ インラインレベルボックスが途中で行ボックスを跨ぐ場合は断片化する (いい感じに改行する) ● 行ボックスは個別のブロックフロー方向の寸法を持ちうる ○ 一部の文字がデカくてもちゃんと行がいい感じに大きくなってくれるあの動作 ● など、他にも細かい挙動がたくさんあります

Slide 15

Slide 15 text

「整形コンテキスト」が レイアウトを支配している

Slide 16

Slide 16 text

ところで:display: flex; な要素を作るとどうなるか ● 生成されるボックスはブロックレベルなのかインラインレベルなのか ○ ブロックレベル。インラインレベルにするなら display: inline-flex; と書く。 ● ブロック整形コンテキストとは全然動作が違う ○ flex-directionプロパティの初期値 rowはフレックスアイテムをインラインベース方向に並べる flex-wrapプロパティでアイテムの並びがおさまらなかったら折り返すこともできる ○ ブロック整形コンテキストはブロックフロー方向に並べる ブロックレベルボックスの折り返しの機能はない display: block; を display: flex; にしたらこうなるわけです

Slide 17

Slide 17 text

インラインレベルボックスか、ブロックレベルボックスか フローレイアウトか、フレックスボックスか、他のレイアウトモデルか 外側:ツリー上の親や兄弟ボックスとの関係に影響 外側表示型 / Outer display type 内側:ツリー上の子孫のレイアウトに影響 内側表示型 / Inner display type ボックスの種別には、外側と内側がありそうだ これをdisplayプロパティだけで指定している? →実はそうでした、それだけではなく ……!

Slide 18

Slide 18 text

displayプロパティには2値の構文がある ※1 2023年11月からBaseline入り(現在はNewly Available) ※2 flow-rootはブロック整形コンテキストを明示的に生成させる指定( Widely Available) block block flow inline inline flow inline-block inline flow-root flow-root block flow-root flex block flex inline-flex inline flex

Slide 19

Slide 19 text

ほかの整形コンテキストをもつレイアウトモデル ● フレックスボックスレイアウト / Flexible Box Layout ○ displayプロパティの値がflex, inline-flexであるならば、フレックスコンテナボックスを成す ○ フレックスコンテナボックスはフレックスボックス整形コンテキストを成す ● グリッドレイアウト / Grid Layout ○ displayプロパティの値がgrid, inline-gridであるならば、グリッドコンテナボックスを成す ○ グリッドコンテナボックスはグリッド整形コンテキストを成す ● テーブル ○ displayプロパティの値がtable, inline-tableであるならば、テーブルラッパーボックスを成す ○ テーブルラッパーボックスを主ボックスとして、直下にテーブルボックスを成し、 テーブルボックスはテーブル整形コンテキストを成す ● ルビ ○ displayプロパティの値がrubyであるならば、ルビコンテナボックスを成す ○ ルビコンテナボックスはルビ整形コンテキストを成す

Slide 20

Slide 20 text

独自の整形コンテキストを伴わないレイアウト ● floatプロパティにnone以外が与えられた浮動要素 ○ フローレイアウト のもとで、通常フローから「浮動」して配置する動作をする ○ floatプロパティがnone以外の値を持つ場合、 displayプロパティの計算値が調整される ■ が、フローレイアウトのもとでなければ浮動は起きない ● positionプロパティによる位置指定レイアウト / Positioned Layout ○ 値がstatic, relative, stickyの場合は属する整形コンテキストのレイアウトに従う ■ stickyの場合はそこから粘着の動作をする ○ 値がabsolute, fixedの場合は属する整形コンテキストの「フローから除外 / out-of-flow」、 その上で包含ブロックに対して絶対位置での配置が行われる ■ fixedの場合、ビューポート上で最初に描画された位置に固定される 何かしらの形で整形コンテキストに依存している

Slide 21

Slide 21 text

整形コンテキストがわかれば レイアウトがわかる! わかった?

Slide 22

Slide 22 text

ほかに知っておくと良いこと ● (済)整形コンテキスト ● 包含ブロック ● 重ね合わせコンテキスト ● CSSのプロパティが使われる・使われないがどこに書いてあるか

Slide 23

Slide 23 text

包含ブロック / Containing block 何に影響するか ● width, height, margin, paddingのパーセント値の基準 ○ min/max-width/heightや、block-size, inline-sizeのほか、flex-basisなども同様 ○ 100%が思った通りの値になったりならなかったりするときに思い出したい ● position: absolute;指定時の絶対配置の基準 識別するには ● 最寄りの祖先のブロックコンテナを成す要素のコンテンツボックス ● 最寄りの祖先の整形コンテキストを成す要素のコンテンツボックス ● position: absoluteのとき、position: staticでない最寄りの祖先のパディングボックス ● position: fixedのとき、ビューポート(ブラウザ上でページが見えている領域) ● ほか、一部プロパティの指定により異なる場合がある

Slide 24

Slide 24 text

重ね合わせコンテキスト / Stacking context 何に影響するか ● 重ね合わせの動作 ○ z-indexをめちゃめちゃ大きくしても勝てないときに裏にかならずいる ○ z-indexを与えてない場合は positionプロパティで重ね合わせのルールがあることに注意 いつ生成されるか ● 文書のルート要素 ● positionがabsoluteかrelativeで、かつz-indexがautoでない要素 ● positionがfixedかstickyの要素 ● フレックスアイテム、グリッドアイテムでz-indexがautoでない要素 ● container-typeがsizeまたはinline-sizeの要素 ● ほか、レンダリング系や描画結果を使うプロパティの指定があるとき

Slide 25

Slide 25 text

CSSの各プロパティが使われる・使われないとは 実はプロパティの定義には何に対して適用されるかが書いてある(”Applies to”)

Slide 26

Slide 26 text

CSSの各プロパティが使われる・使われないとは 実はプロパティの定義には何に対して適用されるかが書いてある(”Applies to”) が、ものによっては広く使えそうに書いてありながら 動作としては実質的に特定のときにしか意味がないことがある

Slide 27

Slide 27 text

このトークで想定するレベル感 ● それっぽいプロパティを書いてランダムウォークしている ● 他人の実装をコピペしている ● いつもMDNとにらめっこして時間がかかる ● 経験則的にはわかる(つもりだ)が論理的に説明することが難しい CSSを使ったレイアウト実装がなんとなくできる人 後から自分で検索して 理解を深めていくための足がかりをつくります

Slide 28

Slide 28 text

で、誰だったの ● berlysia (べるりしあ、と読む) ○ Webとアイマスが両本業 ● 株式会社ドワンゴ 教育事業 ○ Webフロントをやる人 ○ Webフロントのためにいろいろやる人 ■ フロントエンド周り採用中です! ● TSKaigiコアスタッフ ○ TSKaigiは2025も企画中! ○ 11/16に京都でTSKaigi Kansai 2024があります ■ 9/17までCfPを募集しています