Webページの見た目(レイアウト・色・余白・文字)を担当するのが CSS(Cascading Style Sheets) です。HTMLが「文章の構造」なら、CSSは「デザインと配置」。この記事では CSSの基本概念 → よく使うプロパティ → レイアウト(Flex/Grid)→ レスポンシブ までをひと通り押さえ、最後に ミニLP(ランディングページ)を作るハンズオン を用意しました。
この記事でできるようになること
- CSSの当て方(外部CSS / 内部CSS / インライン)を理解する
- セレクタ、優先順位(詳細度)、カスケードがわかる
- 余白・枠線・サイズ(ボックスモデル)を扱える
- Flexbox / Gridでレイアウトできる
- レスポンシブ対応(メディアクエリ)ができる
- それっぽい見た目のミニLPを自作できる(ハンズオン)
CSSの基本:どこに書いてどう当てる?
CSSの当て方は3種類あります。
1) 外部CSS(おすすめ)
ファイルを分けて管理します。
<link rel="stylesheet" href="styles.css">
2) 内部CSS(小規模向け)
HTMLの<style>に書きます。
<style>
body { font-family: sans-serif; }
</style>
3) インライン(原則非推奨)
要素のstyle=""に直書き。保守しづらいです。
<p style="color: red;">赤い文字</p>
基本は 外部CSS にしましょう。
セレクタ:どの要素に適用するかを指定する
CSSは「セレクタ { プロパティ: 値; }」が基本です。
h1 { color: #333; }
よく使うセレクタ:
要素セレクタ
p { line-height: 1.8; }
classセレクタ(超重要)
.card { border: 1px solid #ddd; }
HTML側:
<div class="card">...</div>
idセレクタ(多用は注意)
#header { padding: 16px; }
HTML側:
<header id="header">...</header>
子孫・子・隣接など
.article p { color: #444; } /* .article の中の p */
.list > li { margin-bottom: 8px; } /* 直下の li */
h2 + p { margin-top: 0; } /* h2 の直後の p */
擬似クラス(ホバーなど)
a:hover { text-decoration: underline; }
button:disabled { opacity: 0.5; }
CSSのキモ:カスケードと優先順位(詳細度)
CSSが「上書きされる」仕組みを理解すると一気に楽になります。
- 基本:後に書いた方が勝つ(同じ強さなら)
- 強さ(詳細度):
id > class > 要素 - !important:最終手段(乱用すると地獄)
例:どっちが勝つ?
p { color: blue; }
.text { color: green; }
#main p { color: red; }
#main p が一番強いので赤になります。
ボックスモデル:レイアウトの基礎中の基礎
すべての要素は箱です。
- content(中身)
- padding(内側余白)
- border(枠線)
- margin(外側余白)
.box {
width: 300px;
padding: 16px;
border: 1px solid #ccc;
margin: 24px auto;
}
重要:box-sizing: border-box;
これがないと「幅 + padding + border」で想定より大きくなりがち。
*,
*::before,
*::after {
box-sizing: border-box;
}
よく使うプロパティ(まずここから)
文字
body {
font-family: system-ui, sans-serif;
font-size: 16px;
line-height: 1.7;
color: #222;
}
色・背景
.hero {
background: #f5f7ff;
color: #111;
}
幅・高さ
.container { max-width: 960px; margin: 0 auto; }
角丸・影
.card {
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0,0,0,.08);
}
表示方式
.inline { display: inline; }
.block { display: block; }
.flex { display: flex; }
.grid { display: grid; }
レイアウトの主役:Flexbox(1次元)
「横並び」「中央揃え」「均等配置」が得意です。
.nav {
display: flex;
align-items: center; /* 縦方向 */
justify-content: space-between; /* 横方向 */
gap: 12px;
}
子要素に対して:
.item {
flex: 1; /* 余白を均等に */
}
レイアウトのもう一人の主役:Grid(2次元)
カードを「いい感じに並べる」が得意です。
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
レスポンシブで列数を変えたいなら後述のメディアクエリが便利。
レスポンシブ:メディアクエリ(スマホ対応)
例:幅が768px以下なら1列にする
@media (max-width: 768px) {
.cards {
grid-template-columns: 1fr;
}
}
変数(CSSカスタムプロパティ)で管理がラクになる
色や余白の共通化に効きます。
:root {
--bg: #0b1020;
--text: #eaf0ff;
--primary: #4f7cff;
--radius: 14px;
}
body { background: var(--bg); color: var(--text); }
.button { background: var(--primary); border-radius: var(--radius); }
ハンズオン:ミニLPを作ってCSSの基本を体で覚える
ここからは コピペで動く ハンズオンです。
完成イメージ:ヘッダー、ヒーロー、特徴カード、料金、フッターがあるシンプルなLP。
1. フォルダを作る
css-hands-on/
index.html
styles.css
2. index.html を作る(コピペOK)
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>CSS入門ハンズオン:ミニLP</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="header">
<div class="container header__inner">
<a class="logo" href="#">MiniLP</a>
<nav class="nav">
<a href="#features">特徴</a>
<a href="#pricing">料金</a>
<a class="button button--ghost" href="#cta">お問い合わせ</a>
</nav>
</div>
</header>
<main>
<section class="hero" id="top">
<div class="container hero__inner">
<div class="hero__text">
<p class="badge">CSS入門ハンズオン</p>
<h1>“それっぽい”デザインを<br>最短で作れるCSSの基本</h1>
<p class="lead">
セレクタ・ボックスモデル・Flex/Grid・レスポンシブまで。
このページを作りながら一気に理解します。
</p>
<div class="hero__actions" id="cta">
<a class="button" href="#pricing">料金を見る</a>
<a class="button button--ghost" href="#features">特徴を見る</a>
</div>
<p class="note">※デザインはCSSだけ。画像なしでも雰囲気が出ます。</p>
</div>
<div class="hero__panel">
<div class="panel">
<h2 class="panel__title">学べること</h2>
<ul class="panel__list">
<li>セレクタと優先順位</li>
<li>余白・枠線・サイズの考え方</li>
<li>Flexbox / Gridの使い分け</li>
<li>レスポンシブ対応</li>
</ul>
</div>
</div>
</div>
</section>
<section class="section" id="features">
<div class="container">
<div class="section__head">
<h2>特徴</h2>
<p>初心者がつまずきやすいポイントを先回りして整理します。</p>
</div>
<div class="cards">
<article class="card">
<h3>シンプルな設計</h3>
<p>class中心でスタイルを当て、再利用しやすくします。</p>
</article>
<article class="card">
<h3>レイアウトが理解できる</h3>
<p>Flex/Gridを用途で使い分け。崩れにくい配置へ。</p>
</article>
<article class="card">
<h3>スマホ対応まで</h3>
<p>メディアクエリで見た目を整え、実運用に近づけます。</p>
</article>
</div>
</div>
</section>
<section class="section section--alt" id="pricing">
<div class="container">
<div class="section__head">
<h2>料金</h2>
<p>見た目の練習用なので内容はダミーです。</p>
</div>
<div class="pricing">
<div class="price">
<h3>Starter</h3>
<p class="price__value">¥0</p>
<ul>
<li>基本スタイル</li>
<li>カードレイアウト</li>
<li>レスポンシブ</li>
</ul>
<a class="button button--ghost" href="#cta">はじめる</a>
</div>
<div class="price price--featured">
<p class="badge badge--primary">おすすめ</p>
<h3>Pro</h3>
<p class="price__value">¥980</p>
<ul>
<li>変数で一括管理</li>
<li>ホバー演出</li>
<li>コンポーネント設計</li>
</ul>
<a class="button" href="#cta">申し込む</a>
</div>
<div class="price">
<h3>Team</h3>
<p class="price__value">¥2,980</p>
<ul>
<li>複数人開発の命名</li>
<li>ガイドライン例</li>
<li>拡張の考え方</li>
</ul>
<a class="button button--ghost" href="#cta">相談する</a>
</div>
</div>
</div>
</section>
</main>
<footer class="footer">
<div class="container footer__inner">
<p>© MiniLP CSS Hands-on</p>
<a href="#top">ページ上部へ</a>
</div>
</footer>
</body>
</html>
3. styles.css を作る(コピペOK)
/* ---------------------------------------
0) 初期化(最低限)
---------------------------------------- */
*,
*::before,
*::after {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
}
img {
max-width: 100%;
display: block;
}
/* ---------------------------------------
1) 変数(色・余白)
---------------------------------------- */
:root {
--bg: #0b1020;
--bg-alt: #0f1730;
--surface: rgba(255, 255, 255, 0.06);
--border: rgba(255, 255, 255, 0.12);
--text: #eaf0ff;
--muted: rgba(234, 240, 255, 0.75);
--primary: #4f7cff;
--primary-2: #8aa6ff;
--radius: 16px;
--shadow: 0 18px 50px rgba(0,0,0,0.35);
--container: 980px;
}
/* ---------------------------------------
2) 全体のベース
---------------------------------------- */
body {
background: radial-gradient(1200px 500px at 20% 0%, rgba(79,124,255,0.25), transparent),
radial-gradient(900px 400px at 80% 10%, rgba(138,166,255,0.18), transparent),
var(--bg);
color: var(--text);
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans JP", sans-serif;
line-height: 1.7;
}
a {
color: var(--text);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.container {
max-width: var(--container);
margin: 0 auto;
padding: 0 16px;
}
/* ---------------------------------------
3) ヘッダー
---------------------------------------- */
.header {
position: sticky;
top: 0;
backdrop-filter: blur(10px);
background: rgba(11, 16, 32, 0.7);
border-bottom: 1px solid var(--border);
z-index: 10;
}
.header__inner {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
height: 64px;
}
.logo {
font-weight: 800;
letter-spacing: 0.02em;
}
.nav {
display: flex;
align-items: center;
gap: 12px;
}
.nav a {
padding: 8px 10px;
border-radius: 10px;
}
.nav a:hover {
background: rgba(255,255,255,0.06);
text-decoration: none;
}
/* ---------------------------------------
4) ボタン(再利用コンポーネント)
---------------------------------------- */
.button {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 10px 14px;
border-radius: 12px;
background: linear-gradient(135deg, var(--primary), var(--primary-2));
color: #07102a;
font-weight: 700;
border: 1px solid transparent;
box-shadow: 0 10px 24px rgba(79,124,255,0.25);
}
.button:hover {
text-decoration: none;
transform: translateY(-1px);
}
.button--ghost {
background: transparent;
color: var(--text);
border-color: var(--border);
box-shadow: none;
}
.button--ghost:hover {
background: rgba(255,255,255,0.06);
}
/* ---------------------------------------
5) ヒーロー
---------------------------------------- */
.hero {
padding: 56px 0 32px;
}
.hero__inner {
display: grid;
grid-template-columns: 1.3fr 0.9fr;
gap: 20px;
align-items: start;
}
.badge {
display: inline-block;
padding: 6px 10px;
border-radius: 999px;
background: rgba(255,255,255,0.08);
border: 1px solid var(--border);
color: var(--muted);
font-weight: 700;
font-size: 12px;
letter-spacing: 0.03em;
}
.badge--primary {
background: rgba(79,124,255,0.18);
border-color: rgba(79,124,255,0.35);
color: var(--text);
}
.hero h1 {
margin: 12px 0 10px;
font-size: 40px;
line-height: 1.15;
letter-spacing: -0.02em;
}
.lead {
margin: 0;
color: var(--muted);
font-size: 16px;
}
.hero__actions {
margin-top: 18px;
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.note {
margin-top: 10px;
color: rgba(234, 240, 255, 0.6);
font-size: 13px;
}
.panel {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 18px;
box-shadow: var(--shadow);
}
.panel__title {
margin: 0 0 10px;
font-size: 16px;
}
.panel__list {
margin: 0;
padding-left: 18px;
color: var(--muted);
}
/* ---------------------------------------
6) セクション共通
---------------------------------------- */
.section {
padding: 42px 0;
}
.section--alt {
background: rgba(255,255,255,0.03);
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
.section__head h2 {
margin: 0 0 6px;
font-size: 26px;
}
.section__head p {
margin: 0 0 18px;
color: var(--muted);
}
/* ---------------------------------------
7) カード(Grid)
---------------------------------------- */
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 14px;
}
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 16px;
}
.card h3 {
margin: 0 0 6px;
}
.card p {
margin: 0;
color: var(--muted);
}
/* ---------------------------------------
8) 料金(Flex + ちょい演出)
---------------------------------------- */
.pricing {
display: flex;
gap: 14px;
align-items: stretch;
}
.price {
flex: 1;
background: rgba(255,255,255,0.04);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 16px;
}
.price--featured {
background: rgba(79,124,255,0.12);
border-color: rgba(79,124,255,0.35);
box-shadow: 0 18px 60px rgba(79,124,255,0.18);
transform: translateY(-6px);
}
.price h3 {
margin: 10px 0 6px;
}
.price__value {
margin: 0 0 10px;
font-size: 30px;
font-weight: 900;
letter-spacing: -0.02em;
}
.price ul {
margin: 0 0 14px;
padding-left: 18px;
color: var(--muted);
}
/* ---------------------------------------
9) フッター
---------------------------------------- */
.footer {
padding: 26px 0 36px;
color: var(--muted);
}
.footer__inner {
display: flex;
justify-content: space-between;
gap: 12px;
border-top: 1px solid var(--border);
padding-top: 16px;
}
/* ---------------------------------------
10) レスポンシブ(スマホ)
---------------------------------------- */
@media (max-width: 860px) {
.hero__inner {
grid-template-columns: 1fr;
}
.cards {
grid-template-columns: 1fr;
}
.pricing {
flex-direction: column;
}
.price--featured {
transform: none;
}
.hero h1 {
font-size: 32px;
}
}
4. ブラウザで index.html を開く
ダブルクリックでOK。
見た目が出れば成功です。
ハンズオンで学んだポイント(復習)
- 共通化:
.buttonのような「部品」を作ると拡張が楽 - Grid:カード一覧(特徴)はGridが簡単
- Flex:料金の横並びはFlexが直感的
- レスポンシブ:
@mediaで列数や並びを変える - box-sizing:ほぼ必須のお守り
よくあるつまずきと解決
CSSが反映されない
link rel="stylesheet" href="styles.css"のパスは合ってる?- ファイル名が
style.cssになってない? - ブラウザのキャッシュ対策に再読み込み(Ctrl+F5)
余白が思った通りにならない
marginとpaddingを混同していないか- 親に
display: flex/gridが当たっていて挙動が変わっていないか
レイアウトが崩れる
max-widthを使っているか(.container)- まずは
border: 1px solid red;などで箱を可視化すると原因が追いやすい
コメントを残す