わけがわからん事が時々あります

元々は、単に文字を繋げて送受信するほぼ一次元の通信システムが、これじゃつまらないと文字に色を付けたり文字サイズを変えたり。 その内に画像もやり取り出来る様になり、文字と画像を並べてレイアウトという発想が生まれる。 レイアウトはやはり二次元平面上の配置が自由にできないと困る、というわけで超テキスト印加言語が生まれ育って来たわけだ。

 

忘れてならないのが、これもあれも一次元の文字の送受信が全ての素になっていて、人の体の成分が海水の成分にとても似ている様に、どこまで行っても素材の呪縛から自由ではないという事。 現在のHTMLやCSSは、レイアウト上で色々な事が出来る様になってはいるが、所詮はテキスト連鎖が化けただけ。

 

CSSを弄ってレイアウトをしていて時々感じることだけど、大変に高度化された仕組みに畏怖に近い念を抱きつつも、これって変だなあと思う事があるもんです。 その疑問を調べると、規則を製錬して来た人達の深い思慮にもう一度感心する事もあるが、これはどちらなのでしょう。

 

 

妙な事象をサンプル化したHTMLとCSS

デフォルトで「inline」の扱いをされる要素は、「span」「a」などがすぐ浮かびます。 要素は「<>」で囲まれたもので、HTML上の素の「テキスト」は要素には当たらない様ですが、「テキスト」こそ元祖インラインと言うべきモノです。 また、それらに対して、「div」「p」などはデフォルトで「block」の扱いをされる要素です。

 

CSSを少し齧ると、要素に与えられたデフォルトの素性は、「display」の指定によっで「inline」「block」「inline-block」のどれかに変更出来ることを知ります。

 

前置きが長くなりましたが、最近に出くわした私にとっては謎の問題を紹介します。 解決は別に難しくないのですが。

 

HTML

<html><body>
<div id="container">
    <span id="A">要素A [span]</span>
    <div id="B">要素B [inline-block]</div>
[テキスト]
</div>
</body></html>

 

CSS

#container {
    margin: 50px;
    padding: 20px;
    height: 60px;
    border: 1px solid #000;
    background: #eee;}

#A {
    margin-right: 10px;
    padding: 2px 6px;
    border: 1px solid #000;
    background: #fff; }

#B {
    display: inline-block;
    padding: 2px 6px;
    border: 1px solid #000;
    background: #fff; }

 

このHTMLは、「span要素」「inline-block要素」「テキストC」を並べただけですが、問題にしているのはインライン扱いの要素の縦方向の並びです。 このため、要素A、要素Bには枠線を付けたり「[]」を入れて、高さ位置を明瞭にしています。

 

上のHTMLとCSSで、ブラウザの表示は下の様になります。

 

 

綺麗に高さが揃っているのは当たり前の様ですが、「インライン」のひとことでこの整列を実現するために、色々な工夫があるのだと思います。

 

この様な場所で、要素Bのエリプシス表示に不可欠の指定の「overflow: hidden;」を指定した時に、困ったことが生じました。 要素BのCSSだけですが以下の様に1行を加えただけです。

 

#B {
    display: inline-block;
    padding: 2px 6px;
    border: 1px solid #000;
    background: #fff;
    overflow: hidden; }

 

この結果、ブラウザの表示は以下の様になります。

 

 

これって、どこかで時々見た様な「手元違い」みたいな状態です。 行の中で要素Bが上にズレたが、これが行全体の高さを拡げ、行自体は外枠との距離(padding)は変わらずに、結果として周囲の要素が押し下げられた配置になってます。

 

こんな場合の対策

最初は、これを戻そうとB要素の「margin」「line-height」や「position:relative;」「top」まで繰り出して、なんとか元の整列に戻していたのですが、これはきっととても下手な事をしているに違いないと思い始めて、ネット検索。

 

 `display:inline-block;` が微妙に下にずれる問題の解決方法「Qiita」

 

うーむ、これかぁという答え「vertical-align:top」を教わりました。 実は、この問題に出くわした事例は、実際には他の色々な構成の指定が周囲要素にあり、この「top」がドンピシャだったのですが、この例ではだめで下の様になります。

 

 

既定にある指定では「middle」が一番マシですが、下の様に不完全です。

 

 

「vertical-align」は実値の指定が出来、値を調整すると「-10px」が最適でした。

 

 

「overflow: hidden;」を指定前の状態と比べると、完全に配置も一致しています。 現実的には「vertical-align」を調整すればなんとかなるという事は判りました。

 

 

何を隠したのでそうなるの

しかし、これは解決方法を得たというだけで、何ゆえにこんな事が生じるのかが判りません。「overflow: hidden;」は、何を隠したクックロビン。

 

もっと判り易くするために、要素A、Bの枠線とpaddingを外して、DevToolsで外枠のpaddingを表示したのが以下です。 グリーンが外枠のpaddingです。

 

 

「overflow: hidden;」を指定したところ。

 

 

関係する配置の仕様

まず、前提としては「フォントサイズ」「base-line」「行間隔」「ラインボックス」と言ったキーワードで、インラインの要素がどの様な高さ位置に配置されるかを知る必要があります。 ネットを調べると以下のページが良く判りました。

 

  Take off with CSS / 行送りとラインボックス

 

このページの内容で今回の問題に関係する部分は、以下の部分です。

『vertical-align によって垂直方向の配置を決め,もっとも上にあるものの上端からもっとも下にあるものの下端までをラインボックスの高さとする』

このラインボックスの理解があると、要素A、要素B、テキストCがシーソーの様に高さの配置を変える事が納得出来ます。

 

また「vertical-align」の意味は、インラインの要素の整列基準は「base-line」にあり、当該要素の「base-line」からのシフト値を指定するのが「vertical-align」プロパティだということです。

 

以上の仕様を今回に当てはめると下図の様になります。

 

 

DevToolsによる要素の値から、フォントサイズは16px、白背景は「line-height」に相当します。 base-lineのシフト量は、このページの最初は要素A,Bにpaddingと枠線があったので、ここでは「7px」でした。(vertical-aline: -7px; で整列)

 

上図の最上部と最下部のグリーンの線の間が、31px幅のラインボックスです。

 

で、「overflow: hidden;」は何を隠したのか。 これは本来は「-7px」のシフトがあったのを隠したから、その分を「vertical-aline: -7px;」で補正する必要が生じたと考えるべきではないでしょうか。 抽象的ですが、「inline-block」は他のインラインの要素にbsae-lineを合わせるために、ここでは「-7px」のシフトを自動的に保っていて、「overflow: hidden;」がその「負のはみ出し」を削ったと考えるわけです。

 

私にはそれ以上の説明が出来ません。 Chromeでの実証ですが、他のブラウザだと違う結果になるかも知れませんが、全くけったいな話です。