寄せ・割り付け
何らかの仮想的な箱の中での位置決めの話になる。
一般的には、上下と左右の位置決めがあり、それぞれが3通りで、組み合わせて9通りになる。
上寄せ
上下中央寄せ
下寄せ
左寄せ
左右中央寄せ
右寄せ
ただし、これはとても大雑把な概念で、実情とあまり合っていない。
そのほかに「両端揃え」「均等割り(均等割り付け)」と呼ばれる物もある。
書字方向(左から右、右から左、上から下)にも依存していることに注意。
上下左右中央寄せを英語で明確に表記する標準的な方法がない。
中央寄せ Centering (抽象的な呼び方)
上下中央寄せ Vertically centering
左右中央寄せ Horizontally centering
上下左右中央寄せ vertically/horizontally centering (むりやり書くとこうなるらしい)
難しくなる原因
そもそも、簡潔な指定方法が根本的に存在しない。(直感的ではない。)
複数の機能を組み合わせてようやく実現できる。
現状のCSSとHTMLのレイアウトの仕組みが人間の一般的な理解と乖離している。
なぜこんなに難しくなっている?
HTML のレイアウトシステムの基本が自動流し込み方式(いわゆる文章が左から右、改行を挟んで上から下に自動的に並ぶ)であり、本来図形的に処理したい物もその影響を受けてしまっているため。
幅は外側の要素が基準(トップダウン)となり、高さは内側の要素が基準(ボトムアップ)となってしまう。(トップダウンとボトムアップが混在状態)
人間が見た時には1つ(1行)のつもりだが、HTMLレイアウタから見た場合は任意行の中の1行。
どちらにどう指定するのかが混乱しやすい。
コンテナ側 (表示したい物が入る、入れ物)
コンテンツ側 (入れ物の中に入る物で、本当に表示したい物)
人間の直感的な考え方では、コンテンツ側に指定をすると思いがちだが、コンテナ側に指定しなければならないことがある。
場合によっては二段にしなければ機能しないようなケースがある。(table と table-cell など)
揃えたい要素がどれなのかで指定方法が異なる。また揃えたい内容によっては display 属性で要素を切り換える必要がある。
ブロック要素
インライン要素
インラインブロック要素
HTML5以降は「ブロック要素」「インライン要素」という概念がなくなっているとのことだが、実際には複雑度が増しただけで基本的な理解としては必要。
インラインブロック要素とインライン要素の違い
インライン要素は一般に連続した複数の要素(文字と同等に扱われる。)
インラインブロック要素は一般にそれ単体でレイアウトに使われる。(インライン要素の一部になるなら、インライン要素と同等)
どちらの幅や高さが有効になるのかが混乱しやすい。
margin-left, margin-right を auto にする方法が知られているが、その場合は内側の要素のサイズが先に固定されなければならない。
コンテンツを position: absolute にすると、幅、高さの計算からは除外される。このため、コンテナで幅や高さ無指定だと、コンテナの幅や高さが0になったりする。
マージン、パディングで代用する方法は、本来の意味で使いたい時に困る。
grid, flexbox でも実際には思い通りにならない。
grid は分割してからしか使えない。(昔の table レイアウトに近い)
flexbox は複数のアイテムを1次元で折り返しながら並べるような時に使うもので、画面のレイアウトには余り適さない。
画面のレイアウトにも使えないことはないという程度のもの。
1つのものを中央に置くのは例外的にできるという話。
複数の寄せを同じ場所でやりたいような場合、要素を重ねてしまう方がたぶん楽
(例えば、右寄せ、中央寄せ、左寄せを同時にやりたいようなケース)
ベースとなる div で position:relative を指定。
重ねる div で position: absolute を指定。
うまく行かないケース
座標値を直接設定してしまう。(初心者がやりがち)
画面サイズを変えると簡単に破綻する。
結局、どうするのが簡単なのか?
まず、揃えたい要素を1つのブロックまたはインラインブロックにする。
そのブロックが外側のブロック内でどの位置に揃うかを決める。
インラインブロックの場合
position: absolute で指定する方法
左寄せ
code:css
position: absolute;
left: 10px;
}
位置を合わせるのが単品の場合
位置を合わせるのが複数の場合
部品Aは左寄せ、部品Bは中央寄せ、部品Cは右寄せ、という指定がしたい場合がある。単品の位置合わせ(たいていコンテナ側への設定)はこの時には上手く機能しない。
参考
CSS で寄せ・割り付けを直接規定しているのは以下の属性
text-align
横方向(書字方向)の指定
text-align-last
行の最後のみの特殊指定
justify (均等割り付け)だけど最後だけ右寄せあるいは中央寄せのようなことができる。
vertical-align
縦方向(書字の改行方向)の指定
top, bottom, left, right (起点がどこからかを指定する。)
justify-content (flexbox, glid)
align-content (flexbox)(複数行の並び方)
align-items (flexbox)(1行の中で主軸に垂直な方向での位置)
間接的に規定しているのは以下の属性
margin
margin-left: auto, margin-right: 0 とすると結果的に右寄せになる。
padding
width (左右の部品のサイズを指定する)
height (上下の部品のサイズを指定する)
display: table-cell;
vertical-align について
vertical-align は、一見すると単純な上下位置指定に見えて、vertical-align: middle で中央寄せになるのではと期待させるがそうならない。
vertical-align: middle は現在の行のベースラインに並んでしまう。
実質的に行内で最も大きなフォントのベースラインに並ぶ。
コンテナに display: table-cell を使った場合どうなるのか?
コンテナの幅がコンテンツの幅になってしまう。width: 100% (相対指定)が効かない。
margin について
margin:
標準的な方法を書く
寄せや割り付けをする前に、そもそもそのためのボックスができていなければならない。(ここが重要)
テキストのみ。単品。
右寄せ
code:css
text-align: right;
}
均等割り
code:css
text-align: justify;
text-justify: inter-ideograph;
}
上下中央寄せ
コンテナを display: table-cell として、vertical-align: middle でコンテンツを中央に寄せる。
code:css
display: table;
width: 100%;
}
display: table-cell;
vertical-align: middle;
}
display: table-cell は高さを必ず内側から取るようになる。
このため、height: 100% は機能しない。
ボタンや入力ボックスの右寄せ
code:html
<div>
<button type="button" id="hello" name="hello">Hello</button>
</div>
インライン要素なら、コンテナ側に text-align: right で右寄せできる。
ChatGPT に言わせると、もう calc 使えという御宣託。(合っているかどうか怪しい)
code:css
.target {
margin: 5px
width: calc(100% - 10px)
height: calc(100% - 10px)
}
参考