Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
CSSレイアウト再入門:完全に理解してCSSを記述するために
Search
berlysia
August 24, 2024
16
8.2k
CSSレイアウト再入門:完全に理解してCSSを記述するために
フロントエンドカンファレンス北海道2024
で発表させていただきました。
スライド中のリンク一覧
CSS Snapshot 2023
CSS: カスケーディングスタイルシート | MDN
berlysia
August 24, 2024
Tweet
Share
More Decks by berlysia
See All by berlysia
JavaScriptのモジュール解決の相互運用性 / JSConf JP 2024 - Interoperability of Module Resolutions in JavaScript
berlysia
4
3k
ESLintのローカルルールで独自のコーディング規約を実装する
berlysia
7
3.8k
Webフロントエンドのリプレイスにおけるテストとの付き合い方
berlysia
0
360
自然発生した実装パターンに、マイクロフロントエンドと名がつきました / JSConf JP 2022
berlysia
5
8k
N予備校とWebフロントエンドの新陳代謝 / iCARE Dev Meetup #30
berlysia
2
11k
Webフロントエンドのリプレースを支えるテストの考え方 / JSConf JP 2021
berlysia
21
14k
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
88
5.7k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Six Lessons from altMBA
skipperchong
27
3.5k
The Cult of Friendly URLs
andyhume
78
6.1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
Practical Orchestrator
shlominoach
186
10k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Optimizing for Happiness
mojombo
376
70k
Keith and Marios Guide to Fast Websites
keithpitt
410
22k
Designing Experiences People Love
moore
138
23k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.9k
Transcript
CSSレイアウト再入門: 完全に理解して CSSを記述するために berlysia / フロントエンドカンファレンス北海道2024
お品書き 1. はじめに:このトークについて 2. 整形コンテキスト / Formatting context a. ボックスモデル
b. 通常フロー、またはフローレイアウト c. displayプロパティ d. その他のレイアウトモデル 3. ほかのやつ
このトークで想定するレベル感 • それっぽいプロパティを書いてランダムウォークしている • 他人の実装をコピペしている • いつもMDNとにらめっこして時間がかかる • 経験則的にはわかる(つもりだ)が論理的に説明することが難しい CSSを使ったレイアウト実装がなんとなくできる人
後から自分で検索して 理解を深めていくための足がかりをつくります
このトークの前提となること • 「計算値 / Computed value」が定まっているところからスタートします ◦ カスケーディング、継承、詳細度の話をしません • どんな道具を使ってもCSSを扱う人間が決して逃げられない話をします
◦ CSSを管理する道具、周辺のツールの話をしません ◦ 全部自前でCanvasにレンダリングしたら逃げられるかもしれない • 最低限言及に必要な範囲にとどめ、メンタルモデルの再構築に努めます ◦ CSSの特定モジュールの詳細には必要以上に分け入りません • 一般的な「Webブラウザ」上での視覚的なレイアウトの話をします ◦ 「視覚整形モデル」のもと、特に「連続メディア」について扱います ◦ 印刷用のような「ページメディア」の場合でもほとんど共通しています
このトークが主に参照する文書 • CSS Snapshot 2023 ◦ https://www.w3.org/TR/css-2023/ ◦ 仕様の言葉はこの文書の索引から追いかけたものを示します •
CSS: カスケーディングスタイルシート | MDN ◦ https://developer.mozilla.org/ja/docs/Web/CSS ◦ 訳語はMDNに(あれば)合わせるようにしています このトークでよくわからなかったら MDNなどにもだいたい書いてあります! ゆっくり自分のペースで咀嚼してみてください
Original image from Understanding the critical path | web.dev by
Google / CC-BY 4.0 このあたりの話をします このトークはだいたい
整形コンテキスト Formatting context CSS Display Module Level 3 整形コンテキストの紹介 -
CSS: カスケーディングスタイルシート | MDN これがわかるとレイアウトはたちどころにわかる
こういうタスクをしたい header article article footer h2 p computed style span
lorem…
CSSのボックスモデル margin border padding content 文書のある要素につき、ゼロ個以上の「ボックス」を生成する 文書の要素のツリーに対応するボックスのツリーを得る ※1 だいたい0個か1個と思ってよい 複数の場合は「主ボックス」を代表として
1個と同様に考えられる ※2 要素に対応しない「無名ボックス」が必要に応じて生成されることがある <div>...</div>
フローレイアウト ボックスを並べる基本の仕組みで、何も指定しない場合の動作のこと。 文書を記述するためのレイアウトモデル。 テキストを与えると行が伸びていく。特定の要素を使って一部をマークアップでき、端ま でいけば折り返したりする。 段落を新たに作ると、行の伸びる方向とは直交する方向に並ぶ。 段落の並ぶ方向 ブロックフロー方向 Block flow
direction 行の伸びる方向 インラインベース方向 Inline base direction
ブロックとインライン フローレイアウトにおけるボックスは大別して2種類 • ブロックレベルのボックス、ブロックレベルボックス ◦ フローレイアウトにおいて、段落のような振る舞いをする ◦ ブロックレベルボックスは「ブロック 整形コンテキスト 」に参加する
• インラインレベルのボックス、インラインレベルボックス ◦ フローレイアウトにおいて、行の中に現れる振る舞いをするボックス ◦ インラインレベルボックスは「インライン 整形コンテキスト 」に参加する 各「整形コンテキスト」がボックスの並びを制御する
ボックスを並べる基本の仕組みで、何も指定しない場合の動作のこと。 文書を記述するためのレイアウトモデル。 テキストを与えると行が伸びていく。特定の要素を使って一部をマークアップでき、端ま でいけば折り返したりする。 段落を新たに作ると、行の伸びる方向とは直交する方向に並ぶ。 「インライン整形コンテキスト」が引き起こすこと 「ブロック整形コンテキスト」が引き起こすこと フローレイアウト
ブロック整形コンテキスト 前提 • ページのルート要素の主ボックスはブロック整形コンテキストをなす ◦ ページのルート要素の主ボックスはブロックレベルボックスである ◦ ブロックレベルボックスは通常フローではほとんどの場合ブロックコンテナボックスでもある ◦ ブロックコンテナボックスは自分がブロック整形コンテキストにいないとき、新たに生成する
• 参加するボックスはすべてブロックレベルボックスである ◦ インラインレベルボックスが現れた場合は無名ブロックレベルボックスで囲むことで達成 次のようにレイアウトする • 「包含ブロック」の中に、ブロックフロー方向の順にボックスを並べる ◦ 包含ブロックは後述。初期値ではブロック整形コンテキストをなすブロックと一致する • ボックス間の距離はブロックフロー方向のmarginによって定める ◦ このときmarginの相殺が起きる。相殺の挙動はブロック整形コンテキストの仕業である • 包含ブロックのインラインベース方向の始点側の辺に接するように配置する ◦ ブロックフロー方向の寸法の初期値は autoなので、何もしなければ終点側までを占める
インライン整形コンテキスト 前提 • 参加するボックスはすべてインラインレベルボックスである ◦ テキストノードは無名インラインレベルボックスで囲まれる ◦ ブロックコンテナボックスがインラインレベルボックスのみを含むとき生成される 次のようにレイアウトする •
「包含ブロック」の中に、インラインベース方向の順にボックスを並べる ◦ 行に対応する「行ボックス」が生成され、その中にボックスが並べられていく ◦ 複数行に渡る場合は行ボックスも複数生成される ◦ インラインレベルボックスが途中で行ボックスを跨ぐ場合は断片化する (いい感じに改行する) • 行ボックスは個別のブロックフロー方向の寸法を持ちうる ◦ 一部の文字がデカくてもちゃんと行がいい感じに大きくなってくれるあの動作 • など、他にも細かい挙動がたくさんあります
「整形コンテキスト」が レイアウトを支配している
ところで:display: flex; な要素を作るとどうなるか • 生成されるボックスはブロックレベルなのかインラインレベルなのか ◦ ブロックレベル。インラインレベルにするなら display: inline-flex; と書く。
• ブロック整形コンテキストとは全然動作が違う ◦ flex-directionプロパティの初期値 rowはフレックスアイテムをインラインベース方向に並べる flex-wrapプロパティでアイテムの並びがおさまらなかったら折り返すこともできる ◦ ブロック整形コンテキストはブロックフロー方向に並べる ブロックレベルボックスの折り返しの機能はない display: block; を display: flex; にしたらこうなるわけです
インラインレベルボックスか、ブロックレベルボックスか フローレイアウトか、フレックスボックスか、他のレイアウトモデルか 外側:ツリー上の親や兄弟ボックスとの関係に影響 外側表示型 / Outer display type 内側:ツリー上の子孫のレイアウトに影響 内側表示型
/ Inner display type ボックスの種別には、外側と内側がありそうだ これをdisplayプロパティだけで指定している? →実はそうでした、それだけではなく ……!
displayプロパティには2値の構文がある ※1 2023年11月からBaseline入り(現在はNewly Available) ※2 flow-rootはブロック整形コンテキストを明示的に生成させる指定( Widely Available) <display-legacy> <display-outside>
<display-inside> block block flow inline inline flow inline-block inline flow-root flow-root block flow-root flex block flex inline-flex inline flex
ほかの整形コンテキストをもつレイアウトモデル • フレックスボックスレイアウト / Flexible Box Layout ◦ displayプロパティの値がflex, inline-flexであるならば、フレックスコンテナボックスを成す
◦ フレックスコンテナボックスはフレックスボックス整形コンテキストを成す • グリッドレイアウト / Grid Layout ◦ displayプロパティの値がgrid, inline-gridであるならば、グリッドコンテナボックスを成す ◦ グリッドコンテナボックスはグリッド整形コンテキストを成す • テーブル ◦ displayプロパティの値がtable, inline-tableであるならば、テーブルラッパーボックスを成す ◦ テーブルラッパーボックスを主ボックスとして、直下にテーブルボックスを成し、 テーブルボックスはテーブル整形コンテキストを成す • ルビ ◦ displayプロパティの値がrubyであるならば、ルビコンテナボックスを成す ◦ ルビコンテナボックスはルビ整形コンテキストを成す
独自の整形コンテキストを伴わないレイアウト • floatプロパティにnone以外が与えられた浮動要素 ◦ フローレイアウト のもとで、通常フローから「浮動」して配置する動作をする ◦ floatプロパティがnone以外の値を持つ場合、 displayプロパティの計算値が調整される ▪
が、フローレイアウトのもとでなければ浮動は起きない • positionプロパティによる位置指定レイアウト / Positioned Layout ◦ 値がstatic, relative, stickyの場合は属する整形コンテキストのレイアウトに従う ▪ stickyの場合はそこから粘着の動作をする ◦ 値がabsolute, fixedの場合は属する整形コンテキストの「フローから除外 / out-of-flow」、 その上で包含ブロックに対して絶対位置での配置が行われる ▪ fixedの場合、ビューポート上で最初に描画された位置に固定される 何かしらの形で整形コンテキストに依存している
整形コンテキストがわかれば レイアウトがわかる! わかった?
ほかに知っておくと良いこと • (済)整形コンテキスト • 包含ブロック • 重ね合わせコンテキスト • CSSのプロパティが使われる・使われないがどこに書いてあるか
包含ブロック / 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のとき、ビューポート(ブラウザ上でページが見えている領域) • ほか、一部プロパティの指定により異なる場合がある
重ね合わせコンテキスト / Stacking context 何に影響するか • 重ね合わせの動作 ◦ z-indexをめちゃめちゃ大きくしても勝てないときに裏にかならずいる ◦
z-indexを与えてない場合は positionプロパティで重ね合わせのルールがあることに注意 いつ生成されるか • 文書のルート要素 • positionがabsoluteかrelativeで、かつz-indexがautoでない要素 • positionがfixedかstickyの要素 • フレックスアイテム、グリッドアイテムでz-indexがautoでない要素 • container-typeがsizeまたはinline-sizeの要素 • ほか、レンダリング系や描画結果を使うプロパティの指定があるとき
CSSの各プロパティが使われる・使われないとは 実はプロパティの定義には何に対して適用されるかが書いてある(”Applies to”)
CSSの各プロパティが使われる・使われないとは 実はプロパティの定義には何に対して適用されるかが書いてある(”Applies to”) が、ものによっては広く使えそうに書いてありながら 動作としては実質的に特定のときにしか意味がないことがある
このトークで想定するレベル感 • それっぽいプロパティを書いてランダムウォークしている • 他人の実装をコピペしている • いつもMDNとにらめっこして時間がかかる • 経験則的にはわかる(つもりだ)が論理的に説明することが難しい CSSを使ったレイアウト実装がなんとなくできる人
後から自分で検索して 理解を深めていくための足がかりをつくります
で、誰だったの • berlysia (べるりしあ、と読む) ◦ Webとアイマスが両本業 • 株式会社ドワンゴ 教育事業 ◦
Webフロントをやる人 ◦ Webフロントのためにいろいろやる人 ▪ フロントエンド周り採用中です! • TSKaigiコアスタッフ ◦ TSKaigiは2025も企画中! ◦ 11/16に京都でTSKaigi Kansai 2024があります ▪ 9/17までCfPを募集しています