基本框
CSS假定每個元素都會生成一個或多個矩形框温眉,這稱為元素框慨绳。各元
素框中心有一個內(nèi)容區(qū)(content area)挟伙。這個內(nèi)容區(qū)周圍有可選的內(nèi)邊距、邊框和外邊距荐开。這些項之所以被認(rèn)為是可選的优床,是因為它們的寬
度可以設(shè)置為0,實際上這就從元素框去除了這些項誓焦。
可以用多種屬性設(shè)置各外邊距胆敞、邊框和內(nèi)邊距,如margin-left或border-bottom杂伟。內(nèi)容的背景(例如某種顏色或平鋪圖像)也會應(yīng)用到內(nèi)邊
距移层。外邊距通常是透明的,從中可以看到父元素的背景赫粥。內(nèi)邊距不能是負(fù)值观话,但是外邊距可以。
包含塊
每個元素都相對于其包含塊擺放越平,包含塊就是一個元素的布局上下文频蛔。
對于正常的西方語言文本流中的一個元素,包含塊由最近的塊級祖先框秦叛、表單元格或行內(nèi)塊祖先框的內(nèi)容邊界(content edge)構(gòu)成晦溪。
正常流
這是指西方語言文本從左向右、從上向下顯示挣跋,這也是我們熟悉的傳統(tǒng)HTML文檔的文本布局三圆,注意,在非西方語言中避咆,流方向可能不同舟肉。大多數(shù)元素都在正常流中,要讓一個元素不在正常流中查库,唯一的辦法就是使之成為浮動或定位元素路媚。這里我們談?wù)摰亩际窃谡A髦械脑亍?br>
塊級元素
這是指段落、標(biāo)題或div之類的元素樊销。這些元素在正常流中時整慎,會在其框之前和之后生成“換行”脏款,所以處于正常流中的塊級元素會垂直擺放。通過聲明display:block院领,可以讓元素生成塊級框弛矛。
行內(nèi)元素
這是指strong或span之類的元素,這些元素不會在之前或之后生成“行分隔符”比然,它們是塊級元素的后代丈氓。通過聲明display:inline∏糠ǎ可以讓元素生成一個行內(nèi)框万俗。
塊級元素
水平格式化
控制盒模型水平方向的有7個值:margin-left、border-left, padding-left饮怯、width闰歪、 padding-right、border-right和margin-right蓖墅。
這7個屬性的值加在一起必須是元素包含塊的寬度库倘,這往往是塊元素的父元素的width值。
關(guān)于auto
在這7個屬性中有3個可以設(shè)置為auto:margin-left论矾、width教翩、margin-right吗冤。其余的要不必須是確定的值罢杉,要不就是默認(rèn)值0。
有這么幾種情況:
- 3個都不是auto:按CSS的術(shù)語來講给郊,這些格式化屬性過分受限闰靴,此時總會把margin-right強制為auto來適應(yīng)父元素的寬度彪笼。
- 2個不是auto:這個最簡單,剩下的一個是auto的將自動調(diào)整到適應(yīng)父級元素的寬度蚂且。
- 兩個外邊距是auto:他們會自動設(shè)置為相等的長度配猫,導(dǎo)致此元素在其父級元素中居中。
- 一個外邊距和width是auto:auto的外邊距會減為0膘掰,width自動填充章姓。
- 3個都是auto:兩個外邊距減為0,width自動充滿识埋。
注意:由于水平外邊距不會合并,父元素的內(nèi)邊距零渐、邊距和外邊距可能影響其子元素窒舟。
負(fù)外邊距
這個是允許的,也只有它是允許為負(fù)值的诵盼,這個還有好多用處呢惠豺。
百分?jǐn)?shù)
百分?jǐn)?shù)也是可以的银还,當(dāng)然還是要遵守加起來為父元素寬度的限制,這里為內(nèi)外邊距洁墙,寬度設(shè)置的百分比都是相對父元素來說的蛹疯。邊框不能是百分?jǐn)?shù)。
替換元素
剛才說的是非替換塊級元素的水平格式化热监,替換塊級元素其他的規(guī)則都一樣捺弦,只有一個例外,當(dāng)width為auto 時孝扛,元素寬度為內(nèi)容的固有寬度列吼。
垂直格式化
一個元素的默認(rèn)高度由其內(nèi)容確定,可以對任何塊級元素設(shè)置顯式高度苦始。如果內(nèi)容撐不下寞钥,根據(jù)元素的overflow屬性用戶代理會做出選擇。
垂直屬性
也是有7個:margin-top陌选、border-top理郑、padding-top、height咨油、 padding-bottom您炉、border-bottom和margin-bottom。
同樣臼勉,這7個值的和必須等于其包含塊的height邻吭。
同樣有3個值可以是auto,其他的不行宴霸。不過上下外邊距設(shè)置為auto也沒有什么用囱晴,因為會被重置為0。
百分?jǐn)?shù)高度
父元素的高度如果沒有顯式聲明瓢谢,那子元素的高度設(shè)置為百分?jǐn)?shù)也會被重置為auto畸写。
利用上下外邊距auto垂直居中顯然是不可能的。
auto高度的問題
如果塊級正常流元素的高度設(shè)置為auto氓扛,而且只有塊級子元素枯芬,其默認(rèn)高度將是從最高塊級子元素的外邊框邊界到最低塊級子元素外邊框邊界
之間的距離。因此采郎,子元素的外邊距會“超出”包含這些子元素的元素(由于垂直合并外邊距)千所。
不過,如果塊級元素有上內(nèi)邊距或下內(nèi)邊距蒜埋,或者有上邊框或下邊框淫痰,其高度則是從其最高子元素的上外邊距邊界到其最低子元素的下外邊距邊界之間的距離。
合并垂直外邊距
垂直格式化的另一個重要方面是垂直相鄰?fù)膺吘嗟暮喜⒄荨_@種合并行為只應(yīng)用于外邊距待错。如果元素有內(nèi)邊距和邊框籽孙,它們的垂直外邊距絕對不會合并。
負(fù)外邊距
這個在垂直方向上也是允許的火俄,重疊的時候犯建,如果垂直外邊距都設(shè)置為負(fù)值,瀏覽器會取兩個外邊距絕對值的最大值瓜客。如果一個正外邊距與一個負(fù)外邊距合并适瓦,會從正外邊距減去這個負(fù)外邊距的絕對值。
行內(nèi)元素
除了塊級元素忆家,最常見的就是行內(nèi)元素了犹菇。通過為行內(nèi)元素設(shè)置框?qū)傩裕梢赃M入到一個更有意思的領(lǐng)域芽卿。非替換元素和替換元素在內(nèi)聯(lián)內(nèi)容方面的處理稍有不同揭芍,討論行內(nèi)元素的構(gòu)造時我們將分別進行討論。
一些概念
匿名文本
匿名文本(anonymous text)是指所有未包含在行內(nèi)元素中的字符串卸例。因此称杨,在標(biāo)記(p) I'm (em)so(/em) happy!(/p)中,序列“I'm”和 “happy!”都是匿名文本筷转。注意姑原,空格也是匿名文本的一部分,因為空格與其他字符一樣都是正常的字符呜舒。
em框
em框在字體中定義锭汛,也稱為字符框(character box)。實際的字形可能比其em框更高或更矮袭蝗。在CSS 中唤殴,font-size的值確定了各個em框的高度。
內(nèi)容區(qū)
在非替換元素中到腥,內(nèi)容區(qū)可能有兩種朵逝,CSS2.1規(guī)范允許用戶代理選擇其中任意一種。內(nèi)容區(qū)可以是元素中各字符的em框串在一 起構(gòu)成的框乡范,也可以是由元素中字符字形描述的框配名。
在替換元素中,內(nèi)容區(qū)就是元素的固有高度再加上可能有的外邊距晋辆、邊框或內(nèi)邊距渠脉。
行間距
行間距(leading)是font-size值和line-height值之差。這個差實際上要分為兩半瓶佳,分別應(yīng)用到內(nèi)容區(qū)的頂部和底部连舍。行間距只應(yīng)用于非替換元素。
行內(nèi)框
這個框通過向內(nèi)容區(qū)增加行間距來描述涩哟。對于非替換元素索赏,元素行內(nèi)框的高度剛好等于line-height的值。對于替換元素贴彼,元素行內(nèi)框的高度則恰好等于內(nèi)容區(qū)的高度潜腻,因為行間距不應(yīng)用到替換元素。
行框
這是包含該行中出現(xiàn)的行內(nèi)框的最高點和最低點的最小框器仗。換句話說融涣,行框的上邊界要位于最高行內(nèi)框的上邊界,而行框的底邊要放在最低行內(nèi)框的下邊界精钮。
還有幾點要格外注意:
- 內(nèi)容區(qū)類似于一個塊級元素的內(nèi)容框威鹿。
- 行內(nèi)元素的背景應(yīng)用于內(nèi)容區(qū)及所有內(nèi)邊距。
- 行內(nèi)元素的邊框要包圍內(nèi)容區(qū)及所有內(nèi)邊距和邊框轨香。
- 非替換元素的內(nèi)邊距忽你、邊框和外邊距對行內(nèi)元素或其生成的框沒有垂直效果,也就是說臂容,它們不會影響元素行內(nèi)框的高度(也不會影響包含該元素的行框的高度)科雳。
- 替換元素的外邊距和邊框確實會影響該元素行內(nèi)框的高度,相應(yīng)地脓杉,也可能影響包含該元素的行框的高度糟秘。
- line-height實際上只影響行內(nèi)元素和其他行內(nèi)內(nèi)容,而不影響塊級元素球散,至少不會直接影響塊級元素尿赚。也可以為一個塊級元素設(shè)置line-height值,但是這個值只是應(yīng)用到塊級元素的內(nèi)聯(lián)內(nèi)容時才會有視覺影響蕉堰。
對于一個行框凌净,其高度確定的基本步驟如下:
- 按以下步驟確定行中各元素行內(nèi)框的高度: 得到各行內(nèi)非替換元素及不屬于后代行內(nèi)元素的所有文本的font-size值和line-height值,再將line-height減去font-size嘁灯,這就 得到了框的行間距泻蚊。這個行間距除以2,將其一半分別應(yīng)用到em框的頂部和底部丑婿。 得到各替換元素的height性雄、margin-top、margin-bottom, padding-top羹奉、 padding-bottom, border-top-width和border-bottomwidth值秒旋,把它們加在一起。
- 對于各內(nèi)容區(qū)诀拭,確定它在整行基線的上方和下方分別超出多少迁筛。這個任務(wù)并不容易:你必須知道各元素及匿名文本各部分的基線的位置, 還要知道該行本身基線的位置耕挨,然后把它們對齊细卧。另外尉桩,對于替換元素,要將其底邊放在整行的基線上贪庙。
- 對于指定了vertical-align值的元素蜘犁,確定其垂直偏移量。由此可知該元素的行內(nèi)框要向上或向下移動多遠(yuǎn)止邮,并改變元素在基線上方或下 方超出的距離这橙。
- 既然已經(jīng)知道了所有行內(nèi)框會放在哪里,再來計算最后的行框高度导披。為此屈扎,只需將基線與最高行內(nèi)框頂端之間的距離加上基線與最低行內(nèi) 框底端之間的距離。
行內(nèi)非替換元素
我們來看看如果行中只包含非替換元素(或匿名文本)將如何構(gòu)造撩匕。
建立框
首先鹰晨,對于行內(nèi)非替換元素或匿名文本某一部分,font-size值確定了內(nèi)容區(qū)的高度滑沧。如果一個行內(nèi)元素font-size為15px并村,則內(nèi)容區(qū)的高度為 15像素,因為元素中所有em框的高度都是15像素滓技。
下面再來考慮元素的line-height值哩牍,以及它與font-size值之差。如果一個行內(nèi)非替換元素的font-size為15px令漂,line-height為21px膝昆,則相差6 像素。用戶代理將這6像素一分為二叠必,將其一半分別應(yīng)用到內(nèi)容區(qū)的頂部和底部荚孵,這就得到了行內(nèi)框。
假如纬朝,font-size為24px收叶,line-height為12px。line-height和font-size之差是-12px共苛,將其除2來確定半間距(-6px)判没,再把這個半間距分別增加到內(nèi)容區(qū)的頂部和底部,就得到了行內(nèi)框隅茎。由于這里增加的都是負(fù)數(shù)澄峰,所以最后行內(nèi)框高度為12像素。12像素高的行內(nèi)框在元素內(nèi)容區(qū)(24像素高)中垂直居中辟犀,所以行內(nèi)框?qū)嶋H上小于內(nèi)容區(qū)俏竞。 那么行框也就可能小于內(nèi)容區(qū)了,那就意味著內(nèi)容會重疊到相鄰行。
垂直對齊
vertical-align各個關(guān)鍵字值的效果描述如下:
- top:將元素行內(nèi)框的頂端與包含該元素的行框的頂端對齊魂毁。
- bottom:將元素行內(nèi)框的底端與包含該元素的行框的底端對齊玻佩。
- text-top:將元素行內(nèi)框的頂端與父元素內(nèi)容區(qū)的頂端對齊。
- text-bottom:將元素行內(nèi)框的底端與父元素內(nèi)容區(qū)的底端對齊漱牵。
- middle:將元素行內(nèi)框的垂直中點與父元素基線上0.5ex處的一點對齊夺蛇。
- super:將元素的內(nèi)容區(qū)和行內(nèi)框上移。上移的距離未指定酣胀,可能因用戶代理的不同而不同。
- sub:與super相同娶聘,只不過元素會下移而不是上移闻镶。
- percentage:將元素上移或下移一定距離。這個距離由相對于元素line-height值指定的一個百分?jǐn)?shù)確定丸升。
管理line-height
在前幾節(jié)中我們已經(jīng)了解到铆农,改變一個行內(nèi)元素的line-height可能導(dǎo)致文本行相互重疊。不過狡耻,在所有情況下墩剖,這種修改都是針對單個元素的,所以夷狰,如何以一種更一般的方式影響元素的line-height而避免內(nèi)容重疊呢?
一種方法是對font-size有改變的元素結(jié)合使用em單位岭皂。
<p>
Not only does this paragraph have "normal" text, but it also<br>
contains a line in which <span>some big text </span> is found.<br>
This large text helps illustrate our point.
</p>
p {
font-size: 14px;
line-height: 1em;
}
p span {
font-size: 250%;
line-height: 1em;
}
或者使用line-height數(shù)值值會被直接繼承而不是計算繼承的特性。
p {fpnt-size: 14px; line-height: 1;}
p span {font-size: 250%;}
基線與行高
各行框的具體高度取決于其組成元素相互之間如何對齊沼头。這種對齊往往很大程度上依賴于基線落在各元素(或匿名文本各部分)中的哪個位置爷绘,因為這個位置確定了其行內(nèi)框如何擺放〗叮基線在各em框中的位置對于不同的字體是不同的土至。這個信息內(nèi)里在字體文件中,除非直接編輯字體文件猾昆,否則無法修改陶因。
縮放行高
設(shè)置line-height的最好辦法是使用一個原始數(shù)字值。之所以說這種方法最好垂蜗,是因為這個數(shù)會成為縮放因子楷扬,而該因子是一個繼承值而非計算值。假設(shè)你希望一個文檔中所有元素的line-height都是其font-size的1.5倍么抗,可以如下聲明:
body {line-height: 1.5;}
縮放因子1.5在元素間逐層傳遞毅否,在各層上,這個因子都作為一個乘數(shù)與各元素的font-size相乘蝇刀。
增加框?qū)傩?/strong>
內(nèi)邊距螟加,外邊距和邊框都可以應(yīng)用于行內(nèi)非替換元素,行內(nèi)元素的這些方面根本不會影響行框的高度。
對于邊框來說:
行內(nèi)元素的邊框邊界由font-size而不是line-height控制捆探。換句話說然爆,如果一個span元素的font-size為12px,line-height為36px黍图,其內(nèi)容區(qū)就是12px高曾雕,邊框?qū)鼑搩?nèi)容區(qū)。
對于內(nèi)邊距來說:
左右內(nèi)邊距是有作用的助被。
上下內(nèi)邊距是會影響到元素行內(nèi)框的高度剖张,如果有邊框的話會看到邊框外擴了,有背景的話背景也會變大揩环。但是行框的高度是不會改變的搔弄,行間距自然也不變。
對于外邊距來說:
左右外邊距是有作用的丰滑。
上下外邊距根本不會應(yīng)用別想了顾犹。
要注意的是:
盡管內(nèi)邊距和外邊距(以及邊框)不影響行高,但是它們確實能影響一個元素內(nèi)容的布局褒墨,可能將文本推離其左右兩端炫刷。實際上,如果左、右外邊距為負(fù)郁妈,可能會把文本拉近行內(nèi)元素浑玛,甚至導(dǎo)致重疊。上下內(nèi)邊距過大的話背景和邊框會擴到另一行圃庭。
這個例子可以試試:
<p>
<span>Not only does this paragraph have "normal" text, but it also</span><br>
<span>contains a line in which some big text is found.</span>
<span>This <a href="www.baidu.com">Baidu</a> large text helps illustrate our point.</span>
</p>
span{
border:1px solid red;
line-height:1;
padding:4px;
margin:4px;
background-color: rgba(255,1,1,0.5);
}
行內(nèi)替換元素
一般認(rèn)為行內(nèi)替換元素(如圖像)有固有的高度和寬度锄奢。有固有高度的替換元素可能導(dǎo)致行框比正常要高。這不會改變行中任何元素的line-height值剧腻,包括替換元素本身拘央。相反,只是會讓行框的高度恰好能包含替換元素(以及所有框?qū)傩裕┦樵凇Q句話說灰伟,會用替換元素整體(包括內(nèi)容、外邊距儒旬、邊距和內(nèi)邊距)來定義元素的行內(nèi)框栏账。
<p>
Not only does this paragraph have "normal" text, but it also<br>
contains a line in which is found.<br>
This <img src="img/marker_red.png" alt="test image"> large text helps illustrate our point.
</p>
p {
font-size: 15px;
line-height: 18px;
}
p img {
height: 30px;
margin: 0;
padding: 0;
border: none;
}
這個例子里line-height是18px,img的height是30px栈源。所以img的行內(nèi)框是30px挡爵。行框的高度也因此被撐高了。盡管是這樣甚垦,但不論是段落還是圖像本身的line-height的有效值并沒有因此改變茶鹃。line-height對圖像的行內(nèi)框沒有任何影響涣雕。
然而行內(nèi)替換元素還是需要line-height來作為一個垂直對齊時的基準(zhǔn)。vertical-align的百分?jǐn)?shù)值要相對于元素的line-height來計算闭翩。
p img {
vertical-align: 50%;
}
比如剛才的例子再加一個這個挣郭,那img就會往上升18*50%px。
還有就是替換元素會繼承這個line-height疗韵,它本身或它的后代有可能會用到這個值兑障。
增加框?qū)傩?/strong>
在行內(nèi)替換元素上應(yīng)用框?qū)傩允谴_實會影響到行框的高度的。因為不同于行內(nèi)非替換元素蕉汪,它們會作為替換元素行內(nèi)框的一部分流译。
甚至是外邊距都會被包含在元素的行內(nèi)框中,負(fù)的外邊距也有用哦肤无,會減少替換元素的行內(nèi)框先蒋。
替換元素和基線
默認(rèn)地,行內(nèi)替換元素位于基線上宛渐,如果向替換元素增加下內(nèi)邊距、外邊距或邊框眯搭,內(nèi)容區(qū)會上移窥翩。替換元素并沒有自己的基線,所以相對來講最好的辦法是將其行內(nèi)框的底端與基線對齊鳞仙。因此寇蚊,實際上是下外邊距邊界與基線對齊。
改變元素顯示
比如將a標(biāo)簽改為塊顯示棍好,將li改為行內(nèi)顯示等仗岸,使用display屬性,我們可以將元素的顯示角色改變借笙。不過要注意的是扒怖,你改變的只是元素的顯示角色,而不是其本質(zhì)业稼。換句話說盗痒,讓一個段落生成行內(nèi)框并不會把這個段落真正變成一個行內(nèi)元素。因此低散,盡管鏈接可以放在一個段落中俯邓,但是鏈接卻不建議包圍段落。
行內(nèi)塊元素
看上去display:inline-block是一個混合產(chǎn)物熔号,實際上也確實如此稽鞭。
行內(nèi)塊元素作為一個行內(nèi)框與其他元素和內(nèi)容相關(guān)。換句話說引镊,它就像圖像一樣放在一個文本行中朦蕴,實際上篮条,行內(nèi)塊元素會作為替換元素放在行中。這說明梦重,行內(nèi)塊元素的底端默認(rèn)地位于文本行的基線上兑燥,而且內(nèi)部沒有行分隔符。在行內(nèi)塊元素內(nèi)部琴拧,會像塊級元素一樣設(shè)置內(nèi)容的格式降瞳。就像所有塊級或行內(nèi)替換元素一樣,行內(nèi)塊元素也有屬性width和height蚓胸,如果比周圍內(nèi)容高挣饥,這些屬性會使行高增加。下面的例子可以用作對比:
<div>
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>
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>
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>
div {
margin: 1em 0;
border: 1px solid;
}
p {
border: 1px dotted;
}
div:nth-child(1) p {
display: block;
width: 6em;
text-align: center;
}
div:nth-child(2) p {
display: inline;
width: 6em;
text-align: center;}
div:nth-child(3) p {
display: inline-block;
width: 6em;
text-align: center;
}
有時行內(nèi)塊元素很有用沛膳,例如:如果有5個超鏈接扔枫,你希望它們在一個工具條中寬度相等。為了讓它們分別占其父元素寬度的20%锹安,但是仍保持其為行內(nèi)元素短荐,可以聲明如下:
#navbar a {display: inline-block; width: 20%;}
計算值
display也是有計算值噠,如果元素是浮動元素或定位元素叹哭,display的計算值可以改變忍宋。如果為一個根元素聲明display值,計算值也可以改變风罩。實際上糠排,display、
position和float值會以很有意思的方式相互影響超升。