前面兩章講到了CSS的一些基礎用法量没,這一章主要聚集于CSS的框結構和布局等玉转。
基本框
CSS認為每一個元素都會生成一個或多個矩形框,這些被稱為元素框殴蹄。實際上究抓,框不一定要是矩形的猾担,不過就現(xiàn)在來講,框都是矩形的刺下。將框想像為矩形绑嘹,也更加方便大家對框結構進行理解。
每一個元素框都具有外邊距橘茉、框和內(nèi)邊距工腋。元素內(nèi)容的背景會應用到內(nèi)邊距,但是不會應用到外邊距捺癞。外邊距一般是透明的夷蚊,透過外邊距可以看到父元素的背景。內(nèi)邊距不能為負值髓介,外邊距可以惕鼓。
如果元素未設置邊框顏色,則邊框顏色默認取元素的前景顏色唐础。如果邊框樣式有某種縫隙箱歧,那么透過這些縫隙應該是可以看到元素的背景的。
塊級元素
一般的一膨,一個元素的width
被定義為從左內(nèi)邊界到右內(nèi)邊界的距離呀邢,height
則是從上內(nèi)邊距到下內(nèi)邊界的距離。在大多情況下豹绪,文檔的高度和寬度都是由瀏覽器自動確定的价淌。
水平格式化
width影響的是元素內(nèi)容區(qū)的寬度,而非整個可見的元素框瞒津。如元素<p style="width: 200px; border: 1px solid #ccc; padding: 0 5px; margin: 0 5px">
蝉衣,其width
為200px
,但是在默認的盒模型下巷蚪,該元素的實際寬度為200px + 1px * 2 + 5px * 2 + 5px * 2 = 222px
病毡。在CSS3中,引入了box-sizing
屬性來控制盒模型屁柏。為了盡量簡化理解啦膜,我們這里都默認使用的box-sizing
為content-box
,或者假裝暫時不知道box-sizing
屬性淌喻。
水平屬性
水平屬性的七大基本屬性是:margin-left
僧家、border-left
、padding-left
裸删、width
啸臀、padding-right
、border-right
和margin-right
。這七個屬性中乘粒,只有margin-left
、width
和margin-right
可以設置為auto
伤塌,其余屬性必須要設定為特定的值灯萍。
大家要記住一點,元素框的寬度(之和)應該等為父元素的width
每聪。因此旦棉,如果以上三個可以設置為auto
的屬性中有一個被設置為auto
時,該屬性的值由其余兩個被指定的屬性以及父元素的width
來決定药薯。那么绑洛,如果用戶“強迫癥”式地為三個屬性都指定了值,但是其指定值不能滿足子元素框與父元素width
之間的關系(過度受限)童本,會發(fā)生什么呢真屯?這種情況下,在從左往右的閱讀模式中穷娱,margin-right
會被自動設置為auto
绑蔫;從右往左閱讀模式時情況則正好相反。
在不止一個auto
的情況下泵额,需要進行分類討論:
-
如果兩個邊距都設置為
auto
配深,則它們會被設置為相等的值,而最終達到的效果則是元素會相對于父元素進行水平居中顯示嫁盲。大家要注意這與text-align
的區(qū)別:text-align
是對元素內(nèi)部的內(nèi)容進行居中篓叶,而自動左右外邊距則是會將元素進行居中。
如果
width
和外邊距之一被設置為auto
羞秤, 余下的另一個外邊距被設置為指定值缸托,則設置為auto
的外邊距會被自動設置為0
。如果三個屬性都被設置為
auto
锥腻,則左右外邊距都會被設置為0
嗦董,width
保持為auto
,最終會使元素的內(nèi)容區(qū)盡可能得寬瘦黑。這種情況是默認情況京革,即用戶不顯式地設置這三個值時,瀏覽器會默認進行這樣的處理幸斥。
負外邊距
如果我們?yōu)樵卦O置了負外邊距匹摇,那么會是怎樣的顯示效果呢?
舉個例子:
div {width: 400px; border: 3px solid black}
p.wide {margin-left: 10px; width: auto; margin-right: -50px; background: #eee}
這樣會得到什么效果甲葬?
你會看到子元素的內(nèi)容超出了父元素的內(nèi)容區(qū)廊勃,視覺上會覺得子元素比父元素寬。那么,這樣的情況有違反之前說的“元素框的寬度(之和)應該等為父元素的
width
”這樣的規(guī)則嗎坡垫?
答案是:沒有梭灿。
為什么呢?因為此時元素的width
的值為440px
冰悠,大家可以計算一下堡妒,上述原則在這樣的情況下是否成立。
正是由于這種情況溉卓,具有負邊距的元素有時會與父元素之外的元素發(fā)生重疊皮迟。
在元素發(fā)生過度受限的情況時,大家記住桑寨,受傷的永遠都是右邊距(從左向右閱讀模式)伏尼。即當元素過度受限,導致父子元素寬度關系得不到滿足時尉尾,右邊距會被強制設置為使等式成立的值爆阶,而不會管此時右邊距的值為正還是負。
內(nèi)邊距代赁、邊框和內(nèi)容的寬度(和高度)是絕對不能為負的扰她,唯一可以被設置為負值的只有外邊距。
如果以百分數(shù)來設置這些屬性芭碍,其表現(xiàn)方式與以具體單位設置時是一樣的徒役。只是要記住一點,百分數(shù)的基數(shù)是包含元素的width
窖壕。同時需要注意的是:邊框的寬度不能是百分數(shù)忧勿,而只能是長度。所以瞻讽,想通過百分數(shù)來完全指定一個元素的尺寸鸳吸,是不可能的。
對于替換元素速勇,我們在非替換元素介紹的所有規(guī)則都適合晌砾。只有一點不同,當設置替換元素的width
為auto
時烦磁,該元素的寬度是其實際內(nèi)容的寬度养匈。如果一個替換元素的width
被設置為一個不等于其原始寬度的值,則其height
值會等比例縮放都伪,除非用戶顯式地指定了一個height
值呕乎。
順便補充一點,在使用jQuery時陨晶,可以用不同的方法獲得元素的不同寬度猬仁。
<script type="text/javascript">
$("selector").width(); //返回元素的寬度;不包括padding/border/margin
$("selector").innerWidth(); //返回元素的寬度 + padding
$("selector").outerWidth(); //返回元素的寬度 + padding + border
$("selector").outerWidth(true); //返回元素寬度 + padding + border + margin
</script>
垂直格式化
一個元素的默認高度由其內(nèi)容決定。同時湿刽,與width
一樣的烁,height
定義的是元素內(nèi)容區(qū)的高度(默認盒模型的情況下),而非元素框的總高度叭爱。
與寬度屬性不一樣撮躁,如果正常流中的一個塊元素的margin-top
和margin-bottom
被設置為auto
,它會自動被設置為0
买雾,這也說明我們不能通過將margin-top
和margin-bottom
設置為auto
來達到垂直居中的效果。
如果一個塊級正常流元素的height
被設置為一個百分數(shù)杨帽,這個值則是其包含塊height
值的一個而百分數(shù)漓穿。如果沒有顯式地聲明包含塊的height
,百分數(shù)高度會被重置為auto
注盈。
如果塊級正常流元素的高度設置為auto
晃危,而且只有塊級子元素,那么它的默認高度將是從最高塊級子元素的外邊框邊界到最低塊級子元素的外邊框邊界之間的距離老客。所以,子元素的外邊距會超出包含該元素的父元素的邊框胧砰。不過鳍鸵,如果塊級元素有上內(nèi)邊距或下內(nèi)邊距偿乖,或者有上邊框或下邊框画切,則其高度值是從其最高子元素的上外邊距到其最低子元素的下外邊距之間的距離光涂。這是為什么呢私恬?
合并垂直外邊距
垂直格式化的另一個重要特性就是垂直相鄰外邊距會發(fā)生合并,且這種合并只會發(fā)生在外邊距。如果元素有內(nèi)邊距和邊框署咽,則它們不會發(fā)生合并窒升。這也就解釋了為什么在不設置包含元素的邊框和內(nèi)邊距的情況下,子元素的外邊距會超出包含該元素的父元素的邊框。
負外邊距會影響垂直格式化,而且會影響到外邊距如何合并号杠。如果垂直外邊距都設置為負值堂飞,那么瀏覽器會取兩個外邊距絕對值的最大值的相反數(shù)衡蚂;如果一個正外邊距和一個負外邊距合并丽啡,會從正外邊距減去這個負外邊距的絕對值啸蜜。
由于負邊距的存在噪叙,可能會造成元素之間的重疊子眶。發(fā)生重疊的元素要怎么顯示呢?由于瀏覽器總會按從前到后的順序顯示元素,所以文檔中后出現(xiàn)的正常流元素可能會覆蓋較早出現(xiàn)的元素脉顿。
列表項
大家在使用列表時需要注意艾疟,與一個列表元素關聯(lián)的標志可能在列表項內(nèi)容之外,也可能處理為內(nèi)容開始處的一個內(nèi)聯(lián)標志敢辩,這取決于屬性list-style-position
的值蔽莱。
行內(nèi)元素
在開始進一步的介紹之前,我們先回顧一些基本概念戚长。
em框
em
框在字體中定義盗冷,也稱為字符框。實際的字形有可能比em
框更高或更矮同廉。
內(nèi)容區(qū)
內(nèi)容區(qū)可以是元素中各字符的em框串在一起構成的框仪糖,也可以是由元素中字符字形描述的框。
行間距
行間距是font-size
和line-height
之差迫肖。
行內(nèi)框
行內(nèi)框等于內(nèi)容框加行間距所構成的框锅劝。對于非替換元素,元素行內(nèi)框的高度剛好等于line-height
的值蟆湖。對于替換元素故爵,元素行內(nèi)框的高度則恰好等于內(nèi)容區(qū)的高度,因為行間距不能應用于替換元素隅津。
行框
包含一行中出現(xiàn)的行內(nèi)框的最高點和最低點的最小框。各行行框的頂端緊挨著上一行行框的底端伦仍。
下面我們再了解一組有用的行為和概念:
內(nèi)容區(qū)類似于一個塊級元素的內(nèi)容框结窘。
行內(nèi)元素的背景應用于內(nèi)容區(qū)及所有的內(nèi)邊距。
行內(nèi)元素的邊框要包圍內(nèi)容區(qū)及所有的內(nèi)邊距和邊框呢铆。
非替換元素的內(nèi)邊距晦鞋、邊框和外邊距對行內(nèi)元素或其生成的框沒有垂直效果。即棺克,它們不會影響元素行內(nèi)框的高度悠垛。
替換元素的外邊距和邊框會影響該元素行內(nèi)框的高度,相應地娜谊,也可以影響包含該行內(nèi)框的行框的高度确买。
行內(nèi)框在行中根據(jù)其vertical-align
屬性垂直對齊。
行內(nèi)格式化
line-height
實際只影響行內(nèi)元素和其他行內(nèi)內(nèi)容纱皆,而不會影響塊級元素湾趾,至少不會直接地影響到塊級元素芭商。也可以為一個塊級元素設置line-height
,但是這個值只是應用于塊級元素的內(nèi)聯(lián)內(nèi)容時才會影響到視覺效果搀缠。
可以為一個塊級元素設置line-height
铛楣,并將這個值應用于塊中的所有內(nèi)容,而不論內(nèi)容是否包含在行內(nèi)元素中艺普。實際上簸州,我們可以認為塊級元素中包含的各文本行本身都是行內(nèi)元素,而不論是否真正用行內(nèi)元素的標記包圍起來歧譬。也就是說岸浑,在塊級元素上設置line-height
,實際會應用于其包含的行內(nèi)元素瑰步。
垂直對齊
對于行內(nèi)元素的垂直對齊矢洲,我們使用vertical-align
樣式來控制。vertical-align
的各關鍵字的含義如下:
top
將元素行內(nèi)框的頂端與包含該行內(nèi)框的元素的行框的頂端對齊
bottom
將元素行內(nèi)框的底商與包含該行內(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
將元素的內(nèi)容區(qū)和行內(nèi)框下移。下移的距離因瀏覽器的不同而各不相同袁滥。
vertical-align
的百分數(shù)計算值是相對于元素的line-height
來計算的掘譬。
管理行高
首先,大家需要記住一點:line-height
相對于元素本身的font-size
設置呻拌,而不是相對于父元素設置。在使用百分比或em
等進行line-height
的設置時睦焕,需要牢記這一點藐握。
不知大家是否還記得,之前已經(jīng)提過垃喊,非替換元素的內(nèi)邊距猾普、邊框和外邊距對行內(nèi)元素或其生成的框不會影響行框的高度,也就是說本谜,如果為行內(nèi)元素設置了邊框初家,且邊框較寬,則容易導致不同行之間產(chǎn)生元素的覆蓋乌助。這時就需要使用line-height來解決這個問題溜在。
在設置line-height
,并且想讓子元素繼承line-height
的設置時他托,最好是設置一個原始數(shù)據(jù)掖肋。如line-height:1.5
。這樣赏参,在子元素繼承此值之后志笼,也會基于此值來計算出相對于子元素的字體大小的正確行高沿盅。
上例中我們只是將span
的字體大小設置為28px
,如果使用更大的值(如50px
)纫溃,你會發(fā)現(xiàn)在父元素的line-height
設置為1.5em
時腰涧,各行之間發(fā)生了重疊。而當line-height
設置為1.5
時紊浩,無論字體如何設置窖铡,由于子元素繼承的是縮放因子,而非計算值郎楼,所以總是能得到正確的行高万伤。
行內(nèi)替換元素
一般認為行內(nèi)替換元素有固有的高度和寬度,有固有高度的替換元素可能導致行框比正常要高呜袁。這不會改變行中任何元素的line-height
值敌买,包括替換元素本身。它只是會讓行框的高度恰如能包含替換元素及其所有框屬性阶界。換句話說虹钮,會用替換元素整體(內(nèi)容、外邊距膘融、邊框和內(nèi)邊距)來定義元素的行內(nèi)框芙粱。
需要注意的是,不同于非替換元素氧映,替換元素的邊距和邊框會影響行框的高度春畔,因為它們要作為行內(nèi)替換元素的行內(nèi)框的一部分。
默認地岛都,行內(nèi)替換元素位于基線上律姨,在對行內(nèi)替換元素進行垂直布局的時候需要注意這一點。
改變元素顯示
我們可以使用display
樣式來改變元素的角色臼疫。如將行內(nèi)元素顯示為塊元素择份。但是需要注意的是,我們使用display
改變的只是元素的顯示角色烫堤,但是并不改變其本質荣赶。也就是說,即便是使用display
將行內(nèi)元素顯示為塊級元素鸽斟,但是此行內(nèi)元素本質上還是行內(nèi)元素拔创,因上并不會改變一些約定人俗成的東西。如“行內(nèi)元素可能是一個塊元素的后代富蓄,但是反過來卻不行”伏蚊。
這里,我們將inline-block
單獨拿出來講一下格粪。什么叫“inline-block”躏吊?即行內(nèi)塊元素氛改。對于該元素的理解,可以將其理解為嵌在行中的替換元素比伏。它的底端默認位于文本行的基線上胜卤。如果行內(nèi)塊元素的width
未定義,或者顯式聲明為auto
赁项,則元素框會收縮以適應內(nèi)容葛躏。