← CSS言語ページに戻る
🎨

CSS言語の文法解説

CSSはプログラムのように処理を実行する言語ではなく、ブラウザに「どう見せるか」を宣言するスタイルシート言語です。そのため本ページでは、基本文法に加えて、ブラウザがCSSを解釈して画面を描画する仕組み(レンダリング・詳細度・カスケード)まで、基本情報技術者試験に頻出する範囲を深掘りして解説します。

文法解説

1. CSSの基本構文(セレクタ・プロパティ・値・コメント)

CSSのルールは「セレクタ { プロパティ: 値; }」という形式で書きます。セレクタはスタイルを適用する対象(どのHTML要素か)を指定し、宣言ブロック内には「プロパティ: 値;」の組を複数書けます。コメントは/* ... */で囲みます(//によるコメントは使えません)。

SAMPLE
/* pタグの見た目を指定する */
p {
  color: #333333;      /* 文字色 */
  font-size: 16px;     /* 文字サイズ */
}

h1 {
  color: navy;
  text-align: center;
}

2. 記述方法(インライン・内部スタイルシート・外部スタイルシート)

CSSを適用する方法は3つあります。要素のstyle属性に直接書くインラインスタイル、HTMLの<head>内に<style>要素で書く内部スタイルシート、別ファイル(.css)に書き<link>要素で読み込む外部スタイルシートです。保守性・再利用性の観点から、複数ページで使う場合は外部スタイルシートが推奨されます。

SAMPLE
<!-- ① インラインスタイル(要素ごとに直接指定) -->
<p style="color: red;">赤い文字</p>

<!-- ② 内部スタイルシート(そのHTMLファイル内だけで有効) -->
<head>
  <style>
    p { color: blue; }
  </style>
</head>

<!-- ③ 外部スタイルシート(複数ページで共有できる) -->
<head>
  <link rel="stylesheet" href="style.css">
</head>

3. セレクタの種類と詳細度(Specificity)

セレクタには要素セレクタ(p)、クラスセレクタ(.card)、IDセレクタ(#header)、子孫セレクタ(.card p)、子セレクタ(.card > p)、属性セレクタ(input[type="text"])などがあります。同じ要素に複数のルールが競合したとき、どれが適用されるかは詳細度(specificity)という数値で決まります。詳細度は「(インラインスタイル, IDセレクタの数, クラス/属性/疑似クラスの数, 要素/疑似要素の数)」の4つの値を左から優先して比較し、数値が大きいほうが優先されます。同じ詳細度であれば、CSSファイル内で後に書かれたルールが勝ちます。

SAMPLE
/* 詳細度 (0,0,1,0) = クラス1個 */
.title { color: blue; }

/* 詳細度 (0,0,1,1) = 要素1個+クラス1個 → 上より優先 */
h1.title { color: green; }

/* 詳細度 (0,1,0,0) = ID1個 → クラスより強い */
#main-title { color: red; }

/* インラインスタイルは (1,0,0,0) 相当で最優先(IDより強い) */
<h1 id="main-title" class="title" style="color: orange;">見出し</h1>
<!-- 実際に表示される色は orange(インラインが最優先) -->

/* !important は詳細度の計算を無視して最優先されるが、
   保守性を落とすため多用は避けるべき */
p { color: black !important; }

4. カスケードと継承

CSS(Cascading Style Sheets)の「カスケード」とは、複数のスタイル指定が競合したときに最終的な値を決定する仕組みです。優先順位は大きく「①詳細度(数値が高いほど優先)→②記述順(同じ詳細度なら後に書いたものが優先)→③!important(詳細度を無視して最優先)」の順で決まります。また、colorfont-familyなど一部のプロパティは、指定しなくても親要素から値を引き継ぐ継承が起こります。widthmarginなどレイアウト系のプロパティは基本的に継承されません。

SAMPLE
body {
  color: #333;       /* 継承されるプロパティ:子要素すべてに文字色が伝わる */
  font-family: sans-serif;
}

.box {
  width: 300px;       /* 継承されないプロパティ:子要素には伝わらない */
}

/* 明示的に親の値を継承させたい場合 */
.child {
  width: inherit;
}

/* 親から継承された値をリセットしたい場合 */
.reset {
  color: initial;    /* ブラウザの初期値に戻す */
}

5. ボックスモデル(content / padding / border / margin)

すべてのHTML要素は、内側から順に「content(内容)」「padding(内側の余白)」「border(枠線)」「margin(外側の余白)」という入れ子の箱として描画されます。box-sizing: content-box(初期値)ではwidth/heightはcontentのみのサイズを表し、padding・borderは別加算されます。box-sizing: border-boxにすると、width/heightにpadding・borderを含めた「見た目のサイズ」で指定できるため、レイアウト計算がしやすくなります。

SAMPLE
.box-content {
  box-sizing: content-box;  /* 初期値 */
  width: 200px;
  padding: 16px;
  border: 2px solid #333;
  /* 実際の描画幅 = 200 + 16*2 + 2*2 = 236px */
}

.box-border {
  box-sizing: border-box;
  width: 200px;
  padding: 16px;
  border: 2px solid #333;
  /* 実際の描画幅 = 200px(padding/borderはwidthの内側に収まる) */
}

/* 全要素にborder-boxを適用するのが実務での定番 */
* {
  box-sizing: border-box;
}

6. 色の指定方法と単位(px / % / em / rem / vw / vh)

色はキーワード(red)、16進数(#ff0000)、rgb()/rgba()hsl()などで指定できます。長さの単位には、常に一定サイズの絶対単位pxと、基準に応じて変化する相対単位があります。相対単位のうち%は親要素のサイズ、emは自身(または親)のフォントサイズ、remはルート要素(html)のフォントサイズ、vw/vhはビューポート(表示画面)の幅・高さの1%を基準とします。

SAMPLE
.badge {
  color: white;
  background-color: rgba(255, 0, 0, 0.8);  /* 最後の値0.8は不透明度 */
  font-size: 1.2rem;   /* ルート(html)のfont-sizeを基準に計算 */
  padding: 0.5em 1em;  /* 自身のfont-sizeを基準に計算 */
  width: 80%;          /* 親要素の幅の80% */
}

.hero {
  width: 100vw;   /* 画面の横幅いっぱい */
  height: 50vh;   /* 画面の高さの半分 */
}

7. 配置(position: static / relative / absolute / fixed / sticky)

positionプロパティは要素の配置方法を決めます。初期値のstaticは通常の文書の流れに従います。relativeは元の位置を基準に自身をずらせます。absoluteは直近のpositionが指定された祖先要素(無ければhtml)を基準に配置され、文書の流れから外れます。fixedはビューポート(画面)を基準に固定表示され、スクロールしても位置が変わりません。stickyは通常はstaticのように流れるが、指定した位置(topなど)に達するとfixedのように固定されます。

SAMPLE
.parent {
  position: relative;   /* 子のabsoluteの基準点になる */
}

.child-absolute {
  position: absolute;
  top: 10px;
  right: 10px;   /* .parentの右上を基準に配置 */
}

.header-fixed {
  position: fixed;
  top: 0;
  width: 100%;   /* スクロールしても画面上部に固定される */
}

.sidebar-sticky {
  position: sticky;
  top: 20px;     /* スクロールしてtop:20pxに達すると固定される */
}

8. Flexboxレイアウトの基礎

display: flexを指定すると、その要素は「フレックスコンテナ」になり、子要素(フレックスアイテム)を1方向(主軸)に柔軟に並べられます。flex-directionで並べる方向、justify-contentで主軸方向の配置、align-itemsで交差軸方向の配置、gapで要素間の間隔を指定します。1次元(横一列 or 縦一列)の整列に向いています。

SAMPLE
.nav {
  display: flex;
  flex-direction: row;          /* 横並び(初期値) */
  justify-content: space-between; /* 主軸方向:均等に間隔をあける */
  align-items: center;           /* 交差軸方向:縦中央揃え */
  gap: 12px;
}

.item {
  flex: 1;   /* 余った幅を均等に分け合う(flex-grow: 1と同義の一部) */
}

.wrap-list {
  display: flex;
  flex-wrap: wrap;   /* 幅が足りなければ折り返す */
  gap: 16px;
}

9. CSS Gridレイアウトの基礎

display: gridを指定すると、行と列からなる2次元の格子(グリッド)でレイアウトできます。grid-template-columns/grid-template-rowsで列・行のサイズを定義し、repeat()fr単位(利用可能な余白の比率)を組み合わせるとギャラリーやカード一覧のような整列に便利です。grid-column/grid-rowで特定のアイテムに複数マスを跨がせることもできます。Flexboxが1次元、Gridが2次元のレイアウトに向く、と覚えておくとよいでしょう。

SAMPLE
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);  /* 幅を3等分した列を3つ */
  gap: 16px;
}

.gallery-item--wide {
  grid-column: span 2;   /* 横方向に2マス分を占有 */
}

.layout {
  display: grid;
  grid-template-columns: 200px 1fr;   /* サイドバー固定+残りは可変 */
  grid-template-rows: auto 1fr auto;  /* header/main/footer */
  grid-template-areas:
    "sidebar header"
    "sidebar main"
    "sidebar footer";
}

10. レスポンシブデザイン(メディアクエリ・モバイルファースト)

@mediaを使ったメディアクエリにより、画面幅などの条件に応じて異なるスタイルを適用できます。近年推奨される設計手法がモバイルファーストで、まずスマートフォン向けの基本スタイルを書き、min-widthを使って画面が広がるほどスタイルを追加していきます(逆に大画面を基本としてmax-widthで崩していく設計もありますが、モバイル利用が主流の現在はモバイルファーストが一般的です)。

SAMPLE
/* モバイルファースト:まずスマホ向けの基本スタイル */
.container {
  width: 100%;
  padding: 0 16px;
}

/* 画面幅が768px以上(タブレット以上)になったら適用 */
@media (min-width: 768px) {
  .container {
    width: 720px;
    margin: 0 auto;
  }
}

/* 画面幅が1024px以上(PC)になったら適用 */
@media (min-width: 1024px) {
  .container {
    width: 960px;
  }
}

11. 疑似クラス・疑似要素

疑似クラス(コロン1つ、:hoverなど)は要素の「状態」に応じてスタイルを適用します。:hover(マウスオーバー時)、:focus(フォーカス時)、:nth-child()(n番目の子要素)などがあります。疑似要素(コロン2つ、::beforeなど)は要素の一部(存在しない仮想的な部分)を指定します。::before/::aftercontentプロパティと組み合わせて要素の前後に装飾的な内容を追加するのに使われます。

SAMPLE
button:hover {
  opacity: 0.8;
}

input:focus {
  border-color: blue;
}

li:nth-child(odd) {
  background: #f5f5f5;   /* 奇数番目の行に背景色 */
}

.badge::before {
  content: "★";
  margin-right: 4px;
}

.tooltip::after {
  content: attr(data-tooltip);   /* data属性の値を表示内容にする */
}

12. トランジション・アニメーション(transition / @keyframes / transform)

transitionはプロパティの値が変化するときに、その変化を滑らかに補間して見せます。より複雑な動きには@keyframesで複数の中間状態(0%〜100%)を定義し、animationプロパティで適用します。transformは要素の見た目上の移動・回転・拡大縮小を、レイアウトそのものを変更せずに行えるプロパティです(後述するレンダリング負荷の観点でも重要です)。

SAMPLE
.button {
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.button:hover {
  transform: translateY(-3px);   /* 上に3pxずらす */
  box-shadow: 0 6px 14px rgba(0,0,0,0.2);
}

@keyframes fadeIn {
  from { opacity: 0; transform: scale(0.9); }
  to   { opacity: 1; transform: scale(1); }
}
.fade {
  animation: fadeIn 0.5s ease-in forwards;
}

13. カスタムプロパティ(CSS変数)

--変数名: 値;の形式で独自の変数(カスタムプロパティ)を定義できます。:roothtml要素相当の擬似クラス)で定義すると、ページ全体で共有できるグローバル変数として使えます。値の参照にはvar(--変数名, 初期値)を使い、テーマカラーの一括管理や、JavaScriptからの動的な値変更に活用されます。

SAMPLE
:root {
  --main-color: #6f8cff;
  --spacing: 16px;
}

.button {
  background: var(--main-color);
  padding: var(--spacing);
}

.card {
  /* 第2引数は変数が未定義のときのフォールバック値 */
  border-color: var(--card-border, #ccc);
}

/* JavaScriptから動的に変更する例
   document.documentElement.style.setProperty('--main-color', '#ff0000'); */

14. ブラウザのレンダリングとの関係(CSSOM・リフローとリペイント)

ブラウザはHTMLを解析してDOM(文書構造の木構造)を、CSSを解析してCSSOM(CSS Object Model、スタイル情報の木構造)を構築します。DOMとCSSOMを組み合わせて「どの要素をどこに、どのくらいの大きさで表示するか」を計算するレンダーツリーを作り、要素の位置とサイズを計算するレイアウト(reflow / 再フロー)を経て、実際にピクセルを描画するペイント(repaint / 再描画)が行われます。widthheightpositionmarginなど要素の配置やサイズに関わるプロパティを変更するとレイアウト計算からやり直すreflowが発生し、影響範囲も含めて再計算されるため重い処理になります。一方、colorbackground-colorのように見た目の色だけが変わる場合はレイアウト計算は不要で、repaintだけで済みます。さらにtransformopacityの変更は、多くの場合レイアウト・ペイントの段階を飛ばし、GPUが扱う合成(コンポジット)レイヤーの変更だけで完結するため、reflow・repaintのどちらも避けられる最も軽い処理です。

SAMPLE
/* reflow(レイアウト再計算)が発生しやすい:
   要素のサイズ・位置が変わるため、周囲の要素の配置も再計算される */
.box-reflow {
  width: 300px;    /* JSでこの値をアニメーションさせるとreflowが連続発生 */
  top: 50px;
  margin-left: 20px;
}

/* repaintのみで済む:レイアウトは変わらず見た目の色だけ変化 */
.box-repaint {
  background-color: #eee;
  color: #333;
}

/* reflow・repaintを避け、コンポジットのみで完結しやすい:
   アニメーションに最も適した書き方 */
.box-composite {
  transition: transform 0.3s, opacity 0.3s;
}
.box-composite:hover {
  transform: translateX(10px);
  opacity: 0.9;
}

処理速度改善のポイント(描画パフォーマンス)

CSSはプログラムのように実行されるわけではありませんが、書き方によってブラウザの描画(レンダリング)速度に大きな差が出ます。

サンプルページへ進む →