這一章主要講解下CSS在渲染的時(shí)候的理論原理冈涧。沒(méi)人或書籍能夠覆蓋到css的所有細(xì)節(jié),所以在我們?nèi)粘J褂弥杏龅絚ss的問(wèn)題的時(shí)候正蛙,了解CSS的渲染邏輯將有效幫助大家排查問(wèn)題督弓。
基本的盒模型
CSS的基本思想就是假定每個(gè)元素都是由1個(gè)或多個(gè)盒子組成的,稱為element boxes乒验。在每個(gè)box的中間有一塊內(nèi)容區(qū)域(content area),而包圍內(nèi)容區(qū)域的就是像padding愚隧, border, outline和margin的各種可選邊框锻全,之所以說(shuō)是可選的因?yàn)樗羞@些邊框的默認(rèn)寬度都是0狂塘,如下圖所示:
像padding录煤,border和margin都有各自的設(shè)置選項(xiàng),但outline就沒(méi)有了荞胡。另外內(nèi)容的背景也只應(yīng)用與padding內(nèi)部妈踊,margins都設(shè)置為透明的,這樣可以讓所有父元素的背景都看的見(jiàn)硝训。padding是不準(zhǔn)有負(fù)數(shù)的响委,但margin卻可以,在后面咱們會(huì)詳細(xì)討論窖梁。
我們先從border開(kāi)始赘风,border類型包括solid和inset(inset就是內(nèi)嵌的意思,看起來(lái)效果像凹槽)纵刘。border的顏色通過(guò)border-color設(shè)置邀窃,如果沒(méi)有被設(shè)置的話,那就默認(rèn)采用前景色(foreground color假哎,不清楚么瞬捕,如果說(shuō)元素內(nèi)容的顏色是不是清楚了),最后要記住border的寬度是不準(zhǔn)設(shè)置負(fù)值的舵抹。
快覽
首先我們來(lái)解釋下后面要用到的幾個(gè)重要的概念:
Normal flow:正常的流
這個(gè)指的是文本默認(rèn)的渲染順序肪虎,一般語(yǔ)言都是一樣的:從左到右,從上到下惧蛹。而在某些特殊的語(yǔ)言中會(huì)有所不同扇救,而咱們HTML語(yǔ)言其實(shí)也是遵循這一規(guī)則的,既然前面說(shuō)過(guò)每個(gè)元素都是box香嗓,所以正常的流的意思就是迅腔,元素的box默認(rèn)以這種順序排列。那怎么樣才能跳出這種normal flow呢靠娱?方法也有很多沧烈,可以設(shè)置為float, position像云, 或是flexible box 和grid layout锌雀。Nonreplaced element: 無(wú)法替代的元素
這主要指那種內(nèi)容放在document的元素,舉個(gè)例子迅诬,<p>就是一個(gè)無(wú)法替代的元素汤锨,因?yàn)槠湮谋緝?nèi)容就在元素自己當(dāng)中。Replaced element: 可替代元素
和上面相反百框,這里的元素是可以替換的闲礼,例如img元素,他其實(shí)就是指向一張圖片;同樣柬泽,大部分的表單元素也都是可替換的慎菲。Root element: 根元素
這個(gè)我們很熟悉了,就是document文檔樹的根節(jié)點(diǎn)锨并,像咱們常用HTML文檔露该,其根節(jié)點(diǎn)就是html;而在XML文檔中第煮,根節(jié)點(diǎn)可以任意指定解幼,例如RSS文件的根節(jié)點(diǎn)就是rss。Block box
block的盒子它就像積木一樣是縱向堆疊的包警,常用的有段落p撵摆,標(biāo)題h1~6,和最常用的div害晦。想要生成block盒子的元素可以通過(guò)聲明display:block來(lái)實(shí)現(xiàn)特铝。Inline box
跟block相對(duì)的就是inline box, 常見(jiàn)的inline類型有strong和span等壹瘟。如果想要變成inline box 只要聲明display:inline就好鲫剿。Inline-block box
這個(gè)box在內(nèi)部表現(xiàn)的像block,而在外部表現(xiàn)的像inline稻轨。就是有點(diǎn)像可替換元素灵莲。
除了以上的這幾種盒子,其實(shí)還有像table-ce的其他盒子殴俱,由于各種原因就不一一細(xì)說(shuō)了笆呆。
containing block
對(duì)于CSS的盒子來(lái)說(shuō),父元素的box是很重要的粱挡,類似于編程的繼承,子元素也會(huì)繼承父元素的框架上下文(layout context)俄精。在CSS中定義了一系列的規(guī)則來(lái)確定盒子的containing block询筏。
來(lái)看個(gè)具體的例子:
<body>
<div>
<p>This is a paragraph.</p>
</div>
</body>
p的containing box就是div,而div的就是body竖慧。而這個(gè)body因?yàn)槭堑谝粋€(gè)元素被稱為初始的containing box嫌套,之所以這么特殊,單獨(dú)命名因?yàn)橐暱趘iewport決定了該元素的布局大小圾旨,而不是由根元素的內(nèi)容大小決定的踱讨。
調(diào)整element顯示display
在css中應(yīng)該是最重要的一個(gè)屬性了:
改變默認(rèn)的顯示方式
<nav>
<a href="index.html">WidgetCo Home</a>
<a href="products.html">Products</a>
<a href="services.html">Services</a>
<a href="fun.html">Widgety Fun!</a>
<a href="support.html">Support</a>
<a href="about.html" id="current">About Us</a> <a href="contact.html">Contact</a>
</nav>
nav默認(rèn)誰(shuí)inline的布局,如果我們想要改變他的顯示方式砍的,可以這樣設(shè)置:
nav a {display: block;}
這會(huì)使所有的a元素都以block的元素來(lái)呈現(xiàn)痹筛。
下面再考慮另一種情況,就是把block的元素改變從inline的
<ul id="rollcall">
<li>Bob C.</li>
<li>Marcio G.</li>
<li>Eric M.</li>
<li>Kat M.</li>
<li>Tristan N.</li>
<li>Arun R.</li>
<li>Doron R.</li>
<li>Susie W.</li>
</ul>
#rollcall li {display: inline; border-right: 1px solid; padding: 0 0.33em;}
#rollcall li:first-child {border-left: 1px solid;}
雖然大部分時(shí)候都可以這樣來(lái)操作,但是h5本身是有限制的帚稠,即block元素包含inline元素可以谣旁,但是inline元素中包含block是不允許的,尤其是對(duì)于某些默認(rèn)的inline和block元素滋早,來(lái)看個(gè)例子:
<span style="display: block;">
<p style="display: inline;">this is wrong!</p>
</span>
上面的強(qiáng)行轉(zhuǎn)換其實(shí)是沒(méi)用的榄审,display只能改變?cè)氐恼故荆环Ω淖冊(cè)氐念愋透唆铮杂行└愋蛷?qiáng)綁定的屬性是無(wú)法通過(guò)display來(lái)修改的搁进。
接下面我們就來(lái)看看不同的box:包括block box, inline box昔头, inline-block box 和list-item box饼问。
Block box
block 盒子其實(shí)用的是最多的布局元素,但有時(shí)候其顯示會(huì)超出你的預(yù)期减细,這就需要對(duì)該盒子的某些邊界有清楚的了解匆瓜,來(lái)看看下面這張圖:
默認(rèn)來(lái)說(shuō),block box的寬度設(shè)置的是left inner edge 到right inner edge的距離未蝌,height同理驮吱。
不過(guò)我們可以通過(guò)設(shè)置box-sizing屬性來(lái)修改這一規(guī)則:
這個(gè)屬性就是用來(lái)設(shè)置widht和height的定義規(guī)則的,默認(rèn)的上面說(shuō)了萧吠,如果設(shè)置為border-box左冬,那么其寬度的界定將基于左右border邊界的距離,同理可知padding-box的含義纸型。
box-sizing水平的變化
通過(guò)改變box-sizing會(huì)導(dǎo)致水平方向計(jì)算的變化拇砰,來(lái)看個(gè)例子:
<p style="width: 200px; padding: 10px; margin: 20px;">wideness?</p>
水平方向的屬性
共有7個(gè)屬性決定水平的長(zhǎng)度:margin-left, border-left, padding-left, width, padding-right, border-right 和 margin-right。具體參照下圖:
之前有提到過(guò)的一個(gè)containing block的概念狰腌,其寬度就是這7中長(zhǎng)度的和除破。而在這7個(gè)值里面,只有三個(gè)是默認(rèn)設(shè)置為auto的琼腔,那三個(gè)呢瑰枫?左右的margin和width,其余的值都需要設(shè)置數(shù)值丹莲,有些的默認(rèn)值為0.
而width只能出現(xiàn)2中情況光坝,auto和非負(fù)的數(shù)值。
使用auto
auto的意思就是自動(dòng)調(diào)整甥材,調(diào)整的目標(biāo)就是子元素的整個(gè)長(zhǎng)度等于父元素的寬度盯另。
那有人就問(wèn)啦,如果三個(gè)auto都設(shè)置了具體值洲赵,那怎么計(jì)算呢鸳惯?這在CSS中有個(gè)專有名詞overcontrained商蕴,意思就是限制過(guò)多了,那么css就用將margin-right強(qiáng)制設(shè)置為auto悲敷。
div {width: 500px;}
p {margin-left: 100px; margin-right: 100px;
width: 100px;} /* right margin forced to be 300px */
如果左右margin都設(shè)置了究恤,但width為auto,那么width就承擔(dān)起自動(dòng)填充的任務(wù):
p {margin-left: 100px; margin-right: 100px; width: auto;}
多個(gè)auto的情況
比如margin都設(shè)置為auto后德,那么左右都會(huì)設(shè)置相同的長(zhǎng)度部宿,來(lái)看個(gè)例子:
div {width: 500px;}
p {width: 300px; margin-left: auto; margin-right: auto;}
/* each margin is 100 pixels wide, because (500-300)/2 = 100 */
所以很多想要居中的內(nèi)容都是講margin設(shè)置為auto來(lái)實(shí)現(xiàn)的。
最后一種情況就是三個(gè)都設(shè)置為auto瓢湃,那么margin就會(huì)都被設(shè)置為0理张,width會(huì)盡量填充父元素寬度。
負(fù)的margin
來(lái)看個(gè)例子:
div {width: 500px; border: 3px solid black;}
p.wide {margin-left: 10px; width: auto; margin-right: -50px; }
看起來(lái)已經(jīng)超出了父元素的范圍绵患,但在數(shù)學(xué)上還是對(duì)的:
10px+0+0+540px+0+0?50px = 500px
還記得之前說(shuō)的auto么雾叭,在這里,我們同樣可以通過(guò)設(shè)置auto來(lái)抵消子元素的邊界超出問(wèn)題:
div {width: 500px; border: 3px solid black;}
p.wide {margin-left: 10px; width: 600px; margin-right: auto;
border: 3px solid gray;}
對(duì)應(yīng)的公式如下:
10px+3px+0+600px+0+3px?116px = 500px
記住padding落蝙, border 和width是不能有負(fù)數(shù)的织狐。
百分比
有時(shí)候百分比還是很有用的,尤其是在動(dòng)態(tài)確定寬度比例的情況下:
<p style="width: 67%; padding-right: 5%; padding-left: 5%; margin-right: auto; margin-left: 5%;">playing percentages</p>
不過(guò)如果要混合使用百分比和具體數(shù)值的話會(huì)讓人很困惑:
<p style="width: 67%; padding-right: 2em; padding-left: 2em; margin-right: auto; margin-left: 5em;">mixed lengths</p>
值的注意的是border是不接受百分比值的筏勒。
可替換元素
對(duì)于圖片元素這種可替換元素來(lái)說(shuō)移迫,如果width指定為auto,那么元素的width將會(huì)是元素內(nèi)容的實(shí)際寬度:
<img src="smile.svg" style="display: block; width: auto; margin: 0;">
當(dāng)然我們應(yīng)該設(shè)置圖片的實(shí)際寬度:
<img src="smile.svg" style="display: block; width: 25px; margin: 0;">
<img src="smile.svg" style="display: block; width: 50px; margin: 0;">
<img src="smile.svg" style="display: block; width: 100px; margin: 0;">
垂直方向的格式化
剛說(shuō)完水平的管行,下來(lái)來(lái)看看垂直高度的幾個(gè)有趣的地方枢赔。首先是一個(gè)元素的內(nèi)容決定了元素的默認(rèn)高度起胰,同時(shí)內(nèi)容的寬度也會(huì)影響高度令蛉。那就會(huì)出現(xiàn)兩個(gè)問(wèn)題狸膏,自己設(shè)置的高度高于內(nèi)容高度,自己設(shè)置的高度低于內(nèi)容高度迅涮。對(duì)于前者废赞,會(huì)保留正常的空白;而對(duì)于后者叮姑,則依賴于另一個(gè)屬性overflow:
垂直方向?qū)傩?/h2>
對(duì)照水平方向唉地,也是有7個(gè)屬性:margin-top, border-top, padding-top, height, padding-bottom, border-bottom, and margin-bottom.
跟水平一樣,垂直方向的auto也是這三個(gè):
auto的觸發(fā)規(guī)則與水平方向是一樣的戏溺。
百分比高度
<div style="height: 6em;">
<p style="height: 50%;">Half as tall</p>
</div>
其中p的高度就是3em。由于top和bottom的margin如果設(shè)置為auto都會(huì)被強(qiáng)制設(shè)置為0屠尊,因此想要垂直居中的方式就是各設(shè)置為25%旷祸。但萬(wàn)一父元素的高度沒(méi)有設(shè)置,那么這個(gè)百分比高度就會(huì)被重置為auto:
<div style="height: auto;">
<p style="height: 50%;">NOT half as tall; height reset to auto</p>
</div>
垂直方向margin的合并
合并(可能翻譯不太準(zhǔn)確讼昆,英文為collapsing)托享, 只會(huì)發(fā)生在margin中,而不會(huì)在padding和border中。
舉個(gè)例子:
li {margin-top: 10px; margin-bottom: 15px;}
在一串li中設(shè)置每個(gè)的上下margin間距闰围,一般是不是都會(huì)以為每個(gè)li的間距應(yīng)該是25px赃绊,而實(shí)際上結(jié)果卻是15px。這是因?yàn)榘l(fā)生了合并羡榴,在兩個(gè)相鄰的margin中會(huì)選取其中大的那個(gè)碧查。
再來(lái)看個(gè)例子:
ul {margin-bottom: 15px;}
li {margin-top: 10px; margin-bottom: 20px;}
h1 {margin-top: 28px;}
從上面可知,這次li和h1的實(shí)際間隔其實(shí)是28px
負(fù)的margin和合并collapsing
來(lái)看另一個(gè)例子:
p.neg {margin-top: -50px; margin-right: 10px; margin-left: 10px; margin-bottom: 0; border: 3px solid gray;}
<div style="width: 420px; background-color: silver; padding: 10px; margin-top: 50px; border: 1px solid;">
<p class="neg"> A paragraph.
</p>
A div.
</div>
再來(lái)看個(gè)margin為負(fù)的例子:
p.neg {margin-bottom: -50px; margin-right: 10px; margin-left: 10px; margin-top: 0;
border: 3px solid gray;}
<div style="width: 420px; margin-top: 50px;"> <p class="neg">
A paragraph.
</p> </div>
<p>
</p>
List Item
我們常用的list item本身其實(shí)是有不少特殊的顯示規(guī)則的校仑,比如marker忠售,圓點(diǎn)和數(shù)字,而且這些都不在內(nèi)容區(qū)域中迄沫,所以上面所說(shuō)的一系列css規(guī)則在他們身上也是通用的:
內(nèi)聯(lián)元素
介紹完了block元素就可以來(lái)看看inline元素了稻扬,常見(jiàn)的有em和a標(biāo)簽,這兩個(gè)都是不可替代的羊瘩,而像image則是可替代的元素泰佳。注意我們后面討論的內(nèi)容不適用于table元素,在CSS2中引入了很多新的屬性和行為來(lái)出來(lái)表單元素的顯示尘吗,而這遠(yuǎn)遠(yuǎn)超過(guò)了本書的范圍逝她。
可替換和不可替換的元素在inline模式下CSS的處理是有所區(qū)別的。
Line Layout 線框
首先我們要確定的就是inline的內(nèi)容是怎么放的摇予,因?yàn)檫@不像block元素那么簡(jiǎn)單的創(chuàng)建個(gè)block 盒子汽绢,而且其他元素是不能共存在同一塊區(qū)域的。那人們自然會(huì)很好奇侧戴,inline元素在block元素中是如何展示及修改樣式的宁昭。
為了了解線是怎么生成的,首先來(lái)看下單行長(zhǎng)文本的情況酗宋,如下圖所示:
span {border: 1px dashed black;}
我們給span元素設(shè)置了一個(gè)簡(jiǎn)單的虛線邊框积仗。
基本概念
在我們進(jìn)一步深入之前,讓我們來(lái)回顧下線框中用到的基本概念:
- 匿名文本:
這個(gè)主要指的是沒(méi)有包含在inline元素里面的內(nèi)容蜕猫,比如
<p> I'm <em>so</em> happy!</p>
其中的i'm happy寂曹!就是匿名文本,注意空格也算是字符回右。
Em box
這是在給定字體中定義的隆圆,或者稱為字符box。在CSS中期em box的高度由font-size來(lái)定義翔烁。leading
leading其實(shí)是font-size和line-height的差渺氧。一般來(lái)說(shuō),這個(gè)差值將會(huì)一分為二蹬屹,均勻分布在內(nèi)容區(qū)域的top和bottom部分侣背。leading只會(huì)應(yīng)用在不可替換的元素上面白华。
inline 不可替換元素
接下來(lái)我們就來(lái)一步步 看下inline元素的創(chuàng)建過(guò)程,首先引入的是font-size的大小來(lái)決定內(nèi)容區(qū)域的高度贩耐。如果一個(gè)元素的font-size為15px的話弧腥,那么內(nèi)容區(qū)域的高度就是15px,如下圖所示:
接下來(lái)需要考慮的就是元素的行高,同時(shí)注意與font-size的高度差潮太。如果元素的font-size=15px而line-height=21px那么這個(gè)差就是6px管搪,接下來(lái)瀏覽器會(huì)將這6px均分到上下兩部分,如下圖所示:
讓我們假定下面是沒(méi)問(wèn)題的:
<p style="font-size: 12px; line-height: 12px;">
This is text, <em>some of which is emphasized</em>, plus other text<br> which is <strong style="font-size: 24px;">strongly emphasized</strong> and which is<br>
larger than the surrounding text.
</p>
可以看到消别,大多數(shù)文本的字體大小為12px抛蚤,而strong的行高為24px,但由于行高是繼承的寻狂,所以strong繼承的行高為12px岁经。對(duì)于strong來(lái)說(shuō)line-height與font-size的差為-12px,所以上下都有-6px的分配蛇券,所以strong所代表的inline box是要小于內(nèi)容區(qū)域的缀壤,最后的效果如下圖所示。
從上圖看出纠亚,中間那行會(huì)比其他兩行高塘慕,但卻沒(méi)有完全包裹全部的文本內(nèi)容。
垂直對(duì)齊
如果我們改變inline box的垂直對(duì)齊方式蒂胞,高度計(jì)算的原理還是一樣的:
<p style="font-size: 12px; line-height: 12px;">
This is text, <em>some of which is emphasized</em>, plus other text<br> which is <strong style="font-size: 24px; vertical-align: 4px;">strongly emphasized</strong> and that is<br>
larger than the surrounding text.
</p>
上面的變化同時(shí)抬升了storng元素的內(nèi)容區(qū)域和inline box图呢,因?yàn)閟trong元素決定這inline box的上邊界,因此這一改變會(huì)同時(shí)抬升inline box的上邊界:
讓我們考慮另一種情況:
<p style="font-size: 12px; line-height: 12px;">
This is text, <em>some of which is emphasized</em>,<br>
plus other text that is <strong style="font-size: 24px;">strong</strong>
and <span style="vertical-align: top;">tall</span> and is<br> larger than the surrounding text.
</p>
雖然樣式跟之前是一樣的骗随,但又沒(méi)有發(fā)現(xiàn)tall文本的高度對(duì)齊到了inline box的上邊界蛤织。因?yàn)閠all的文本具有相同的fontsize和line-height。
再來(lái)看下:
<p style="font-size: 12px; line-height: 12px;">
This is text, <em>some of which is emphasized</em>,<br>
plus other text that is <strong style="font-size: 24px;">strong</strong>
and <span style="vertical-align: top; line-height: 2px;">tall</span> and is<br> larger than the surrounding text.
</p>
由于tall文本的行高小魚font-size鸿染,tall文本的inline box小魚內(nèi)容其余指蚜,這一小小的改變改變了tall文本的高度:
再來(lái)看看設(shè)置tall行高高于font-size的情況:
<p style="font-size: 12px; line-height: 12px;">
This is text, <em>some of which is emphasized</em>, plus other text<br> that is <strong style="font-size: 24px;">strong</strong>
and <span style="vertical-align: top; line-height: 18px;">tall</span> and that is<br>
larger than the surrounding text.
</p>
最后結(jié)合本章內(nèi)容總結(jié)下vertical-align的關(guān)鍵詞:
- top:對(duì)齊元素inline box的上邊界
- bottom: 對(duì)齊元素inline box的下邊界
- text-top: 對(duì)齊父元素文本上邊界
- text-bottom: 對(duì)齊父元素文本下邊界
- middle: 對(duì)齊元素inline box的垂直中點(diǎn)
- super: 上移內(nèi)容區(qū)域和inline box,具體依賴瀏覽器實(shí)現(xiàn)
- sub:跟super一樣涨椒,下移內(nèi)容
- <百分比>:基于line-height的百分比來(lái)移動(dòng)
管理行高
為了防止重疊摊鸡,我們建議使用em單位:
p {line-height: 1em;}
big {font-size: 250%; line-height: 1em;}
<p>
Not only does this paragraph have "normal" text, but it also<br> contains a line in which <big>some big text</big> is found.<br> This large text helps illustrate our point.
</p>
通過(guò)設(shè)置big的行高,我們?cè)龃罅藢?duì)應(yīng)inline box蚕冬,而且不用改變所有行的行高免猾。同時(shí)1em正好對(duì)應(yīng)字體的大小:
設(shè)置行高的比例因子
最好的設(shè)置行高的方式就是設(shè)置純數(shù)字囤热,可以被所有的元素所繼承:
body {line-height: 1.5;}
p {font-size: 15px; line-height: 1.5;} small {font-size: 66%;}
big {font-size: 200%;}
<p>This paragraph has a line-height of 1.5 times its font-size. In addition, any elements within it <small>such as this small element</small> also haveline-heights 1.5 times their font-size...and that includes <big>this big element right here</big>. By using a scaling factor, line-heights scale to match the font-size of any element.</p>
p {font-size: 15px; line-height: 1.5;} small {font-size: 66%;}
big {font-size: 200%; line-height: 1em;}
添加box 屬性
想看看為inline 元素添加border的效果么:
inline元素的border屬性其實(shí)是由font-size控制的猎提,而不是line-height。 換句話說(shuō)赢乓,如果一個(gè)span元素的font-size為12px然后行高為36px忧侧,那么其實(shí)際的內(nèi)容區(qū)域的高度還是12px。但是border還是會(huì)包裹在inline元素周圍的.
接下來(lái)來(lái)看看padding屬性牌芋,padding的添加并不會(huì)改變內(nèi)容的高度
span {padding: 4px;}
改變breaking 行為
在上一節(jié)蚓炬,我們看到了一個(gè)inline不可替代元素跨行顯示的例子,它本身其實(shí)是單行的文本躺屁,每個(gè)字符被單獨(dú)的box包圍肯夏,行末被單獨(dú)分割。這種默認(rèn)的行為可以通過(guò)box-decoration-break來(lái)修改:
就兩個(gè)值:slice和clone犀暑。slice就是之前的默認(rèn)值驯击。而對(duì)于clone,其主要特定為將每個(gè)片段都作為獨(dú)立得box耐亏,那這個(gè)獨(dú)立是什么意思呢徊都?來(lái)看個(gè)例子:
發(fā)現(xiàn)在下方的clone選項(xiàng)里面,背景圖案不依賴文本獨(dú)立克隆了背景信息广辰。box-decoration-break屬性雖然大多用在inline box中暇矫,不過(guò)其實(shí)它適用于任何的存在break的元素中。
inline 可替換元素
說(shuō)到可替換元素择吊,直接想到的就是img了李根。如下圖所示:
p {font-size: 15px; line-height: 18px;}
img {height: 30px; margin: 0; padding: 0; border: none;}
可替換元素最大的特點(diǎn)就是就有自己的固有高度和寬度,而這是會(huì)影響布局的几睛,在inline 元素中嵌入img房轿,那么整行的line box就會(huì)被img的高度給撐開(kāi)(假如img固有高度大于line-height)。上圖中所森,由于圖片沒(méi)有margin囱持,padding,border必峰,因此inline box的高度就等于img的content 高度洪唐,也就是30px。
p {font-size: 15px; line-height: 18px;}
img {vertical-align: 50%;}
<p>the image in this sentence <img src="test.gif" alt="test image"> will be raised 9 pixels.</p>
替代元素和baseline
從上面的討論中可以明白inline的可替換元素默認(rèn)情況下是沿著baseline來(lái)排布的吼蚁。如果元素有底部的padding,margin或是border的話,那么內(nèi)容區(qū)域也會(huì)相應(yīng)的抬升凭需。而由于替代元素自己是沒(méi)有baseline的,所以對(duì)齊的就是inline box的baseline:
inline-block 元素
inline-block是在CSS2.1引入的聚合屬性肝匆,融合了inline和block粒蜈。那這個(gè)inline-block到底是什么意思呢?其核心就表現(xiàn)為對(duì)外顯示inline屬性旗国,就像image一樣枯怖,而對(duì)內(nèi)則表現(xiàn)出block屬性,可以設(shè)置相應(yīng)的width和height屬性能曾。讓我們來(lái)看個(gè)具體的例子:
<div id="one">
This text is the content of a block-level level element. Within this block-level element is another block-level element. <p>Look, it's a block-level paragraph.</p> Here's the rest of the DIV, which is still block-level.
</div>
<div id="two">
This text is the content of a block-level level element. Within this block-level element is an inline element. <p>Look, it's an inline paragraph.</p> Here's the rest of the DIV, which is still block-level.
</div>
<div id="three">
This text is the content of a block-level level element. Within this block-level element is an inline-block element. <p>Look, it's an inline-block paragraph.</p> Here's the rest of the DIV, which is still block-level.
</div>
然后在上面的三個(gè)div分別應(yīng)用下面的樣式:
div {margin: 1em 0; border: 1px solid;}
p {border: 1px dotted;}
div#one p {display: block; width: 6em; text-align: center;}
div#two p {display: inline; width: 6em; text-align: center;} div#three p {display: inline-block; width: 6em; text-align: center;}
再舉個(gè)具體的使用例子度硝,比如在導(dǎo)航欄中有5個(gè)鏈接肿轨,一邊想要他們inline顯示,而同時(shí)要設(shè)置他們的寬度為父元素的20%蕊程,name就可以使用inline-block來(lái)設(shè)置:
nav a {display: inline-block; width: 20%;}
Flow 顯示
flow和flow-root的屬性還是值得一說(shuō)的椒袍。其實(shí)CSS的顯示分為兩個(gè)類型:外部類型和內(nèi)部類型。像之前說(shuō)的inline藻茂,block都是控制外部類型顯示的驹暑,而flow就表示內(nèi)部元素的排列方式。
display:flow默認(rèn)會(huì)同時(shí)綁定block和inline的外部框架辨赐,如果沒(méi)有定義inline优俘,name就以block形式展示:
#first {display: flow;}
#second {display: block flow;}
#third {display: inline flow;}
上面的例子中first和second顯示結(jié)果為block,而third則表現(xiàn)為inline box掀序。
所以一般在display后面的參數(shù)中帆焕,第一個(gè)表示外部類型,而第二個(gè)表示內(nèi)部類型不恭。比如:display: inline table视搏。含義就是在外面以inline形式表示,而對(duì)內(nèi)則生成一個(gè)table的上下文县袱。
說(shuō)完了flow浑娜,下面看看flow-root,這個(gè)值和flow不一樣式散,默認(rèn)就是block類型的筋遭。這個(gè)值一般是針對(duì)root 元素的,一般就是html暴拄。
最后來(lái)看下display 新老值得對(duì)應(yīng)關(guān)系:
老的值 | 新的值 |
---|---|
block | block flow |
inline | inline flow |
inline-block | inline flow-root |
list-item | list-item inline flow |
table | block table |
inline-table | inline table |
flex | block flex |
inline-flex | inline flex |
grid | block grid |
inline-grid | inline grid |
內(nèi)容顯示
另一個(gè)新增的display值就是contents漓滔,這個(gè)值的用處試講元素從頁(yè)面格式中去除。來(lái)看個(gè)例子:
ul {border: 1px solid red;}
li {border: 1px solid silver;}
<ul>
<li>The first list item.</li>
<li>List Item II: The Listening.</li>
<li>List item the third.</li>
</ul>
上面的例子會(huì)渲染一個(gè)帶紅色白框的ul list乖篷,而如果我們?cè)趗l上加上display:contents,name瀏覽器在渲染的時(shí)候就會(huì)像忽略外框的ul一樣响驴,如圖所示:
其他的display值
在本章中我們其實(shí)還有很多display的值沒(méi)有被覆蓋到,大多數(shù)都是跟ruby相關(guān)的值撕蔼,直到2018年底也沒(méi)得到很好的支持豁鲤。
計(jì)算得出的值
如果元素設(shè)置為float或是position,那么計(jì)算出的display值也可能發(fā)生變化鲸沮。事實(shí)上琳骡,display,position和float這三個(gè)值是有制約關(guān)系的讼溺。
如果一個(gè)元素的position設(shè)置為absolute楣号,那么float就被自動(dòng)設(shè)為none。而對(duì)于浮動(dòng)和絕對(duì)定位的元素,其計(jì)算值由下表給出:
小結(jié)
雖然CSS的format模型在有些地方是反直覺(jué)的炫狱,但隨著使用的深入會(huì)慢慢理解它們藻懒。block元素是比較好理解的,而inline元素相比較就會(huì)顯得比較麻煩视译。