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>
これが正常な動作である場合、なぜどこにも記述されていないのですか?このような方法でベースラインとトップ/ボトムが互いに干渉するというソースは見つかりませんでした。
vertical-align
は、整列に使用されます インラインレベル要素 。これらは、 display
プロパティの評価が以下の要素です。
inline
inline-block
inline-table
(この回答では考慮されていません)インラインレベルの要素は、横に並んで配置されます。現在の行に収まるよりも多くの要素があると、その下に新しい行が作成されます。これらのすべての行には、その行のすべてのコンテンツを囲む、いわゆる行ボックスがあります。異なるサイズのコンテンツは、異なる高さのラインボックスを意味します。
次の図では、行ボックスの上部と下部が赤い線で示されています。
これらの行ボックス内では、プロパティvertical-align
が個々の要素の整列を担当します。
垂直に整列するための最も重要な基準点は、関連する要素のベースラインです。場合によっては、要素を囲むボックスの上端と下端も重要になります。
行の高さの上端と下端は赤い線で示され、フォントの高さは緑の線で示され、ベースラインは青い線で示されます。
左側では、テキストの行の高さがfont-sizeと同じ高さに設定されています。緑と赤の線は、各側で1本の線に折り畳まれました。
中央では、行の高さはfont-sizeの2倍です。
右側では、行の高さはfont-sizeの半分です。
行の高さがフォントの高さより小さい場合、インライン要素の外側の端(赤い線)は重要ではないことに注意してください。
左から右へ:
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(右の例)
vertical-align
を操作する場合、これはおそらく最も複雑な部分です。つまり、vertical-align
やminimizingラインボックスの高さなど、他のすべての条件を満たすために必要な場所にベースラインが配置されます。方程式の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 の抜粋であることに注意してください。
問題は、なぜvertical-align: baseline;
無視されます。さて、私はそうは思いません。最初のスニペットでは、baseline
とbottom
を使用しています。これにより、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
アライメントと同じように正常に機能します。
次に、他の何かをテストしましょう。 baseline
とmiddle
の配置を交換し、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
を取得するためです。親の高さは通常なので、baseline
とtop
の配置には影響しません。ただし、middle
またはsub
を使用する場合、明らかに違いがあります。
各配置の詳細については、これを確認してください link 。