「CSSで画像を重ねて表示したいけど、どうやるの?」 「商品画像にバッジをつけたり、写真にテキストを重ねたい!」
Webサイトを作っていると、画像を重ねて表示したい場面がよくあります。実は、CSSを使えば簡単に実装できます。
この記事では、CSS初心者の方でもすぐに使える画像の重ね方を、基本から実用例まで詳しく解説します。
CSSで画像を重ねるとは?
画像を重ねるとは、複数の画像や要素を同じ位置に配置して、レイヤーのように重ね合わせるテクニックです。
よくある使用例
- 商品画像に「SALE」バッジを表示
- 写真の上にテキストを重ねる
- 背景画像とロゴを組み合わせる
- ビフォーアフター画像の比較
- アイコンと背景の組み合わせ
NetflixやAmazonなどの大手サイトでも、この技術は頻繁に使われています。
画像を重ねる4つの方法
CSSで画像を重ねる方法は主に4つあります。それぞれの特徴を理解して、用途に合わせて使い分けましょう。
方法の比較表
| 方法 | 難易度 | メリット | おすすめ用途 |
|---|---|---|---|
| position | ★☆☆ | シンプルで柔軟 | 基本的な重ね合わせ |
| Grid | ★★☆ | モダンで整列が簡単 | 複数画像の配置 |
| 背景画像 | ★☆☆ | HTMLがシンプル | 装飾的な背景 |
| Flexbox | ★★☆ | 中央配置が簡単 | オーバーレイ表示 |
方法1:position(最も基本的で重要)
positionプロパティを使った方法は、最も基本的で汎用性が高い方法です。初心者の方はまずこの方法をマスターしましょう。
基本の書き方
.container {
position: relative; /* 基準となる親要素 */
width: 400px;
height: 300px;
}
.image1 {
position: absolute; /* 絶対配置 */
top: 0;
left: 0;
width: 100%;
}
.image2 {
position: absolute;
top: 50px; /* 上から50px */
left: 50px; /* 左から50px */
width: 200px;
}
<div class="container">
<img src="background.jpg" class="image1" alt="背景画像">
<img src="overlay.png" class="image2" alt="前面画像">
</div>
仕組みの解説
親要素の設定
position: relative:子要素の基準点になる- サイズを指定して配置エリアを確保
子要素(画像)の設定
position: absolute:親要素を基準に自由配置top、left:配置位置を指定- 後に書いた要素ほど前面に表示される
positionのプロパティ値
/* 配置位置の指定方法 */
.image {
position: absolute;
/* 上下左右からの距離を指定 */
top: 20px; /* 上から20px */
bottom: 20px; /* 下から20px */
left: 20px; /* 左から20px */
right: 20px; /* 右から20px */
/* 中央配置する場合 */
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
方法2:z-indexで重なり順を制御
z-indexを使うと、要素の前後関係を明示的に指定できます。
z-indexの使い方
.container {
position: relative;
width: 400px;
height: 300px;
}
.background-image {
position: absolute;
z-index: 1; /* 一番後ろ */
width: 100%;
height: 100%;
}
.middle-image {
position: absolute;
z-index: 2; /* 真ん中 */
top: 30px;
left: 30px;
width: 60%;
}
.foreground-image {
position: absolute;
z-index: 3; /* 一番前 */
top: 60px;
left: 60px;
width: 40%;
}
z-indexのルール
- 数字が大きいほど前面に表示される
- デフォルト値は
0 - マイナスの値も使用可能(
z-index: -1で要素の後ろに配置) positionが指定されていないと効かない
z-indexの実用例
/* 画像の上にテキストを確実に表示 */
.image {
z-index: 1;
}
.text-overlay {
z-index: 10; /* 確実に前面に */
}
.background-decoration {
z-index: -1; /* 全ての要素の後ろに */
}
方法3:CSS Grid(モダンな方法)
CSS Gridを使うと、シンプルなコードで複数の画像を重ねられます。
Gridの基本
.container {
display: grid;
width: 400px;
height: 300px;
}
.container img {
grid-area: 1 / 1; /* すべて同じセルに配置 */
}
.image1 {
z-index: 1;
width: 100%;
height: 100%;
object-fit: cover;
}
.image2 {
z-index: 2;
align-self: end; /* 下に配置 */
justify-self: end; /* 右に配置 */
width: 50%;
}
<div class="container">
<img src="base.jpg" class="image1" alt="ベース画像">
<img src="overlay.png" class="image2" alt="オーバーレイ">
</div>
Gridのメリット
- コードが短くシンプル
align-selfとjustify-selfで位置調整が簡単- 複数要素の整列に強い
配置位置の指定
.overlay {
/* 上下の配置 */
align-self: start; /* 上 */
align-self: center; /* 中央 */
align-self: end; /* 下 */
/* 左右の配置 */
justify-self: start; /* 左 */
justify-self: center; /* 中央 */
justify-self: end; /* 右 */
}
方法4:背景画像として重ねる
CSSのbackground-imageを使えば、HTMLに画像タグを書かずに重ねられます。
複数背景画像の指定
.hero-section {
width: 100%;
height: 400px;
/* 複数の背景をカンマ区切りで指定 */
background-image:
url('logo.png'), /* 前面 */
url('pattern.png'), /* 中間 */
url('background.jpg'); /* 背景 */
/* それぞれの位置を指定 */
background-position:
center top,
center,
center;
/* それぞれのサイズを指定 */
background-size:
200px auto,
50%,
cover;
/* 繰り返しの設定 */
background-repeat:
no-repeat,
repeat,
no-repeat;
}
背景画像のメリットとデメリット
メリット
- HTMLがシンプルになる
- 複数の画像を一度に指定できる
- レスポンシブ対応が簡単
デメリット
- SEO的には画像タグのほうが有利
- altテキストを設定できない
- JavaScriptでの制御が少し複雑
使い分けの目安
/* 装飾的な画像 → 背景画像 */
.decoration {
background-image: url('pattern.png');
}
/* コンテンツとして重要な画像 → imgタグ */
<img src="product.jpg" alt="商品名">
実践例1:商品画像にSALEバッジをつける
ECサイトでよく見る、商品画像の角にバッジを表示するパターンです。
HTML
<div class="product-card">
<img src="product.jpg" alt="商品画像" class="product-image">
<span class="sale-badge">SALE</span>
</div>
CSS
.product-card {
position: relative;
width: 300px;
border-radius: 8px;
overflow: hidden; /* 角を丸くする場合 */
}
.product-image {
width: 100%;
display: block;
}
.sale-badge {
position: absolute;
top: 10px;
right: 10px;
background: #ff4444;
color: white;
padding: 8px 16px;
border-radius: 4px;
font-weight: bold;
font-size: 14px;
z-index: 10;
}
応用:複数のバッジ
.new-badge {
position: absolute;
top: 10px;
left: 10px;
background: #4CAF50;
color: white;
padding: 8px 16px;
border-radius: 4px;
}
.discount-badge {
position: absolute;
bottom: 10px;
right: 10px;
background: #2196F3;
color: white;
padding: 8px 16px;
border-radius: 4px;
}
実践例2:画像にテキストオーバーレイ
写真の上にタイトルや説明文を重ねる、ブログやポートフォリオでよく使うパターンです。
HTML
<div class="image-card">
<img src="photo.jpg" alt="風景写真" class="card-image">
<div class="card-overlay">
<h3 class="card-title">美しい風景</h3>
<p class="card-description">山と海が織りなす絶景</p>
</div>
</div>
CSS
.image-card {
position: relative;
width: 100%;
max-width: 600px;
border-radius: 12px;
overflow: hidden;
}
.card-image {
width: 100%;
height: 400px;
object-fit: cover;
display: block;
}
.card-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.8) 0%,
rgba(0, 0, 0, 0.4) 50%,
transparent 100%
);
color: white;
padding: 30px 20px;
}
.card-title {
margin: 0 0 10px 0;
font-size: 24px;
font-weight: bold;
}
.card-description {
margin: 0;
font-size: 16px;
opacity: 0.9;
}
ホバーエフェクト付き
.card-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 20px;
transform: translateY(100%); /* 最初は隠れている */
transition: transform 0.3s ease;
}
.image-card:hover .card-overlay {
transform: translateY(0); /* ホバーで表示 */
}
実践例3:アイコン付き画像
プロフィール画像に認証バッジをつけるなど、アイコンを重ねる実装です。
HTML
<div class="profile-image">
<img src="user.jpg" alt="ユーザー名" class="avatar">
<img src="verified.svg" alt="認証済み" class="verified-badge">
</div>
CSS
.profile-image {
position: relative;
display: inline-block;
}
.avatar {
width: 100px;
height: 100px;
border-radius: 50%;
border: 3px solid white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.verified-badge {
position: absolute;
bottom: 2px;
right: 2px;
width: 24px;
height: 24px;
background: white;
border-radius: 50%;
padding: 2px;
}
実践例4:疑似要素で装飾を重ねる
::beforeや::afterを使うと、HTMLを増やさずに装飾を追加できます。
フレーム効果
.image-frame {
position: relative;
display: inline-block;
}
.image-frame img {
display: block;
width: 300px;
border-radius: 8px;
}
.image-frame::before {
content: '';
position: absolute;
top: -10px;
left: -10px;
right: 10px;
bottom: 10px;
border: 3px solid #333;
border-radius: 8px;
z-index: -1;
}
グラデーションオーバーレイ
.image-gradient {
position: relative;
display: inline-block;
}
.image-gradient img {
display: block;
width: 100%;
}
.image-gradient::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
135deg,
rgba(255, 0, 150, 0.3),
rgba(0, 204, 255, 0.3)
);
pointer-events: none; /* クリックを透過 */
}
レスポンシブ対応のテクニック
画像を重ねる際、スマホでも崩れないようにする工夫が重要です。
基本のレスポンシブ対応
.responsive-container {
position: relative;
width: 100%; /* 親要素に合わせる */
max-width: 600px; /* 最大幅を制限 */
}
.responsive-container img {
width: 100%;
height: auto; /* 縦横比を維持 */
display: block;
}
.responsive-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 中央配置 */
width: 80%; /* 親の80%幅 */
text-align: center;
}
メディアクエリで調整
/* PC用 */
.badge {
position: absolute;
top: 20px;
right: 20px;
font-size: 16px;
padding: 10px 20px;
}
/* スマホ用 */
@media (max-width: 768px) {
.badge {
top: 10px;
right: 10px;
font-size: 12px;
padding: 6px 12px;
}
}
アスペクト比を維持する
.aspect-ratio-box {
position: relative;
width: 100%;
padding-top: 56.25%; /* 16:9の比率 */
}
.aspect-ratio-box img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
アスペクト比の計算
- 16:9 →
56.25%(9÷16×100) - 4:3 →
75%(3÷4×100) - 1:1 →
100%(1÷1×100)
よくある質問(FAQ)
Q1. 画像が重ならない場合は?
A. 以下を確認してください。
- 親要素に
position: relativeが設定されているか - 子要素に
position: absoluteが設定されているか - z-indexの値が適切か
Q2. スマホで配置がずれる
A. width: 100%とheight: autoを使い、相対的な位置指定(%やvw)を活用しましょう。メディアクエリで細かく調整するのも効果的です。
Q3. positionとGridどちらを使うべき?
A. 基本はpositionがおすすめです。複数の要素を整列させる場合はGridが便利です。古いブラウザ対応が必要ならpositionを選びましょう。
Q4. 画像の読み込みが遅いときは?
A. loading="lazy"属性を使うか、画像を圧縮しましょう。重ねる画像は特に軽量化が重要です。
<img src="large-image.jpg" alt="説明" loading="lazy">
Q5. クリックできない要素がある
A. 上に重なった要素が邪魔をしている可能性があります。pointer-events: none;を使うとクリックを透過できます。
.overlay {
pointer-events: none; /* クリックを透過 */
}
.overlay button {
pointer-events: auto; /* ボタンだけクリック可能に */
}
パフォーマンスの最適化
画像を重ねる際のパフォーマンス向上のコツをご紹介します。
1. 画像の最適化
/* 画像のレンダリング品質を指定 */
img {
image-rendering: auto; /* デフォルト */
image-rendering: crisp-edges; /* シャープに */
image-rendering: pixelated; /* ピクセルアートに */
}
2. transformを使う
/* 推奨:GPUアクセラレーションが効く */
.overlay {
transform: translate(10px, 10px);
}
/* 非推奨:再描画が発生 */
.overlay {
top: 10px;
left: 10px;
}
3. will-changeで最適化
.animated-overlay {
will-change: transform, opacity;
/* アニメーションする要素に指定 */
}
ブラウザ対応状況
| 方法 | Chrome | Firefox | Safari | Edge | IE11 |
|---|---|---|---|---|---|
| position | ✅ | ✅ | ✅ | ✅ | ✅ |
| z-index | ✅ | ✅ | ✅ | ✅ | ✅ |
| Grid | ✅ | ✅ | ✅ | ✅ | ❌ |
| 複数背景 | ✅ | ✅ | ✅ | ✅ | ✅ |
※ IE11のサポートは2022年に終了しているため、現在は気にする必要はほとんどありません。
まとめ
CSSで画像を重ねる方法は、用途に応じて使い分けることが重要です。
この記事のポイント
- 基本は
position: relativeとposition: absoluteの組み合わせ - z-indexで重なり順を明示的に制御できる
- CSS Gridはモダンでシンプルな記述が可能
- レスポンシブ対応には相対的な単位を使う
- 商品バッジ、テキストオーバーレイなど実用例が豊富
まずは簡単なpositionを使った実装から始めて、徐々に複雑なレイアウトに挑戦していくのがおすすめです。
画像を効果的に重ねることで、ユーザーの目を引く魅力的なWebデザインを実現できます。ぜひ、あなたのサイトでも試してみてください!