overflow: hiddenを指定したのに、画像や子要素が枠からはみ出したままになる。CSSではよくある問題ですが、原因の多くはoverflow自体ではなく、サイズ・表示形式・配置基準・FlexboxやGridの最小サイズにあります。
この記事では、overflow: hiddenが効かないように見える代表的な原因を5つに分け、確認方法と修正例を紹介します。カード画像、角丸、横スクロール、絶対配置の装飾などにも応用できます。
overflow:hiddenの基本
overflowは、内容が要素のpadding boxからはみ出した時の扱いを指定するプロパティです。hiddenでは、はみ出した内容をpadding boxの境界で切り取ります。スクロールバーは表示されませんが、要素はスクロールコンテナになります。
.frame {
width: 320px;
height: 180px;
overflow: hidden;
}
.frame img {
width: 120%;
}
重要なのは、切り取る基準となるボックスが存在することです。縦方向ならheightやmax-height、横方向ならwidthやmax-widthなど、はみ出しを判断できる制約が必要です。
原因1:親要素の幅や高さが決まっていない
親要素のサイズが内容に合わせて広がっている場合、内容は親の外へはみ出していません。はみ出しが存在しないため、overflow: hiddenで切り取るものもありません。
/* 内容に合わせて高さが広がる */
.box {
overflow: hidden;
}
/* 高さの上限を決める */
.box {
max-height: 240px;
overflow: hidden;
}
画像のトリミングなら、固定の高さよりaspect-ratioを使うとレスポンシブに管理しやすくなります。
.thumbnail {
width: 100%;
aspect-ratio: 16 / 9;
overflow: hidden;
}
.thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
}
原因2:overflowを指定する要素が違う
overflow: hiddenが切り取るのは、その要素の子孫です。はみ出している要素と親子関係にない要素へ指定しても効きません。また、角丸の内側で画像を切りたい場合は、角丸とoverflowを同じラッパーへ指定するのが確実です。
<figure class="card-media">
<img src="photo.jpg" alt="写真の説明">
</figure>
.card-media {
overflow: hidden;
border-radius: 20px;
}
.card-media img {
display: block;
width: 100%;
transition: transform .3s ease;
}
.card-media:hover img {
transform: scale(1.08);
}
DevToolsで対象要素を選択し、はみ出している要素の直接の祖先をたどってください。切り取りたい境界を持つ要素へoverflowを指定します。
原因3:通常のinline要素へ指定している
overflowは主にブロックコンテナ、Flexコンテナ、Gridコンテナへ適用されます。通常のspanなど、非置換inline要素へ幅・高さとoverflowを指定しても期待どおり動きません。
/* 幅や高さが効かず、切り取り領域を作れない */
.label {
width: 120px;
overflow: hidden;
}
/* ボックスを作る */
.label {
display: inline-block;
width: 120px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
1行テキストを省略する場合は、overflow: hiddenだけでなく、white-space: nowrapとtext-overflow: ellipsisも組み合わせます。
原因4:Flexbox・Gridの子要素が縮まない
FlexboxやGridでは、子要素の初期最小サイズによって長いURL、コード、画像などがカラムを押し広げることがあります。この場合、内側へoverflowを指定しても、その親のFlex/Gridアイテム自体が縮まないため、ページ全体が横へはみ出します。
<div class="layout">
<main class="content">長いURLやコード...</main>
<aside class="sidebar">サイドバー</aside>
</div>
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 280px;
gap: 32px;
}
.content {
min-width: 0;
overflow: hidden;
}
Flexboxでも同様に、縮ませたいFlexアイテムへmin-width: 0を指定します。Gridでは列を1frではなくminmax(0, 1fr)にすると、内容の最小幅による押し広げを防ぎやすくなります。
.flex-item {
min-width: 0;
}
.long-url {
overflow-wrap: anywhere;
}
原因5:position:fixedの要素を切ろうとしている
position: fixedの要素は、通常はviewportを基準に配置されます。そのため、親要素のoverflow: hiddenでは切り取られない場合があります。モーダル、追従ボタン、装飾要素で起こりやすい状態です。
.parent {
overflow: hidden;
}
.child {
position: fixed;
right: -20px;
/* 通常はviewport基準なので親の切り取りから外れる */
}
親の内側だけで配置したい要素なら、position: absoluteへ変更し、親へposition: relativeを指定します。
.parent {
position: relative;
overflow: hidden;
}
.child {
position: absolute;
right: -20px;
}
本当に画面へ固定する必要がある要素なら、親で切り取る設計そのものを見直します。transformなどによってfixed要素の包含ブロックが変わる場合もあるため、祖先要素の指定も確認してください。
overflow:hiddenとoverflow:clipの違い
hiddenは見た目上スクロールバーを出しませんが、プログラムやフォーカス移動によって内部をスクロールできるスクロールコンテナです。一方、clipはプログラムによるスクロールもできず、単純に切り取ります。
.decoration-wrapper {
overflow: clip;
}
.scrollable-panel {
overflow: auto;
}
横方向だけページのはみ出しを止めたい目的で、body { overflow-x: hidden; }を付けると原因を隠してしまうことがあります。まず、どの要素が横幅を押し広げているか特定してください。単純な装飾の切り取りならoverflow-x: clipも選択肢です。
CodePen
最短で原因を見つけるチェックリスト
- 親要素にwidth、height、max-width、max-heightなどの制約があるか
- overflowを切り取りたい子要素の祖先へ指定しているか
- 対象が通常のinline要素になっていないか
- Flex/Gridアイテムへmin-width: 0が必要ではないか
- Gridの列をminmax(0, 1fr)にする必要がないか
- はみ出している要素がposition: fixedではないか
- 長いURLやコードにはoverflow-wrapが必要ではないか
よくある失敗
- bodyへoverflow-x:hiddenを付けて終わる:横にはみ出した原因を隠すだけで、レイアウトの問題が残ります。
- 画像へoverflowを付ける:画像を切り取る場合は、通常は画像を包む要素へ指定します。
- 高さを固定して本文を切る:重要な文章や操作要素が見えなくなる可能性があります。
- スクロール領域の操作性を確認しない:
overflow: autoを使う場合はキーボード操作や領域名も検討します。 - hiddenとclipを同じだと考える:スクロールコンテナになるか、プログラムでスクロールできるかが異なります。
まとめ
overflow: hiddenが効かない時は、プロパティを増やす前に、切り取り領域となる親のサイズと、はみ出している要素との親子関係を確認します。次にdisplay、Flex/Gridの最小サイズ、positionを調べると原因を絞り込めます。
特に実務で多いのは、親のサイズが未確定、Flex/Gridアイテムにmin-width: 0がない、fixed要素を親で切ろうとしているケースです。横はみ出しをbodyで隠す前に、DevToolsで原因要素を特定してください。


