摘要:看上面的例子我們也能看出來,實際上一個內(nèi)聯(lián)元素是有兩個高度的高度實際渲染的那個高度和高度實際區(qū)域占空間的高度也就是。
前言
總括: 本文通過實例講解CSS中最大的難點之一,行內(nèi)元素的布局,主要是挖掘line-height和vertical-align兩個屬性在布局方面的使用。
原文博客地址:深入理解行內(nèi)元素的布局
知乎專欄&&簡書專題:前端進(jìn)擊者(知乎)&&前端進(jìn)擊者(簡書)
博主博客地址:Damonare的個人博客
白茶清歡無別事,我在等風(fēng),也在等你。?
正文講道理line-height和vertical-align 這對基是十分低調(diào)的,日常開發(fā)中碰到的很多莫名其妙的bug很大一部分都是這倆貨搞出來了的,但很少有人知道這對基的罪惡,因為可能花式改寫一下CSS代碼問題就解決了。實際上搞明白這倆東西才能讓我們在布局工作中游刃有余。本文接下來就通過這對基的關(guān)系來了解內(nèi)聯(lián)元素具體的布局問題~we are刨根問底攔不住~?
? 讀這篇文章之前請確定您有以下知識基礎(chǔ):
line-height的數(shù)字值是和font-size大小相關(guān)的;
vertical-align的百分比值是和line-height值相關(guān)的;
引出vertical-align首先來看一個?:
Xx
.test { background: red; } img { width: 50px; height: 50px; } span { background: white; }
下面無實例內(nèi)容的話戳這里
? 如上代碼片段result所示,圖片下面有一明顯的紅色條條,?什么鬼,很詭異不是么,我要的是img充滿整個div啊!!!好吧,我加了一個額外的inline元素填寫內(nèi)容Xx,發(fā)現(xiàn)原來多出來的那一塊正好是文字的下半空白部分。吆喝,這么巧?實際上,如果將這里的Xx內(nèi)容去掉,只剩下img,那個條條依然存在,表現(xiàn)行為好像父元素div里面除了img元素還有一個空白的元素一樣,?姑且叫它空白節(jié)點吧(肉眼中不存在卻在影響著布局),這個是比較詭異的一個表現(xiàn),查標(biāo)準(zhǔn)沒找到有相關(guān)的說明。但請將這個空白節(jié)點先記住,我們的重點是研究條條是咋出來的。這條條看上去貌似是文本和圖片垂直方向上對齊生成的,那么這就引粗來一個問題,inline元素默認(rèn)的垂直方向的對齊方式是什么樣的?也就是vertical-align的默認(rèn)值是啥?
? OK,?I know you know。vertical-align默認(rèn)值是baseline,OK,那就先來挖一挖vertical-align具體是個什么鬼。
Vertical-align(1)vertical-align這個屬性我感覺是CSS中最復(fù)雜的屬性之一了...好多問題概念也讓人看不懂...一方面它是作用在inline元素和table-cell元素身上,屬性值特別多,另一方面該屬性規(guī)范里并沒有一個定論,導(dǎo)致一些屬性不同瀏覽器的實現(xiàn)也不同,所以兼容性問題很多。對于一些 可替換元素,比如textarea, HTML標(biāo)準(zhǔn)沒有說明它的基線,這意味著對其使用這個關(guān)鍵字,各瀏覽器表現(xiàn)可能不一樣。我們這里先研究一下它的默認(rèn)值baseline。
baseline字面意思就是基線,何為基線?首先請記住下面這幾個概念:
基線:小寫字母"x"的下邊緣所在的那條線;
x-height: 小寫字母"x"的高度;
ex: 1ex就是一個小寫字母"x"的高度,類似em單位,注意,ex和em都是相對單位;
我們看下CSS標(biāo)準(zhǔn)里怎么說的:相關(guān)標(biāo)準(zhǔn)鏈接
The baseline of an "inline-block" is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its "overflow" property has a computed value other than "visible", in which case the baseline is the bottom margin edge.
中文翻譯如下:
"inline-block"元素的基線是標(biāo)準(zhǔn)流中最后一個line box(行盒)的基線, 除非這個line box里面既沒有in-flow line boxes(行內(nèi)框)或者本身’overflow’屬性的計算值不是’visible’, 這種情況下基線是該元素margin底邊緣。
那么上面現(xiàn)象就很容易解釋的通了,我們知道img元素默認(rèn)的表現(xiàn)形式和inline-block元素一樣,它的基線就是margin底邊緣,而inline元素本身是有高度的,兩者基線對齊自然就如上面那樣表現(xiàn)了。?
?好吧,等會,到這里,我們發(fā)現(xiàn)實際又多了倆概念——inline元素的高度問題和標(biāo)準(zhǔn)里說的line box(IFC)。
首先我們先來看下inline元素的高度問題,即——line-height屬性。
Line-heightCSS中起高度作用的只有height和line-height兩個屬性吧。如果一個元素沒設(shè)置height那么其最終的高度一定是由line-height決定的。之前inline元素的高度我以為是文字內(nèi)容撐開的,但實際研究了下并不是這樣的,看下面的?:
.demo1{ font-size: 20px; line-height: 0; border: 1px solid blue; background: red; } .demo2{ font-size: 0; line-height: 20px; border: 1px solid red; background: yellow; }
HTML代碼:
測試測試
下面沒內(nèi)容戳這或者自行拷貝代碼本地測試
如上可證明,inline元素的高度決定者是line-height,并不是文字內(nèi)容撐開的。??
CSS規(guī)范里對line-height的默認(rèn)值有這么一句話:
We recommend a used value for "normal" between 1.0 to 1.2.
只是推薦...?是不是說實際上各個瀏覽器對于line-height的默認(rèn)值實現(xiàn)不一定是一樣的,但都介于1.0-1.2之間。具體各大瀏覽器的實現(xiàn)值待查證。這里需要記住line-height的默認(rèn)值是啥就OK。
IFC在之前的博文CSS的盒子模型里面,有拓展過相關(guān)知識,簡短的介紹了下BFC和IFC,相較于BFC,IFC要復(fù)雜得多,規(guī)范里IFC的篇幅也要比BFC多得多。
簡要總結(jié)下BFC,即塊級元素可能會觸發(fā)塊級格式上下文(BFC),在塊級格式上下文中,塊級盒子豎直方向排列,不受上下文外部元素影響,自成一方世界。塊容器盒指的是那些包含元素的盒子,塊容器盒可能包含其它塊級盒,也可能生成一個行內(nèi)格式上下文(IFC)。?
但塊容器盒要么只包含行內(nèi)盒,要么只包含塊級盒。但通常會同時包含兩者。在這種情況下,將創(chuàng)建匿名塊盒來包含毗鄰的行內(nèi)級盒。
看個?:
//demo1Some inline text// demo2followed by a paragraph
followed by more inline text.Some inline text followed by a paragraph followed by more inline text.
如上,demo1將創(chuàng)建兩個匿名塊盒,一個包含 p前面的文本 (Some inline text), 一個包含 p 后面的文本(followed by more inline text)。
demo2將生成一個行內(nèi)格式上下文,生成一個匿名行盒(line box),里面包含兩個匿名行內(nèi)盒(inline box),Some inline text 和followed by more inline text.和一個span行內(nèi)盒。
OK,至于怎么觸發(fā)塊級格式上下文請看塊格式化上下文。這里只為了說明IFC而介紹下BFC。
當(dāng)元素的 CSS 屬性 display 的計算值為 inline, inline-block 或 inline-table 時,稱它為行內(nèi)級元素。
行內(nèi)級元素生成行內(nèi)級盒(inline-level boxes),參與行內(nèi)格式化上下文(inline formatting context)。同時參與生成行內(nèi)格式化上下文的行內(nèi)級盒稱為行內(nèi)盒(Inline boxes)。
規(guī)范里IFC文字很多,提煉下我們需要的:
Vertical-align(2)如果一個矩形區(qū)域,包含著一些排成一條線的盒子,稱為line box。
一個line box的寬度,由他的包含塊(containg block)和floats的存在情況決定。line box的高度,由你給出的代碼決定。(line-height),即所有inline box的最大高度差。
當(dāng)盒子的高度小于父級盒子高度時,垂直方向的對齊"vertical-align"屬性決定。
在上面的vertical-align(1)中主要了解了什么是baseline,以及它是如何確定的。我們繼續(xù)研究這個屬性,看下面說明表格:
值 | 描述 |
---|---|
baseline | 默認(rèn)。元素放置在父元素的基線上。 |
top | 把元素的頂端與行中最高元素的頂端對齊 |
text-top | 把元素的頂端與父元素字體的頂端對齊 |
middle | 把此元素放置在父元素的中部。 |
bottom | 把元素的頂端與行中最低的元素的頂端對齊。 |
text-bottom | 把元素的底端與父元素字體的底端對齊。 |
除了baseline我們已經(jīng)很了解之外,其它幾個屬性我們貌似也能看懂,唯一的問題可能是父元素的頂端低端都是什么鬼??需要確定一下,好的再次拿我們第一個例子來講解,但我們需要變一下,加點東西進(jìn)去:
Xx
.demo { background: red; } .line-box { background: blue; line-height: 200px; } .line-box img { vertical-align: text-bottom; width: 50px; } .line-box span { margin-left: 20px; color: yellow; }
實例
通過IFC部分我們知道,之前的例子實際上有生成一個匿名行盒(line box),雖然他可以繼承父元素的屬性,但我們沒法直觀的去操作它?,OK,把這個匿名行盒變成可控的span元素就好了?,如上demo所示。
我們通過設(shè)置line box的line-height來控制line-box的高度,然后設(shè)置img的vertical-align屬性值,來觀察具體的對齊方式。OK,讀者你可以自行本地測試或是直接更改fiddle內(nèi)容來看效果。但這里很容易有個誤區(qū),就是父元素的middle,top這些值是怎么確定的?如上,我們通過更改img元素的vertical-align的值,來觀察區(qū)別,表面上看著好像是父元素根據(jù)Xx內(nèi)容來進(jìn)行確定的,實則不然。我們再來看一個例子:
下面沒內(nèi)容戳這
上面例子中,我們更改了Xx的對齊方式,發(fā)現(xiàn)了很奇特的現(xiàn)象?,當(dāng)Xx設(shè)置為text-bottom或是text-top的時候父元素(ling box)被撐大了?,但這另一方面這也證明了,父元素的基線和中線等并不是由文本Xx決定的,誰決定的呢?前面提過的那個空白節(jié)點決定的!?這個空白節(jié)點實際上是理解內(nèi)聯(lián)元素布局的重點!不知道它的存在,很多問題是搞不清楚的。那么這個空白節(jié)點又到底是怎么影響布局的呢?前面說過基線的決定著是小寫字母x,這個時候問題就來了,可能你早就想問了,不同字體下面的小寫字母x底部邊緣肯定是有區(qū)別的啊,好,我們在研究下font-family。
Font-family我們再來看一個?:
下面沒示例內(nèi)容請戳這
關(guān)于字體具體的知識可以看這篇博文,我簡單的總結(jié)一下重點。首先字體是有一個字體度量的概念的,
一款字體會定義一個 em-square,它是用來盛放字符的金屬容器。這個 em-square 一般被設(shè)定為寬高均為 1000 相對單位,不過也可以是 1024、2048 相對單位。
字體度量都是基于這個相對單位設(shè)置的,包括 ascender、descender、capital height、x-height 等。注意這里面的值是可以超出em-square范圍的。
在瀏覽器中,上面的 1000 相對單位會按照你需要的 font-size 縮放。
看上面的例子我們也能看出來,實際上一個內(nèi)聯(lián)元素是有兩個高度的content-area 高度(background-color實際渲染的那個高度)和 virtual-area 高度(實際區(qū)域占空間的高度也就是line-height)。?
結(jié)論
所有的內(nèi)聯(lián)元素都有兩個高度
基于字體度量的 content-area
virtual-area(也就是 line-height )
內(nèi)聯(lián)元素都有一個空白節(jié)點存在著來確定基線等概念;
基線的確定和字體有關(guān),和內(nèi)部的內(nèi)聯(lián)元素?zé)o關(guān);
IFC很難懂;
line-box(行盒) 的高度的受其子元素的 line-height 和 vertical-align 的影響;
我們貌似沒法用CSS來更改字體度量。
題目確實有些標(biāo)題黨的嫌疑了,實際上也沒有挖很深,比如vertical-align在inline-table元素的作用效果以及sup,sub等其他的屬性值,以及l(fā)ine-height具體的屬性值如何生效的都沒有涉及。我想把這篇文章重點放在布局上,而且篇幅也有限。沒涉及的請自行查閱資料吧,在此說聲抱歉。?
??以上。
后記? 從剛開始做前端,身邊CSS簡單易學(xué)但很坑的聲音就不絕于耳,很多人也說HTML、CSS一星期就能學(xué)會,現(xiàn)在漸漸覺得真是謬論。是,單純掌握浮動,定位,對齊,居中等基礎(chǔ)能解決一大半的布局問題,甚至百分之百,因為很多情況真的是變個寫法莫名其妙就實現(xiàn)了想要的結(jié)果。可能這也是很多人說CSS坑的原因,但實際上很多開發(fā)者是不看CSS標(biāo)準(zhǔn)的,模仿個網(wǎng)站或是看著視頻寫個demo就覺得掌握了CSS,遠(yuǎn)遠(yuǎn)不是這樣的。漸漸覺得深挖CSS要比深挖JavaScript難的多...你覺得CSS坑?誰讓你不看標(biāo)準(zhǔn)呢....??♀?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/115586.html
摘要:為了實現(xiàn)文字環(huán)繞效果,規(guī)范規(guī)定的措施是使父容器塌陷,元素脫離文檔流浮動產(chǎn)生,元素周圍的內(nèi)容轉(zhuǎn)換為圍繞元素排列。 選擇器注意點 屬性選擇器 [attr^=value] - 開頭或全等 [attr$=value] - 結(jié)尾或全等 [attr*=value] - 包含值 [attr~=value] - 字符串包含 選擇器組 A > B - 直接子節(jié)點 A + B - 下一個兄弟節(jié)點 A...
摘要:看上面的例子我們也能看出來,實際上一個內(nèi)聯(lián)元素是有兩個高度的高度實際渲染的那個高度和高度實際區(qū)域占空間的高度也就是。 前言 總括: 本文通過實例講解CSS中最大的難點之一,行內(nèi)元素的布局,主要是挖掘line-height和vertical-align兩個屬性在布局方面的使用。 原文博客地址:深入理解行內(nèi)元素的布局 知乎專欄&&簡書專題:前端進(jìn)擊者(知乎)&&前端進(jìn)擊者(簡書) 博...
摘要:深入布局盒模型元素分類在知識體系中,除了選擇器,樣式屬性等基礎(chǔ)知識外,布局相關(guān)的知識才是比較核心和重要的點。從元素的布局特性來分,主要可以分為三類元素塊級元素,行內(nèi)元素,行內(nèi)塊級元素。行內(nèi)級元素屬性取的元素。? 深入css布局(1)—— 盒模型 & 元素分類 ? ? ? 在css知識體系中,除了css選擇器,樣式屬性等基礎(chǔ)知識外,css布局相關(guān)的知識才是css比較核心和重要的點。今天我們...
摘要:深入布局盒模型元素分類在知識體系中,除了選擇器,樣式屬性等基礎(chǔ)知識外,布局相關(guān)的知識才是比較核心和重要的點。規(guī)定元素和屬性是包含元素的邊框內(nèi)邊距內(nèi)容的。后來微軟也慢慢轉(zhuǎn)向了的標(biāo)準(zhǔn),在以后支持了標(biāo)準(zhǔn)盒模型。行內(nèi)級元素屬性取的元素。 深入css布局(1)—— 盒模型 & 元素分類 ????在css知識體系中,除了css選擇器,樣式屬性等基礎(chǔ)知識外,css布局相關(guān)的知識才是css比較核心和重...
摘要:垂直格式化,有一個很重要的方面是會造成垂直相鄰?fù)膺吘嗪喜ⅲ鉀Q這個的方式見想要清晰的明白一中的部分。參考資料權(quán)威指南第三版為負(fù)值產(chǎn)生的影響和常見布局應(yīng)用布局圣杯布局雙飛翼布局深入理解和的基友關(guān)系深入理解中的行高 在上一篇想要清晰的明白(一): CSS視覺格式化模型|盒模型|定位方案|BFC比較宏觀的了解了盒子模型的作用,接下來就詳細(xì)的介紹兩種盒子的具體細(xì)節(jié) Block Box show...
閱讀 1023·2023-04-25 23:50
閱讀 2173·2021-11-19 09:40
閱讀 669·2019-08-30 13:50
閱讀 2783·2019-08-29 17:11
閱讀 1099·2019-08-29 16:37
閱讀 3081·2019-08-29 12:54
閱讀 2860·2019-08-28 18:17
閱讀 2724·2019-08-26 16:55