限られたスペースに情報を収めたり、横スクロールメニューを作ったりする際に利用するのがoverflowプロパティです。
本記事では、ユーザーにとって見やすいレイアウトを作るhiddenやscrollなどの使い分けを解説します。
CSSのoverflowとは
HTML要素は、すべて四角い「箱」でできます。
箱のサイズ(widthやheight)を固定してる場合、中に入る文章が長かったり画像が大きいと、箱に収まりきらず外へはみ出します。
overflowプロパティは、「はみ出した(オーバーフローした)中身を隠すのか、スクロールさせるのか、そのまま見せるのか」を指示するCSSです。
overflowの使い方overflowの4つの値- 縦や横のみ指定する
overflow-xとoverflow-y
overflowの使い方
セレクタ { overflow: 値; }
はみ出しを防ぎたい「親要素(枠となる箱)」に対してoverflow: 値;を指定します。
箱の高さ(height)や幅(width)が固定されていないと、overflowは機能しません。
箱のサイズが決まっていない場合、箱自体が中身に合わせてどこまでも伸びてしまうため、はみ出すという現象自体が起きないからです。
ここは高さが「120px」に固定された箱です。
文章が長すぎると、枠に収まりきらずに外へはみ出してしまい、下の要素と重なる原因になります。
overflowプロパティを使えば、このはみ出しを綺麗にコントロールできます!
HTMLコード表示
<div class="ov1-wrapper">
<input type="radio" name="ov1-state" id="ov1-off" class="ov1-radio" checked>
<input type="radio" name="ov1-state" id="ov1-on" class="ov1-radio">
<div class="ov1-controls">
<label for="ov1-off" class="ov1-btn">❌ overflowなし(はみ出す)</label>
<label for="ov1-on" class="ov1-btn">⭕️ overflowを指定して隠す</label>
</div>
<div class="ov1-demo-area">
<div class="ov1-box target-box-1">
<div class="ov1-title">お知らせ</div>
<p class="ov1-text">
ここは高さが「120px」に固定された箱です。<br>
文章が長すぎると、枠に収まりきらずに外へはみ出してしまい、下の要素と重なる原因になります。<br>
overflowプロパティを使えば、このはみ出しを綺麗にコントロールできます!
</p>
</div>
</div>
</div>CSSコード表示
.ov1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.ov1-radio {
display: none;
}
.ov1-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.ov1-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#ov1-off:checked ~ .ov1-controls [for="ov1-off"] {
background-color: #dc3545;
color: white;
}
#ov1-on:checked ~ .ov1-controls [for="ov1-on"] {
background-color: #198754;
color: white;
}
.ov1-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
height: 250px;
display: flex;
justify-content: center;
align-items: flex-start;
padding-top: 20px;
}
.ov1-box {
width: 280px;
height: 120px; /* ★高さを固定しているのではみ出しが発生する */
background-color: #e3f2fd;
border: 3px solid #0d6efd;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
transition: all 0.3s;
}
.ov1-title {
margin: 0 0 10px 0;
color: #0d6efd;
font-size: 16px;
font-weight: bold;
}
.ov1-text {
margin: 0;
color: #333;
font-size: 14px;
line-height: 1.6;
}
/* ⭕️ ボタンが押されたら overflow: hidden; を追加してはみ出しを隠す */
#ov1-on:checked ~ .ov1-demo-area .target-box-1 {
overflow: hidden;
background-color: #d1e7dd;
border-color: #198754;
}overflowの4つの値
overflowは、はみ出した部分をどう扱うかを決める4つの代表的な値があります。
visible
初期値です。
はみ出した部分は隠れず、そのまま枠を飛び出して表示されます。hidden
はみ出した部分は切り取られて隠れます。
スクロールもできません。scroll
はみ出た部分は隠れ、常にスクロールバーが表示されてスクロールすれば見られます。auto
基本はscrollと同じですが、はみ出していない時はスクロールバーが消え、はみ出した時だけスクロールバーが現れます。
現在の設定を確認中…
テキスト1行目:ここはスクロールエリアです。
テキスト2行目:枠からはみ出るとどうなるでしょうか。
テキスト3行目:overflowプロパティの威力を確認します。
テキスト4行目:ここから先ははみ出しています!
テキスト5行目:見えていますか?
テキスト6行目:一番下まで到達しました。
HTMLコード表示
<div class="ov2-wrapper">
<input type="radio" name="ov2-state" id="ov2-visible" class="ov2-radio" checked>
<input type="radio" name="ov2-state" id="ov2-hidden" class="ov2-radio">
<input type="radio" name="ov2-state" id="ov2-scroll" class="ov2-radio">
<input type="radio" name="ov2-state" id="ov2-auto" class="ov2-radio">
<div class="ov2-controls">
<label for="ov2-visible" class="ov2-btn">① visible (初期値)</label>
<label for="ov2-hidden" class="ov2-btn">② hidden (隠す)</label>
<label for="ov2-scroll" class="ov2-btn">③ scroll (常時バー)</label>
<label for="ov2-auto" class="ov2-btn">④ auto (自動でバー)</label>
</div>
<div class="ov2-demo-area">
<div class="ov2-box target-box-2">
<div class="ov2-content">
<p style="font-weight:bold; color:#d63384; margin-top:0;">現在の設定を確認中…</p>
<p>テキスト1行目:ここはスクロールエリアです。</p>
<p>テキスト2行目:枠からはみ出るとどうなるでしょうか。</p>
<p>テキスト3行目:overflowプロパティの威力を確認します。</p>
<p>テキスト4行目:ここから先ははみ出しています!</p>
<p>テキスト5行目:見えていますか?</p>
<p>テキスト6行目:一番下まで到達しました。</p>
</div>
</div>
</div>
</div>CSSコード表示
.ov2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.ov2-radio {
display: none;
}
.ov2-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.ov2-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#ov2-visible:checked ~ .ov2-controls [for="ov2-visible"],
#ov2-hidden:checked ~ .ov2-controls [for="ov2-hidden"],
#ov2-scroll:checked ~ .ov2-controls [for="ov2-scroll"],
#ov2-auto:checked ~ .ov2-controls [for="ov2-auto"] {
background-color: #0d6efd;
color: white;
}
.ov2-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
height: 300px;
display: flex;
justify-content: center;
align-items: flex-start;
padding-top: 20px;
}
/* 対象となる固定サイズの箱 */
.ov2-box {
width: 280px;
height: 150px;
background-color: #fff;
border: 3px solid #333;
border-radius: 4px;
/* ここは変更せず、下の設定で上書き */
}
.ov2-content {
padding: 15px;
font-size: 14px;
color: #444;
line-height: 1.5;
background-color: rgba(13, 110, 253, 0.1);
}
.ov2-content p {
margin: 0 0 10px 0;
}
/* ① visible(初期値:はみ出す) */
#ov2-visible:checked ~ .ov2-demo-area .target-box-2 {
overflow: visible;
}
/* ② hidden(はみ出た部分を隠す) */
#ov2-hidden:checked ~ .ov2-demo-area .target-box-2 {
overflow: hidden;
}
/* ③ scroll(常時スクロールバーを表示) */
#ov2-scroll:checked ~ .ov2-demo-area .target-box-2 {
overflow: scroll;
}
/* ④ auto(はみ出した時だけスクロールバーを表示) */
#ov2-auto:checked ~ .ov2-demo-area .target-box-2 {
overflow: auto;
}縦や横のみ指定するoverflow-xとoverflow-y
overflow: hidden;やoverflow: auto;を指定すると、縦(上下)と横(左右)の両方に対して設定が適用されてしまいます。
実務では、「縦にはみ出た部分は隠したいけど、横にはみ出た部分はスクロールできるようにしたい」という場面が多々あります。(例:スマホ向けの横スクロールメニューや、横幅が広い表・テーブルなど)
そんな時は、軸を個別に指定できるプロパティを使います。
overflow-x: 横方向(X軸)のはみ出しを指定overflow-y: 縦方向(Y軸)のはみ出しを指定
下のメニューを横にスクロール(またはスワイプ)してみてください。
HTMLコード表示
<div class="ov3-wrapper">
<p class="ov3-desc">下のメニューを横にスクロール(またはスワイプ)してみてください。</p>
<div class="ov3-demo-area">
<div class="ov3-scroll-container">
<div class="ov3-item">ホーム</div>
<div class="ov3-item">会社概要</div>
<div class="ov3-item">サービス</div>
<div class="ov3-item">実績紹介</div>
<div class="ov3-item">ブログ</div>
<div class="ov3-item">よくある質問</div>
<div class="ov3-item">お問い合わせ</div>
</div>
</div>
</div>CSSコード表示
.ov3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.ov3-desc {
text-align: center;
font-weight: bold;
color: #333;
margin-bottom: 20px;
}
.ov3-demo-area {
background-color: #ffffff;
padding: 20px 0;
border-radius: 8px;
}
/* ★ 横スクロールの親要素 */
.ov3-scroll-container {
display: flex;
gap: 10px;
padding: 0 20px; /* 左右に少し余白を持たせる */
/* 縦方向は隠す(意図しない縦スクロール防止) */
overflow-y: hidden;
/* 横方向は、はみ出た時だけスクロールバーを出す */
overflow-x: auto;
/* スクロールを滑らかにする */
-webkit-overflow-scrolling: touch;
}
/* メニューの各項目(横幅を固定してはみ出させる) */
.ov3-item {
/* flex要素が勝手に縮まないようにする */
flex-shrink: 0;
width: 120px;
padding: 15px 0;
background-color: #0d6efd;
color: white;
font-weight: bold;
text-align: center;
border-radius: 30px;
font-size: 14px;
}overflow: visible;でそのまま表示
overflow: visible;は、親要素のサイズに中身が収まりきらなかった場合、はみ出た部分をそのまま表示するという設定です。
単純に見えますが、実はレイアウト崩れを起こしやすい設定でもあります。
理由と対策を見ていきます。
visibleは全要素の初期値- 下の要素と重なって文字が読めない
- 解決策は
overflowだけじゃない
visibleは全要素の初期値
よくある盲点として、「overflowを指定してないのに、勝手にはみ出した。」と焦ることがあります。
実は、HTMLのすべての要素はoverflow: visible;が設定されているというルールがあります。
つまり、意図してhiddenやscrollに変更しない限り、箱のサイズ(高さや幅)をオーバーした中身は、当然外へ飛び出してしまいます。
ここは高さが「80px」に固定された箱です。
文章が長いため、枠からはみ出してしまっています。
初期値がvisibleなので、指定してもしなくても見た目は変わりません!
HTMLコード表示
<div class="vis1-wrapper">
<input type="radio" name="vis1-state" id="vis1-off" class="vis1-radio" checked>
<input type="radio" name="vis1-state" id="vis1-on" class="vis1-radio">
<div class="vis1-controls">
<label for="vis1-off" class="vis1-btn">❌ 指定なし(初期状態)</label>
<label for="vis1-on" class="vis1-btn">⭕️ overflow: visible; を追加</label>
</div>
<div class="vis1-demo-area">
<div class="vis1-box target-box-vis1">
<div class="vis1-title">お知らせ</div>
<p class="vis1-text">
ここは高さが「80px」に固定された箱です。<br>
文章が長いため、枠からはみ出してしまっています。<br>
初期値がvisibleなので、指定してもしなくても見た目は変わりません!
</p>
</div>
</div>
</div>CSSコード表示
.vis1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.vis1-radio {
display: none;
}
.vis1-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.vis1-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#vis1-off:checked ~ .vis1-controls [for="vis1-off"] {
background-color: #dc3545;
color: white;
}
#vis1-on:checked ~ .vis1-controls [for="vis1-on"] {
background-color: #0d6efd;
color: white;
}
.vis1-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
height: 200px;
display: flex;
justify-content: center;
padding-top: 20px;
}
.vis1-box {
width: 280px;
height: 80px; /* 高さを小さく固定 */
background-color: #e3f2fd;
border: 3px solid #0d6efd;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
}
.vis1-title {
margin: 0 0 10px 0;
color: #0d6efd;
font-size: 16px;
}
.vis1-text {
margin: 0;
color: #333;
font-size: 14px;
line-height: 1.6;
}
/* ⭕️ visibleを明示的に指定しても、初期値と同じなので変化しない */
#vis1-on:checked ~ .vis1-demo-area .target-box-vis1 {
overflow: visible;
}下の要素と重なって文字が読めない
overflow: visible;のまま放置していると、レイアウトにおいて恐ろしい事態が発生します。
はみ出したテキストや画像は、自身の下にある別要素の背景や文字の上に覆い被さります。
これにより、文字が重なって読めなくなったり、ボタンが押せなくなるレイアウト崩れが起きます。
固定された箱からはみ出た文字が、下の要素を侵食しています…
こんにちは。この文章は長すぎるため、「上のお知らせ」という枠からはみ出してしまいます。そのまま下に流れ込み、次の要素のレイアウトを完全に破壊します。非常に読みにくいですね。
ここは次のセクションですが、上の文字が重なってしまって内容が全く頭に入ってきません。
HTMLコード表示
<div class="vis2-wrapper">
<p class="vis2-desc">固定された箱からはみ出た文字が、下の要素を侵食しています…</p>
<div class="vis2-demo-area">
<div class="vis2-box-top">
<div class="vis2-title">上のお知らせ</div>
<p class="vis2-text">
こんにちは。この文章は長すぎるため、「上のお知らせ」という枠からはみ出してしまいます。そのまま下に流れ込み、次の要素のレイアウトを完全に破壊します。非常に読みにくいですね。
</p>
</div>
<div class="vis2-box-bottom">
<div class="vis2-title-bottom">次のコンテンツ</div>
<p class="vis2-text-bottom">
ここは次のセクションですが、上の文字が重なってしまって内容が全く頭に入ってきません。
</p>
</div>
</div>
</div>CSSコード表示
.vis2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.vis2-desc {
text-align: center;
font-weight: bold;
color: #dc3545;
margin-bottom: 20px;
}
.vis2-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
/* 上の箱 */
.vis2-box-top {
width: 100%;
max-width: 300px;
height: 80px; /* ★ここが原因 */
background-color: #fff3cd;
border: 2px solid #ffc107;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
/* 初期値の visible が効いている */
overflow: visible;
}
/* 下の箱 */
.vis2-box-bottom {
width: 100%;
max-width: 300px;
background-color: #e9ecef;
border: 2px solid #adb5bd;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
/* 上の箱との間に本来あるべき余白を設定しているが… */
margin-top: 20px;
}
.vis2-title,
.vis2-title-bottom {
margin: 0 0 10px 0;
font-size: 16px;
font-weight: bold;
}
.vis2-title { color: #856404; }
.vis2-title-bottom { color: #495057; }
.vis2-text,
.vis2-text-bottom {
margin: 0;
font-size: 14px;
line-height: 1.6;
}
.vis2-text { color: #dc3545; font-weight: bold; }
.vis2-text-bottom { color: #666; }解決策はoverflowだけじゃない
実務において、文字のはみ出しトラブルは「高さをheight: 100px;のように固定してること」が原因です。
overflowをいじるのではなく、箱の高さをheight: auto;(中身に合わせて伸びる)や、min-height(最低限の高さを決めておく)に変更するのが正しい解決策です。
この文章は重要なお知らせです。
最後までしっかり読んでいただきたいのですが、箱の高さが固定されているとはみ出してしまいます。
箱自体が文章の長さに合わせて伸びてくれれば、一番綺麗に解決しますよね!
HTMLコード表示
<div class="vis3-wrapper">
<input type="radio" name="vis3-state" id="vis3-bad" class="vis3-radio" checked>
<input type="radio" name="vis3-state" id="vis3-hidden" class="vis3-radio">
<input type="radio" name="vis3-state" id="vis3-good" class="vis3-radio">
<div class="vis3-controls">
<label for="vis3-bad" class="vis3-btn">❌ はみ出し状態 (height固定)</label>
<label for="vis3-hidden" class="vis3-btn">🔺 hiddenで隠す (文字が読めない)</label>
<label for="vis3-good" class="vis3-btn">⭕️ height: auto; にする (箱が伸びる!)</label>
</div>
<div class="vis3-demo-area">
<div class="vis3-box target-box-vis3">
<div class="vis3-title">お知らせ</div>
<p class="vis3-text">
この文章は重要なお知らせです。<br>
最後までしっかり読んでいただきたいのですが、箱の高さが固定されているとはみ出してしまいます。<br>
箱自体が文章の長さに合わせて伸びてくれれば、一番綺麗に解決しますよね!
</p>
</div>
<div class="vis3-box-bottom target-bottom-vis3">
次のコンテンツ
</div>
</div>
</div>CSSコード表示
.vis3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.vis3-radio {
display: none;
}
.vis3-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.vis3-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#vis3-bad:checked ~ .vis3-controls [for="vis3-bad"] {
background-color: #dc3545;
color: white;
}
#vis3-hidden:checked ~ .vis3-controls [for="vis3-hidden"] {
background-color: #ffc107;
color: #333;
}
#vis3-good:checked ~ .vis3-controls [for="vis3-good"] {
background-color: #198754;
color: white;
}
.vis3-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
/* ターゲットの箱 */
.vis3-box {
width: 100%;
max-width: 300px;
height: 90px; /* ★ここが原因 */
background-color: #e3f2fd;
border: 3px solid #0d6efd;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
transition: all 0.4s ease;
}
.vis3-title {
margin: 0 0 10px 0;
color: #0d6efd;
font-size: 16px;
}
.vis3-text {
margin: 0;
color: #333;
font-size: 14px;
line-height: 1.6;
}
.vis3-box-bottom {
width: 100%;
max-width: 300px;
background-color: #e9ecef;
border: 2px solid #adb5bd;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
text-align: center;
font-weight: bold;
color: #666;
/* 上の箱からの距離 */
margin-top: 20px;
transition: all 0.4s ease;
}
/* 🔺 hidden で隠す(見た目はよいが、文章が途切れる) */
#vis3-hidden:checked ~ .vis3-demo-area .target-box-vis3 {
overflow: hidden;
}
/* ⭕️ 高さの固定をやめて、auto にする(箱が伸びて全て解決!) */
#vis3-good:checked ~ .vis3-demo-area .target-box-vis3 {
height: auto;
/* または min-height: 90px; */
background-color: #d1e7dd;
border-color: #198754;
}overflow: hidden;で非表示
overflow: hidden;は、親要素の枠(高さや幅)に収まらなかった中身を非表示にするプロパティです。
スクロールバーも出ないため、はみ出た部分はユーザーからアクセスできません。
- はみ出た部分を隠す機能
- 画像を角丸に切り抜く
position: absolute;の要素が消えてしまう現象
はみ出た部分を隠す機能
hiddenは、装飾用の背景文字や枠外にはみ出させたいデザインパーツなどを枠内に収めるために使うのが原則です。
重要なテキストに対して使うと、文章の後半が読めなくなるので注意が必要です。
ここは高さが固定された箱です。このように文章が長かったり、デザインの要素が大きかったりすると枠からはみ出します。hiddenを指定すると、この境界線を越えた部分は問答無用で切り取られ、完全に非表示になります。
HTMLコード表示
<div class="hid1-wrapper">
<input type="radio" name="hid1-state" id="hid1-visible" class="hid1-radio" checked>
<input type="radio" name="hid1-state" id="hid1-hidden" class="hid1-radio">
<div class="hid1-controls">
<label for="hid1-visible" class="hid1-btn">❌ そのまま表示 (visible)</label>
<label for="hid1-hidden" class="hid1-btn">⭕️ バッサリ隠す (hidden)</label>
</div>
<div class="hid1-demo-area">
<div class="hid1-box target-box-hid1">
<div class="hid1-title">デザイン要素</div>
<p class="hid1-text">
ここは高さが固定された箱です。このように文章が長かったり、デザインの要素が大きかったりすると枠からはみ出します。hiddenを指定すると、この境界線を越えた部分は問答無用で切り取られ、完全に非表示になります。
</p>
<div class="hid1-bg-text">BACKGROUND</div>
</div>
</div>
</div>CSSコード表示
.hid1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hid1-radio {
display: none;
}
.hid1-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.hid1-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#hid1-visible:checked ~ .hid1-controls [for="hid1-visible"] {
background-color: #dc3545;
color: white;
}
#hid1-hidden:checked ~ .hid1-controls [for="hid1-hidden"] {
background-color: #198754;
color: white;
}
.hid1-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
height: 250px;
display: flex;
justify-content: center;
padding-top: 20px;
}
.hid1-box {
width: 280px;
height: 120px; /* 高さを固定 */
background-color: #fff;
border: 3px solid #333;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
position: relative;
/* ここで切り替えます */
overflow: visible;
transition: all 0.3s;
}
.hid1-title {
margin: 0 0 10px 0;
color: #333;
font-size: 16px;
position: relative;
z-index: 2;
}
.hid1-text {
margin: 0;
color: #666;
font-size: 14px;
line-height: 1.6;
position: relative;
z-index: 2;
}
/* はみ出す装飾用テキスト */
.hid1-bg-text {
position: absolute;
bottom: -30px;
right: -20px;
font-size: 40px;
font-weight: bold;
color: rgba(13, 110, 253, 0.2);
z-index: 1;
white-space: nowrap;
}
/* ⭕️ hiddenにすると、文字も背景テキストも境界線で切れる */
#hid1-hidden:checked ~ .hid1-demo-area .target-box-hid1 {
overflow: hidden;
border-color: #198754;
}画像を角丸に切り抜く
実務においてoverflow: hidden;が最も活躍する場面の一つが「画像(imgタグ)などを親の枠に合わせて角丸に切り抜く」というテクニックです。
例えば、親の枠(divなど)にborder-radiusを設定して角を丸くしても、中に入っている四角い画像は角が尖ったままで、親の丸みを無視してはみ出します。
そこで親要素にoverflow: hidden;を追加すると、親の丸い形に合わせて画像のはみ出た角が削られ、角丸カードが完成します。
親要素にhiddenをつけるだけで、中の画像が綺麗に角丸になります。
HTMLコード表示
<div class="hid2-wrapper">
<input type="radio" name="hid2-state" id="hid2-bad" class="hid2-radio" checked>
<input type="radio" name="hid2-state" id="hid2-good" class="hid2-radio">
<div class="hid2-controls">
<label for="hid2-bad" class="hid2-btn">❌ 中の画像の角がはみ出す</label>
<label for="hid2-good" class="hid2-btn">⭕️ hiddenで丸く切り抜く!</label>
</div>
<div class="hid2-demo-area">
<div class="hid2-card target-card-hid2">
<div class="hid2-image">
<span>Image</span>
</div>
<div class="hid2-content">
<div style="margin:0 0 5px 0; color:#333;">カードタイトル</div>
<p style="margin:0; font-size:12px; color:#666;">親要素にhiddenをつけるだけで、中の画像が綺麗に角丸になります。</p>
</div>
</div>
</div>
</div>CSSコード表示
.hid2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hid2-radio {
display: none;
}
.hid2-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.hid2-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#hid2-bad:checked ~ .hid2-controls [for="hid2-bad"] {
background-color: #dc3545;
color: white;
}
#hid2-good:checked ~ .hid2-controls [for="hid2-good"] {
background-color: #198754;
color: white;
}
.hid2-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 30px;
display: flex;
justify-content: center;
}
/* 親のカード枠(border-radiusで角を丸くしている) */
.hid2-card {
width: 240px;
background-color: #fff;
border: 3px solid #333;
border-radius: 20px; /* ★親の角を丸く設定 */
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
/* 初期状態はそのまま(角がはみ出る) */
overflow: visible;
transition: all 0.3s;
}
/* 画像の代わり(四角い要素) */
.hid2-image {
width: 100%;
height: 120px;
background: linear-gradient(135deg, #0d6efd, #6ea8fe);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 20px;
/* ★画像自身は四角いまま(角丸指定なし) */
}
.hid2-content {
padding: 15px;
}
/* ⭕️ hiddenを追加すると、親の丸みに合わせて子要素の角が切り取られる */
#hid2-good:checked ~ .hid2-demo-area .target-card-hid2 {
overflow: hidden;
}position: absolute;の要素が消えてしまう現象
overflow: hidden;を設定した箱の中にあるposition: absolute;の要素(バッジやアイコンなど)が、枠外に出ようとして消滅するという現象です。
「カードの中身のはみ出しは隠したいが、カードの右上に『NEW!』というバッジを半分はみ出させて目立たせたい。」 という2つの願いは、同じ箱(親要素)の中では両立できません。
これを解決するには、HTMLの構造を「隠す箱」と「バッジ」で分ける必要があります。
中の文章は長くても
ここで隠れます。
中の文章は長くても
綺麗に隠れます。
HTMLコード表示
<div class="hid3-wrapper">
<input type="radio" name="hid3-state" id="hid3-bad" class="hid3-radio" checked>
<input type="radio" name="hid3-state" id="hid3-good" class="hid3-radio">
<div class="hid3-controls">
<label for="hid3-bad" class="hid3-btn">❌ 罠にハマる (バッジが切れる)</label>
<label for="hid3-good" class="hid3-btn">⭕️ 解決策 (構造を分ける)</label>
</div>
<div class="hid3-demo-area">
<div class="hid3-bad-wrap target-bad-hid3">
<div class="hid3-content">
<p>中の文章は長くても<br>ここで隠れます。</p>
</div>
<div class="hid3-badge">NEW!</div>
</div>
<div class="hid3-good-wrap target-good-hid3">
<div class="hid3-content-inner">
<p>中の文章は長くても<br>綺麗に隠れます。</p>
</div>
<div class="hid3-badge-good">NEW!</div>
</div>
</div>
</div>CSSコード表示
.hid3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hid3-radio {
display: none;
}
.hid3-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.hid3-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#hid3-bad:checked ~ .hid3-controls [for="hid3-bad"] {
background-color: #dc3545;
color: white;
}
#hid3-good:checked ~ .hid3-controls [for="hid3-good"] {
background-color: #198754;
color: white;
}
.hid3-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
height: 250px;
display: flex;
justify-content: center;
align-items: center;
}
/* =========================================
❌ 罠の構造のCSS
========================================= */
.hid3-bad-wrap {
width: 200px;
height: 100px;
background-color: #fff3cd;
border: 2px solid #ffc107;
border-radius: 8px;
/* ここが間違い!relativeとhiddenを同居させている */
position: relative;
overflow: hidden;
display: flex; /* 初期表示用 */
}
.hid3-content {
padding: 15px;
font-size: 13px;
color: #856404;
}
.hid3-badge {
position: absolute;
top: -15px;
right: -15px;
background-color: #dc3545;
color: white;
padding: 5px 10px;
border-radius: 20px;
font-weight: bold;
font-size: 12px;
/* hiddenのせいで半分切り取られる */
}
/* =========================================
⭕️ 解決策の構造のCSS
========================================= */
.hid3-good-wrap {
width: 200px;
height: 100px;
/* 親はpositionの基準(relative) だけ持つ。overflowは書かない。 */
position: relative;
display: none; /* 初期表示は隠す */
}
/* 中のコンテンツを包む箱にだけ hidden を持たせる */
.hid3-content-inner {
width: 100%;
height: 100%;
background-color: #d1e7dd;
border: 2px solid #198754;
border-radius: 8px;
box-sizing: border-box;
padding: 15px;
font-size: 13px;
color: #0f5132;
overflow: hidden; /* 文章のはみ出しはここでストップ */
}
.hid3-badge-good {
position: absolute;
top: -15px;
right: -15px;
background-color: #dc3545;
color: white;
padding: 5px 10px;
border-radius: 20px;
font-weight: bold;
font-size: 12px;
/* 親にはhiddenがないので、飛び出せる */
z-index: 10;
}
/* ラジオボタン切り替え */
#hid3-good:checked ~ .hid3-demo-area .target-bad-hid3 {
display: none;
}
#hid3-good:checked ~ .hid3-demo-area .target-good-hid3 {
display: block;
}positionプロパティを詳しく知りたい人は「【html&css】positionの使い方とabsolute・fixed・relativeの使い分け」を一読ください。
overflow: scroll;でスクロールさせる
枠に収まらない文章や画像をはみ出させずかつ隠さずユーザーに見せる場合は、スクロールバーを表示させるのが最適です。
しかし、overflow: scroll;を指定するだけではデザインが不格好になり、思い通りにスクロールしてくれなかったりするケースがあります。
scrollは常にスクロールバーが出てしまうscrollよりもautoを使う- 文字の折り返しの悩みと解決策
scrollは常にスクロールバーが出てしまう
overflow: scroll;という値は、中身がはみ出していようがいまいが、強制的に縦と横のスクロールバーの枠を表示するといった仕様を持ちます。
そのため、中身が少なくてスクロールする必要がない時でも、無駄な空のスクロールバーが表示され、デザインを損ねる原因になります。(※Macなど一部の環境では隠れることもありますが、Windows等ではしっかり表示されます。)
中身が少ないので、はみ出していません。
HTMLコード表示
<div class="scr1-wrapper">
<input type="radio" name="scr1-state" id="scr1-off" class="scr1-radio" checked>
<input type="radio" name="scr1-state" id="scr1-on" class="scr1-radio">
<div class="scr1-controls">
<label for="scr1-off" class="scr1-btn">❌ 指定なし (スッキリ)</label>
<label for="scr1-on" class="scr1-btn">🔺 overflow: scroll; を指定</label>
</div>
<div class="scr1-demo-area">
<div class="scr1-box target-box-scr1">
<div class="scr1-title">短いお知らせ</div>
<p class="scr1-text">
中身が少ないので、はみ出していません。
</p>
</div>
</div>
</div>CSSコード表示
.scr1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.scr1-radio {
display: none;
}
.scr1-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.scr1-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#scr1-off:checked ~ .scr1-controls [for="scr1-off"] {
background-color: #dc3545;
color: white;
}
#scr1-on:checked ~ .scr1-controls [for="scr1-on"] {
background-color: #ffc107;
color: #333;
}
.scr1-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
.scr1-box {
width: 280px;
height: 120px;
background-color: #fff3cd;
border: 2px solid #ffc107;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
/* ここで切り替えます */
transition: all 0.3s;
}
.scr1-title {
margin: 0 0 10px 0;
color: #856404;
font-size: 16px;
}
.scr1-text {
margin: 0;
color: #666;
font-size: 14px;
}
/* 🔺 scrollを指定すると、はみ出していなくても無駄なバーが出る */
#scr1-on:checked ~ .scr1-demo-area .target-box-scr1 {
overflow: scroll;
}scrollよりもautoを使う
無駄なスクロールバーが出てしまう問題を解決するために、実務で使うのがoverflow: auto; です。
autoを指定するとブラウザが中身の量を判断し、枠内に収まっている時はスクロールバーを隠しはみ出した時だけスクロールバーを表示するという動きをします。
そのため、実務でスクロールさせたい場合は、特別な理由がない限りscrollではなくautoを使うのが便利です。
中身が「はみ出していない時」の見た目の違いに注目!
文字が少なくても、強制的にバーの枠が出ます。
文字が少ない時は、バーを出さずにスッキリ!
HTMLコード表示
<div class="scr2-wrapper">
<p class="scr2-desc">中身が「はみ出していない時」の見た目の違いに注目!</p>
<div class="scr2-demo-area">
<div class="scr2-box box-scroll">
<span class="scr2-label">overflow: scroll;</span>
<p>文字が少なくても、強制的にバーの枠が出ます。</p>
</div>
<div class="scr2-box box-auto">
<span class="scr2-label-good">overflow: auto;</span>
<p>文字が少ない時は、バーを出さずにスッキリ!</p>
</div>
</div>
</div>CSSコード表示
.scr2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.scr2-desc {
text-align: center;
font-weight: bold;
color: #333;
margin-bottom: 20px;
}
.scr2-demo-area {
display: flex;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
}
.scr2-box {
width: 220px;
height: 120px;
background-color: #ffffff;
border: 2px solid #adb5bd;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
font-size: 14px;
color: #555;
}
.scr2-label {
display: inline-block;
background-color: #dc3545;
color: white;
font-weight: bold;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
margin-bottom: 10px;
}
.scr2-label-good {
display: inline-block;
background-color: #198754;
color: white;
font-weight: bold;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
margin-bottom: 10px;
}
/* 強制的にバーが出る */
.box-scroll {
overflow: scroll;
}
/* はみ出した時だけバーが出る(今ははみ出していないので出ない) */
.box-auto {
overflow: auto;
}文字の折り返しの悩みと解決策
実務でよくあるトラブルが「スマホ向けにテーブルやメニューを横スクロールさせようとしてoverflow-x: auto;を指定したのに、横スクロールせず文字が下へ折り返し(改行)縦に伸びてしまった。」という現象です。
これはoverflowのバグではありません。
HTMLのテキストは、「親の枠の端まで来たら、自動的に改行して折り返す」という標準ルールを持っています。
横スクロールを実現するには、テキストに対してwhite-space: nowrap;(改行しない命令) をセットで指定して、強制的に横へはみ出させる必要があります。
HTMLコード表示
<div class="scr3-wrapper">
<input type="radio" name="scr3-state" id="scr3-bad" class="scr3-radio" checked>
<input type="radio" name="scr3-state" id="scr3-good" class="scr3-radio">
<div class="scr3-controls">
<label for="scr3-bad" class="scr3-btn">❌ auto のみ (勝手に折り返す)</label>
<label for="scr3-good" class="scr3-btn">⭕️ nowrap を追加 (横スクロール成功!)</label>
</div>
<div class="scr3-demo-area">
<div class="scr3-scroll-box target-box-scr3">
これはとても長い横長のテキストメニューです。設定を間違えるとここで勝手に折り返してしまいますが、正しく設定すれば綺麗に横スクロールしてくれます!
</div>
</div>
</div>CSSコード表示
.scr3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.scr3-radio {
display: none;
}
.scr3-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.scr3-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#scr3-bad:checked ~ .scr3-controls [for="scr3-bad"] {
background-color: #dc3545;
color: white;
}
#scr3-good:checked ~ .scr3-controls [for="scr3-good"] {
background-color: #198754;
color: white;
}
.scr3-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 30px 20px;
display: flex;
justify-content: center;
}
.scr3-scroll-box {
width: 100%;
max-width: 300px;
background-color: #e3f2fd;
border: 2px solid #0d6efd;
border-radius: 8px;
padding: 15px;
font-weight: bold;
color: #0d6efd;
font-size: 16px;
line-height: 1.5;
/* スクロール設定自体はしている */
overflow-x: auto;
}
/* ❌ エラー状態:文字が折り返す標準設定のまま */
#scr3-bad:checked ~ .scr3-demo-area .target-box-scr3 {
white-space: normal;
}
/* ⭕️ 成功状態:改行を禁止することで、初めて横にはみ出してスクロールする */
#scr3-good:checked ~ .scr3-demo-area .target-box-scr3 {
white-space: nowrap;
background-color: #d1e7dd;
border-color: #198754;
color: #0f5132;
}overflow: auto;とは
overflow: auto;はブラウザが中身の量を計算し、はみ出していない時はスクロールバーを隠し、はみ出した時だけスクロールバーを表示するという柔軟な設定です。
スクロールさせたいなら、基本はautoを使うと覚えておきましょう。
- スクロールバーを必要な時だけ出す
max-heightと組み合わせて箱を可変にする- Flexboxの中でスクロールが効かない時の解決策
スクロールバーを必要な時だけ出す
overflow: scroll;は中身が少なくても強制的にスクロールバーの枠が出てしまいます。
autoは、普段はvisible(通常表示)のような見た目ですが、枠をオーバーした瞬間にスクロールバーが現れて機能し始めます。
ここは height: 150px; に固定された箱で、overflow: auto; が指定されています。
ここから追加の長〜い文章です!
中身が増えて、設定された150pxの枠に収まりきらなくなりました。
するとブラウザが「あ、はみ出た!」と判断し、自動的にスクロールバーを表示してくれます。
無駄なバーが出ないので、デザインを邪魔しない最強の設定です!
HTMLコード表示
<div class="oau1-wrapper">
<input type="radio" name="oau1-state" id="oau1-short" class="oau1-radio" checked>
<input type="radio" name="oau1-state" id="oau1-long" class="oau1-radio">
<div class="oau1-controls">
<label for="oau1-short" class="oau1-btn">① 文章が短い時 (バーなし)</label>
<label for="oau1-long" class="oau1-btn">② 文章が長くなった時 (バー出現!)</label>
</div>
<div class="oau1-demo-area">
<div class="oau1-box">
<div class="oau1-title">最新のお知らせ</div>
<div class="oau1-content target-text-oau1">
<p>ここは height: 150px; に固定された箱で、overflow: auto; が指定されています。</p>
<div class="oau1-extra-text">
<p>ここから追加の長〜い文章です!</p>
<p>中身が増えて、設定された150pxの枠に収まりきらなくなりました。</p>
<p>するとブラウザが「あ、はみ出た!」と判断し、自動的にスクロールバーを表示してくれます。</p>
<p>無駄なバーが出ないので、デザインを邪魔しない最強の設定です!</p>
</div>
</div>
</div>
</div>
</div>CSSコード表示
.oau1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.oau1-radio {
display: none;
}
.oau1-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.oau1-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#oau1-short:checked ~ .oau1-controls [for="oau1-short"] {
background-color: #0d6efd;
color: white;
}
#oau1-long:checked ~ .oau1-controls [for="oau1-long"] {
background-color: #198754;
color: white;
}
.oau1-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 30px;
display: flex;
justify-content: center;
}
.oau1-box {
width: 280px;
height: 150px; /* 高さを固定 */
background-color: #e3f2fd;
border: 3px solid #0d6efd;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
/* ★ここで賢い auto を指定! */
overflow: auto;
}
.oau1-title {
margin: 0 0 10px 0;
color: #0d6efd;
font-size: 16px;
border-bottom: 1px solid #86b7fe;
padding-bottom: 5px;
}
.oau1-content {
font-size: 13px;
color: #333;
line-height: 1.5;
}
.oau1-content p {
margin: 0 0 8px 0;
}
/* 初期状態は追加テキストを隠す */
.oau1-extra-text {
display: none;
}
/* ② 長い時:追加テキストを表示させて箱を溢れさせる */
#oau1-long:checked ~ .oau1-demo-area .target-text-oau1 .oau1-extra-text {
display: block;
}max-heightと組み合わせて箱を可変にする
初心者はheight: 200px;のように高さを固定した上でoverflow: auto;を指定します。
しかし、「中身が1行しかない時でも、無駄に200pxの空間が空いてしまう」という不格好なデザインになります。
実務では、高さを固定するのではなくmax-height(最大の高さ) と組み合わせて使います。
こうすることで、中身が少ない時はそれに合わせて箱も縮み、限界サイズ(max-height)に達したらスクロールバーを出すといったレイアウトを作れます。
今日は「1行だけ」のお知らせです。
HTMLコード表示
<div class="oau2-wrapper">
<input type="radio" name="oau2-state" id="oau2-bad" class="oau2-radio" checked>
<input type="radio" name="oau2-state" id="oau2-good" class="oau2-radio">
<div class="oau2-controls">
<label for="oau2-bad" class="oau2-btn">❌ heightを固定 (無駄な余白)</label>
<label for="oau2-good" class="oau2-btn">⭕️ max-heightを指定 (ピッタリ縮む!)</label>
</div>
<div class="oau2-demo-area">
<div class="oau2-box target-box-oau2">
<div class="oau2-title">お知らせ</div>
<p class="oau2-text">今日は「1行だけ」のお知らせです。</p>
<p class="oau2-text" style="display:none;">
文章が長くなると、どちらの設定でもスクロールバーが出ます。
</p>
</div>
</div>
</div>CSSコード表示
.oau2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.oau2-radio {
display: none;
}
.oau2-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
.oau2-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#oau2-bad:checked ~ .oau2-controls [for="oau2-bad"] {
background-color: #dc3545;
color: white;
}
#oau2-good:checked ~ .oau2-controls [for="oau2-good"] {
background-color: #198754;
color: white;
}
.oau2-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
height: 250px;
display: flex;
justify-content: center;
align-items: flex-start;
padding-top: 30px;
}
.oau2-box {
width: 250px;
background-color: #fff3cd;
border: 2px solid #ffc107;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
overflow: auto;
transition: all 0.3s;
}
.oau2-title {
margin: 0 0 10px 0;
color: #856404;
font-size: 16px;
}
.oau2-text {
margin: 0;
color: #666;
font-size: 13px;
}
/* ❌ 高さを「200px」に固定してしまう */
#oau2-bad:checked ~ .oau2-demo-area .target-box-oau2 {
height: 200px;
}
/* ⭕️ 高さは基本auto。ただし「最大200px」まで */
#oau2-good:checked ~ .oau2-demo-area .target-box-oau2 {
height: auto;
max-height: 200px;
background-color: #d1e7dd;
border-color: #198754;
}width(横幅)やheight(高さ)の詳細設定を知りたい人は「【html&css】width(横幅)とheight(高さ)の指定とボックスモデル」を一読ください。
Flexboxの中でスクロールが効かない時の解決策
display: flex;を使った親要素の中で、子要素にoverflow: auto;を指定しても、スクロールせず親の枠を突き破り無限に伸びる」という現象です。
Flexboxの子要素は、自身の中身の最小サイズより小さくは縮まない(min-height: auto;の状態)というルールが原因です。
解決策は、スクロールさせたい子要素にmin-height: 0;(または横なら min-width: 0;)を追加します。
↓↓ ここから長文 ↓↓
親の黒い枠は高さ300pxなのに、
中身の長文に押し出されて
枠線を完全に突き破っています!
1行目
2行目
3行目
4行目
5行目
6行目
7行目
8行目
9行目
10行目
ここまで突き破る!!
HTMLコード表示
<div class="oau3-wrapper">
<input type="radio" name="oau3-state" id="oau3-bad" class="oau3-radio" checked>
<input type="radio" name="oau3-state" id="oau3-good" class="oau3-radio">
<div class="oau3-controls">
<label for="oau3-bad" class="oau3-btn">❌ 枠を突き破る</label>
<label for="oau3-good" class="oau3-btn">⭕️ min-height: 0; を追加 (解決)</label>
</div>
<div class="oau3-demo-area">
<div class="oau3-flex-parent">
<div class="oau3-header">固定ヘッダー</div>
<div class="oau3-flex-wrapper target-wrapper-oau3">
<div class="oau3-scroll-content">
<p style="color: #dc3545; font-weight: bold; margin-top: 0;">
↓↓ ここから長文 ↓↓<br>
親の黒い枠は高さ300pxなのに、<br>
中身の長文に押し出されて<br>
枠線を完全に突き破っています!
</p>
<p>1行目</p><p>2行目</p><p>3行目</p><p>4行目</p><p>5行目</p>
<p>6行目</p><p>7行目</p><p>8行目</p><p>9行目</p><p>10行目</p>
<p style="font-weight: bold; color: #dc3545;">ここまで突き破る!!</p>
</div>
</div>
</div>
</div>
</div>CSSコード表示
.oau3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.oau3-radio {
display: none;
}
.oau3-controls {
display: flex;
justify-content: center;
gap: 10px;
margin-bottom: 30px;
flex-wrap: wrap;
}
.oau3-btn {
background-color: #e9ecef;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #495057;
transition: 0.2s;
font-size: 14px;
}
#oau3-bad:checked ~ .oau3-controls [for="oau3-bad"] {
background-color: #dc3545;
color: white;
}
#oau3-good:checked ~ .oau3-controls [for="oau3-good"] {
background-color: #198754;
color: white;
}
.oau3-demo-area {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 30px;
display: flex;
justify-content: center;
}
/* ①大枠(高さ300pxのFlexコンテナ) */
.oau3-flex-parent {
width: 250px;
height: 300px;
background-color: #fff;
border: 3px solid #333;
border-radius: 8px;
display: flex;
flex-direction: column;
}
.oau3-header {
background-color: #333;
color: white;
padding: 15px;
font-weight: bold;
text-align: center;
flex-shrink: 0; /* 潰れないようにする */
}
/* ②中間ラッパー */
.oau3-flex-wrapper {
flex-grow: 1; /* 残りのスペースを埋める */
display: flex;
flex-direction: column;
background-color: #fff3cd;
transition: all 0.3s;
/* ここが min-height: auto(初期値)だと、中身に合わせて無限に伸びて親枠を突き破る */
}
/* ③スクロールさせたいコンテンツ */
.oau3-scroll-content {
flex-grow: 1;
overflow: auto; /* スクロール設定 */
padding: 15px;
box-sizing: border-box;
font-size: 14px;
color: #555;
line-height: 1.5;
}
.oau3-scroll-content p {
margin: 0 0 10px 0;
}
#oau3-good:checked ~ .oau3-demo-area .target-wrapper-oau3 {
min-height: 0;
background-color: #d1e7dd;
}まとめ
分かりやすいようにまとめを記載します。
overflowは箱のサイズをオーバーした中身をどう処理するか決めるプロパティ。visible(初期値)はそのままはみ出す。
下の要素と文字が重なるレイアウト崩れの原因になりやすい。hiddenは、はみ出た部分を切り取る。
親のborder-radiusと合わせて画像を角丸に切り抜く。scrollとautoの違いはスクロールさせたい時、無駄なバーが出るか出ないか- スクロールの作り方はスマホ向けメニューなど
overflow-x: auto;に加え、文字の折り返しを防ぐwhite-space: nowrap;をセットで使う。 - Flexboxの中で枠を突き破ってしまう時は、スクロールさせたい要素に
min-height: 0;を追加する。

