成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

CSS > 行內(nèi)格式化上下文中的各種高度計(jì)算

yearsj / 2450人閱讀

摘要:行內(nèi)級(jí)元素生成行內(nèi)級(jí)盒,而這些盒會(huì)參與行內(nèi)格式化上下文。行盒在行內(nèi)格式化上下文中,盒從包含塊的頂部一個(gè)接一個(gè)地水平擺放。我們進(jìn)入下一個(gè)話題,行盒高度計(jì)算。整個(gè)行盒的高度即盒上邊緣到盒下邊緣。

前言碎碎語(yǔ):標(biāo)題問(wèn)題在昨天困擾了筆者很久很久,早上把問(wèn)題提到了各網(wǎng)絡(luò)也暫時(shí)沒(méi)有回復(fù)。因?yàn)槊魈煲缙痫w異地參加一場(chǎng)校招面試,筆者還是很緊張的,但奈何問(wèn)題不解決寢食難安……所以還是卯起勁重新思考這個(gè)問(wèn)題,算是暫時(shí)有了一個(gè)自己比較認(rèn)可以及清晰的答案,與各位讀者分享。如您有不同觀點(diǎn)想法意見(jiàn)建議,懇請(qǐng)斧正!

正式探討之前,我們觀察一個(gè)現(xiàn)象(在 Chrome 下的表現(xiàn),其他瀏覽器下的表現(xiàn)和計(jì)算可能有細(xì)微差別):

上圖對(duì)應(yīng)的 HTML 是(之后的探討均基于此):





Line Height



    
Some Text

我們來(lái)計(jì)算下 DIV 和 SPAN 的高度

document.getElementsByTagName("div")[0].offsetHeight
//93
document.getElementsByTagName("span")[0].offsetHeight
//42

對(duì)于此圖,筆者產(chǎn)生如下疑問(wèn):

line-height 為 32px,為何 SPAN 的高度為 42px?

DIV 的高度 93px,比 IMG 高度加外邊距 90px 以及 SPAN 高度 42px 都要大,如何計(jì)算的?

圖片和文本下的空白(即便沒(méi)有文本一樣存在)是如何產(chǎn)生的?

假設(shè)我們把 IMG 刪除,HTML 部分改為:


    
Some Text

此時(shí)來(lái)計(jì)算:

document.getElementsByTagName("div")[0].offsetHeight
//32
document.getElementsByTagName("span")[0].offsetHeight
//42

新問(wèn)題又來(lái)了:

DIV 的子元素高度為 42px,為何沒(méi)有“撐起” DIV 的高度?

以上問(wèn)題就是本文要探討的了。覆蓋了五個(gè)知識(shí)點(diǎn):

行內(nèi)盒(或行內(nèi)不可替換元素)的高度

行內(nèi)可替換元素的高度

行盒的高度

行距與行高

建立行內(nèi)格式化上下文的塊盒的 auto 高度

所以在探討之前,筆者已假設(shè)您知道這些概念:行內(nèi)盒、行內(nèi)不可替換元素、行內(nèi)可替換元素、行盒、行內(nèi)格式化上下文。如果您還有點(diǎn)不清楚,我們可以快速補(bǔ)習(xí)下:

可替換元素、不可替換元素

簡(jiǎn)單地講,可替換元素是指須根據(jù)其標(biāo)簽和屬性來(lái)決定具體顯示內(nèi)容的元素,如本文中會(huì)探討的 IMG 元素,其具體顯示內(nèi)容由 src 等屬性決定; 不可替換元素則是內(nèi)容直接呈現(xiàn)的元素。如本文會(huì)探討的 DIV 和 SPAN 等。

塊盒

此概念是塊格式化上下文的內(nèi)容,要解釋起來(lái)就更復(fù)雜啦,筆者粗陋地給您一個(gè)描述:塊盒通常是 display: block 的不可替換元素。

行內(nèi)級(jí)元素、行內(nèi)級(jí)盒、行內(nèi)盒、行內(nèi)格式化上下文

display: inline|inline-table|inline-block 產(chǎn)生行內(nèi)級(jí)元素。行內(nèi)級(jí)元素生成行內(nèi)級(jí)盒,而這些盒會(huì)參與行內(nèi)格式化上下文。

display 值是 inline 的不可替換元素會(huì)生成一個(gè)行內(nèi)盒。

不是行內(nèi)盒的行內(nèi)級(jí)盒被稱(chēng)為原子行內(nèi)級(jí)盒。

行盒

在行內(nèi)格式化上下文中,盒從包含塊的頂部一個(gè)接一個(gè)地水平擺放。包含了一行里所有盒的矩形區(qū)域被稱(chēng)為行盒。一個(gè)段落就是多個(gè)行盒的垂直堆疊。

因此,我們可以得到下圖(大致描摹):

現(xiàn)在開(kāi)始計(jì)算!

1 行內(nèi)可替換元素和文檔流內(nèi)行內(nèi)塊可替換元素高度計(jì)算

W3C 有明確規(guī)范,如下:

如果 heightwidth 計(jì)算值均為 auto 且該元素有固有高度,那么該固有高度為 height 使用值。

否則,如果 height 計(jì)算值為 auto,且該元素有一個(gè)固有比例,則 height 的使用值為:

width 使用值 / 固有比例

否則,如果 height 計(jì)算值為 auto,且該元素有固有高度,那么該固有高度為 height 使用值。

否則,如果 height 計(jì)算值為 auto,但以上情況均不符合,那么 height 的使用值必須設(shè)定為一個(gè)最大矩形的高度,該矩形比例為2:1,高度不超過(guò)150px,且寬度不大于設(shè)備寬度。

因此,在我們的實(shí)例中,IMG 盒的高度為 80+10 = 90px。

2 行內(nèi)盒的高度計(jì)算

“高度”一詞在這里頗有歧義,筆者認(rèn)為,總共可以有三種概念需要辨析:

行內(nèi)盒的內(nèi)容區(qū)域高度

行內(nèi)盒的盒高度

計(jì)算行盒高度時(shí)的行內(nèi)盒的盒高度

您可能對(duì)第二和第三解釋抱有疑問(wèn),但我們先擱置懷疑,把清楚明白的東西先解決。

當(dāng)我們用 JavaScript 去獲取一個(gè)行內(nèi)盒的 offsetHeight 值時(shí),如我們上面所做的:

document.getElementsByTagName("span")[0].offsetHeight

筆者將此高度稱(chēng)作“行內(nèi)盒的盒高度”,類(lèi)比于我們所熟知的塊盒盒高度。其計(jì)算值是:

內(nèi)容區(qū)域高度 + 上下邊框 + 上下內(nèi)邊距 = 行內(nèi)盒的盒高度

邊框和內(nèi)邊距的寬度默認(rèn)為 0,否則為我們自己指定,但“內(nèi)容區(qū)域高度”是怎么計(jì)算的呢?

W3C 這么說(shuō):

height 不適用。內(nèi)容區(qū)域的高度應(yīng)基于字體,但本規(guī)范沒(méi)有指定如何。用戶代理可能,比如說(shuō),使用行高盒 EM-Box 或字體的最大上端部 Ascender 和下端部 Descender。(后一種會(huì)確保有部分在行高盒之上或之下的字符仍然落在內(nèi)容區(qū)域內(nèi),但會(huì)導(dǎo)致不同字體有大小不一的盒子;前者則確保作者可以控制相對(duì)于 line-height 的背景設(shè)計(jì),但也導(dǎo)致字符繪制在其內(nèi)容區(qū)域之外。)

言下之意:

height 屬性無(wú)效

行內(nèi)盒內(nèi)容區(qū)域高度在規(guī)范里面沒(méi)有定義,瀏覽器可以自己折騰

既然規(guī)范沒(méi)有明確規(guī)定計(jì)算,我們讓瀏覽器實(shí)測(cè)一下。筆者瀏覽器測(cè)試如下:

Chrome 42

IE11 42

Firefox 43

如果我們更改字體,假設(shè)應(yīng)用如下 CSS

body { font-family: Simsun; }

Chrome 33

IE11 37

Firefox 35

而如果我們修改 line-height,以上結(jié)果均不受影響。

筆者也曾疑惑,這個(gè) offsetHeight 就是內(nèi)容區(qū)域高度嗎?答案:是。筆者的驗(yàn)證方法是基于 W3C 如下規(guī)定:

盡管不可替換元素的外邊距、邊框以及內(nèi)邊距不納入行盒的計(jì)算,它們?nèi)匀讳秩驹谛袃?nèi)盒的周?chē)?。這意味著如果 line-height 指定的高度小于被包含盒的內(nèi)容高度,內(nèi)邊距和邊框的背景和顏色可能“流進(jìn)”毗鄰的行盒。用戶代理應(yīng)當(dāng)按文檔順序渲染這些盒。這會(huì)造成后面的盒的邊框繪制在前面盒的邊框和文本上。

您可以用以下代碼實(shí)測(cè),會(huì)發(fā)現(xiàn)紅色行內(nèi)盒的背景溢出到了黑色行內(nèi)盒所在的行盒。

Some Text
Some Text

可知內(nèi)容區(qū)域高度,即行內(nèi)盒沒(méi)有內(nèi)邊距和邊框時(shí)的 offsetHeight。

因此總結(jié)論是:

行內(nèi)盒的內(nèi)容區(qū)域高度計(jì)算沒(méi)有統(tǒng)一的標(biāo)準(zhǔn),不同的字體或者不同的瀏覽器都可能導(dǎo)致不同的結(jié)果,且其高度與 line-height 無(wú)關(guān)。

由此我們無(wú)法確切地獲得一個(gè)跨瀏覽器的行內(nèi)盒的內(nèi)容區(qū)域高度。同樣我們也無(wú)法確切獲得一個(gè)跨瀏覽器的行內(nèi)盒高度(因?yàn)槠溆?jì)算式里面就包括了不定變量?jī)?nèi)容區(qū)域高度)。

但問(wèn)題來(lái)了,不同瀏覽器都采用不同的行內(nèi)盒內(nèi)容區(qū)域高度,又如何能統(tǒng)一計(jì)算行盒以及塊容器的高度呢?這個(gè)問(wèn)題便導(dǎo)致了筆者在上面所提到的“計(jì)算行盒高度時(shí)的行內(nèi)盒的盒高度”概念。

我們進(jìn)入下一個(gè)話題,行盒高度計(jì)算。

3 行盒高度計(jì)算

根據(jù)規(guī)范,行盒的高度決定如下:

計(jì)算行盒內(nèi)每個(gè)行內(nèi)級(jí)盒的高度。對(duì)于可替換元素、行內(nèi)塊元素以及行內(nèi)表格元素,高度是其外邊距盒的高度;對(duì)于行內(nèi)盒,高度是其 line-height。

行內(nèi)級(jí)盒根據(jù)其 vertical-align 屬性垂直對(duì)齊。如果它們對(duì)齊 topbottom,它們必須以能最小化行盒高度的方式對(duì)齊。如果這些盒足夠高,則有多種解決方案并且 CSS2.1 沒(méi)有規(guī)定此行盒的基線的位置。

行盒高度是最上盒頂部到最下盒底部的距離。

懂了:W3C 盡管允許瀏覽器有自己的行內(nèi)盒內(nèi)容區(qū)域計(jì)算方式,但統(tǒng)一了一個(gè)行盒高度的計(jì)算方式:

計(jì)算行盒的高度時(shí),針對(duì)行內(nèi)盒,高度直接取 line-height。行內(nèi)盒可以有邊框、內(nèi)邊距、外邊距,然而跟行盒的高度完全沒(méi)關(guān)系!

根據(jù)此規(guī)定,我們很快可以得出,計(jì)算行盒高度時(shí),SPAN 盒的高度取 32px。

接著,由于我們的 vertical-align 是默認(rèn)的 baseline,因此,應(yīng)當(dāng)把盒的基線同父盒的基線對(duì)齊。如果盒沒(méi)有基線,對(duì)齊盒的下外邊距邊緣與父盒的基線。也就是說(shuō),把 SPAN 盒的基線同 DIV 盒的基線對(duì)齊,把 IMG 盒的下外邊距邊緣同 DIV 盒的基線對(duì)齊。

下圖是字體的基線、上下端線等位置信息

圖片來(lái)源:http://blog.justfont.com/

筆者作圖如下:

假設(shè)我們?cè)O(shè) DIV 盒的基線是 0,則 IMG 盒的下邊緣同 DIV 盒基線對(duì)齊;上邊緣(上外邊距邊緣頂部)在高于基線 90px 處。而 SPAN 盒由于其基線對(duì)齊 DIV 盒基線,故其行盒下邊緣略低于基線。

整個(gè)行盒的高度即 IMG 盒上邊緣到 SPAN 盒下邊緣。假設(shè)沒(méi)有 IMG 元素,則高度為 SPAN 盒的 line-height。

但讀者您可能注意到了,29 和 -3 是怎么得來(lái)的呢?下面,筆者帶您算!

4 行距和行高計(jì)算

29 和 -3 兩值是在計(jì)算行距和行高后得來(lái)的。我們先來(lái)看規(guī)范:

CSS 假設(shè)每種字體都由字體特性來(lái)指定一個(gè)基線之上的特性高度和之下的特性深度。本節(jié)中我們用A表示(給定字體給定字號(hào)的)高度,用D表示深度。同時(shí)定義 AD = A + D,即從頂部到底部的距離。(參見(jiàn)下面如何找到TrueType和OpenType字體的A和D)注意該字體的這些特性是就整個(gè)而言的,無(wú)須對(duì)應(yīng)任何個(gè)別字符的上端部和下端部。

用戶代理必須在一個(gè)不可替換行內(nèi)盒中依照字符的相應(yīng)基線對(duì)齊各個(gè)字符。接著,就每個(gè)字符來(lái)決定A和D。注意單個(gè)元素的字符可能來(lái)自于不同字體因此不見(jiàn)得所有的A和D一樣。如果行內(nèi)盒完全不包含字符,則被視為包含了一個(gè)具有元素首個(gè)可用字體的A和D的支柱(一個(gè)零寬度的不可見(jiàn)字符)。

接著對(duì)每個(gè)字符添加行距L,其中 L = line-height - AD。行距的一般添加到A之上,另一半添加到D之下,從而賦予字符以及其行距一個(gè)基線之上的完整高度 A" = A + L/2,以及完整深度 D" = D+ L/2。

注意。L可能為負(fù)。

包含了所有字符以及字符兩側(cè)半行距的行內(nèi)盒的高度正是 line-height。

我們?cè)谏鲜鲆?guī)定中接觸到了這些概念:特性高度 A,特性深度 D,頂部到底部距離 AD,完整高度 A",完整深度 D",行距 L。

關(guān)于特性值,筆者 Google 到一個(gè)網(wǎng)站,推薦讀者使用:

http://fontsgeek.com/

不得不吐槽下,國(guó)內(nèi)真的很難找到這樣專(zhuān)業(yè)精致的字體網(wǎng)站(也可能是我的打開(kāi)方式不對(duì) >_<)。

好,我們可以獲得我們實(shí)例中 Microsoft YaHei 的字體特性了:Dcsender -536;Height 2703。

AD 即內(nèi)容區(qū)域高度,在本例中是 42

D 即字體下端(基線之下)高度,為 42*(536/2703) = 8

L = 32 - 42 = -10

故,D" = 8 + -10/2 = 3

即知行內(nèi)盒的下邊緣在基線之下 3px。同時(shí)行內(nèi)盒的高度被視為 32px,故亦知其上邊緣在基線之上 29px 處。

我們說(shuō)啦,整個(gè)行盒的高度即 IMG 盒上邊緣到 SPAN 盒下邊緣。所以得行內(nèi)盒高度為 90 + 3 = 93px。

5 建立行內(nèi)格式化上下文的塊盒的 auto 高度

根據(jù) W3C CSS2.1:10.6.3,該高度是從其上內(nèi)容邊緣到其最后一個(gè)行盒的下邊緣。只考慮文檔流內(nèi)子盒,絕對(duì)定位和浮動(dòng)子盒應(yīng)被忽略,相對(duì)定位子盒不考慮位移,子盒可以是匿名盒。

在本例中,DIV 盒的行內(nèi)格式化上下文僅有一個(gè)行盒,故其高度取該行盒高度,93px。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/111177.html

相關(guān)文章

  • CSS規(guī)范 &gt; 9 視覺(jué)格式模型 Visual Formatting Model

    摘要:盒的類(lèi)型會(huì)影響其在視覺(jué)格式化模型中的表現(xiàn)。浮動(dòng)元素絕對(duì)定位元素根元素都被稱(chēng)為脫離文檔流其他元素被稱(chēng)為文檔流內(nèi)。 視覺(jué)格式化模型 Visual Formatting Model URL:http://www.w3.org/TR/CSS2/visuren.html Translator: HaoyCn Date: 14th of Aug, 2015 本文并未全部翻譯,譯者在原文基礎(chǔ)上...

    魏憲會(huì) 評(píng)論0 收藏0
  • CSS規(guī)范 &gt; 10 視覺(jué)格式模型詳述 Visual Formatting Model De

    摘要:行盒的寬度由其包含塊給予,但可能因浮動(dòng)而縮小。絕對(duì)定位不可替換元素的使用值約束為包含塊寬度如果和均為首先將以及值為的設(shè)為。 2015/10/08: 原10.8標(biāo)題 行盒高度計(jì)算改為10.8 行高計(jì)算。英文原文為line height。由于翻譯時(shí)候看到那段結(jié)論是行盒的高度,腦抽就把原本翻譯對(duì)的標(biāo)題改了下,剛回顧一番深覺(jué)不妥,故改回來(lái)。 原文:http://www.w3.org/TR/CS...

    frolc 評(píng)論0 收藏0
  • CSS規(guī)范 &gt; 8 盒模型 Box Model

    摘要:當(dāng)兩個(gè)及以上外邊距折疊,合并后的外邊距寬度是發(fā)生折疊的外邊距中的最大寬度。如果該元素的外邊距同其父元素的上外邊距折疊,則該盒的上邊框邊緣同其父元盒的上邊框邊緣相同。 2017-07-20: 關(guān)于外邊距折疊, 推薦問(wèn)題: https://segmentfault.com/q/10... 8 盒模型 Box Model URL: http://www.w3.org/TR/CSS2/box...

    suemi 評(píng)論0 收藏0
  • CSS各種布局的背后(*FC)

    摘要:中各種布局的背后,實(shí)質(zhì)上是各種的組合。相反,一些塊容器盒,比如非替換行內(nèi)塊及非替換表格單元格,不是塊級(jí)盒。描述元素跟它的后代之間的影響。行盒行盒由行內(nèi)格式化上下文產(chǎn)生的盒,用于表示一行。彈性容器外和彈性項(xiàng)目?jī)?nèi)的一切元素都不受影響。 CSS中各種布局的背后,實(shí)質(zhì)上是各種*FC的組合。CSS2.1 中只有 BFC 和 IFC, CSS3 中還增加了 FFC 和 GFC。 盒模型(Box M...

    miracledan 評(píng)論0 收藏0
  • CSS查漏補(bǔ)缺

    摘要:而圣杯布局跟雙飛翼布局就是能夠不考慮主體的位置,能夠只通過(guò)代碼就改變相應(yīng)的布局,這也是優(yōu)點(diǎn)之一。如果在圣杯布局的基礎(chǔ)上,給它一個(gè)多余的標(biāo)簽,把包起來(lái),這就是雙飛翼布局。這里有個(gè)嘗試頁(yè)面,利用雙飛翼,實(shí)現(xiàn)了一套柵格化布局系統(tǒng)。 塊級(jí)格式上下文(Block formatting context) 普通流(Normal Flow) 在普通流中,元素按照其在 HTML 中的先后位置至上而...

    smallStone 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<