CSSを触っていると、よく「これどうやればいいんだっけ?」と調べてしまうCSSレイアウトがあります。
自分用メモとしてまとめたものですが、同じ悩みを持つ人の助けになれば嬉しいです!
今回はこちらの3つを紹介します!
1.画像の上に文字を載せる
2.flexで横並びにすると、画像が縦方向に伸びる
3.横並びにしたカード内の要素の高さがずれる
画像の上に文字を載せる
解決策
HTML
<div class="image-wrapper">
<img src="./img/sample.jpg" alt="可愛い猫の画像">
<div class="text-overlay">可愛い猫ちゃん</div>
</div>
CSS
.image-wrapper {
position: relative; /* 子要素をabsoluteで配置するための基準 */
width: 100%;
max-width: 400px;
}
.image-wrapper img {
width: 100%; /* 親幅いっぱいに表示 */
height: auto; /* 縦横比を維持 */
display: block;
}
.text-overlay {
width: 100%;
height: 100%;
display: flex; /* 中央寄せのためflexを使用 */
justify-content: center; /* 横方向中央 */
align-items: center; /* 縦方向中央 */
position: absolute;
top: 50%; /* 中央基準に配置 */
left: 50%;
transform: translate(-50%, -50%); /* 正確に中央寄せ */
color: #fff; /* 文字色 */
background-color: rgba(30, 13, 43, 0.168); /* 半透明の背景色で文字を読みやすく */
}
ポイント
- .image-wrapper(親要素) にposition: relative;をつけることで、.text-overlay(中央寄せにしたい子要素)を上に配置できる
- .text-overlay を absolute + transform: translate(-50%, -50%) で中央に固定
- さらに display: flex; を組み合わせて、テキストを横・縦ともに中央寄せ
flexで横並びにすると、画像が縦方向に伸びる
悩み
flexでテキストと画像を横並びにすると、画像が縦方向に伸びてしまう。
解決策
HTML
<div class="flex-wrapper">
<img src="./img/sample.jpg" alt="可愛い猫の画像">
<div class="flex-text">
<h3>猫ちゃん</h3>
<p>横並びにしたいテキストをここに入れます。</p>
</div>
</div>
CSS
.flex-wrapper {
display: flex; /* 横並びにする */
gap: 16px; /* 画像とテキストの間に余白 */
align-items: flex-start; /* 子要素の縦方向を上揃えにする */
}
.flex-wrapper img {
width: 120px; /* 画像の幅を固定 */
height: 120px; /* 画像の高さを固定 */
object-fit: cover; /* アスペクト比を維持してトリミング */
}
.flex-text {
flex: 1; /* 残りの幅をテキストに割り当てる */
}
ポイント
- display: flex; で画像とテキストを横並び
- align-items: flex-start; を指定して、画像が縦に引き伸ばされるのを防止
- imgにobject-fit: cover;を適用し、比率を維持しつつ余分な部分をトリミング
横並びにしたカード内の要素の高さがずれる
悩み
カードの中の文字量が異なると、高さが揃わずレイアウトが崩れる。(ボタンの位置を揃えたい)
解決策
HTML
<div class="card-list">
<div class="card">
<img src="./img/sample.jpg" alt="可愛い猫の画像">
<div class="card-body">
<p>テキストテキストテキストテキストテキストテキストテキスト</p>
<button>button</button>
</div>
</div>
<div class="card">
<img src="./img/sample.jpg" alt="可愛い猫の画像">
<div class="card-body">
<p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
<button>button</button>
</div>
</div>
</div>
.card-list {
display: flex; /* 子要素(.card)を横並びにする */
justify-content: space-around;/* 均等に余白をとって配置する */
}
.card {
text-align: center; /* カード内のテキストを中央寄せ */
width: 40%; /* 親の幅に対して40%のサイズ */
border: 1px solid #000; /* カードの枠線 */
padding: 30px; /* 内側余白を確保 */
display: flex; /* 子要素(imgと.card-body)をflexで配置 */
flex-direction: column; /* 縦方向に積み重ねる */
}
.card-body {
flex-grow: 1; /* 余白を埋めて高さを揃える */
display: flex; /* 中身(pとbutton)もflexで配置 */
flex-direction: column; /* 縦方向に配置 */
}
.card p {
text-align: left; /* テキストを左寄せ */
font-size: 34px; /* テキストサイズを指定 */
flex-grow: 1; /* テキスト量に応じて伸縮させる */
}
button {
background-color: transparent; /* デフォルトの背景をリセット */
border: none; /* デフォルトの枠線をリセット */
cursor: pointer; /* ホバー時にカーソルをポインタに */
outline: none; /* フォーカス時のアウトラインを消す */
padding: 0; /* デフォルト余白をリセット */
appearance: none; /* ブラウザごとのデフォルトを無効化 */
width: 200px; /* ボタンの幅 */
padding: 20px 30px; /* ボタン内の上下・左右余白 */
background-color: rgb(182, 221, 255); /* 背景色を指定 */
border-radius: 50px; /* 角丸 */
margin: 0 auto; /* 親要素内で中央寄せ */
}
ポイント
- 親要素(.card-list)にdisplay: flex;を指定して横並びレイアウトにすることで、複数のカードを1列に配置
- 子要素(.card)はdisplay: flex;とflex-direction: column;を使い、中の要素を縦方向に積み重ねる
- 孫要素(.card-body)とひ孫要素(p)にflex-grow: 1;を指定して、カード内で余白を自動調整して高さを伸縮させ、カード全体の高さを揃える
まとめ
いかがでしたでしょうか?
特に私は、1番最後に紹介したようなレイアウトによく躓くので、毎回のように調べています…。
CSSは小さな罠が多く、初心者のうちは「なぜ上手くできないのか」がわかりづらいですが、原因と解決パターンを覚えておくと同じ悩みにぶつかってもすぐに直せます✨
余談ですが、Web制作って「全然うまくいかない〜!」となることが多いですよね。
でも、ほんの少し調整したり1つプロパティを追加・修正するだけで、急に綺麗に揃ったり思い通りになる瞬間があります。
あの瞬間って難しいパズルが解けたような感覚で、本当にスッキリして気持ちいいですよね!
個人的には、上手くいっているときより、出来なかったことが出来た瞬間が一番制作していて楽しいと感じます(笑)
なので、うまくいかなくても焦らずにちょっとした成功体験を積み重ねていきましょう!きっとどんどん楽しくなります。
今回のCSSレイアウトもぜひ参考にしてください。