この記事は、CSSの基本から応用までを整理した備忘録です
HTMLやJavaScriptも関連が深い部分については、適宜補足しています
- 目次
- カスタムプロパティ(CSS変数)
- レイアウト関連のプロパティ
- 画像の扱い(imgタグとbackground-image)
- レスポンシブ対応(メディアクエリ・コンテナクエリ)
- 印刷対応
CSSの仕組みと書き方
ブラウザがCSSを解析し表示する流れ
- HTMLの解析(DOMの作成)
ブラウザはHTMLを読み込み、DOMツリーと呼ばれるツリー状の構造をメモリ上に作成
*DOMはHTML文書をプログラムで操作しやすい形にしたもの - CSSの取得と解析(CSSOMの作成)
CSSの情報を含む構造(CSSOM)を作成 - レンダーツリーの作成
レンダーツリーは表示に必要な情報だけを抽出したもの - レイアウトの計算
各要素のサイズ・位置を計算 - 描画(ピクセル単位で画面に描画)
(補足)JavaScriptの実行タイミングについて
JavaScriptの実行タイミングによって、CSSのレンダリングがブロックされることがある
*<script>
タグの配置や属性(async, defer)で、HTML解析やCSS解析に影響を与える
- 1のHTMLの解析中に
<script>
タグを見つけたら→JavaScriptダウンロード → コンパイル(機械語に変換)→ JavaScript実行 <script>
タグのasyncまたはdefer属性で実行タイミングを制御できる
属性 | DOMの解析 | スクリプトの読み込み | スクリプトの実行タイミング |
なし | 停止 | 逐次ダウンロード | ダウンロード後すぐ実行 DOMの解析再開 |
async | 並行 | 並行 | ダウンロード完了後に即時実行 *順番は保証されない |
defer | 並行 | 並行 | DOM解析完了後、*順番通りに実行 |
*deferはDOM解析が終わってから順番通りに実行されるので、CSSのレンダリングに影響を与えにくい
CSSの記述方法の種類(外部・内部・インライン)
1:外部スタイルシート
独立したファイル(拡張子が.css
)にCSSを書き、HTMLの<head>
の中に次のコードを追記する
*href属性の値でスタイルシートのパスを指定
<link rel="stylesheet" href="ファイル名.css" />
2:内部スタイルシート
HTML文書の中に配置
<style>
ここにCSSを書く
</style>
3:インラインスタイル(そのHTML要素のみに影響を与える)
style属性の中に記述
<div style="ここにCSSを書く">
CSSの基本構文
基本的な構造(セレクター・プロパティ・値)
CSSは 「セレクター」「プロパティ」「値」 の組み合わせで成り立っています
CSSの基本構造
セレクター {
プロパティ: 値;
プロパティ: 値;
/* 複数のプロパティを記述 */
}
- セレクター → どの部分?(スタイルを適用する要素)
- プロパティ → 何を変える?(スタイルの種類)
- 値 → どう変える?(具体的な設定内容)
アットルール(@を使ったルール)
アットルール(@ルール) は通常のCSSではできない特定の動作や条件を定義するための構文です@ルール名 オプション(必要に応じて){…}(ブロック)
/* CSSファイルの文字エンコーディングを指定 */
@charset "UTF-8";
/* 別のCSSファイルを読み込み */
@import url('styles.css');
/* メディアクエリ */
@media (max-width: 600px) {
body {
font-size: 14px;
}
}
/*カスタムフォントを定義*/
@font-face {
font-family: "CustomFont";
src: url("custom-font.woff2") format("woff2");
}
/*アニメーションの動きを定義*/
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/*ブラウザが特定のCSS機能をサポートしている場合にのみ適用するスタイルを記述*/
@supports (display: grid) {
.container {
display: grid;
}
}
/*スタイルを「レイヤー」に分けて適用順序を制御(新しいルール)*/
@layer utilities {
.hidden {
display: none;
}
}
ブラウザ対応とベンダープレフィックスの確認について
- CSSの仕様は進化し続けており、新しい機能が追加される一方でブラウザごとの対応状況が異なることがあります
- ベンダープレフィックス(例:-webkit-、-moz-)は、かつて実験的な機能を使う際に必要でしたが、現在は多くのモダンブラウザが標準仕様に対応しているため、使用する場面は減っています
新しいCSSやJavaScriptの機能を使う際は、事前にブラウザ対応状況を確認
Can I Useでブラウザでサポートされているか確認
Autoprefixerなどのツールを使えば、必要なベンダープレフィックスを自動的に付与できます
*ベンダープレフィックスを手動でコピペするならAutoprefixer CSS online
値
CSSの値はプロパティごとに使える種類が決まっています
例えば、colorは色を指定する値を使います
一部のプロパティでは多くのプロパティで共通して使える汎用的なキーワード(auto, none, inherit など)が使えます
その他「特定のプロパティでのみ使用できるキーワード」が多く存在します
色の指定
色をさまざまな方法で指定できます
色名(キーワード) | red(赤)、transparent (透明)など | |
16進数(HEX:00〜FF) *10進数の255は16進数でFF | 6桁:#RRGGBB 3桁:#RGB(2桁が同じ場合に省略) | #ff0000 #f00(赤) |
HEX + 透明度 *最新ブラウザ向け | 8桁:#RRGGBBAA 4桁:#RGBA(省略形) | #ff000080 #f008(赤、50%透明) |
RGB(A) R赤・G緑・B青の値を0〜255 Aは透明度 | rgb(r, g, b) rgba(r, g, b, α) | rgb(255, 0, 0)(赤) rgba(255, 0, 0, 0.5)(赤、50%透明) |
HSL(A) 色相(Hue) 彩度(Saturation) 輝度(Lightness) | hsl(h, s%, l%) hsla(h, s%, l%, α) | hsl(0, 100%, 50%)(赤) hsla(0, 100%, 50%, 0.5)(赤、50%透明) |
HWB 色相(Hue) 白みの量(Whiteness) 黒みの量(Blackness) *最新ブラウザ向け | hwb(h, w%, b%) | hwb(0, 0%, 0%)(赤) |
単位
CSSにはさまざまな単位があり、状況に応じて適切な単位を使う
絶対単位(固定サイズ)
px | ピクセル(画面の点) |
相対単位(環境や親要素に依存)
% | 親要素に対する割合 |
em | 親要素のフォントサイズに対する相対値 |
rem | ルート(html)要素のフォントサイズに対する相対値 |
vw | ビューポートの幅に対する割合 1vw = ビューポート幅の1% |
vh | ビューポートの高さに対する割合 |
vmin | ビューポートの小さい方の1% |
vmax | ビューポートの大きい方の1% |
新しい相対単位(スクロール時のビューポート対応)
*モバイルブラウザはスクロールするとアドレスバーが隠れビューポートの高さが変わる
そのため高さ100vhなどを指定したレイアウトが崩れる問題を解決するために登場
lvh | スクロール後の「大きなビューポート」に基づく単位 |
svh | スクロール直後の「小さなビューポート」に基づく単位 |
dvh | 動的なビューポートサイズ (アドレスバーの表示/非表示に追従) |
*vw・vmin・vmaxも同様にlvw・svw・dvwという形で対応
時間の単位(アニメーションやトランジションで使用)
- s:秒
- ms:ミリ秒(1秒 = 1000ミリ秒)
角度の単位
- deg:度(1回転 = 360deg)
- rad:ラジアン(1回転 = 2π rad)
- grad:グラード(1回転 = 400grad)
- turn:回転(1回転 = 1turn)
単位を指定しない例
- 0(ゼロ):単位を省略
例)margin: 0;
- 数値のみ:単位なし
line-heightプロパティ・opacityプロパティ・z-indexプロパティなどで使用
汎用的なキーワード
- auto: 自動配置やサイズ調整
- none:表示や効果を無効化
- inherit:親要素のスタイルを継承
- initia:CSSの初期値にリセット
- unse:継承可能な場合はinherit、そうでない場合はinitialと同じ動作
- safe-area-inset-* デバイスのセーフエリア(iOSのノッチ部分など)を考慮した値を取得
body {
padding-top: env(safe-area-inset-top); /* セーフエリアの上部に余白を追加 */
}
数学関数(値を動的に計算)
数学関数を使用してスタイルの値を動的に計算
/* calc(<式>) 計算 四則演算(+, -, *, /)を使用できる*/
div {
width: calc(100% - 50px); /* 親の幅から50pxを引いた値 */
margin: calc(10px + 5%); /* 10pxに5%の値を足した値 */
}
/* min(<値1>, <値2>, ...) 複数の値の中から最小値を選択 */
div {
width: min(50%, 300px); /* 50%か300pxのうち小さい方を適用 */
}
/* max(<値1>, <値2>, ...) 複数の値の中から最大値を選択 */
div {
width: max(10vw, 200px); /* 10vwか200pxのうち大きい方を適用 */
}
/* clamp(<最小値>, <優先値>, <最大値>) 指定された最小値、最大値の間で優先値を制限 */
div {
font-size: clamp(12px, 5vw, 24px); /* 最小12px、最大24px、優先値は5vw */
}
セレクター
セレクターは、どのHTML要素にスタイルを適用するかを指定するルールです
複数のCSSルールが同じ要素に適用される場合、「詳細度」 によってどのルールが適用されるかが決まります
*「詳細度」はセレクターの種類に基づいて計算されます
セレクターの種類
- 基本セレクター
- 要素セレクター:要素名(例:div p)
- 全称セレクター(すべての要素を指定):
*
で始める - クラスセレクター:
.
で始める(例 .class) - IDセレクター:
#
で始める(例 #id)
*同じID名をつけられる要素は1つだけ
- 結合セレクター(HTML内の位置関係)
- 子孫セレクター(
A B
)
意味:Aのすべての子孫(直下でなくてもOKであるBを選択
位置:BがAの中にあれば適用 - 子セレクター(
A > B
)
意味:Aの直下にある子要素Bを選択
位置:BはA の「直接の子」である必要がある - 隣接セレクター(
A + B
)
意味:Aの直後に隣接する兄弟要素Bを選択
位置:同じ階層内でAのすぐ後にあるBが対象 - 一般兄弟セレクター(
A ~ B
)
意味:Aの後に現れるすべての兄弟要素Bを選択
位置:同じ階層内でAの後に位置するすべてのBが対象
- 子孫セレクター(
- 擬似クラス(特定の「状態」や「条件」にある要素を選ぶ)
- :hover → マウスが要素に乗ったとき
- :focus → 要素がフォーカスされたとき(例: フォームの入力欄)
- :nth-child(n) → 親の中で特定の順番にある要素を選ぶ
- :first-child / :last-child → 最初または最後の子要素
- :nth-last-child(n) →後ろからn番目の子要素
- :only-child →親の中で唯一の子要素
- :empty→ 子要素を持たない要素
- :not(selector) → 特定のセレクター以外を選ぶ
- :has(selector)→ 指定したセレクターを子孫として含む要素
- :is(selector)→指定したセレクターに一致する要素
- :where(selector)→指定したセレクターに一致する要素(詳細度は0)
- :root→htmlを指定(ドキュメント全体に影響するスタイルを指定:htmlよりも高い詳細度)
- 擬似要素(要素の特定の「一部」にスタイルを適用する)
- ::before → 要素の前に装飾を追加
- ::after → 要素の後に装飾を追加
- ::first-line → 要素の最初の1行だけを装飾
- ::first-letter → 最初の文字だけを装飾
- 属性セレクター(特定の属性を持つ要素)
例: [type=”text”], [href^=”https”] - グループセレクター(
,
を使って複数の要素をまとめて指定)
例:h1, h2, p
例:.box, #main
html・body要素セレクター
- html
ページ全体を表す要素
サイズはブラウザのビューポートサイズに基づく
ページ全体に影響を与えるスタイルを設定 - body
コンテンツ部分(ユーザーが直接目にする部分)を表す要素
サイズはその中のコンテンツによって変わる
ページのコンテンツ部分に影響を与えるスタイルを設定
bodyやhtmlでよく初期設定として指定されるプロパティの例
*htmlの背景色(background-color)はページ全体を覆い、bodyの背景色はhtmlの上に描画される
html {
font-size: 16px; /* ルートフォントサイズ(remの基準) */
height: 100%; /* ビューポート全体の高さを確保 */
background-color: #f0f0f0; /* ページ全体の背景色 */
}
body {
margin: 0; /* マージンとパディングのリセット */
padding: 0;
font-family: Arial, sans-serif;
font-size: 1rem; /* 基本フォントサイズ */
line-height: 1.5; /* 行間 */
background-color: white; /* コンテンツ部分の背景色 */
color: #333; /* 文字色 */
}
ブラウザ全体を覆う背景
html, body {
height: 100%;
}
継承について
CSSは通常、セレクターで指定した要素にのみスタイルが適用されます
しかし、フォントやテキストの色などの 一部のプロパティ は、親要素に指定したスタイルが子要素で自動的に適用されます
例えば、color
やfont-family
などのプロパティは親要素に指定すれば子要素にも適用されます
継承されるプロパティ
親要素のスタイルが子要素に自動的に適用されるプロパティです
主にテキストやフォント関連のプロパティが該当します
- color:テキストの色
- font-family:使用するフォント
- font-size:テキストのサイズ
- font-weight:フォントの太さ
- letter-spacing:文字間の間隔
- line-height:行間の高さ
- font-style:フォントのスタイル(例: italic)
- font-variant:小型大文字(small-caps)などのバリアント
- visibility:要素の可視性(visible, hidden)
ボックスモデルやレイアウト、背景、装飾に関するプロパティは、通常は自動的に継承されませんが、inherit
を指定すると親要素のスタイルを継承させることができます
詳細度の計算とカスケード
詳細度の計算
セレクターの種類 | ポイント計算 | 説明 |
インラインスタイル | 1000 | 要素のstyle属性に直接書かれたスタイル |
IDセレクター | 100 | #id |
クラス・属性・擬似クラス | 10 | .class, [type=”text”], :hoverなど |
擬似クラス :not() と :has() | 引数のセレクターの詳細度 | |
擬似クラス :is() | 引数のセレクターの中で 最も高い詳細度 | |
擬似クラス :where() 全称セレクター* | 0 | |
要素・擬似要素 | 1 | div, ::before など |
#header .menu-item a:hover { color: red; }
/*
(IDセレクター)#header → 100ポイント
(クラス).menu-item → 10ポイント
(要素)a → 1ポイント
(擬似クラス):hover → 10ポイント
合計: 121ポイント
*/
カスケード(スタイルの優先順位)
CSSは複数のスタイルが競合したとき、どのルールを適用するかをカスケードという仕組みで決めています
- 重要度
!important
がついたスタイルが最優先p {color: blue !important;}
*使いすぎると管理が難しくなるため、必要最低限にする - 詳細度が大きいほど優先される
- 同じ詳細度のスタイルが競合する場合、後に書かれたスタイルが優先される
リセットCSSについて
ブラウザごとにデフォルトのスタイル(ユーザーエージェントスタイルシート)が異なるため、統一する
- リセットCSS → デフォルトのスタイルを完全になくす
- ノーマライズCSS → 完全になくすのではなくブラウザ間の差異を調整する
これらはスタイルシートの先頭に記述することが一般的です
このような初期スタイルの調整は、詳細度が低く設定されるため、その後に記述するカスタムスタイルで簡単に上書きできます
シンプルなリセットCSSの例
コードを見る
/* 全要素の余白とパディングをリセット */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* リストのスタイルをリセット */
ul, ol {
list-style: none;
}
/* アンカーリンクの下線をリセット */
a {
text-decoration: none;
color: inherit;
}
/* 画像のデフォルト表示をリセット */
img {
max-width: 100%;
height: auto;
}
/* ボタンのスタイルをリセット */
button {
all: unset;
display: inline-block;
cursor: pointer;
}
/* 入力欄やボタン */
input, textarea, select, button {
margin: 0;
padding: 0;
font: inherit; /* フォントを継承 */
color: inherit; /* テキスト色を継承 */
background: none; /* 背景色を削除 */
border: none; /* 枠線をリセット */
}
/* チェックボックスとラジオボタン */
input[type="checkbox"], input[type="radio"] {
appearance: none; /* デフォルトスタイルを削除 */
margin: 0;
}
/* テキストエリアのリサイズを調整 */
textarea {
resize: vertical; /* 垂直方向のみリサイズ可能 */
}
/* ドロップダウンメニュー */
select {
-webkit-appearance: none; /* ブラウザのスタイルを削除 */
-moz-appearance: none;
appearance: none;
}
/* テーブルのスタイルをリセット */
table {
border-collapse: collapse; /* セル間の隙間をなくす */
border-spacing: 0; /* セル間のスペースを0にする */
width: 100%; /* テーブルを親要素に合わせる */
}
th, td {
padding: 0; /* セルの余白をリセット */
text-align: left; /* デフォルトのテキスト位置を左寄せに */
}
マルチクラスについて
マルチクラスは、1つのHTML要素に複数のクラスを指定する方法です
複数のクラスをスペースで区切って指定し、それぞれのクラスのスタイルが適用されます
<div class="box highlight">マルチクラスの例1</div>
<div class="box highlight blue">マルチクラスの例2</div>
例2の場合、.box
と.box.blue
でborderプロパティが競合しているが .box.blue
が詳細度で優先される
.box {
border: 2px solid red; /* 赤色で幅2ピクセルの実線の枠線を追加 */
}
.highlight {
background: yellow; /* 背景色を黄色に設定 */
}
/*
セレクターとして複数クラスを組み合わせる例
.box(詳細度: 10) で赤い枠線が適用されますが、
.box.blue(詳細度: 20) が詳細度で優先され、青い枠線が適用される
*/
.box.blue {
border: 2px solid blue; /* 青色で幅2ピクセルの実線の枠線を追加 */
}
セレクターのスペースの違いによる意味の違い
.box.blue
:スペースがない場合はマルチクラス
boxクラスとblueクラスを同時に持つ要素を選択.box .blue
:スペースがある場合は子孫セレクター
boxクラスのすべての子孫(直下でなくてもOK)であるblueクラスを選択
カスタムプロパティ(CSS変数)
カスタムプロパティ(CSS変数)は、CSS内で値を変数のように再利用できる機能
カスタムプロパティのルール
--変数名: 値; で宣言(変数を定義する) |
var(--変数名) で参照(変数の値を使う) |
定義した要素内で有効(その要素の子要素でも使える) |
下層で再定義すると上書き(子要素で新しい値を設定可能) |
:root に定義するとグローバル(ページ全体で使える変数になる) |
/* :root でグローバル変数を設定 */
:root {
--main-color: #3498db;
--text-size: 16px;
}
/*
var(--変数名, デフォルト値(フォールバック)) を使うと、変数が未定義のときに代替値を設定できる!
*/
h1 {
color: var(--main-color);
font-size: var(--text-size, 14px); /* デフォルト値付き */
}
/* .dark-theme 内では --main-colorが上書きされる */
.dark-theme {
--main-color: #2c3e50; /* ここで再定義(上書き) */
}
レイアウト関連のプロパティ
(width・height・padding・border・margin)ボックスモデル
ボックスモデルのイメージ
要素は「箱(ボックス)」
ボックスには、コンテンツ・余白・枠線・外側のスペースという4つの要素がある
コンテンツ * width とheight で明示的に大きさを指定できる | 実際に文字や画像が表示される部分 |
内側の余白(padding ) | コンテンツとボーダーの間の余白 |
境界線(border ) | 要素の枠線(装飾) |
外側の余白(margin ) | ボックスと他の要素の間のスペース |
width: 200px;
height: 100px;
padding: 10px;
border: 5px solid black; /*幅、スタイル(solid・dotted・dashed・inset・none)、色を一括指定*/
margin: 20px;
/* marginやpaddingの一括指定 */
margin: 10px 20px 15px 5px; /* 上:10px, 右:20px, 下:15px, 左:5px */
padding: 10px; /* 全方向に10px */
padding: 10px 20px; /* 上下10px 右左20px*/
*パーセンテージ指定は親要素のサイズが基準
(box-sizing)widthにborderとpaddingを含めるか
box-sizingの違い
content-box(デフォルト) | width = コンテンツの幅 |
border-box | width = コンテンツ+padding +border |
.box {
width: 200px;
padding: 10px;
border: 5px solid black;
}
/*
このとき、実際のボックスサイズ
box-sizing: content-box; → 230px(200 + 10px×2 + 5px×2)
box-sizing: border-box; → 200px(paddingとborderをwidthに含める)
*/
border-box を使うとレイアウト崩れを防ぎやすい
すべての要素に適用する場合は、*
に適用すると便利
* {
box-sizing: border-box;
}
(min- と max-)最小サイズ・最大サイズ
min-width
やmax-width
はレスポンシブデザインでよく使う
幅の制限: min-width
とmax-width
/* min-width: 要素が縮小しすぎるのを防ぐ(初期値: 0) */
.button {
min-width: 100px; /* ボタンの幅が最低でも100px */
}
/* max-width: 要素が広がりすぎるのを防ぐ(初期値: none)*/
.content {
max-width: 800px; /* コンテンツ幅を最大800pxに制限 */
}
高さの制限:min-height
とmax-height
/*コンテンツ量が少ない場合でも、指定した高さを保つ (初期値: `0`)*/
div {
height: auto; /* コンテンツに応じた高さ(デフォルト値) */
min-height: 200px; /* 高さが200px未満にはならない */
}
/*
内容が多すぎる場合でも、指定した高さを超えないように制限(初期値: `none`)
スクロール可能なボックスを作成する際に有効
*/
div {
height: auto; /* コンテンツに応じた高さ(デフォルト値) */
max-height: 400px; /* 高さが400pxを超えない */
overflow: auto; /* 超えた部分はスクロール可能に */
}
(aspect-ratio)縦横率を指定する
要素の幅または高さが決まっていれば、縦横比を維持できる
レスポンシブデザインで便利
従来の方法よりシンプルに書ける
/*親要素の幅に基づいて高さが自動計算*/
.container {
width: 100%;
aspect-ratio: 16 / 9; /* 16:9 の比率 */
}
余談:以前は、要素の比率を維持するために、以下のような方法がよく使われていた
*親要素の高さをpadding-topで疑似的に指定し、比率を維持
.container {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9 の比率 */
}
.child {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
マージンの相殺について
垂直方向(上下方向)のマージンが重なったときに、足し合わせるのではなく、最大の値だけが適用される
<!--
隣接する要素間
20pxと30pxのマージンが相殺され、要素間のスペースは30px(大きい方が適用)
-->
<div class="box1" style="margin-bottom: 20px;">Box 1</div>
<div class="box2" style="margin-top: 30px;">Box 2</div>
<!--
親子要素間
40pxと20pxのマージンが相殺され、全体のマージンは40px
-->
<div class="parent" style="margin-top: 40px;">
<div class="child" style="margin-top: 20px;">Child</div>
</div>
<!--
高さが0の空のブロック要素
上下のマージン20pxが相殺され、1つの20pxだけが適用
-->
<div style="margin: 20px 0;"></div>
マージンの相殺を防ぐ方法(親要素に適用)
padding
やborder
を追加する(子要素のmarginを内側に収める)overflow: hidden;
を設定するdisplay: flow-root;
を設定する
(display)要素の表示方法を変える
displayプロパティは外側と内側の表示型を設定するプロパティ
- 外側の表示型(周囲の要素との関係でどのようにレイアウトされるか)
- block(デフォルト): ブロック要素に変更 (次の要素が新しい行に配置)
- inline:インライン要素に変更(次の要素が同じ行内に配置)
- inline-block:インラインブロック要素に変更(次の要素が同じ行内に配置)
- none:要素を非表示、レイアウトからも完全に除外
- 内側の表示型(子要素がどのようにレイアウトされるか)
- flow(デフォルト):通常のブロック要素やインライン要素として子要素を配置
- flex:子要素をフレックスアイテムとして配置(フレックスボックス仕様に従う)
- grid:子要素をグリッドアイテムとして配置(グリッドレイアウト仕様に従う)
- flow-root:要素が新しいBFC(ブロックフォーマッティングコンテキスト )を作成
- table系の表示型:表全体のレイアウト(外側)と、表の構造(行やセルの配置など内側)に影響を与える
- 外側の表示型として、周囲の要素との関係に影響する(
table
やinline-table
) - 内側の表示型として、子要素(
table-row
,table-cell
など)のレイアウトに影響
- 外側の表示型として、周囲の要素との関係に影響する(
/* CSS レベル 3 以降の構文 */
display: <外側の表示型> <内側の表示型>;
/* 具体例 */
display: block; /* 外側の表示型: block, 内側の表示型: flow(デフォルト) */
display: flex; /* 外側の表示型: block(デフォルト), 内側の表示型: flex */
display: inline flex; /* 外側の表示型: inline, 内側の表示型: flex */
display: inline-flex; /* 上と同じ動作。互換性を考慮して display: inline-flex を推奨 */
display: block/ inline/ inline-block
(ブロック要素・インライン要素・インラインブロック要素に変更)
ブロック要素・インライン要素・インラインブロック要素とは
ブロック要素 | インライン要素 | インラインブロック要素 |
次の要素は新しい行に配置 | 横に並ぶ | 横に並ぶ |
width / height指定できる | width / heightは無視される | width / height指定できる |
widthのデフォルト 親のwidthいっぱいに広がる | コンテンツの幅に応じる | コンテンツの幅に応じる |
heightのデフォルト コンテンツの高さに応じる | コンテンツの高さに応じ *line-heightの影響を受ける | コンテンツの高さに応じ *line-heightの影響を受ける |
上下の margin / padding 有効 | margin(上下)無視 padding(上下)影響あり | 上下の margin / padding 有効 |
div・p ・h1・ul・olなど | span・a・em・buttonなど | img・canvas・svg・inputなど |
/* ブロック要素に変更(幅いっぱい使う) */
.box {
display: block;
}
/* インライン要素に変更(改行されず横並び) */
.text {
display: inline;
}
/* インラインブロック要素に変更(横並び + 幅・高さを指定可能) */
.button {
display: inline-block;
width: 100px;
height: 40px;
}
/* 要素を非表示(レイアウトからも除外) */
.hidden {
display: none;
}
(vertical-align)インライン要素 ・インラインブロック要素の垂直方向の配置
vertical-align
はインライン要素 ・インラインブロック要素の垂直位置を調整するためのプロパティ。
*表のセル要素(display: table-cell;
)でも有効
- baseline(デフォルト) :文字の基準線に揃える
- middle :行の中央に配置
- top :行の上端に配置
- bottom :行の下端に配置
実践例
/* インライン画像の配置調整 */
img {
vertical-align: middle; /* 画像をテキストの中央に揃える */
}
/* 表のセル内のテキスト位置を調整 */
td {
vertical-align: top; /* セルの上部にテキストを配置 */
}
display: flex(フレックスボックス / 1方向の配置や折り返し)
display: flex;
を指定すると、親要素(フレックスコンテナ)内の子要素(フレックスアイテム)が自動で並ぶ- 横並び / 縦並びは
flex-direction
、折り返しはflex-wrap
で制御
*flex-wrap
によって、子要素が1行に収まるか、複数行に折り返すかを決める - 子要素のサイズや間隔は
flex-grow
やflex-basis
で自動調整可能
*レスポンシブデザインに便利
フレックスボックスの親要素プロパティ
- フレックスボックスを有効化
display: flex;
- 横方向の配置:
justify-content
- flex-start:左寄せ
- flex-end:右寄せ
- center:中央寄せ
- space-between:均等配置(端は詰める)
- space-around:均等配置(端に余白あり)
- space-evenly:すべての間隔(両端含む)が均等
- 縦方向の配置(1行でも適用):
align-items
- stretch:子要素の高さを伸ばす(デフォルト)
- flex-start:上寄せ
- flex-end:下寄せ
- center:縦中央揃え
- baseline :子要素のテキストのベースライン(文字の基準線)に揃える
- 縦方向の配置(複数行の全体の配置):
align-content
*flex-wrap: wrap;
が必要!- stretch: 行をコンテナの高さいっぱいに 引き伸ばす(デフォルト)
- flex-start :行全体を コンテナの上端(開始位置)に寄せる
- flex-end :行全体を コンテナの下端(終了位置)に寄せる
- center :行全体を 中央に寄せる
- space-between :最初の行を上端・最後の行を下端に配置し、間の行を均等配置
- space-around :各行の間隔を均等に配置し、外側にも半分の余白を作る
- space-evenly :各行の間隔を均等に配置し、外側の余白も均等にする
- 行の折り返し:
flex-wrap
- nowrap:折り返さない(デフォルト)
- wrap:折り返す
- 子要素が並ぶ方向を決める:
flex-direction
- row:子要素が横方向に並ぶ(左から右)(デフォルト)
- column:子要素が縦方向に並ぶ(上から下)
- row-reverse:子要素が逆の横方向に並ぶ(右から左)
- column-reverse:子要素が逆の縦方向に並ぶ(下から上)
フレックスボックスの子要素のプロパティ
/*
子要素の大きさを flex: grow shrink basis; で指定が便利
flex: <伸びる比率> <縮む比率> <基本サイズ>;
*/
.item {
flex: 1 0 100px; /* 100pxの幅を確保しつつ、空いたスペースを均等に分ける */
}
- サイズの調整
- grow(伸びる大きさ):空きスペースがある場合、どれだけ伸ばして埋めるかを指定
flex-grow: 0;
→ (デフォルト)伸びないflex-grow: 1;
→ 空きスペースを均等に分配flex-grow: 2;
→ 他の要素の 2倍の割合で拡張 - shrink(縮む大きさ):スペースが足りなくなったとき、どれだけ縮むかを指定
flex-shrink: 1;
→ (デフォルト)他の要素と同じ割合で縮むflex-shrink: 0;
→ 縮まないflex-shrink: 2;
→ 他の要素の2倍の割合で縮む - basis(基本サイズ):子要素の 初期サイズ(理想のサイズ)を指定
flex-basis: auto;
→ (デフォルト)width
/height
に設定された値を基準、なければ中のコンテンツのサイズflex-basis: 100px;
→ 100pxを基準サイズとする - flex(省略形):
flex: grow shrink basis;
の省略形flex: 0 1 auto;
→(デフォルト)縮むけど伸びないflex: 1;
→ 空いたスペースがあれば均等に分ける(flex: 1 1 0;
の省略形)flex: 0;
→ 伸びも縮みもしない(flex: 0 0 auto;
の省略形)flex: 1 0 100px;
→ まず100pxのスペースを確保 → 余ったスペースを均等に分ける
- grow(伸びる大きさ):空きスペースがある場合、どれだけ伸ばして埋めるかを指定
- 整列:
align-self
子要素ごとalign-itemsを上書き可能- auto:親の
align-items
に従う(デフォルト) - flex-start:上寄せ
- flex-end:下寄せ
- center:縦中央揃え
- stretch:高さを伸ばす
- baseline :テキストのベースラインで揃える
- auto:親の
- 順序:
order
通常、HTMLの順番通りに表示されるがorderで並び順を変更可能order: 0;
(デフォルト)order: 数値;
(数値が小さいほど先に表示)order: -1;
(一番前に来る)
display: grid(グリッドレイアウト/2次元の配置)
display: grid;
を指定すると、親要素(グリッドコンテナ)内の子要素(グリッドアイテム)を
行・列のマス目状(2次元)に配置できる
*フレックスボックス(1方向のみ)とは異なり、縦・横の両方を同時に制御できる
行や列の指定方法
- グリッドレイアウトを有効化:
display: grid;
- (明示的なグリッド)列や行の幅を指定
grid-template-columns
→列の幅を指定grid-template-rows
→行の高さを指定 - (暗黙的なグリッド)足りない場合の自動調整
必要になったときに追加される行・列のサイズを決める
*デフォルトではコンテンツサイズに基づくgrid-auto-columns
→ 暗黙的な列の幅を指定grid-auto-rows
→ 暗黙的な行の高さを指定
/*
「grid-template-○○」を使って、行や列のサイズを明示的に指定する
*/
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 均等な3列 */
grid-template-rows: 100px auto; /* 1行目は100px、2行目はコンテンツサイズ */
}
/*
「grid-auto-○○」を使って、足りなくなったときに自動追加される行・列のサイズを指定できる
*/
.container {
display: grid;
grid-template-columns: 200px auto; /* 2列を明示的に指定 */
grid-auto-columns: 150px; /* もし3列目が追加されたら、150pxで作成される */
grid-auto-rows: 100px; /* 必要な行を追加し、その高さを100pxにする */
}
行や列の値(サイズ指定)
- 固定値(px, %, em など)
- fr : (余ったスペースを分割)グリッドの「余ったスペース」を何分割するか決める単位
1fr → 余ったスペースを1つ分使う
2fr → 余ったスペースを2つ分使う(1frの2倍の広さ) - auto : (中身のサイズ)コンテンツのサイズに合わせて列や行の幅が決まる
文字量や画像のサイズに応じて幅が変わる - minmax(最小, 最大):最小と最大の幅を設定
- repeat(回数, サイズ):繰り返し指定
*grid-auto-columns / grid-auto-rows では使用不可grid-template-columns: repeat(3, 1fr)
;は1fr 1fr 1fr;
と同じ
回数(列数を自動調整)- auto-fit → 余計な空きを作らずに列を伸縮
余ったスペースを使う! - auto-fill → 隙間ができても列の数をキープ
空白ができても列の数を崩さない!
- auto-fit → 余計な空きを作らずに列を伸縮
グリッドアイテムの揃え方
justify-items
→水平方向の配置- start→ 左寄せ
- end →右寄せ
- center →中央揃え
- stretch(デフォルト)→ グリッドセルの幅いっぱいに広げる
align-items
→垂直方向の配置- start →上寄せ
- end →下寄せ
- center →中央揃え
- stretch(デフォルト)→ グリッドセルの高さいっぱいに広げる
place-items
→両方まとめて指定place-items: <align-items> <justify-items>;
暗黙的なトラック(行や列)を作成する際の順序や詰め方を指定
grid-auto-flow
を使うと、未配置のアイテムの自動配置ルールを決められる
通常は「行優先(row)」だが、列優先にすることもできる
denseを指定すると、途中の空白を詰めて配置できる
- row(デフォルト)→ 行がいっぱいになると次の行に折り返す(行優先)
- column→ 列がいっぱいになると次の列に折り返す(列優先)
- row dense→ 行優先だが、空きスペースを詰めて配置
- column dense→ 列優先だが、空きスペースを詰めて配置
(自動レイアウト)レスポンシブデザインの王道テクニック!
列数が自動調整され、画面幅に応じて見た目が最適化される
/*150pxの幅を最小限確保しながら、余ったスペースを使って調整される*/
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 20px; /* 各アイテム間の間隔 */
}
グリッドアイテム(子要素)のプロパティ
grid-column
:開始の線番号 / 終了の線番号を指定(横方向の配置)
アイテムがどの列に配置されるかを指定grid-row
:開始の線番号 / 終了の線番号を指定(縦方向の配置)
アイテムがどの行に配置されるかを指定justify-self
:水平方向の配置(左・中央・右揃え)
親のjustify-itemsを上書きalign-self
:垂直方向の配置(上・中央・下揃え)
親のalign-items
を上書きz-index
が指定されている場合:数値が大きいアイテムが上に重なりますz-index
がない場合:後に記述されたアイテムが上に表示されます(HTMLの順序)
.item {
grid-column: 1 / 3; /* 1列目から3列目まで占有 */
grid-row: 1 / 2; /* 1行目を占有 */
}
(gap)フレックスボックス・グリッドの行間・列間
gap
を使うと、行や列の間隔を簡単に設定できる
従来のmarginのように最後の要素の余白調整を手動で行う必要がない
*gap
プロパティはdisplay: flex;
または display: grid;
のときにのみ機能する
/* フレックスボックス */
.flex-container {
display: flex;
flex-wrap: wrap; /* アイテムが折り返す場合 */
gap: 10px 15px; /* 行間10px, 列間15px */
}
/* グリッドレイアウト */
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px; /* 行間・列間ともに20px */
}
row-gap
→ 垂直方向(行間)のスペースだけ設定column-gap
→ 水平方向(列間)のスペースだけ設定
display: table(テーブルレイアウト)
HTMLの<table>
を使わずに、テーブルのようなレイアウトを作れる
行 (table-row
)・セル (table-cell
)のサイズが自動で調整される
*あくまでもレイアウト目的でセマンティクス(HTMLの意味付け)はない
- 親要素に
display: table
を指定 → テーブル全体の役割を与える - 子要素に
display: table-row
→ テーブルの行のように配置 - さらに子要素に
display: table-cell
→ セルのように並べる display: table-caption
→要素をテーブルのキャプション(タイトル)」として振る舞わせるcaption-side: top(bottom)
→キャプションの表示位置を指定
<table> ← display: table
<caption> ← display: table-caption</caption>
<tr> ← display: table-row
<td> ← display: table-cell
<td> ← display: table-cell
</tr>
</table>
<div class="table">
<p style="display: table-caption; caption-side: bottom;">キャプション</p>
<div class="row">
<div class="cell">セル1</div>
<div class="cell">セル2</div>
</div>
<div class="row">
<div class="cell">セル3</div>
<div class="cell">セル4</div>
</div>
</div>
<style>
.table {
display: table;
width: 100%;
border: 1px solid red;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
padding: 8px;
border: 1px solid blue;
vertical-align: middle; /* 垂直方向の中央揃え */
text-align: center; /* 水平方向の中央揃え */
}
</style>
キャプション
display: contents(要素自身を消し、子要素はそのまま表示)
HTMLの構造を変えずに不要なラッパー要素を取り除くのが主な用途
特に、セマンティックなタグ(意味を示すタグ)をFlexboxやGridの子要素として扱うために使う
<div class="grid">
<article class="wrapper">
<div class="item">1</div>
<div class="item">2</div>
</article>
<article class="wrapper">
<div class="item">3</div>
<div class="item">4</div>
</article>
</div>
<style>
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
.wrapper {
display: contents;
}
.item {
background: lightblue;
padding: 20px;
}
</style>
(position)要素の位置を指定
「要素の配置方法を制御するプロパティ」
- 要素を特定の位置に配置するためのプロパティ
-
top
/right
/bottom
/left
プロパティで調整可能 - 値によって、文書の通常の流れ(フロー)に影響を与えるかどうかが異なる
値
static(デフォルト) | 通常の文書フローに従って配置される | 他の要素に影響を与えない |
relative | 通常の位置から相対的に移動 | 他の要素に影響を与えない *元の位置は保持 |
absolute | *親要素のpositionがrelative・absolute・fixedの場合→その親要素を基準に配置 *そうでない場合→html要素(全体)を基準に配置 | 他の要素に影響を与えない *通常のフローから外れる |
fixed | ビューポートを基準に配置 スクロールしても固定 *例外的にtransformがあると、fixedでも親要素の影響を受ける | スクロールしても動かない |
sticky | スクロールに応じてrelative → fixedに変化 | スクロール時に特定の位置で固定される |
/* relative → 要素の基準位置を微調整 */
.box {
position: relative;
top: 10px; /* 通常の位置から 10px 下に移動 */
left: 20px; /* 通常の位置から 20px 右に移動 */
}
/* absolute → 親要素を基準に配置(親に relative をつける)*/
.container {
position: relative;
width: 300px;
height: 200px;
}
.absolute-box {
position: absolute;
top: 10px;
right: 10px;
}
/*
fixed → スクロールしても固定
ナビゲーションバーやスクロール追従のボタンなど
*/
.fixed-header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background: black;
color: white;
}
/*
sticky → スクロールで固定化
指定位置 (top: 0;) に到達したらfixedのように固定される
*/
.sticky-header {
position: sticky;
top: 0;
background: yellow;
}
top
/ right
/ bottom
/ left
の動き
- 基準
- top:上端を基準
- right:右端を基準
- bottom:下端を基準
- left:左端を基準
- 値の動き
- 0 → 基準の端にピッタリくっつく
- プラスの値 → 基準点から「内側」に移動する
- マイナスの値 → 基準点から「外側」に押し出される(逆方向に移動)
よくあるトラブル
- absoluteが思った位置に配置されない場合
親要素にrelativeが指定されているかチェック! - stickyが動かない
親要素に十分な高さがあるか?
要素にtopなどのプロパティが指定されているかチェック!
(z-index)要素の重なり順
z-index
とposition
を組み合わせることで、要素が前面・背面のどちらに表示されるかを数値で決める
数値が大きいほど前面に、小さいほど背面に配置される
*position
がstaticの場合、z-index
は機能しない
*position
が指定された要素(absolute / fixed)はz-index
を指定しない場合でも非position要素より前面に描画されることが多い
z-indexの値
値は整数値(正の数、0、負の数)
数値が大きいほど手前、小さいほど奥に表示されるz-index
を指定しない場合のデフォルト値はauto(通常の重なり順)
z-index: auto
:スタックコンテキストを作らないz-index: 0
:スタックコンテキストを作成
z-indexが効かないときのチェックポイント
1:position: static;
(デフォルト)では機能しない
relative, absolute, fixed, stickyが必要
2:スタッキングコンテキストが作られていないか?z-index
は同じスタッキングコンテキスト内でのみ有効であり、異なるスタッキングコンテキスト間では影響を及ぼさない
スタッキングコンテキストについて
- スタッキングコンテキストとは?
要素の重なり順(z-index
)のルールを決める領域 - スタッキングコンテキスト内では、子要素同士の
z-index
だけが有効 - 親の
z-index
を超えて、外側の要素に影響を与えることはできない - スタッキングコンテキストが見つからない場合、さらに上の祖先へとたどり、最終的にはルート(html)に行き着く
スタッキングコンテキストを作る条件の例
position: absolute
/relative
+z-index
を指定position: fixed
/sticky
(z-index
なしでも作る)opacity
が1
未満(例:opacity: 0.99;
)transform
(scale
,translate
,rotate
など)filter
(blur
,brightness
など)clip-path
(clip-path: none;
でも作る)display: flex
/grid
の コンテナ直下の子要素 +z-index
を指定will-change: transform;
(ブラウザが最適化のために作る)isolation: isolate;
(明示的にスタッキングコンテキストを作る)
<div class="container">
<div class="absolute-box">BOX</div>
<div class="transparent-wrapper">
<div class="child-box">CHILDBOX</div>
</div>
</div>
<style>
/* 親コンテナ(相対配置の基準) */
.container {
position: relative;
width: 100px;
height: 100px;
}
/* 赤いボックス(最前面) */
.absolute-box {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
z-index: 2; /* 透明ボックスより前面 */
background: red;
color: white;
}
/*
青い子ボックスを最前面にするには
position: relative;
z-index: 3;
を追加
*/
.transparent-wrapper {
opacity: 0.9; /* スタックコンテキストを作る */
}
/* 青い子ボックス(最もz-indexが高いが、親の影響を受ける) */
.child-box {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
z-index: 100; /* 最もz-indexが高いが、親のスタックコンテキスト内でのみ有効*/
background: blue;
color: white;
}
</style>
対策
- 親要素に
position: relative;
を設定してz-index
を上げる - 不要な
opacity
,transform
,filter
,clip-path
は削除する
*これは「意図しないスタッキングコンテキストを作らない」ための予防策
(float)テキストの回り込み
float
は、画像やボックスを左または右に寄せて、テキストをその横に流し込むために使う
FlexboxやGridが登場する前はレイアウトにも使われていたが、現在はほとんど使わない
*親要素の高さ崩れや、後続の要素の回り込みによるレイアウト崩れに注意
/* 画像を右側に寄せ、左側にテキストが回り込む*/
img {
float: right;
margin: 0 0 10px 10px; /* テキストとの間隔 */
}
Lorem ipsum dolor sit amet, consectetur adipisci elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua.
基本的な値
- none(デフォルト)
要素は通常の文書フローに従って配置 - left
要素を親要素の左端に寄せる
要素の右側に他のインライン要素やテキストが流れ込む - right
要素を親要素の右端に寄せる
要素の左側に他のインライン要素やテキストが流れ込む
floatの影響
- floatされた要素がある場合、その後に続く兄弟要素は横に回り込む
*スペースが足りない場合は次の行に回り込む - 親要素の高さは、通常その中に含まれる子要素によって決まるが
floatした子要素は文書フローに含まれないため、親の高さが0と認識されることがある
レイアウト崩れを防ぐ方法
1:clear
プロパティ(floatの影響を受けたくない要素に使う)
clearを指定した要素はfloatされた要素を回避してその下に配置される
clear: left;
:左側の浮動要素を解除clear: right;
:右側の浮動要素を解除clear: both;
:左右の浮動要素を解除
3:親要素にoverflow: hidden;
を指定
*内容がはみ出た場合、非表示になる
4:親要素にdisplay: flow-root;
を指定
*親要素からはみ出てもそのまま表示
BFC(レイアウトの独立)について
BFC(ブロックフォーマッティングコンテキスト)を作ると、その要素のレイアウトが周囲の要素から独立する
BFCの効果
- floatの影響を防ぐ
- marginの相殺を防ぐ
BFCを生成する方法overflow: hidden;
や display: flow-root;
が一般的!
/* `overflow` を `hidden`, `auto`, `scroll` にする */
.bfc-container {
overflow: hidden;
}
/* `display: flow-root;` を指定する(推奨) */
.bfc-container {
display: flow-root;
}
/* `position: absolute` or `fixed` にする */
.bfc-container {
position: absolute;
}
/* `display: table;` にする */
.bfc-container {
display: table;
}
(column)テキストを複数列に分割
長いテキストを新聞や雑誌のように複数のカラムに分割
*すべてのブラウザで均一に表示されるわけではない
column-count
:テキストを何列に分割するかを指定column-width
:カラムの幅を指定
*要素の幅が足りなくなれば列数を減らす、足りれば列数を増やすという形でブラウザが自動調整
column-count(カラムの数)と column-width(カラムの幅)は 通常どちらか一方だけを指定するのが一般的
column-count: 3; → 3カラムに分割(幅は自動調整)
column-width: 200px; → カラムの幅を200pxに指定(数は自動調整)
*どちらも指定した場合、ブラウザはcolumn-widthを優先
.multi-column {
column-count: 3; /* 3カラムにする columns:3に置き換えられます*/
}
.multi-column {
column-width: 200px; /* 各カラムの幅を200pxで確保 column:200pxに置き換えられます*/
}
/*
一括指定
column-widthのほうが優先され、column-countは可能な範囲で調整
*/
.multi-column {
columns: 3 200px; /* カラム数3、幅200pxを同時に指定 */
}
column-gap
:カラム間の余白を指定column-rule
:カラム間に境界線を引く
.multi-column {
column-count: 3;
column-gap: 20px; /* カラム間の余白を20pxに設定 */
column-rule: 1px solid #ccc; /* カラム間に薄いボーダーを表示 */
}
(overflow)親要素の幅や高さを超える子要素の表示
テキストやボックスがはみ出たときの挙動を決めるプロパティ
特にモーダルウィンドウや横スクロール防止でよく使う
overflow-x
:水平方向(横方向)のコンテンツのはみ出しを制御overflow-y
:垂直方向(縦方向)のコンテンツのはみ出しを制御overflow
:まとめて設定
値とその動き
- visible:(デフォルト)親要素を超えたコンテンツをそのまま表示
- hidden:親要素を超えたコンテンツを非表示にする
- scroll:親要素を超えた場合にスクロールバーを常に表示する
- auto:親要素を超えた場合にスクロールバーを必要に応じて表示する
- clip:(CSS3以降)hiddenと似ているが、はみ出た部分を物理的に存在をなくしたように扱う
overflow: hidden;
とposition: relative;
は一般的に一緒に使われる
親要素の中で子要素を動かす場合、親にposition: relative;
を設定すると基準位置が明示される
.parent {
width: 300px;
height: 200px;
overflow: hidden; /* 親要素の外にはみ出す部分を隠す */
position: relative; /* 子要素の動きを親要素の中に限定する */
background: lightgray;
}
.child {
position: absolute;
top: 50px;
left: 350px; /* 子要素のはみ出した部分は非表示になる */
background: lightblue;
width: 100px;
height: 100px;
}
モーダルウィンドウやポップアップ表示時に、背景のスクロールを無効化する
*bodyにoverflow: hidden;
を設定すると縦横スクロールが無効化される
body.modal-open {
overflow: hidden; /* 背景をスクロールできないように */
}
document.body.classList.add('modal-open'); // モーダル表示時
document.body.classList.remove('modal-open'); // モーダル閉じる
画面幅を超える要素が存在する場合に横スクロールを防ぐ
*開発者ツールで原因を調査し、必要に応じて個別要素のスタイルを調整するのがベター
body {
overflow-x: hidden; /* 横スクロールを防止 */
}
横スクロールが発生する主な原因
width: 100vw;
などの指定(スクロールバーを考慮せずvw指定すると問題になる)position: absolute;
やmargin
のマイナス指定で要素がはみ出す- 画像や大きな要素が
max-width
指定なしで入っている
中央配置の手法
margin: auto;
を使う方法
*要素の幅と高さが固定されていることが必須
.box {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
width: 200px;
height: 100px;
}
transform
を使う方法
*要素の左上を50%の位置に移動し、さらに自身の幅と高さの半分だけ調整することで中央に配置
サイズが明確に決まっている必要はない
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* white-space: nowrap; テキストが改行された場合、それを回避して横一列で表示したいとき */
}
フレックスボックスを使う方法(複数要素のレイアウトに向いている)
*親要素に指定することで、子要素を中央に配置
.parent {
display: flex;
justify-content: center;
align-items: center;
}
Gridを使う方法(単一要素の中央配置に向いている)
*親要素に指定することで、子要素を中央に配置
.parent {
display: grid;
place-items: center;
}
(一行のテキストに限定):line-height
を使う方法
.text {
height: 100px; /* 必要な高さ */
line-height: 100px; /* 高さと同じ値 */
text-align: center;
}
画像の扱い(imgタグとbackground-image)
管理対象 | imgタグ(HTML) | background-image(CSS) |
使用シーン | コンテンツ画像 *意味を持つ画像 | 装飾目的 *デザイン要素 |
画像の管理 | src属性 | background-image |
解像度対応 | srcset / sizes 属性を使う | image-set()または@media |
次世代フォーマット対応 | <picture> / <source> | @supports |
サイズ・配置の調整 | width& height / aspect-ratioobject-fitなど | background-size / background-positionなど |
適切な画像管理について
レイアウトシフトの防止・高解像度対応・最適化・遅延読み込み
- レイアウトシフトの防止
レイアウトシフトとは、ページ読み込み後に要素がズレる現象のこと
→ 意図しないクリックや操作ミス の原因になるため、適切な対策が必要 - 高解像度ディスプレイ対応
Retinaディスプレイなどの高解像度画面 では、通常の1x画像だとぼやけることがある
解像度に応じた画像(2x, 3x) を用意し、ユーザーのデバイスに応じて切り替える - ファイルサイズの最適化
画像のサイズを小さくすることで、ページ表示速度を向上できる
次世代フォーマット(WebP・AVIF)を活用
ただし、対応ブラウザを考慮してJPEGやPNGのフォールバックも用意
TinyPNG などの圧縮ツールを使い、不要なデータを削減した画像を準備 - 遅延読み込み
すぐに必要ない画像やコンテンツを後から読み込みぺージの読み込み速度を向上
💡画像の最適化を簡単にするサービス
高解像度ごとに画像を手動でリサイズするのは手間がかかります
imgixやCloudinary などのサービスを利用すると、画像を自動で最適なサイズ・フォーマットに変換し、CDN経由で配信できます
imgタグ(コンテンツ画像)
レスポンシブ対応・配置・装飾
一般的に初期設定(すべての画像に適用)としてCSSファイルの最初に書いておく
レスポンシブ:元の縦横比を維持
img {
max-width: 100%; /* 親要素の幅に合わせて縮小 */
height: auto; /* 元画像の縦横比を維持 */
}
/* レスポンシブ:固定比率を維持したい場合 */
img {
max-width: 100%; /* 親要素の幅に合わせて縮小 */
aspect-ratio: 4 / 3; /* 縦横比を 4:3 に固定 */
}
/*
CSSで幅または高さのどちらかを省略すると、
ブラウザが元のアスペクト比を保ち自動的に計算する
*(注意)CSSで画像の幅や高さを指定する際、元の解像度を超えると画質が低下する
例:元画像のサイズ: 200px × 100pxでCSSで幅400px に指定 → 画質が低下
高解像度ディスプレイ(Retina)への対応は別途必要になる
*/
img {
width: 400px; /* 幅だけを指定 */
height: auto; /* 高さは元のアスペクト比に基づいて計算される */
}
/*
デフォルトはインライン要素。
インライン要素として使用した場合、vertical-alignでテキストや他の要素との高さの調整に使います
*/
img {
vertical-align: middle;
}
/*
中央寄せ
ブロック要素として扱う
*/
img {
display: block;
margin: 0 auto;
}
/*フロート画像*/
img {
float: left;
margin-right: 10px;
}
/*画像の回転や反転*/
img {
transform: rotate(90deg);
}
/*ボーダーを追加*/
img {
border: 2px solid black;
}
/*丸い画像*/
img {
border-radius: 50%;
}
/*シャドウ効果*/
img {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
(object-fit)親要素内の表示方法
object-fit(指定された枠内にどのように収まるか)
/*object-fitの適用例*/
.container {
width: 300px;
height: 200px;
overflow: hidden; /* 親要素の範囲外を隠す */
}
img {
width: 100%; /* 必要に応じて調整 */
height: 100%;
object-fit: cover; /* ここで表示方法を指定 */
}
- fill :枠に完全フィット(アスペクト比は無視)
- contain :アスペクト比を維持して全体を収める(余白あり)
- cover: アスペクト比を維持しつつ枠いっぱいに広げる(切り抜きあり)
- none :元のサイズのまま表示(枠を超える可能性あり)
- scale-down :noneとcontain のどちらか小さい方を選択
(補足)レイアウトシフトの防止
imgタグにwidth属性とheight属性(値はピクセル単位で解釈される) を指定
画像が読み込まれるまでスペースを確保
HTMLのタグで指定したwidthとheightはCSSで上書きできる
<img src="example.jpg" alt="例" width="600" height="400">
/* 初期設定*/
img {
width: 100%; /* 親要素より小さい場合はオリジナルサイズのまま */
height: auto; /* アスペクト比を維持 */
}
/*レイアウトシフト対策にはaspect-ratioを使うのがベスト*/
img {
display: block;
width: 100%; /* 常に親要素いっぱい */
height: auto;
aspect-ratio: 600 / 400; /* 画像のアスペクト比を保持 */
}
(補足)高解像度ディスプレイ対応(srcset属性・ sizes属性)
正しい画像を選べるように情報を提供して、ユーザーのデバイスに応じた解像度の画像をブラウザに選択させる
srcset属性で指定→画像ファイルの情報(解像度または画像の横幅)
sizes属性で指定→表示したい画像の幅(幅が可変の場合)
src属性→非対応の環境向けにフォールバック画像を指定
画像幅が固定の場合 | 画像幅が可変の場合 |
x単位(解像度) | w単位(画像の横幅) |
srcset属性 画像ファイルの情報(解像度) srcset="s.jpg 1x, m.jpg 2x, l.jpg 3x" | srcset属性 画像ファイルの情報(横幅) srcset="s.jpg 400w, m.jpg 800w, l.jpg 1200w" |
sizes属性 表示したい画像の幅 sizes="(max-width: 599px) 100vw, | |
src属性 srcsetに対応していないブラウザ向けフォールバック画像 | src属性 srcsetに対応していないブラウザ向けフォールバック画像 |
<!--
画像幅が固定の場合
デバイス解像度(1x, 2x, 3x)に応じて最適な画像を選択
-->
<img src="small.jpg"
srcset="small.jpg 1x, medium.jpg 2x, large.jpg 3x"
alt="高解像度対応">
<!--
画像幅が可変の場合
(max-width: 599px) 100vw, スマホ:画像は画面いっぱい
(max-width: 1024px) 50vw, タブレット:2カラムにして幅を50%
33vw PC:3カラムなどで1カラムあたり33%
-->
<img srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 599px) 100vw, (max-width: 1024px) 50vw, 33vw"
src="small.jpg"
alt="レスポンシブ対応画像">
全デバイスで画面幅いっぱいに表示する際の問題
同じ画像を使うと…
PC(横長)では画像が大きくなり余白が増える
スマホ(縦長)では画像が小さくなり意図しない表示になる
そこでpictureタグを使い、PC用の横長画像・スマホ用の縦長画像を切り替える
(補足)異なる画像の切り替え・次世代フォーマットの活用(pictureタグ・sourceタグ)
- 次世代フォーマット(WebP)を使う
- デバイスごとに異なる画像を切り替える
picture
タグの仕組み
複数のsource
タグを使い、条件に合う画像を自動選択
*上から順に評価し、最初にマッチした画像が表示される
最後のimg
タグはフォールバック用(すべての条件に当てはまらない場合に表示)
sourceタグの主な属性
- srcset → 使う画像を指定(解像度別の画像もOK)
- media → 表示条件(例:(min-width: 768px) でタブレット用画像)
- type → 画像フォーマットの指定(例:image/webp)
メディアクエリを使用した「異なる画像の切り替え」
<picture>
<!-- スマホ(幅767px以下)の場合:縦長の画像を表示 -->
<source srcset="image-mobile.jpg" media="(max-width: 767px)">
<!-- タブレット(768px〜1279px):横長画像を表示 -->
<source srcset="image-tablet.jpg" media="(max-width: 1279px)">
<!-- PC(1280px以上):ワイドな画像を表示 -->
<source srcset="image-desktop.jpg" media="(min-width: 1280px)">
<!-- フォールバック用(対応していないブラウザ向け) -->
<img src="image-desktop.jpg" alt="レスポンシブ画像">
</picture>
次世代フォーマットをつかう
<picture>
<source srcset="image.webp" type="image/webp">
<source srcset="image.jpg" type="image/jpeg">
<img src="image.jpg" alt="フォールバック画像">
</picture>
(補足)遅延読み込み(loading属性)
対応するタグ: imgとiframe
pictureタグの場合もimgタグに指定するだけで適用可能
- ファーストビュー画像:即時読み込み(
loading="eager"
デフォルトの動作) - ファーストビュー以外の画像:遅延読み込み(
loading="lazy"
)
*ファーストビュー画像とはページを開いた瞬間に見える範囲(スクロールせずに表示される部分)にある画像
background-image(装飾画像)
レスポンシブ対応・配置
background-size
・background-position
を使って配置
background-imageはheight: auto;
が使えないのでレスポンシブ対応にはaspect-ratio
や padding-top
活用
/* 配置(`background-size`・`background-position`)*/
background-image: url('example.jpg'); /* 任意の画像URL */
background-position: center; /* 真ん中に配置 */
background-size: cover; /* 要素全体を覆う */
background-repeat: no-repeat; /* 繰り返さない */
/* aspect-ratioを使って背景画像の比率を固定 */
.aspect-box {
width: 100%; /* 親要素いっぱいに */
aspect-ratio: 16 / 9; /* 16:9 の比率を維持 */
background-image: url("example.jpg");
background-position: center;
background-size: cover; /*画像全体を見せるならcontain、トリミングしてもいいならcover*/
background-repeat: no-repeat;
}
/*
aspect-ratioをサポートしていないブラウザ用の padding-topハック
*/
.aspect-box {
width: 100%;
height: 0; /* 高さをゼロに */
padding-top: 56.25%; /* 16:9 の比率(高さ ÷ 幅 × 100) */
background-image: url("example.jpg");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
}
backgroundのプロパティと値の詳細はリンク先を参照
レイアウトシフトの防止
div {
width: 600px; /* 背景画像の表示幅 */
height: 400px; /* 背景画像の表示高さ */
background-image: url('example.jpg');
background-size: cover;
background-position: center;
}
/* レスポンシブデザインの場合はaspect-ratio(padding-top)を活用するのも有効 */
div {
aspect-ratio: 3 / 2; /* 横:縦の比率を固定 */
background-image: url('example.jpg');
background-size: cover;
background-position: center;
}
高解像度ディスプレイ対応(image-set() / @media)
SVG画像を活用するのも有効
image-set()
の基本
Safariは -webkit-image-set()
を使う必要がある
フォールバックとして background-image: url(…) を併記する のがベスト
.element {
background-image: url("low-res.jpg"); /* フォールバック */
background-image: -webkit-image-set(
url("low-res.jpg") 1x,
url("high-res.jpg") 2x
);
background-image: image-set(
url("low-res.jpg") 1x, /* 通常の解像度用 */
url("high-res.jpg") 2x /* 高解像度ディスプレイ用 */
);
}
メディアクエリを使う
div {
background-image: url('example-1x.jpg'); /* 通常の解像度 */
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
div {
background-image: url('example-2x.jpg'); /* 高解像度用画像 */
}
}
異なる画像の切り替え(@media)
.responsive-bg {
background-image: url("small.jpg"); /* デフォルト(小さい画像) */
background-size: cover;
}
@media (min-width: 768px) {
.responsive-bg {
background-image: url("medium.jpg"); /* タブレット用 */
}
}
@media (min-width: 1200px) {
.responsive-bg {
background-image: url("large.jpg"); /* PC用 */
}
}
次世代フォーマットの活用(@supports)
div {
background-image: url('example.jpg'); /* フォールバック用 */
}
@supports (background-image: url('example.webp')) {
div {
background-image: url('example.webp'); /* WebPをサポートしている場合 */
}
}
遅延読み込み(content-visibility)
背景画像に loading="lazy"
が使えないため、content-visibility: auto;
を使用
<div class="lazy-bg"></div>
<style>
.lazy-bg {
content-visibility: auto;
contain-intrinsic-size: 600px 400px; /* 仮のサイズを確保(CLS対策) */
background-image: url("example.jpg"); /* 事前に指定 */
background-size: cover;
background-position: center;
}
</style>
「(content-visibility)画面外の要素を描画」を参照
レスポンシブ対応(メディアクエリ・コンテナクエリ)
レスポンシブ対応とは、スマートフォン、タブレット、PCなど、異なる画面サイズやコンテンツの表示領域に応じてデザインを最適化することです
メディアクエリとコンテナクエリの違い
メディアクエリ | コンテナクエリ |
画面の大きさで調整 | 親要素の大きさで調整 |
ページ全体のレイアウト変更 | パーツごとのレイアウト変更 |
画面の大きさが変わるとデザインが変わる *どこに置いても同じ | パーツの入る箱の大きさに合わせて変化 *どこでもフィット |
- ページ全体のレイアウトを変更したい → メディアクエリ
例:スマホでは縦並び、PCでは横並び
例:スマホではナビゲーションを隠し、PCでは表示 - コンポーネント(パーツ)のデザインを調整したい → コンテナクエリ
例:カードの横幅が狭いと1列、広いと2列
例:サイドバーの幅によってボタンのサイズを変更
メディアクエリの基本的な書き方
「画面サイズや特徴を基準に、スタイルを切り替える」
min-width
とmax-width
*メディアクエリを使うときは最もよく使う
min-width | max-width |
この幅以上になったら適用する | この幅以下なら適用する |
小さい画面 → 大きい画面へ変更 *モバイルファースト | 大きい画面 → 小さい画面へ変更 *デスクトップファースト |
min-width
(モバイルファースト)
スマホ向けのスタイルを基本にして、大きくなったら調整
*CSSが上書きされる順番を考えやすい(小さい画面 → 大きい画面へ)
/* デフォルトはスマホ向け */
.container {
font-size: 14px;
}
/* タブレット向け(600px以上) */
@media (min-width: 600px) {
.container {
font-size: 16px;
}
}
/* PC向け(1024px以上) */
@media (min-width: 1024px) {
.container {
font-size: 18px;
}
}
max-width
(デスクトップファースト)
PC向けのスタイルを基本にして、小さくなったら調整
/* デフォルトはPC向け */
.container {
font-size: 18px;
}
/* タブレット向け(1024px以下) */
@media (max-width: 1024px) {
.container {
font-size: 16px;
}
}
/* スマホ向け(600px以下) */
@media (max-width: 600px) {
.container {
font-size: 14px;
}
}
min-width
「スマホ(基本スタイル) → タブレット(少し豪華に) → PC(フル機能)」 という 「進化するデザイン」 になるので自然に拡張しやすいmax-width
「PC(フル機能) → タブレット(削る) → スマホ(さらに削る)」 という 「引き算のデザイン」 になるので管理が複雑になりがち
and
を使うことができる
*例えば「タブレット専用のスタイル」を作りたいならandを使う
@media (min-width: 600px) and (max-width: 1023px) {
.container {
background-color: lightgreen;
}
}
max-width
とmin-width
を併用するときは
1pxのズレを防ぐためにmax-width
を1px小さくする
@media (max-width: 1023px) {
/* 1023px 以下のデザイン(タブレット) */
}
@media (min-width: 1024px) {
/* 1024px 以上のデザイン(PC) */
}
縦横比をブレークポイントにする
*メディアクエリは 幅だけでなく、高さやアスペクト比でもスタイルを変えられる
/* スクロール不要なデザインで高さに応じた調整が必要なとき */
@media (max-height: 500px) {
.header {
font-size: 12px; /* 高さが低いと文字を小さく */
}
}
/*
アスペクト比を使うときの基本
ちなみに横:縦 = 16:9(フルHDやワイドスクリーンの比率)
*/
@media (min-aspect-ratio: 16/9) {
/* 横長の画面用のスタイル */
}
@media (max-aspect-ratio: 16/9) {
/* 縦長の画面用のスタイル */
}
コンテナクエリの基本的な書き方
コンテナクエリは「親要素のサイズ」に応じてデザインが変わるため、どこに配置しても適切なレイアウトが適用される
「コンポーネントを再利用しやすい設計」ができる
container-type: inline-size;
を親要素(コンテナ)に設定する
これで 「この要素のサイズを基準にする」 ことができる@container
を使って、親要素のサイズに応じてスタイルを変える
.container {
container-type: inline-size; /* コンテナクエリを有効にする */
}
@container (min-width: 400px) {
.box {
background-color: lightgreen;
}
}
例:カードレイアウト
/* 親要素をコンテナにする */
.card-container {
container-type: inline-size;
display: flex;
gap: 20px;
}
/* カードのデフォルトスタイル */
.card {
width: 100%;
padding: 20px;
background-color: lightblue;
}
/* 親の幅が500px以上なら変更 */
@container (min-width: 500px) {
.card {
width: 45%;
background-color: lightgreen;
}
}
グリッドやフレックスボックスは、子要素のサイズを柔軟に変えられる
コンテナクエリを使えば、そのサイズ変化に応じてデザインを適切に調整できるので、相性が良い
カードのサイズでデザインを変える(コンテナクエリの強み)
*「auto-fit」を使うと「アイテムのサイズ」が変わる
コンテナクエリと組み合わせることで適切なデザイン調整ができる
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
/* カードをコンテナにする */
.card {
container-type: inline-size;
display: flex;
flex-direction: column; /* デフォルトは縦並び */
align-items: center;
text-align: center;
padding: 10px;
background-color: lightblue;
}
/* 画像 */
.card img {
width: 100px;
height: 100px;
object-fit: cover;
}
/* 親の幅が400px以上なら横並びに! */
@container (min-width: 400px) {
.card {
flex-direction: row;
text-align: left;
}
.card img {
margin-right: 10px;
}
}
印刷対応
@media print | @page |
ページの印刷用スタイルを指定 要素の表示・非表示、フォント、色など | 用紙の設定を調整 印刷時のページサイズや余白など |
ほぼすべてのブラウザ対応 | 一部制限あり(Safariなど) |
@media print
/*印刷時に不要な要素を非表示 */
@media print {
nav, aside, .ads, .comments {
display: none; /* メニューや広告を非表示 */
}
}
/*印刷時に背景色をなくす & フォントサイズを調整 */
@media print {
body {
background: none;
font-size: 12pt; /* 読みやすいサイズ */
}
}
(page-break-* / break-*)ページ指定
主に@media print
内で使用し、印刷時のレイアウトを制御するために使う
備考:現在page-break-*
は break-before
/ break-after
/ break-inside
に移行中
*break-*
のLevel4の仕様書ではalwaysはpage
- page-break-before :要素の前でページを区切る
- auto : (デフォルト)自動的に改ページを決定
- always :この要素の前で必ず改ページ
- avoid :できるだけ改ページを避ける
- left :左ページで開始(両面印刷向け)
- right :右ページで開始(両面印刷向け)
- page-break-after:要素の後でページを区切る
- auto : (デフォルト)自動的に改ページを決定
- always :この要素の後で必ず改ページ
- avoid :できるだけ改ページを避ける
- left :左ページで終了(両面印刷向け)
- right :右ページで終了(両面印刷向け)
- page-break-inside:ページ内の改ページを制御
- auto :(デフォルト) 自動的に改ページを決定
- avoid :要素の途中でページが分割されるのを防ぐ
/*
h2が印刷時に新しいページの最初に配置される
*/
@media print {
h2 {
page-break-before: always; /* 各見出しの前で改ページ */
}
}
/*
.chapterの次の要素は新しいページから始まる
*/
@media print {
.chapter {
page-break-after: always; /* 章の終わりで改ページ */
}
}
/*
印刷時にテーブルが途中で分割されるのを防ぐ
*/
@media print {
table {
page-break-inside: avoid;
}
}
@media print {
h2 {
page-break-before: always; /* 旧仕様 */
break-before: page; /* 新仕様(将来的にこちらが主流) */
}
}
@page
@pageを合わせると、より細かく印刷用デザインを調整できるが
一部のブラウザで完全にはサポートされていない!
marks(裁ち落としマーク)や bleed(裁ち落とし範囲)は Safariでは未対応!
その他も動作が不安定なので、margin設定は @media printで補うと安全!
- size: 用紙サイズを指定
例)size: A4;
- margin :余白を調整
例)margin: 10mm;
- marks :裁ち落としマークの指定
例)marks: crop;
- bleed :裁ち落とし範囲の指定
例)bleed: 5mm;
@page {
size: A4; /* 用紙サイズ */
margin: 20mm; /* 余白 */
}
/*
@pageにmarginを指定するだけではSafariで適用されないことがあるため
@media print で補う
*/
@media print {
body {
margin: 20mm; /* Safari でも確実に余白を適用 */
}
}