CSSのプロパティ値「auto」を使ったテクニックのまとめ、マージンやサイズや配置やFlexboxなど

CSSの「auto」は非常に便利な値で、マージンやサイズ(width, height)や配置などのプロパティに使用することができます。「auto」がどのように機能するのか、「auto」を活用したテクニックを紹介します。

自動マージン、autoを使った要素のサイズ指定、中央配置に使用するautoの仕組み、FlexboxやGridで知っておくと便利なautoの使い方、overflowにおけるautoなど、実用的なテクニックが満載です。

CSSのプロパティ値「auto」を使ったテクニックのまとめ

Everything About Auto in CSS
by Ahmad Shadeed

はじめに

autoの使い方はCSSのプロパティによって異なります。
この記事ではそれぞれのプロパティのコンテキストで値を解説します。

widthプロパティにおけるauto

<div>や<p>などのブロックレベルの要素のwidthの初期値はautoです。そのため、要素を含むブロックは水平方向のスペース全体を占めます。

CSSの仕様によると、下記の通りです。

margin-left + border-left-width + padding-left + width + padding-right + border-right-width + margin-right = 包含ブロックの幅

要素のwidthの値にautoを定義した場合、親要素よりも大きくなることなく、margin, padding, borderを持つことができます。つまり、width: auto;を適用したコンテンツボックスの幅は、margin, padding, borderを差し引いたコンテンツそのものになります。

width: auto;とwidth: 100%;の違い

width: auto;とwidth: 100%;の違い

コードで見てましょう。

.itemにwidthを定義していませんが、問題ありません。div要素のwidthの初期値はautoなので、.itemは親の中に収まっています。

div要素のwidthの初期値はauto

.itemのwidthを初期値のautoではなく、100%に変更するとどうなるでしょうか? 親の100%に加えて、左右にmarginを加えた値になります。

.itemのwidthを100%にした場合

.itemのwidthを100%にした場合

.itemの幅は568pxで、計算式は下記のようになります。

border-left-width + padding-left + width + padding-right + border-right-width = アイテムの幅
15 + 16 + 506 + 16 + 15 = 568px

方向がltrの場合は、margin-rightは完全に無視されます。ただし、レイアウトがrtlの場合はmargin-leftが無視されます。

サイトのキャプチャ

レイアウトがrtlの場合

width:auto; の使いどころ

基本的なことを説明しただけではコンセプトを理解するのに十分ではないので、width: auto;の具体的な使用例を紹介します。

スマホとデスクトップで異なる幅のボタン

スマホとデスクトップでボタンの幅を変える

スマホとデスクトップでボタンの幅を変える

2つのボタンがあり、スマホでは横並び(親の50%)に、デスクトップでは親の幅いっぱいに配置するためにはどうすればよいでしょうか?

まずは、スマホ用のCSSはFlexboxを仕様して、ボタンを横並びに配置します。

デスクトップでは幅をいっぱいにする必要があります。width: 100%;を定義したくなるかもしれませんが、もっとよい解決策があります。

これで、.group__itemはブロック要素になるため、width: auto;を定義すると、親の使用可能なスペースを適切に占めます。

heightプロパティにおけるauto

heightプロパティにおけるautoは、widthは少々異なります。要素の高さは初期値はautoであるコンテンツと同じです。

実際の例を見てましょう。

.itemをコンテナの高さいっぱいにする方法は、2つあります。

  1. .wrapperに固定値の高さを与え、.item要素にheight: 100%;を定義する。
  2. .wrapperにFlexboxを定義すると、Flexアイテムの.itemは伸縮する。

子要素を親の高さいっぱいにする

子要素を親の高さいっぱいにする

marginプロパティにおけるauto

marginの場合、幅が分かっている要素を水平方向の中央に配置するために使用するのが一般的な使用例です。

実際の例を見てましょう。

子要素を水平方向の中央に配置したい

子要素を水平方向の中央に配置したい

ブルーの矩形を水平方向の中央に配置するためには、下記のように記述します。

CSSの仕様によると

margin-leftとmargin-rightの両方がautoの場合、適用される値は等しくなります。そのため、要素を含むブロックの端を基準にして要素を水平方向の中央に配置します。

子要素を水平方向の中央に配置

両方をautoにすると、適用される値は等しくなる

絶対配置された要素におけるmarginのauto

子要素を中央に配置

子要素を中央に配置

絶対配置された要素を中央に配置するためのもう一つの使用例は、marign: auto;です。親要素に対して水平・垂直方向の中央に配置したい要素がある場合は、translateXやtranslateYを使用したくなるかもしれません。

これが機能するためには、次の2つが必要です。

  1. widthとheightが固定値であること。
  2. 子要素がposition: absolute;になっていること。

Flexboxにおけるauto

Flexboxで自動マージン(marign: auto;)を使用すると、いくつかのケースで非常に便利です。子アイテムに自動マージンを与えると、その子アイテムは反対側にプッシュされます。例えば、Flexアイテムにmargin-left: auto;を与えると、右寄せになります。

実際の例を見てましょう。
親がFlexコンテナで、子のFlexアイテムが2つあります。

子のFlexアイテムが2つある

子のFlexアイテムが2つある

2の子要素(.item-2)を右寄せにしたい場合、margin-left: auto;を使用します。

2の子要素を右寄せに配置

2の子要素を右寄せに配置

プッシュする方向は水平だけでなく、垂直方向にも機能します。
今後は、margin-top: auto;を与えてみます。

margin-top: auto;は下寄せに配置される

margin-top: auto;は下寄せに配置される

子要素が1つしかない場合であれば、margin: auto;だけで水平と垂直方向の中央に配置できます。

水平と垂直方向の中央に配置

水平と垂直方向の中央に配置

Flexboxのプロパティにおけるauto

Flexboxでは子アイテムにflex: auto;を使用できます。これはどういう意味でしょうか?

子アイテムにflex: auto;を定義した場合、flex: 1 1 autoと同等で、つまり下記と同じになります。

MDNによると、

アイテムはwidthとheightプロパティに応じてサイズが調整されますが、Flexコンテナ内の余分な空きスペースを吸収するために大きくなり、コンテナに合うように最小サイズに縮小されます。flex: 1 1 auto;を定義するのと同等です。

flex: auto;のアイテムは、幅と高さに基づいてサイズが調整されますが、使用可能なスペースに応じて拡大または縮小されます。

1のアイテムにflex: auto;を定義した場合

2と3は幅120pxで、1は使用可能スペースを占める

Gridにおけるauto

Gridのカラムにautoを定義

Gridのカラムにautoを定義

Gridのカラムにautoを定義

CSS Gridではカラムの幅をautoにすると、コンテンツの量に応じた幅になります。

Gridと自動マージン

CSS Gridを使用した場合、自動マージン(margin: auto;)を使用することでFlexboxと同様の結果を得ることができます。例えば、Gridで実装したコンポーネントがあり、Gridアイテムにmargin-left: auto;を与えると、右にプッシュされ、その幅はコンテンツの長さに基づきます。

Gridで実装したコンポーネント

Gridで実装したコンポーネント

Item1の幅はグリッドの領域ではなく、コンテンツにも基づいた幅にしたい場合は、margin-left: auto; を与えることで実現できます。

Item1は右寄せに配置される

Item1は右寄せに配置される

右から左へのレイアウト

margin-left: auto;やmargin-right: auto;の使用は、日本語や英語のように左から右へのレイアウトに最適です。ただし、多言語サイトの場合はこれらの値を反対するように注意してください。さらに、FlexboxやGridのプロパティも使用することをお勧めします。そうでない場合は、自動マージンを最後の手段として使用し、その代わりにCSSの論理プロパティを使用してください。
参考: 知っておくと便利な論理プロパティ、ボックスモデルにおける古い方法とこれからの方法

overflowプロパティにおけるauto

要素を実装する場合、その中のコンテンツ量の最小と最大を考える必要があります。コンテンツ量が最大になった場合は、スクロールバーが必要になるかもしれません。

その場合、下記のCSSを使用したくなるかもしれません。

しかし、このCSSではコンテンツ量が最小の場合でもブラウザによってスクロールバーが表示されてしまいます。

要素にoverflow-y: scroll;を定義

要素にoverflow-y: scroll;を定義

WindowsのChromeでは、スクロールバーは常に表示されます。これは期待されない、紛らわしい挙動です。

その代わりに、autoを使用することで、コンテンツの高さがコンテナよりも大きくない限り、スクロールバーが表示されないようにすることができます。

ユーザーエージェントに依存します。コンテンツがpaddingボックス内に収まる場合、それは可視されているように見えますが、新しいブロックフォーマットのコンテキストは確率されています。コンテンツがオーバーフローした場合、デスクトップブラウザはスクロールバーを提供します。
参考: MDN

配置プロパティにおけるauto

CSSの配置プロパティ、top, right, bottom, leftでは、値にキーワードのautoを使用できます。

padding付きの親要素に、絶対配置された子要素

padding付きの親要素に、絶対配置された子要素

padding付きの親要素があり、その中に子アイテムがあります。子アイテムは絶対配置されていますが、配置場所を定義するプロパティはありません。

CSSでは各プロパティに初期値があります。子アイテムをデベロッパーツールで調べた場合、leftプロパティの値は何になると思いますか?

子アイテムをデベロッパーツールで調査

子アイテムをデベロッパーツールで調査

leftの値は16pxになっていました! 定義していないのになぜそうなってしまったのでしょうか? 理由は絶対配置された要素は、position: relative;で最も近い親に対して相対的になるからです。親にはpadding: 16px;が定義されているので、子要素は上左から16pxに配置されます。面白いですよね。

何のメリットがあるのか疑問に思うかもしれません。話を進めましょう。

ビューポートが小さなサイズのスマホで、子アイテムを左から100pxに配置する必要があるとします。デスクトップではデフォルトの位置に配置されます。

ビューポートが大きなサイズのデスクトップでleftをリセットするにはどうすればよいでしょうか? left: 0;は子が左端にくっつくため、使用できません。

left: 0;だと、左端にくっつくからダメ

left: 0;だと、左端にくっつくからダメ

子アイテムをリセットするための正しい方法は、left: auto;を使用することです。MDNによると、

静的な要素の場合、要素は水平方向に配置されるべき場所に配置される。

つまり、この場合はpaddingが尊重され、子アイテムを親アイテムの端にくっつけないということです。

topプロパティについても同じことが当てはまります。rightとbottomプロパティについては、デフォルトの計算値は要素の幅と高さにそれぞれ等しくなります。

autoを使った使用例

autoを使った使用例をいくつか紹介します。お役に立てれば幸いです。

ツールチップの矢印

ツールチップには、ユーザーに分かりやすくするために矢印が必要です。デザインシステムの場合は、複数の状態を考慮する必要があります。
例えば、ツールチップに左と右向きの2種類の矢印が必要になる場合があります。

左向きと右向きの矢印があるツールチップ

左と右向きの矢印があるツールチップ

left: -15px;をleft: auto;で上書きしていることに注目です。間違いではありませんが、代わりに下記のようにすることをお勧めします。

100%にすることで、矢印のサイズを変更すると失敗する可能性のあるハードコードされた値(矢印の幅)の使用を回避しました。これはより多くの可能性に対応できる解決策です。

カードのコンポーネント

カードがあり、左上にアイコンがある場合、そのアイコンが装飾目的またはアクションのどちらでもよいですが、逆方向にも配置される場合があるとします。

アイコンが配置されたカード

アイコンが配置されたカード

left: auto;でベースとなる実装をリセットし、right: 15px;で右に配置します。

Flexboxと自動マージン

Flexboxに関しては、可能性は無限大です。自動マージンと組み合わせることで、パワフルなレイアウトを構築することができます。

Flexboxと自動マージンで右寄せに配置

Flexboxと自動マージンで右寄せに配置

タイトル、テキスト、アクションボタンを含む行があります。アクションボタンを右寄せに配置したい場合は、自動マージンで簡単に実装できます。

これで完成です!
margin-left: auto;を使用することで、アクションボタンが自動マージンで右端に押し出されます。また、多言語サイト(左右ではなく、右左のレイアウト)の場合でも、CSSの論理プロパティで対応できます。

CSS Gridと自動マージン

Gridアイテムにマージンを追加する場合は、固定値・%・autoのいずれかになります。この記事では、autoに注目してみます。

CSS Gridと自動マージン

CSS Gridと自動マージン

ラベルを右揃え(入力欄の左端)に合わせたい場合は、下記のように記述します。

自動マージンで、ラベルを右揃えに

自動マージンで、ラベルを右揃えに

モーダルと自動マージン

コンテンツ量が多いモーダル

コンテンツ量が多いモーダル

モーダルウインドウを実装する時には、コンテンツ量が多い場合にどうなるかを考慮しておくことが重要です。

これだけで、コンテンツの高さがスクリーンサイズより大きい場合にのみスクロールバーが表示されます。

リソース

これで終わりです。
コメントや提案があれば、@shadeed9までお願いします。

sponsors

top of page

©2020 coliss