ヒント集のインデックスも見てください.
CSSでよくある作業は、テキストや画像を中央寄せすることです。細かく言うと、3種類の中央寄せがあります:
最近の CSS 実装では、レベル3の機能も使えます。これを使えば、絶対配置された要素を中央寄せさせられます:
もっともよくある、(それゆえに)簡単なタイプの中央寄せは、段落や見出し内のテキスト行の中央寄せです。そのために、CSS には `text-align` プロパティがあります。
P { text-align: center } H2 { text-align: center }
PやH2内の各行をそのマージンの間に中央寄せして描画します。すると、このようになります:
この段落の行は、すべて、段落のマージン間を中央に寄せられます。これは、 `text-align` CSS プロパティに `center` という値が指定されているからです。
中央寄せを必要としているのがテキストではなく、ブロック全体であるということもあります。あるいは、言いかたを変えると: 左側と右側のマージンを等しくしたいのです。これを実現するには、両マージンを `auto` に設定します。 これは、通常固定幅のブロックで使われます、なぜなら、もしブロックそのものが フレキシブルだったら、単に利用可能な幅すべてを埋めてしまうからです。これが例です:
P.blocktext { margin-left: auto; margin-right: auto; width: 8em } ... <P class="blocktext">このやや狭い...
このやや狭いテキストのブロックは、中央寄せされます。 ブロック内の行は、中央寄せされない(左寄せされる)ことに注意してください。これは、前の例とは異なります。
これは、画像を中央寄せする方法でもあります: 画像自身をブロックにし、マージンプロパティを適用します。例えば:
IMG.displayed { display: block; margin-left: auto; margin-right: auto } ... <IMG class="displayed" src="..." alt="...">
次の画像は中央寄せされます:
CSS レベル2には、縦に中央寄せするためのプロパティがありません。CSS レベル3には、おそらく加えられることになるでしょう。(以下を参照) しかし、CSS2においても、いくつかの プロパティを組み合わせれば、ブロックを縦に中央寄せすることは可能です。
以下の例は、ブロック内の段落を中央寄せします。ブロックには、いくらかの高さが与えられています。別ページの例は、ブラウザウィンドウ内で、縦に中央寄せされた段落を表示します、なぜなら、 絶対配置された、ウィンドウと同じ高さを持つブロック内に、段落があるからです。
DIV.container { min-height: 10em; display: table-cell; vertical-align: middle } ... <DIV class="container"> <P>この小さな段落... </DIV>
この小さな段落は縦に中央寄せされます。
CSSレベル3は、ほかの可能性ももたらします。現時点(2014年)で、 ブロックを縦に中央寄せする、絶対配置(これはテキストの重なりを引き起こすかもしれません)を使わない良い方法は、いまだ議論があります。 しかし、もしテキストの重なりがあなたのドキュメントでは問題にならないことがわかっているのであれば、 'transform' プロパティを使って、絶対配置された要素を中央に寄せることができます。例えば:
この段落は縦に中央寄せされる
このようにドキュメントを見せるためには:
<div class=container3> <p>この段落… </div>
スタイルシートをこのようにします:
div.container3 { height: 10em; position: relative } /* 1 */ div.container3 p { margin: 0; position: absolute; /* 2 */ top: 50%; /* 3 */ transform: translate(0, -50%) } /* 4 */
本質的なルールは:
近年(だいたい2015年から)、もうひとつのテクニックが、いくつかの CSS実装で利用可能になりました。'display'プロパティ用の新しい 'flex' キーワードをベースにしたものです。このキーワードは、グラフィカルユーザーインターフェース(GUI)での利用を目的としたものですが、 文書で使っていけない理由はありません。ただし、文書が正しい構造を維持する必要はあります。
この段落は縦に中央寄せされます。
スタイルシートはこのようになります:
div.container5 { height: 10em; display: flex; align-items: center } div.container5 p { margin: 0 }
どちらの方法も、縦と横同時に中央寄せするために拡張することができます。
段落を絶対配置にすることの副作用は、それが必要とするまでしか広がらない ということです(もちろん、明示的に幅を指定していない場合に限ります)。以下の例では、それこそがまさに望むものです: ただひとつの単語 (「中央寄せ!」)を含む段落を中央寄せするので、段落の幅は、ちょうど単語の幅となるべきです。
中央寄せ!
黄色の背景は、段落が実際コンテンツと同じ幅しか持たないことを示すためです。前と同じマークアップを想定します:
<div class=container4> <p>中央寄せ! </div>
スタイルシートは、縦の中央寄せにおいて、前の例と似ています。しかし、今度は、コンテナに対して、 'left: 50%' を使い、 要素を横にも移動させます、そして、同時に自分の幅の半分だけ、 'translate'変換で左側にずらします:
div.container4 { height: 10em; position: relative } div.container4 p { margin: 0; background: yellow; position: absolute; top: 50%; left: 50%; margin-right: -50%; transform: translate(-50%, -50%) }
下のほうにある次の例(「レベル3でビューポート内に中央寄せする」)で、なぜ 'margin-right: -50%' が必要なのかを説明します。
CSSフォーマッタが 'flex' をサポートしているなら、もっと簡単です:
中央寄せ!
このスタイルシートで実現できます:
div.container6 { height: 10em; display: flex; align-items: center; justify-content: center } div.container6 p { margin: 0 }
ここで、追加されたのは、 'justify-content: center' だけです。ちょうど、'align-items' がコンテナ内のコンテンツの垂直位置を決定するように、'justify-content' は、水平位置を決定します。(その名前からもわかるように、実際には、もうすこし複雑ですが、単純なケースではまさにそのとおりなのです。) 'flex' の副作用のひとつは、子要素(この場合 P)が、自動的に、最小化されることです。
絶対配置された要素用のデフォルトコンテナは、ビューポートです。(ブラウザにおいては、ブラウザウィンドウを意味します。) ですから、ビューポート内で要素を中央寄せするのはとても簡単です。これは完全な例です。(例では HTML5 の文法を使います。)
<html> <style> body { background: white } section { background: black; color: white; border-radius: 1em; padding: 1em; position: absolute; top: 50%; left: 50%; margin-right: -50%; transform: translate(-50%, -50%) } </style> <section> <h1>きれいに中央寄せされている</h1> <p>このテキストブロックは縦に中央寄せされる。 <p>ウィンドウ幅が十分なら、横にも。 </section>
別の文書で結果を見られます。
'margin-right: -50%' は、 'left: 50%' を補うために必要です。'left' ルールは、要素が利用可能な幅を 50% 減らします。レンダラーは、それゆえ、行をコンテナ幅の半分より短くしようとします。 要素の右マージンが同じ量だけ右側にずれると宣言することで、最大行長は、ふたたび、コンテナ幅と同じになります。
ウィンドウをリサイズしてみてください: ウィンドウが十分広いときは、 各文が1行に収まることがわかるでしょう。ウィンドウが文全体に対して狭すぎる場合に限り、文は複数行に分割されます。 'margin-right: -50%' を取り除いて、ふたたびウィンドウをリサイズすると、ウィンドウがまだテキスト行の 二倍広いのに、すでに文が分割されていることがわかるでしょう。
(ビューポート内での中央寄せへの 'translate' の利用は、「Charlie」による Stack Overflow での回答 ではじめて提案されました。)