標籤:

關於vertical-align:top問題?

我給aaa設置的vertical-align:top,aaa沒有發生變化,但是其他文本的卻變動了,請問這是為什麼?

給aaa設置vertical-align:top

以下是代碼部分:

CSS 部分:

div {font-size:20px; line-height:20px; border:1px solid red; width:500px;}
span {background:lime; line-height:60px; vertical-align:top;}

HTML 部分:

&
one two three four &aaa& 一 二 三 四
&


額,本想貼個 url 完事,然後發現…… 死 w3help 已經掛了好久……

只好再畫圖解釋下。

首先

&
one two three four &aaa& 一 二 三 四
&

div 的行內元素里會被切成三段

1、匿名行內框 one two three four

2、具名span函內框 aa

3、匿名行內框 一 二 三 四

再看樣式:

div {font-size:20px; line-height:20px; border:1px solid red; width:500px;}
span {background:lime; line-height:60px; vertical-align:top;}

由於匿名緣故,1、3 行內框無法直接設置樣式,它們的樣式從父容器框中可繼承的樣式中繼承。

那麼父容器框可繼承的行內樣式是:

font-size:20px; line-height:20px;

那好,2個匿名行內框產生高度為 20px 的兩個框框。

span 行內框呢?它設置了樣式,所以就不繼承了唄。產生 60px 的框框。

那好問題來了,這一橫排的行內框怎麼排布呢?

內個鳥CSS 2.1 規範里這麼扯這事兒:

1、一個容器裡頭得有行框注意啊,這是行框,不是行內框)

2、行框這貨呢,沒法用 CSS 直接設置高度

3、行框的高度,咱得用算的:按這一行內所有行內框的最高頂邊和最低底邊的差值為行框高度

最後一句好難理解,怎麼確定一排行內框的最底邊和最頂邊的距離呢。

好吧,這個例子里,其實還有個屬相剛才沒說,就是 vertical-align。

樣式里沒寫啊,沒寫啊,它是沒有么?

肯定有啊,別忘了 UA 會給定好啊,UA就是內個瀏覽器啦(userAgent)你懂的,鳥CSS規範要這麼叫,沒辦法啊。

恩, vertical-align 的 UA 給了啥默認值…… 規範里也說了,得是 baseline。

額,又得說 baseline,這玩意不展開了,簡單點說……呃呃呃……你就當是行內框里文字底下的一條線吧(好不嚴謹的說,沒辦法了,實在懶得敲)

還有約束呢…… 行內框高度有了,但是baseline 就說了是文字最下方的一條標準線,它放在行內框啥地方啊。

內啥啥 CSS 規範這麼大致這麼說,文字得渲染在它所屬行內框的垂直中心,然後巴拉巴拉如果字型大小於行內框的寬怎麼樣,小於怎麼怎麼樣,引出差異與半差異概念,等等。哈哈哈,給個圖,懶得敲了……

所以吧,幾個行內框高度不同的時候,字型大小也不同,都按 baseline 對齊,它們就得垂直移動各自的行內框,好讓它們的 baseline 對在一條線上。

我擦……解釋的好累 &>_&< 給個圖,這是都按 vertical-align: baseline 時的排布情況:

一圖勝千言,希望能看的明白啦。

由於是 baseline 對其,三個行內框的 baseline 得在一條線上。

然後呢,整個行框的高度是,最高的頂邊與最低的底邊差。此時最高的頂邊與底邊不就是 span 行內框的么,整個行框高不就是60px了。

內倆匿名行內框,得跟著 span 行內框的baseline對齊啊,可span 行內框比它們高啊,它們被啦下來了,對齊就是這樣子的了。

渲染是這個樣子的,請對照示意圖看:

差點以為敲完了……

還沒完呢(粗口若干),以後真不能再寫這麼多,多寫多錯,還是混日子的好……←_← 吐槽就別看了。

咳咳,內個吧,現在不是 span 行內框里有個 vertical-align: top 么。那麼,就是說,兩個匿名行框還得按各自的 baseline 對齊。span 行內框的行內框頂邊得對齊到行框的頂邊去吧。

再給個圖。。。

對應渲染結果:

剩下就不用解釋了吧 = =||| 收工。

標準參考

關於 Line Height (行高)計算說明,請參照 W3C CSS 2.1 規範 10.8 節: Visual formatting model details

關於 Leading and half-leading (差異半差異) 說明,請參照 W3C CSS 2.1 規範 10.8.1 節: Visual formatting model details

關於 Inline formatting context (行內格式化上下文)說明,請參照 W3C CSS 2.1 規範 9.4.2 節: Visual formatting model

關於 "line-height" 特性說明,請參照 W3C CSS 2.1 規範: Visual formatting model details

關於 "vertical-align" 特性說明,請參照 W3C CSS 2.1 規範: Visual formatting model details


你的span有60px高,撐起了整個linebox,所以它的位置在整個linebox中是固定的。改變它的對齊方式影響了它與其他內容的對齊,但因為它自己在linebox中位置不變,所以看上去就是其他內容的位置發生了變化。


先謝謝幾位給我的思路!由於要放一個圖,不能再評論里插入圖片,所以我就「自己回答自己的問題」了。

參考大家的意見,按照《CSS權威指南(第三版)》給的vertical-align:top的定義:

將元素行內框的頂端與包含該元素的行框的頂端對齊。

那是不是 先把aaa的60px的行內框,與div的20px的行框,頂端對齊。然後aaa的60px的行內框撐大其所在行框的高度?


能調整元素則調整元素,否則調整整行。

即:子元素仍在內容區域內,則調整子元素,直到與邊緣平齊,之後調整整行,此時如果超出內容區域,則擴充內容區域。

減少span行高,你再定義,top bottom,移動的都是span,但是當你設置數值,例如vertical-align:21px,超出了內容區域,你會發現,其他元素,下降了1px,是因為整行為了與span對齊,會下降1px,而因此內容區域也擴充了1px。

div {
font-size:20px;
line-height:60px;
border:1px solid red;
width:500px;
}
span {
background:lime;
line-height:20px;
vertical-align:top; /* 設置為21px試試 */
}

而題主所述此處,span上下邊框均頂到了內容區域,設置top/bottom,都不會影響內容區域高度,但是會調整整行,使整行的top/bottom與span對齊。

行這個概念,是因為html渲染是一行一行的,所以哪怕你調整的是一個div的子元素span,處在整行的所有元素,都可能被影響到。例如

html

&
one two three four &aaa& 一 二 三 四
& &1233&

css:

div {
font-size:20px;
line-height:60px;
border:1px solid red;
width:350px;
display: inline-block;
}
span {
background:lime;
line-height:50px;
vertical-align:20px;
}


我理解是一行的基線是由這一行元素中基線高度最大的行內元素決定,這樣行基線位置由&基線決定,按照top對齊的話,會使得其他元素和&的top對齊


我最近也在學習這個屬性的相關知識,發現了很多奇怪難以理解的現象,當你把這個盒子的整個line-height設置為200px時候再去改變span的對齊方式你會發現另一種現象


推薦閱讀:

為什麼說 html 和 css 根本不算編程?
如何評價ClojureScript?
Angular2與React,前端的未來志向何方?
為什麼 CSS :not 選擇器不支持複雜選擇?
985待業半年多,想去做前端,不知道現在還行嗎?

TAG:前端開發 | CSS |