実務でautoを使うプロパティはほぼmargin系のみですが、
autoとはどんな値なのかも含め、主要なプロパティの挙動を解説していきます。
autoとは
autoは何を宣言している?【重要】
- cssの仕様で定義された計算ルールに従い、
- レイアウト計算時に
- ブラウザが値を算出・確定する
という、値の決め方を宣言している。
めっちゃ短くいうと、
auto = 「値を後で決める」という値
autoの本質(共通点)
autoには、どのプロパティに対しても共通点がある。
それは 「最終値が他の値との関係で決まる」 ということ。
・width → 親サイズ・displayの種類に依存
・height → 中身のサイズに依存
・margin → 余り空間のサイズに依存
・flex-basis → 元サイズに依存
全て自分以外の要素が関わっている。
autoが効く条件
autoが効いているとは
→レイアウト計算フェーズにブラウザが参加していること。
もっというと、その上で計算が解決できていること。
「解決」とは
cssにおける解決とは、
レイアウト計算の最終的な結果として、具体的な値を算出できること。
効く条件
-
autoが指定可能なプロパティであること
(つまりautoを指定した時の計算方法がcss仕様上に存在していること) -
計算に必要な材料(数値等)が整っていること。
効かないケースは2種類
1. 解決不能
計算に必要な数値が揃っておらず、
最終値が算出不可。
2. 値 autoが無効なプロパティ
paddingです。
有効にしてしまうと問題があるため、
css仕様上、そもそも指定自体が無効。
【例外】 効いてはいるけど見た目に現れない
auto指定前、指定後でプロパティの値が変わらない場合は
見た目には影響しない。(効いてはいる)
ここまでのまとめ
autoは指定可能なプロパティ・不可能なプロパティが存在している。
そして指定可能なプロパティには、
autoを指定した場合の計算方法(振る舞い)が個別に指定されている。
つまり開発でautoを使いこなすには、
autoを指定できる主要なプロパティとその振る舞いを抑えておけばいい。
ということで、以下に参ります。
余白系 - margin
余白系プロパティでautoが使用できるのはmargin系のみ。
そして大前提としてmargin各種の初期値は0。
たまにUA(ブラウザ)が勝手に上書きしてる場合がある。
margin: 0;
そもそもmarginとは?
- 値で指定した分の距離(px,em,auto等)を
- 余白(他要素との間隔として)
- 可能な限り
- 確保しようとする プロパティ
autoと交えて解説すると、
- 自身と周囲との距離を指定するプロパティであり、
- 固定値の場合はその距離を、
- autoの場合は利用可能な余剰空間を距離として分配する。
- つまり余剰分がなければ効かない。
通常フローでのmarginの振る舞い
今回はflexboxやgrid指定時の挙動は省きます。
詳しい解説はflexbox時に取り扱います。
横方向 - ブロック要素
ブロック要素における横方向のmargin指定は、
親要素のサイズが確定・解決されていてかつ余剰空間がある場合有効。
両側auto
{ margin: 0 auto; }
左右の余剰空間を均等に確保しようとするため、
結果的に中央寄せになる。
片側auto
margin-left: auto;
margin-rightは未指定のため値が0となる。
左側余剰だけ余剰空間を可能な限り確保しようとするため、
結果的に右寄せになる。
横方向 - インライン要素・インラインブロック要素
余剰空間のオペレーション権限がmarginに無いため、未解決。
通常フローでは意味なし。
縦方向 - ブロック要素・他
横marginでは余剰空間の分配をしていましたが、
縦marginでは要素同士の距離指定となります。
ただしこれはmargin自体の仕様差ではなく、
ブロックレイアウトの性質によるものです。
1. 数値を指定した場合
.box {
margin-top: 30px;
margin-bottom: 20px;
}
親の高さ・余剰空間とは無関係に、指定量の距離が現れます。
autoを指定した場合
通常フローでは、縦方向のmarginは解決不可のため
結果として0と同じ扱いになります。
理由:
通常フローでは各要素の高さは中身の高さに従って決まり、
親要素の高さは子要素を積み上げた結果として最終的に算出される。
そのためレイアウト計算の時点で「余剰スペース」という計算材料が存在せず、
縦方向のmarginは解決不能となる。
インライン要素、インラインブロック要素も似たような理由により未解決となり、
autoが無意味になるため説明は省略します。
margin collapse(マージン相殺)
隣接するブロック要素の縦方向marginの値が足し算できず、
ひとつの距離として扱われる仕様。
.box1 { margin-bottom: 40px;}
.box2 { margin-top: 20px;}
この場合二つの縦間隔は、
40 + 20 = 60pxではなく、
大きい方が採用されるため、40pxとなる。
※親子同士でも条件を満たしてしまうと
margin collapseが発動してしまう場合があるので注意。
サイズ系
width/heightについては、値が未指定の場合
そもそも初期値がautoのため、意味がありません。
そのため、autoによる振る舞いというよりも
それぞれの要素が初期状態でどのような振るまいをするかを抑えれば十分です。
width: auto
大前提として、ブロック・インライン・インラインブロック要素の
widthの初期値は「auto」であり、レイアウト計算にも参加します。
そのためわざわざ宣言する必要はありません。
ブロック要素の場合
div {
width: auto;
}
振る舞い:親のコンテンツ幅いっぱいに広がる。
解決される条件:親要素の幅が定義済かつ解決済
使い方:実務ではあまり使用しない
→まあつまり、未指定の振る舞いとほぼ一緒。
インライン要素の場合
インライン要素に対するwidth指定はcss仕様上許されてはいるものの、
インライン要素自体が中身にしたがってサイズを決定するという性質上、
widthがレイアウト計算に参加しない。
つまり:
そもそもwidth自体が無意味なプロパティなので、
autoもまた無意味。
インラインブロック要素の場合
インライン要素とは違い、値の解決はされるものの
未指定・auto指定で挙動が同じなためほぼ無意味。
height: auto
こちらも各要素初期状態でautoです。
詳しくはデフォルトサイジングをご覧ください。
max-width, min-height等
.box {
max-width: auto;
max-height: auto;
min-width: auto;
min-height: auto;
}
これらは要素の大きさの最小値・最大値を指定するもので、
auto指定すると単に「上限・下限を設けない」という意味になり、
結果的に無意味に等しい。
position系
position系のautoは位置を計算する値ではなく、
その方向の拘束に参加しないことを示す値。
噛み砕いていうと:
自身(autoが指定されたプロパティ)が
レイアウト計算の材料から外れることを宣言する値。
position系でautoが使えるプロパティ
top:
bottom:
left:
right:
inset:
そしてこれら全ての初期値は autoです。
まとめ
position系でautoが指定できるプロパティはそもそも初期値がautoのため、
詳しい挙動を知りたい場合は
「各positionを指定した際の挙動」を理解すればいい。
未指定とautoの違い
初期値がautoのプロパティでは、未指定 = autoとなる。
初期値がauto以外の場合は挙動が異なる場合がある。