min-heightとmin-widthの正しい使い方|IE終了後の現代CSS

天才エンジニアあらわる!

「ボックスの高さを最低でもこれだけ確保したい」「狭い画面でも要素がつぶれない下限を決めたい」。レイアウトを組んでいると、こういう“最小サイズ”の指定はしょっちゅう出てきます。それを担うのが min-heightmin-width の2つです。

ところが昔は、この当たり前の指定が当たり前に効きませんでした。原因はもちろん、長らくWeb制作者を悩ませ続けたあのブラウザ、Internet Explorerです。私もIE6が現役だった時代、min-height を効かせるためだけにCSSハックや条件分岐コメントを書き、検証用の古いWindowsを起動しては小さなズレと格闘していました。Web制作歴25年のなかでも、思い出したくない手間の代表格です。

でも、その苦労はもう過去のものです。Internet ExplorerはMicrosoftのサポートが2022年6月15日に終了し、いまや min-height・min-width はハックなしで素直に書けばどのモダンブラウザでも普通に効きます。この記事では、2つのプロパティの意味と使いどころを整理したうえで、max系プロパティとの組み合わせ、フレックスボックスやグリッドで初心者がつまずく min-width:0 問題、そして clamp() など現代の関数まで、いま知っておけば困らない知識を一本にまとめます。

対象は初心者〜中級者の方。かつてのIEハックは「もう書かなくていいもの」として歴史の整理から入り、これからの正しい書き方に乗り換えていきましょう。

min-heightとmin-widthとは何か

min-height は要素の高さの下限、min-width は幅の下限を決めるプロパティです。「これ以上は小さくならない」という床(フロア)を設定するもの、と考えるとイメージしやすいと思います。

たとえば min-height:100px を指定した要素は、中身が少なくても高さ100pxを保ちます。逆に中身が増えれば100pxを超えてどんどん伸びていきます。あくまで“下限の保証”であって、固定値ではないのがポイントです。

.box {
  min-height: 100px; /* 中身が少なくても高さ100pxは確保 */
}

.card {
  min-width: 240px;  /* 幅はどんなに狭くても240pxまで */
}

両プロパティの初期値は auto です。通常のブロック要素やインラインブロック要素では auto は実質 0 として扱われるため、何も指定しなければ下限はありません。値には pxrem などの長さ、%(親要素基準)のほか、min-contentmax-contentfit-content といったキーワードも使えます。

なお min-heightmin-width は、表示崩れの心配なく使える「広く利用可能(Baseline widely available)」なプロパティです。MDNによれば2015年7月時点で主要ブラウザに広く実装済みで、今となっては安心して使える土台になっています。

出典:MDN Web Docs: min-heightMDN Web Docs: min-width

かつてIEで苦労した経緯と、今それが不要になった理由

この記事はもともと、「IE6で min-height が効かない問題」をハックで回避するTipsでした。当時よく使われたのが、次のような書き方です。

/* かつてのIE6向けハック(今は不要) */
.foo {
  min-height: 100px;
  height: auto !important;
  height: 100px;
}

IE6は !important を正しく解釈せず、さらにコンテンツ量に合わせてボックスが広がる独自の挙動を持っていました。その2つを逆手に取って、結果的に min-height っぽく見せる、というかなり力技のテクニックです。動きはしましたが、仕様に沿った素直なコードではありませんでした。

そして時代は変わりました。Internet Explorer 11のデスクトップアプリは2022年6月15日にサポートが終了し、IEはもう「対応すべきブラウザ」ではなくなりました。Microsoft自身も、後継のMicrosoft Edge(IEモードでの互換維持を含む)への移行を案内しています。

つまり、上のようなハックを書く理由はもう存在しません。今は min-height:100px と一行書けば、Chrome・Edge・Firefox・Safariのいずれでもそのとおりに効きます。古い回避策をコピペし続けると、かえってコードが読みにくくなるだけ。見つけたら消してしまって構いません。

出典:Microsoft Learn: Lifecycle FAQ – Internet Explorer and Microsoft Edge

関連記事:CSSハックとは?今はもう不要?IE終了後のモダンなブラウザ差異対処法

min/maxとwidth/heightの関係を整理する

最小サイズを正しく扱うには、widthheight(基準値)と min-*(下限)、max-*(上限)の3者の関係を押さえておくと迷いません。結論を先に言うと、min系は最後に勝ちます。

具体的には、min-heightheightmax-height より大きい場合、要素の高さは min-height の値になります。幅も同様で、min-widthwidthmax-width を上回れば、最終的な幅は min-width が決めます。下限は“何があっても守られる”わけです。

min-widthとmax-widthを組み合わせる

実務でよく使うのが、コンテンツ幅に下限と上限の両方を与えるパターンです。次のように書くと、画面が広いときは最大960px、狭いときは親の90%、ただし最低でも320pxは確保、という伸縮するボックスになります。

.container {
  width: 90%;
  min-width: 320px; /* これ以上は縮まない */
  max-width: 960px; /* これ以上は広がらない */
  margin-inline: auto;
}

この3行は、レスポンシブなレイアウトの土台として今でも非常に出番が多い書き方です。width:100%max-width の組み合わせは画像の表示にも応用でき、はみ出しを防ぎながら自然に縮小させられます。

img {
  max-width: 100%;
  height: auto; /* 縦横比を保ったまま縮小 */
}

フレックスボックス・グリッドでの最小サイズ(min-width:0問題)

ここが、現代CSSで初心者がいちばんつまずきやすいポイントです。フレックスアイテムとグリッドアイテムは、初期状態だと「中身より小さくは縮まない」という見えない最小サイズを持っています。

これは min-widthmin-height の初期値 auto の挙動が、通常の要素とフレックス/グリッドアイテムとで違うために起こります。通常要素では auto0 ですが、フレックス/グリッドアイテムでは「自動最小サイズ」として、中身(min-content)に基づく下限が暗黙に設定されるのです。

典型的なのが、長いテキストや折り返さない要素を含むアイテムが、親をはみ出してしまう症状です。「flex:1 を付けたのに想定どおり縮まない」「横スクロールバーが出てしまう」――その多くは、この自動最小サイズが原因です。

解決策はシンプルで、縮ませたいアイテムに min-width:0(縦方向なら min-height:0)を明示します。これで「中身より小さくなってもよい」と許可でき、はみ出しが収まります。

.item {
  flex: 1;
  min-width: 0; /* これでアイテムが中身より縮めるようになる */
}

/* 中の長文を省略表示したいとき */
.item .text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

私自身、カードを横並びにしたレイアウトで原因がわからず小一時間悩んだことがあります。答えを知っていれば一行で済む話なので、「フレックス/グリッドで縮まない=まず min-width:0 を疑う」と覚えておくと、確実に時間を節約できます。

出典:MDN Web Docs: min-width(automatic minimum size of flex/grid items)

clamp()・min()・max()で最小サイズをよりスマートに

下限・上限の指定は、いまや専用のCSS関数でもっと柔軟に書けます。レスポンシブ対応の場面で覚えておきたいのが clamp()min()max() の3つです。これらは2020年7月ごろから主要ブラウザで広く使えるようになっています。

役割を整理すると、max() は「最小値を保証する(下限を作る)」、min() は「最大値を抑える(上限を作る)」、そして clamp() は下限・適正値・上限の3つを一度に指定する関数です。clamp(MIN, VAL, MAX)max(MIN, min(VAL, MAX)) と同じ意味で、下限と上限の両方をたった一行で表現できます。

/* フォントサイズを画面幅に応じて伸縮させつつ、下限1rem・上限2rem */
.title {
  font-size: clamp(1rem, 2.5vw, 2rem);
}

/* 幅は親の90%、ただし最大960px(min()で上限) */
.container {
  width: min(90%, 960px);
}

/* 余白は最低16px、画面が広ければ4vwまで(max()で下限) */
.section {
  padding-inline: max(16px, 4vw);
}

従来 min-widthmax-width を別々に書いていた指定の一部は、clamp()min() でまとめて表現できます。とくにフォントサイズや余白を画面幅にあわせて滑らかに変化させたいとき、メディアクエリを増やさずに済むのが大きな利点です。

ただし、要素そのものの最小・最大の“箱”を決めるなら、引き続き min-widthmax-width プロパティを使うほうが意図が明確です。関数とプロパティは対立するものではなく、用途で使い分けるのがコツだと考えています。

出典:MDN Web Docs: clamp()

関連記事:CSSでフォントサイズの最大値・最小値を指定する方法|clamp(), min(), max()完全解説

関連記事:CSS calc()の使い方と実務例!よくあるレイアウトパターンも紹介

まとめ:min-height・min-widthは、もう素直に書ける

長らくIEのせいで“ひと手間かかるプロパティ”だった min-heightmin-width。その時代はとっくに終わりました。

あらためて要点を整理します。min-heightmin-width は要素サイズの「下限を保証する」プロパティで、中身が増えれば下限を超えて伸びます。widthheightmax-* と競合したときは min系が優先され、下限は必ず守られます。レスポンシブでは min-widthmax-width を組み合わせた伸縮ボックスが今も定番です。

そして現代ならではの注意点が、フレックス/グリッドアイテムの自動最小サイズ。「想定どおり縮まない」「はみ出す」ときは、まず min-width:0(または min-height:0)を疑うのが鉄則です。さらに clamp()min()max() を使えば、下限と上限を一行でまとめて表現でき、メディアクエリに頼りきらない柔らかいレイアウトが組めます。

IEのサポートは2022年6月15日に終了しました。古いCSSハックを見つけたら、思い切って消して、仕様どおりの素直なコードに置き換えてください。コードはシンプルになり、メンテナンスもずっと楽になります。私のように古い回避策と長く付き合ってきた人ほど、この身軽さは実感できるはずです。今日から最小サイズの指定は、迷わず一行で書いていきましょう。