元のアドレス:vertical-Align: 知っておくべきことすべて
要素を垂直方向に整列する必要があることがよくあります。
CSS には、いくつかの可能なメソッドが用意されています。場合によっては float を使用して解決したり、position:Absolute; を使用したりすることもありますが、嫌なことにマージンとパディングを手動で追加しなければならない場合もあります。
私はこれらの解決策があまり好きではありません。フロートは上部にのみ整列できるため、手動でクリアする必要があります。絶対配置では、ドキュメント フローから要素が削除されるため、要素は含まれているブロックを引き伸ばす (影響を与える) ことがなくなります。固定マージンとパディングを使用すると、小さな変更によって簡単に壊れてしまいます。
しかし、ここに別の方法があります。vertical-align です。これはもっと評価されるべきだと思います。技術的に言えば、垂直方向の配置をレイアウトに使用することはハックです。なぜなら、垂直方向の配置はこのような理由で発明されたものではないからです。テキストとその隣の要素を整列させるために存在します。それにもかかわらず、さまざまなコンテキストでvertical-alignを使用して、要素を非常に柔軟かつ正確に位置合わせすることもできます。利点は、要素のサイズを知る必要がなくドキュメント フロー内に残るため、他の要素 (ブロックを含む) がレイアウト サイズの変更に対応できるため、貴重なオプションとなることです。
ただし、Vertical-Align は時々非常に意地悪で、イライラさせることがあります。いくつかの不思議なルールが働いているようです。たとえば、vertical-align が変更された要素の配置は変更されないが、同じ行にある他の要素は変更されることがよくあります。私は今でも時々、垂直方向の整列によって暗い隅に引きずり込まれ、髪が引き裂かれることがあります。
残念ながら、これに関するほとんどのチュートリアルは、特にレイアウトに垂直配置を使用する場合には少し浅いです。ほとんどの人は、要素を垂直方向に整列させようとすることについてのいくつかの誤解に焦点を当てており、基本的な概要を示し、非常に単純な場合に要素を整列させる方法について説明していますが、難しい部分については説明していません。
そこで、私は自分自身に目標を設定しました: 歴史的な問題を一切残さずに垂直配置の動作を完全に理解する 。私は最終的に W3C CSS 仕様を調べ、いくつかの例を試してみました - この記事です。
vertical-align は、インラインレベルの要素を調整するために使用されます。これらの要素の表示属性は次のとおりです:
inline 要素は基本的にテキストの折り返しタグです。
インライン ブロック要素はその名の通り、インラインに存在するブロック要素です。幅と高さ (内部コンテンツによって引き伸ばされることもあります)、パディング、境界線、マージンを持つことができます。
インライン要素は左から右に 1 つずつ配置されます。要素を追加して現在の行を配置できなくなると、下に新しい行が生成されます。これらすべての行には、すべてのコンテンツが含まれるいわゆる 行ボックス があります。コンテンツのサイズが異なると、ライン ボックスの高さも異なります。下の図では、ライン ボックスの上部と下部が赤い線で表されています。
ライン ボックスは、私が実験している領域を示しています。これらの行ボックスでは、vertical-align 属性が個々の要素を調整します。 それでは、要素の配置は何に関係するのでしょうか?
垂直方向の配置で注目すべき最も重要なことは、その要素のベースラインです。場合によっては、要素の境界ボックスの上端と下端も重要になります。各タイプの要素のベースラインと外縁がどこにあるのかを見てみましょう:
ここでは、3 行のテキストが隣り合って配置されています。行の高さの上下は赤い線で表され、フォントの高さは緑の線で表され、ベースラインは青の線で表されます。左側では、テキストの行の高さはフォント サイズと同じで、緑と赤の線が上下に重なっています。中央では、行の高さがフォント サイズの 2 倍になっています。右側では、行の高さがフォント サイズの半分になっています。
インライン要素の外側の端は、それ自身の行の高さの上端と下端に揃えられます。行の高さがフォントサイズより小さい場合、変更されません。したがって、上の図の行の外側の境界は赤い線です。
インライン要素のベースライン文字の下部にある線は、図の青い線です。大まかに言うと、ベースラインはフォント サイズの中央より下の位置です。W3C 仕様の詳細な定義を参照してください。
左から右に、フロー コンテンツを含む inline-block 要素 (「c」)、フロー コンテンツとオーバーフローを含む inline-block 要素: hidden、および inline-block が表示されます。フローするコンテンツのない要素 (ただし、コンテンツ領域には高さがあります)。マージン境界は赤い線、黄色の境界線、緑色のパディング、青色のコンテンツ領域で表されます。青色の線は各インライン ブロック要素のベースラインです。
インラインブロック要素の外側の端は、マージンボックスの上端と下端であり、図の赤い線です。
インライン ブロックのベースラインは、要素にフロー コンテンツがあるかどうかによって異なります。
今回は、ラインボックス、テキストボックス(下にも緑の線)、ベースライン(青の線)の上下のエッジを描きました。また、この領域のテキスト要素を強調するために、テキスト要素に灰色の背景を追加しました。
ラインボックスには、行の一番上の要素の上端に合わせて上端があり、行の一番下の要素の下端に合わせて下端があり、これは図の赤い線です。上はボックスで表されます。
ライン ボックスのベースラインは可変です:
CSS 2.1 はライン ボックスのベースラインを定義しません
これはおそらく、vertical-align を使用するときに最も混乱する部分です。これは、垂直方向の位置合わせ設定やライン ボックスの高さの最小化など、他のすべての条件を満たすことによってベースラインの位置を決定する必要があることを意味します。これは方程式内の自由なパラメーターです。
ラインボックスのベースラインは目に見えないため、直感的に認識することができません。ただし、簡単に表示させることができます。上の図の文字「×」など、行の先頭に文字を追加します。この文字がいかなる方法でも位置合わせされていない場合、その底部はデフォルトでベースライン上に位置します。
ベースラインに基づいて、ライン ボックスには テキスト ボックス と呼ばれるものがあります。テキスト ボックスは、単純に位置合わせのない行ボックス内の inlne 要素と考えることができます。その高さは親要素のフォントサイズと同じです。したがって、テキスト ボックスは、上の図の緑色の線で示されているように、行ボックス内の書式設定されていないテキストのみを折り返します。テキスト ボックスの位置はベースラインに基づいているため、ベースラインに合わせて移動します。 (注: このテキスト ボックスは、W3C 仕様では strut と呼ばれます)
残念ながら、これが最も難しい部分です。分析原理の前提条件がすべて揃ったので、最も重要な事実を簡単に要約しましょう:
上記のリストにまとめたvertical-align を使用する際の重要なポイントから、いくつかの関係例を設定しました。
テキスト ボックスの位置は次のように決定されるため、これら 2 つの状況は、ライン ボックスのベースラインを基準にして揃えることによっても表示できます。ベースライン。
正式な定義は W3C 仕様に記載されています。
これで、特定の状況、特に物事がうまくいかない可能性がある状況での垂直方向の配置を研究できるようになりました。
以前、次の問題に悩まされました。アイコンをその隣のテキスト行と垂直方向に揃えたいのですが、アイコンにvertical-align: middle; を設定するだけでは中央揃えにならないようです。期待される。以下の例を見てください:
<!-- left mark-up --><spanclass="icon middle"></span>Centered? <!-- right mark-up --><spanclass="icon middle"></span><spanclass="middle">Centered!</span> <styletype="text/css"> .icon { display: inline-block; /* size, color, etc. */ } .middle{ vertical-align: middle; }</style>
下面的图还是上面的例子,但我画了一些之前提到过的辅助线:
这揭示了我们的问题。左边的x和Centered?没有设置对齐属性,所以它坐在baseline上。重要的是,用 vertical-align: middle; 对齐灰色方块(即图标)后,我们把它的中点与line box的baseline加上x高度的一半处对齐了(图中黄线),然而由于Centered?中部并不在黄线上,所以就显得高于灰色方块(图标)。
在右边,我们进一步把文字中点也对齐了,这使得文本的baseline略微往line box的baseline下方偏移了一点。最终得到了完美的结果。
这里有一个使用 vertical-align 常见的盲点:line box baseline的位置会被行内所有元素所影响。让我们假设这种情况,一个元素以使得line box baseline必须移动的方式进行对齐。由于大多数垂直对齐方式(除了顶部和底部)与baseline相关,这会导致该行中的所有其他元素移动。
一些例子:
<!-- left mark-up --><spanclass="tall-box text-bottom"></span><spanclass="short-box"></span> <!-- right mark-up --><spanclass="tall-box text-top"></span><spanclass="short-box"></span><styletype="text/css"> .tall-box, .short-box { display: inline-block; /* size, color, etc. */ } .text-bottom{ vertical-align: text-bottom; } .text-top { vertical-align: text-top; }</style>
当用 vertical-align 的其他值来对齐高方块时也有相似的表现。
<!-- left mark-up --><spanclass="tall-box bottom"></span><spanclass="short-box"></span> <!-- right mark-up --><spanclass="tall-box top"></span><spanclass="short-box"></span> <styletype="text/css"> .tall-box, .short-box{ display: inline-block; /* size, color, etc. */ } .bottom { vertical-align: bottom; } .top { vertical-align: top; }</style>
<!-- left mark-up --><spanclass="tall-box text-bottom"></span><spanclass="tall-box text-top"></span> <!-- mark-up in the middle --><spanclass="tall-box text-bottom"></span><spanclass="tall-box text-top"></span><spanclass="tall-box middle"></span> <!-- right mark-up --><spanclass="tall-box text-bottom"></span><spanclass="tall-box text-top"></span><spanclass="tall-box text-100up"></span> <styletype="text/css"> .tall-box { display: inline-block; /* size, color, etc. */ } .middle { vertical-align: middle; } .text-top { vertical-align: text-top; } .text-bottom{ vertical-align: text-bottom; } .text-100up { vertical-align: 100%; }</style>
这是在试图垂直对齐 li 元素时很常见的情况。
<ul> <liclass="box"></li> <liclass="box"></li> <liclass="box"></li></ul> <styletype="text/css"> .box{ display: inline-block; /* size, color, etc. */ }</style>
正如你所看到的, li 元素坐在baseline上,而baseline下面是留给下标的空间,这导致了空白间隙。解决的办法很简单:将baseline上移一点。例如用 vertical-align: middle; 来对齐 li 元素。
<ul> <liclass="box middle"></li> <liclass="box middle"></li> <liclass="box middle"></li></ul> <styletype="text/css"> .box { display: inline-block; /* size, color, etc. */ } .middle{ vertical-align: middle; }</style>
这种情况不会发生在具有文本内容的inline-block中,因为 内容已经使baseline往上移动了 。
这主要是inline级元素本身的一个问题,但因为vertical-align的需要它们,所以还是知道比较好。
你在前一个例子的 li 中已经看到了这个间隙,它来自于你的html中inline元素之间的空白符号(空格、回车、换行)。html中多个连续的空白符号会在显示时被合并为一个空格,也就是图中的间隙。如果我们想把两个inline元素水平放置并给它们设置 width: 50% ,就无法跟额外的那个空格放在同一行,所以就会换行破坏布局(左图)。为了消除这个间隙,我们需要去除空白符号,比如使用HTMl注释(右图)。
<!-- left mark-up --><divclass="half">50% wide</div><divclass="half">50% wide... and in next line</div> <!-- right mark-up --> <divclass="half">50% wide</div><!----><divclass="half">50% wide</div> <styletype="text/css"> .half{ display: inline-block; width: 50%; }</style>
就是这样,当你知道规则那就不复杂了。所以如果 vertical-align 并没有如预期发挥作用,仔细思考下面两点,就能得到结果:
源于 Warrior!博客