1 人で 25 日間の CSS 特訓アドベントカレンダーに挑戦します!ぜひ暖かく見守っていただけると嬉しいです。
コンテンツの内容は生成 AI と壁打ちをしてきました。以下の構成を考えています。
テーマ構成案:CSS 完全攻略の旅
大きく 4 つのフェーズに分けました。
- 基礎とレイアウトの週 (土台を固める)
- 装飾と表現の週 (見た目を極める)
- 動きとインタラクションの週 (命を吹き込む)
- モダン CSS と総合演習 (最新技術と実践)
Phase 1: レイアウトの達人になる (Day 1 - 7)
まずは要素を思い通りに配置する力をつけます。
-
Day 1: ボックスモデルの再確認
- お題:
box-sizing: border-boxの有無でどう挙動が変わるか比較するデモを作る。marginの相殺(collapse)をあえて発生させて理解する。
- お題:
-
Day 2: Flexbox (基礎)
- お題: 典型的な「ナビゲーションバー(ロゴ左寄せ、リンク右寄せ)」を作る。
justify-contentとalign-itemsを完璧にする。
- お題: 典型的な「ナビゲーションバー(ロゴ左寄せ、リンク右寄せ)」を作る。
-
Day 3: Flexbox (応用)
- お題: 聖杯レイアウト(ヘッダー、フッター、3 カラムの中身)を Flexbox だけで作る。
flex-grow,flex-shrinkを理解する。
- お題: 聖杯レイアウト(ヘッダー、フッター、3 カラムの中身)を Flexbox だけで作る。
-
Day 4: CSS Grid (基礎)
- お題: 田の字型のグリッド配置。
fr単位を使って均等配置を作る。
- お題: 田の字型のグリッド配置。
-
Day 5: CSS Grid (エリア)
- お題:
grid-template-areasを使って、直感的に複雑な雑誌風レイアウトを組む。
- お題:
-
Day 6: レスポンシブデザイン
- お題: モバイル、タブレット、PC で列数が変わるカードレイアウトを作る(Media Queries の使用)。
-
Day 7: Position 完全理解
- お題:
absolute,relative,fixed,stickyをすべて使った画面を作る(特にstickyで追従するヘッダーなど)。
- お題:
Phase 2: デザインの表現力を高める (Day 8 - 14)
CSS だけでリッチな見た目を作ります。
-
Day 8: 背景とグラデーション
- お題:
linear-gradient,radial-gradientを重ねて、複雑な模様や「夕焼け空」を作る。
- お題:
-
Day 9: 影(Box-shadow)の魔術
- お題: ニューモーフィズム(凹凸感のあるデザイン)や、紙が浮いているようなマテリアルデザイン風のカードを作る。
-
Day 10: ボーダーと角丸
- お題:
border-radiusの値を個別に設定して、円ではない有機的な「歪んだ形(Blob)」を作る。
- お題:
-
Day 11: テキスト装飾と Web フォント
- お題: 文字の縁取り、グラデーション文字、Google Fonts を使った美しい見出しを作る。
-
Day 12: 疑似要素 (::before / ::after)
- お題: HTML を汚さずに、リストアイコンやリボン風の見出しを CSS だけで作る。
-
Day 13: 画像加工 (object-fit / filter)
- お題: インスタグラム風のフィルタ(モノクロ、セピア、ぼかし)を CSS
filterだけで画像にかける。
- お題: インスタグラム風のフィルタ(モノクロ、セピア、ぼかし)を CSS
-
Day 14: クリップパス (clip-path)
- お題: 画像を星型や多角形に切り抜く。
Phase 3: 動きと最新機能 (Day 15 - 21)
ユーザー体験を向上させるアニメーションと、モダンな書き方。
-
Day 15: Transition (変化)
- お題: ホバーすると色やサイズが「気持ちよく」変わるボタンセットを作る。イージング(
ease-in-outなど)にこだわる。
- お題: ホバーすると色やサイズが「気持ちよく」変わるボタンセットを作る。イージング(
-
Day 16: Animation (キーフレーム)
- お題: ぐるぐる回るローディングスピナーや、ふわふわ浮く要素を作る。
-
Day 17: Transform (2D/3D)
- お題: ホバーするとカードがくるっと裏返る「フリップカード」を作る。
-
Day 18: 変数 (Custom Properties)
- お題: CSS 変数を使って、数行の変更だけで「ダークモード」に切り替わる仕組みを作る。
-
Day 19: スクロールスナップ
- お題: JavaScript なしで、スワイプでピタッと止まる全画面スライダー(カルーセル)を作る。
-
Day 20: モダン CSS (:has / :is / :where)
- お題: 親要素セレクタ
:has()を使って、「チェックボックスにチェックが入ったら、親の背景色を変える」などを実装する。
- お題: 親要素セレクタ
-
Day 21: コンテナクエリ (Container Queries)
- お題: 画面幅ではなく「親要素の幅」に応じてレイアウトが変わるコンポーネントを作る(最新のレスポンシブ)。
Phase 4: 総合演習とアート (Day 22 - 25)
学んだことを組み合わせて作品にします。
-
Day 22: CSS アート (初級)
- お題: HTML の
div1 つ(と疑似要素)だけで、日の丸弁当やシンプルなアイコンを描く。
- お題: HTML の
-
Day 23: 実践 UI トレース
- お題: 好きな Web サイト(Netflix や Apple など)の特定パーツ(ヘッダーや特徴的なボタン)を完璧に模写する。
-
Day 24: インタラクティブな仕掛け
- お題: JS なしのアコーディオンメニュー、または CSS のみで作るタブ切り替え UI。
-
Day 25: クリスマスカード制作 (Finale)
- お題: これまでの技術を総動員して、アニメーション付きの Web クリスマスカードを作る(雪を降らせる、ツリーが光るなど)。
この 25 日間が終わる頃には、CSS に対する苦手意識が消え、どんなデザインでも「あ、こう書けばいいな」と想像できるようになれるように頑張ります!
それでは、早速 1 日目の内容です。
初日は、地味ですが 最も重要 と言っても過言ではない「ボックスモデル」の理解です。ここが曖昧だと、将来レイアウト崩れに延々と悩まされることになります。
コードを書く準備(エディタや CodePen など)をして、始めていきましょう!
Day 1: すべての基礎「ボックスモデル」と「box-sizing」
🎯 本日の目標
-
box-sizing: border-boxの重要性 を体感する。 - CSS 初心者が必ずつまずく 「マージンの相殺(Margin Collapse)」 を目撃する。
📝 ミッション内容
以下の 3 つのステップで CSS を記述し、挙動の違いを確認してください。
Step 1: デフォルトの挙動(content-box)を知る
- 幅
200px、高さ100px、パディング20px、ボーダー10pxのボックスを作ってください。 - 問い: ブラウザ上で表示される「実際の箱の横幅」は何 px になっていますか?(開発者ツールで確認してみましょう)
Step 2: 現代の常識(border-box)を知る
- Step 1 と同じボックスをもう一つ作り、今度は
box-sizing: border-box;を指定してください。 - 問い: Step 1 のボックスと比べて、サイズはどう変わりましたか?なぜ変わったのでしょうか?
Step 3: マージンの相殺(Margin Collapse)
- 上下に並んだ 2 つの
div要素を作ってください。 - 上の要素には
margin-bottom: 30px;を、下の要素にはmargin-top: 20px;を指定してください。 - 問い: 2 つの要素の間隔は「50px」になっていますか?それとも…?
💻 実装サンプル
まずは自分で書いてみて、詰まったら以下のコードを参考にしてください。
🧠 解説と振り返り
実装できたら、以下の解説を読んで理解を深めてください。
-
content-box (Step 1)
- 指定した
width: 200pxは「中身の幅」になります。 - 実際の幅 = 200px (中身) + 40px (左右 padding) + 20px (左右 border) = 260px
- これだと「200px の箱を作ったつもりなのに、入らない!」という事故が起きます。
- 指定した
-
border-box (Step 2)
- 指定した
width: 200pxは「ボーダーまで含めた幅」になります。 - 実際の幅 = 200px (CSS が自動で中身の幅を計算して縮めてくれる)
- 実務では、全要素に
* { box-sizing: border-box; }を当てるのが定石です。
- 指定した
-
マージンの相殺 (Step 3)
- ブロック要素が縦に並ぶとき、margin は足し算(30 + 20 = 50)されず、 「大きい方の値」が適用されます。
- 答えは 30px になります。
なぜ、マージンの相殺(Margin Collapse)は起こるのか?
1. 直感的なイメージ:お互いの「縄張り」は重ねて OK
マージンを「壁」ではなく 「確保したいパーソナルスペース(縄張り)」 だと考えてみてください。
- 上の箱: 「俺の下には、最低でも 30px の空き地が必要だ!」
- 下の箱: 「俺の上には、最低でも 20px の空き地が必要だ!」
この 2 人が縦に並ぶ時、どうなるでしょうか?
もし 2 人の間の距離が 30px あれば…
- 上の箱: 「30px 空いてるな。よし、満足だ。」
- 下の箱: 「30px 空いてるな。俺は 20px あればいいから、十分すぎるくらいだ。満足だ。」
両方の要求を満たす最小限の距離は「30px」 になりますよね。
わざわざ 50px 離れなくても、お互いのスペース(余白)は 共有(重ねる)しても良い というのが、CSS の基本的なルールなんです。
これを専門用語で 「マージンの相殺(Margin Collapse)」 と呼びます。
2. 歴史的な背景:文章を読みやすくするため
「なぜそんな仕様にしたの?」というと、CSS が作られた当初、Web は「論文やドキュメントを表示するためのもの」だったからです。
例えば、ブログや Word で文章を書く時を想像してください。段落(<p>タグ)がいくつか続くとします。
- 段落 A(下マージン 20px)
- 段落 B(上マージン 20px / 下マージン 20px)
- 段落 C(上マージン 20px)
もしマージンが「足し算」されてしまうと、段落と段落の間だけ 40px になってしまい、やたらとスカスカな文章になってしまいます。一番上や一番下は 20px なのに、間だけ倍の広さになるのは変ですよね。
「段落がいくつ続いても、行間を一定(20px)に保ちたい」
この要望を叶えるために、「縦方向のマージンは重ねる」という仕様が生まれました。
まとめ
- ルール: 縦に並ぶブロック要素のマージンは、 「大きい方の数値」が採用される (足し算にはならない)。
- 例外(重要): 実は、このルールが適用されるのは「通常の配置(block)」の時だけです。Flexbox や Grid でレイアウトした中身では、この相殺は起きず、素直に足し算(50px)になります。
Day 1 クリア ![]()
地味ですが、プロでもたまに「あれ?」となる基本中の基本でした。
明日は、現代 CSS レイアウトの主役 「Flexbox(基礎編)」 です。お楽しみに!