web-dev-qa-db-ja.com

vertical-align:ベースラインとは何ですか?

CSSについて自分のやり方を知っていると思っていましたが、今誰かに何かを説明する必要があり、できないことがわかりました。

私の質問は基本的に次のように要約されます。同じ行に他の配置がある場合、なぜvertical-align:baselineは無視されるのですか?

例:2番目のスパンにvertical-align:bottomがある場合、baselineの場合、最初のスパンの垂直方向の配置は無視されます。 bottomも持っているかのように動作します。

span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:bottom;}
<p>
  <span>one</span> <span>two</span>
</p>

一方、すべてのスパンにbaseline以外の垂直方向の配置がある場合、またはそれらがすべてbaselineである場合、期待どおりに動作します。

span:first-child {vertical-align:top}
span:last-child {font-size:3em; vertical-align:bottom;}
<p>
  <span>one</span> <span>two</span>
</p>
span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:baseline;}
<p>
  <span>one</span> <span>two</span>
</p>

これが正常な動作である場合、なぜどこにも記述されていないのですか?このような方法でベースラインとトップ/ボトムが互いに干渉するというソースは見つかりませんでした。

28
Mr Lister

垂直方向に整列

vertical-align は、整列に使用されます インラインレベル要素 。これらは、 display プロパティの評価が以下の要素です。

  • inline
  • inline-block
  • inline-table(この回答では考慮されていません)

インラインレベルの要素は、横に並んで配置されます。現在の行に収まるよりも多くの要素があると、その下に新しい行が作成されます。これらのすべての行には、その行のすべてのコンテンツを囲む、いわゆる行ボックスがあります。異なるサイズのコンテンツは、異なる高さのラインボックスを意味します。

次の図では、行ボックスの上部と下部が赤い線で示されています。enter image description here

これらの行ボックス内では、プロパティvertical-alignが個々の要素の整列を担当します。

ベースライン

垂直に整列するための最も重要な基準点は、関連する要素のベースラインです。場合によっては、要素を囲むボックスの上端と下端も重要になります。

インライン要素

enter image description here

行の高さの上端と下端は赤い線で示され、フォントの高さは緑の線で示され、ベースラインは青い線で示されます。

左側では、テキストの行の高さがfont-sizeと同じ高さに設定されています。緑と赤の線は、各側で1本の線に折り畳まれました。

中央では、行の高さはfont-sizeの2倍です。

右側では、行の高さはfont-sizeの半分です。

行の高さがフォントの高さより小さい場合、インライン要素の外側の端(赤い線)は重要ではないことに注意してください。

インラインブロック要素

enter image description here

左から右へ

  • in-flow contentを持つinline-block要素

  • in-flow contentおよびinline-blockを含むoverflow: hidden要素

  • in-flow contentのないinline-block要素(ただし、コンテンツ領域には高さがあります)

マージンの境界は赤い線で示され、境界は黄色、パディングは緑色、コンテンツ領域は青色です。各inline-block要素のベースラインは青い線で示されています。

inline-block要素のベースラインは、要素に in-flow コンテンツがあるかどうかによって異なります。の場合には:

  • in-flow content inline-block要素のベースラインは、通常フローの最後のコンテンツ要素のベースラインです(左の例

  • in-flow contentですが、overflowプロパティは可視以外のものに評価され、ベースラインはマージンボックスの下端です(中央の例

  • no in-flow content再び、ベースラインがmargin-boxの下端Edge(右の例

ラインボックス

enter image description here

vertical-alignを操作する場合、これはおそらく最も複雑な部分です。つまり、vertical-alignminimizingラインボックスの高さなど、他のすべての条件を満たすために必要な場所にベースラインが配置されます。方程式のfreeパラメーターです。

ラインボックスのベースラインは目に見えないため、どこにあるかすぐにはわかりません。ただし、非常に簡単に表示できます。図の「x」のように、質問の行の先頭に文字を追加するだけです。この文字が何らかの方法で整列されていない場合、デフォルトでベースラインに配置されます。

ラインボックスには、そのベースラインの周りにテキストボックスと呼ばれるものがあります(図の緑の線)。テキストボックスは、単に位置合わせなしのラインボックス内のインライン要素と考えることができます。その高さは、親要素のfont-sizeと同じです。したがって、テキストボックスは、行ボックスの書式設定されていないテキストのみを囲みます。このテキストボックスはベースラインに関連付けられているため、ベースラインが移動すると移動します。

スニペット

さまざまなvertical-alignおよびfont-sizeを使用して実験を行いたい場合は、試用できるスニペットがあります。 JSFiddle でも利用可能です。

let sl1 = document.getElementById('sl1');
let sl2 = document.getElementById('sl2');
let sl3 = document.getElementById('sl3');
let sl4 = document.getElementById('sl4');
let Elm1 = document.getElementById('Elm1');
let Elm2 = document.getElementById('Elm2');
let Elm3 = document.getElementById('Elm3');
let Elm4 = document.getElementById('Elm4');
let ip1 = document.getElementById('ip1');
let ip2 = document.getElementById('ip2');
let ip3 = document.getElementById('ip3');
let ip4 = document.getElementById('ip4');
let slArr = [sl1, sl2, sl3, sl4];
let elmArr = [Elm1, Elm2, Elm3, Elm4];
let ipArr = [ip1, ip2, ip3, ip4];
let valueArr = ['baseline', 'top', 'middle', 'bottom'];
for (let i = 0; i < slArr.length; i++) {
  slArr[i].addEventListener('change', (event) => {
    elmArr[i].style.verticalAlign = event.target.value;
    elmArr[i].innerHTML = event.target.value;
    addDiv();
  })
}
for (let i = 0; i < ipArr.length; i++) {
  ipArr[i].addEventListener('change', (event) => {
    elmArr[i].style.fontSize = event.target.value + 'em';
    addDiv();
  })
}

document.getElementById('btnRandom').addEventListener('click', () => {
  for (let i = 0; i < elmArr.length; i++) {
    let element = elmArr[i];
    let fontSize = Math.floor(Math.random() * 4 + 1);
    ipArr[i].value = fontSize;
    element.style.fontSize = fontSize + 'em';
    let styleIndex = Math.floor(Math.random() * 4);
    element.style.verticalAlign = valueArr[styleIndex];
    element.innerHTML = valueArr[styleIndex];
    slArr[i].selectedIndex = styleIndex;
  }
}, this);

function addDiv() {
  let view = document.getElementById('viewer');
  view.innerHTML = "";
  elmArr.forEach(function(element) {
    let div = document.createElement('div');
    div.appendChild(element.cloneNode());
    view.appendChild(div);
  }, this);
}
.header span {
  color: #000;
}

select {
  width: 100px;
}

#elms {
  border: solid 1px #000;
  margin-top: 20px;
  position: relative;
}

span {
  color: #FFF;
  font-size: 1em;
}

#Elm1 {
  background-color: #300;
}

#Elm2 {
  background-color: #6B0;
}

#Elm3 {
  background-color: #90A;
}

#Elm4 {
  background-color: #B00;
}

div {
  z-index: -1;
}

#div1 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 25%;
}

#div2 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 50%;
}

#div3 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 75%;
}
<div class="header"> <span style="width: 100px;display: block;float: left;margin-right: 20px;">vertical align</span> <span>font-size(em)</span> </div>
<div>

  <select name="sl1" id="sl1">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip1" />
  <br>
  <select name="sl2" id="sl2">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip2" />
  <br>
  <select name="sl3" id="sl3">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip3" />
  <br>
  <select name="sl4" id="sl4">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip4" />
  <br>
  <button id="btnRandom" (onclick)="random()">Random</button>
</div>
<div id="elms">
  <span id="Elm1">one</span>
  <span id="Elm2">two</span>
  <span id="Elm3">three</span>
  <span id="Elm4">four</span>
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
</div>
<div id="viewer"></div>

このスニペットは Duannxによって作成されます


出典:これは Vertical-Align:You Know Need To Know の抜粋であることに注意してください。

35
Paolo Forgia

問題は、なぜvertical-align: baseline;無視されます。さて、私はそうは思いません。最初のスニペットでは、baselinebottomを使用しています。これにより、2つの<span>要素。それで、baselineは何をしますか? Well baseline要素のベースラインを親要素のベースラインに揃えます。以下の例では、違いを与えるためにいくつかの部分をコピーして調整しました。

span.one {vertical-align:baseline}
span.two {vertical-align:middle;}
<p>
  <span class="one">one</span> <span class="two">two</span>
</p>

ご覧のとおり、baselineアライメントは、middleアライメントと同じように正常に機能します。

次に、他の何かをテストしましょう。 baselinemiddleの配置を交換し、middleを編集して3番目の<span>

span.one { vertical-align: top;}
span.two { vertical-align: baseline;}

span.three {vertical-align: middle; height: 20px; }
p {
height: 50px;
background-color: grey;
}
<p>
  <span class="one">one</span> <span class="two">two</span> <span class="two">two</span><br><br> <span class="three">three</span>
</p>

2番目のスニペットを編集して、vertical-align of <span class="three">配置を変更すると、テキストがその位置を変更することが明確にわかります。

ただし、同じ行のテキストに関連する質問なので、下のスニペットを見てみましょう。

span.one { vertical-align: middle;}
span.two { vertical-align: baseline;}

span.three {vertical-align: middle; height: 20px; }
p {
height: 50px;
background-color: grey;
}
<p>
  <span class="one">one</span> <span class="two">two</span> <span class="two">two</span><span class="three">three</span>
</p>

この3番目のスニペットでわかるように、3番目の<span> 1と2の隣。そして、それは違いを生みます。この場合のbaselineは、middleアライメントとは異なります。これは、baselineが親のbaselineを取得するためです。親の高さは通常なので、baselinetopの配置には影響しません。ただし、middleまたはsubを使用する場合、明らかに違いがあります。

各配置の詳細については、これを確認してください link

5
Deathstorm