目錄
一. 我對標簽宋下、元素、盒子的理解
1. web相關(guān)概念的職責(zé)
2. 在瀏覽器與人類交互的過程中辑莫,它們的扮演的角色
二. 視覺格式化模型的相關(guān)概念
三. display屬性
四. 定位策略
1. position屬性
2. 正常文檔流
3. 相對定位
4. 浮動
5. 絕對定位
6. display学歧、position和float的關(guān)系
內(nèi)容
一. 我對標簽、元素各吨、盒子的理解
相信很多人和我之前一樣枝笨,對于web的許多概念也都知道是什么意思,大家平時交流起來也沒什么障礙;但是如果仔細定義横浑、區(qū)分這些概念時剔桨,卻好像又表達不出來,如:
- 標簽和元素是同一事物嗎徙融?
- 如果是同一事物领炫,哪為什么它起2個名字?這些名字的使用場景又是什么张咳?
- 如果不是同一事物帝洪,那它們又分別是什么?
等等脚猾,類似這樣的問題我們似乎能理解葱峡,但又表達不出來!為會會這樣龙助,其實這是因為我們沒有真正地嚴格地理解它們砰奕,簡單來說就是:我們并不理解它們!為了幫助大家理解提鸟,我就簡單描述一下我對他們的理解军援,在這里我并不描述這些概念的定義,因為在不更加事物之前,僅描述定義是不能幫助大多數(shù)人深刻理解的;
1. web相關(guān)概念的職責(zé)如下:
- 元素包含標簽龙优、標簽屬性和標簽之間的內(nèi)容详炬;標簽桑逝、標簽屬性和標簽之間的內(nèi)容是用來描述元素的;
- CSS規(guī)則是用來描述元素的呈現(xiàn)效果的;
- 網(wǎng)頁的顯示是通過視覺格式化模型呈現(xiàn)的;
- 視覺格式化模型是根據(jù)元素和CSS規(guī)則建立的嘲更;
2. 在瀏覽器與人類交互的過程中,它們的扮演的角色如下:
- HTML標簽揩瞪、CSS規(guī)則赋朦、JavaScript腳本是人與瀏覽器溝通相互的語言,主要用于人向瀏覽器表達信息李破;
- 元素是瀏覽器能直接理解的數(shù)據(jù)模型宠哄;
- 視覺格式化模型是瀏覽器表達自己對元素的理解的規(guī)制及方式,主要用于瀏覽器向人表達信息喷屋;
瀏覽器讀取人類傳達給他的HTML琳拨、CSS規(guī)則、JavaScript腳本屯曹,然后通過對它的翻譯、理解,建立了自己的能直接理解的數(shù)據(jù)模型——元素恶耽;瀏覽器為了能把自己的數(shù)據(jù)模型以人類能直接理解的方式傳達給人類密任,它便以具視覺格式化模型把自己的數(shù)據(jù)開模呈現(xiàn)出來;
所以偷俭,標簽是HTML語言中的事物浪讳;元素是瀏覽器數(shù)據(jù)模型中的事物;盒模型是瀏覽器對人類表達方式中的事物涌萤;
二. 視覺格式化模型的相關(guān)概念
-
盒子: 為了呈現(xiàn)文檔樹中的元素淹遵,瀏覽器會根據(jù)視覺格式化模型為每個元素生成0或多個盒子;這些盒子的布局由如下因素決定:
- 盒子的尺寸和類型负溪;
- 定位策略(如:正常文檔流透揣、浮動或者絕對定位);
- 和文檔樹中其他元素的關(guān)系川抡;
- 額外的信息(如:視口的大小辐真、圖片的原始尺寸等);
塊容器盒子: 即可以產(chǎn)生塊級上下文崖堤,又可以產(chǎn)生行內(nèi)上下文的盒子叫做塊容器盒子侍咱;
-
包含塊: 既然元素可以有子元素和父元素,而盒子是依據(jù)元素生成的密幔,所以盒子也可以包含其它盒子楔脯,也可以被其它盒子包含;盒子是根據(jù)包含它的盒子的邊界來定位的胯甩,當(dāng)一個盒子包含另一個盒子時淤年,就稱為這個盒子是另一個盒子的包含塊;
所以蜡豹,包含塊只是盒子在某個場景下的別名麸粮;
-
格式化上下文: “上下文”是環(huán)境的意思;“化”是使轉(zhuǎn)化的意思镜廉;所以“格式化上下文”就是使其轉(zhuǎn)化為一定格式的環(huán)境弄诲;在當(dāng)前語境中,更通術(shù)地講:“格式化上下文”是合其中的盒子具備一定格式的環(huán)境娇唯;或者可以理解為:“格式化上下文”是放置盒子的環(huán)境齐遵;所以,盒子必須放置在格式化上下文中塔插;
根據(jù)其中放置盒子的類型不同(或者說:使盒子轉(zhuǎn)化的格式不同)梗摇,格式化上下文可分為:
- 塊級格式化上下文: 只能放置塊級盒子的格式化上下文;
- 行級格式化上下文: 只能放置行級盒子的格工化上下文想许;
- 行內(nèi)格式化上下文: 只能放置行內(nèi)級盒子的格式化上下文伶授;
當(dāng)盒子需要包含其它盒子時断序,便會生成自己的格式化上下文,用來包含其它盒子糜烹;每個盒子在同一時刻违诗,只會擁有一個格式化上下文;
塊級盒子: 放置在塊級格式化上下文的盒子疮蹦;
主塊級盒子: 每個塊級元素都會產(chǎn)生一個主要的塊級盒子诸迟,它用來鈴后代盒子和其它生成的內(nèi)容,同時還參與任何的定位策略愕乎,這個主要的塊級盒子就稱為主塊級盒子阵苇;有些塊級元素,除了主塊級盒子以外感论,還將產(chǎn)生其他的盒子绅项,如”list-item”元素。這些額外的盒子會根據(jù)主塊級盒子進行布局笛粘;
塊容器盒子: 即可以生成塊級格式化上下文趁怔,又可以生成行級格式化上下文的盒子叫做塊容器盒子;
塊盒子: 即是塊容器盒子薪前,又是塊級盒子的盒子叫做塊盒子润努;
行級盒子: 當(dāng)盒子里包含的是文本時,文本會一行一行的排列示括,每一行文本都是被包含在行級盒子里面铺浇;所以,有多少行垛膝,就有多少個行級盒子鳍侣;行級盒子存在于行級格式化上下文中;
行內(nèi)級盒子: 行級盒子會生成行內(nèi)級格式化上下文吼拥,用于放置行內(nèi)級盒子倚聚;行內(nèi)級盒子里面一般直接存放的就是文本或者其它行可用于直接展示的行內(nèi)級內(nèi)容;
以下內(nèi)容參考了《CSS中的視覺格式化模型》凿可,并對其進行了修正
三. display屬性
display屬性的值決定元素產(chǎn)生盒子的種類惑折,具體如下:
block:應(yīng)用該屬性值的元素將會產(chǎn)生一個塊盒子;
inline-block:應(yīng)用該屬性值的元素將產(chǎn)生一個行級塊容器枯跑。inline-block的內(nèi)部被格式化成一個塊盒子惨驶,元素本身被格式化成一個原子行級盒子;
inline 應(yīng)用該屬性值的元素將會產(chǎn)生一到多個行盒子敛助;
list-item 應(yīng)用該屬性值的元素(比如html中的li)將會產(chǎn)生一個主塊級盒子和一個標簽盒子粗卜;
-
none 應(yīng)用該屬性值的元素將不會出現(xiàn)在格式化結(jié)構(gòu)(formatting structure)中,也就是說纳击,元素不產(chǎn)生任何盒子续扔,對布局沒有任何影響攻臀。元素的后代元素也不產(chǎn)生盒子,元素和元素的內(nèi)容被從格式化結(jié)構(gòu)中完全刪除测砂。通過設(shè)置后代元素的"display"屬性值也不能改變茵烈。
請注意百匆,"display"為"none"時不產(chǎn)生任何不可見的盒子砌些,實際上,根本不產(chǎn)生任何盒子加匈。如果想產(chǎn)生既不可見又影響格式化結(jié)構(gòu)的盒子存璃,請參考visibility屬性。
table,inline-table,table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, and table-caption
應(yīng)用以上屬性值的元素將表現(xiàn)得像一個表格元素雕拼。
注意纵东,盡管"display"屬性的初始值為"inline",但是瀏覽器的默認樣式表可能覆蓋這個值啥寇。
四. 定位策略
盒子的定位方式?jīng)Q定于定位策略偎球;共有3種定位策略,如下:
- 正常文檔流:盒子根據(jù)它所在的格式化上下文逐個排列辑甜;
- 浮動:在浮動模型中衰絮,一個盒子先根據(jù)正常文檔流定位,然后被從文檔流中拿出來盡可能的放到左/右邊磷醋。上下文中的其他內(nèi)容將流動到浮動元素的某一邊猫牡;
- 絕對定位:在絕對定位模型中,盒子被從正常文檔流中完全移除(被移除的盒子對它原來的兄弟盒子將不再產(chǎn)生任何影響) 并且根據(jù)它的包含塊進行定位邓线。
如果一個元素是浮動的淌友、絕對定位的或者是根元素,那么就稱這個元素脫離了文檔流骇陈。如果一個元素沒有脫離文檔流震庭,那么就稱這個元素在文檔流內(nèi)。一個脫離文檔流的元素A你雌,它的文檔流包括元素A本身以及所有A的在文檔流內(nèi)的后代元素器联。
1. position屬性
position屬性的取值范圍是:static | relative | absolute | fixed | inherit, 初始值為static匪蝙。每個取值的含義如下:
static: 應(yīng)用該屬性值的盒子就是正常的盒子主籍,根據(jù)正常的文檔流來進行定位。top逛球、right千元、bottom和left屬性不生效。
relative: 應(yīng)用該屬性值的盒子颤绕,其位置將根據(jù)盒子在正常文檔流中初始的位置以及一個偏移量來計算幸海。即盒子的最終位置將相對于原來的位置發(fā)生一定的偏移祟身。當(dāng)盒子B采用相對定位后,盒子B后面的其他盒子的定位將不受影響物独,就好像盒子B沒有采用相對定位一樣袜硫。
absolute: 應(yīng)用該屬性值的盒子,其位置由top挡篓、right婉陷、bottom和left屬性來決定,這些屬性將根據(jù)盒子的包含塊來確定偏移量官研。采用絕對定位的盒子完全脫離正常文檔流秽澳,也就是說,絕對定位的盒子對其他盒子將不再產(chǎn)生任何影響戏羽。采用絕對定位的盒子的外邊距(margin)不與其他盒子的外邊距重疊担神。
fixed: 應(yīng)用該屬性值的盒子,其位置將根據(jù)絕對定位來計算始花,另外妄讯,盒子還將相對于一定的參照物固定不動。例如在視覺媒體中酷宵,采用fixed定位的盒子將相對于視口固定不動亥贸。
如果一個元素的position屬性值不為static,那么就稱這個元素被定位了忧吟。被定位的元素將產(chǎn)生被定位的盒子砌函,然后根據(jù)top、right溜族、bottom讹俊、left這四個屬性進行放置;
瀏覽器可能默認根元素的定位為static定位煌抒。
2. 正常文檔流
在正常文檔流中的盒子都屬于一個格式化上下文仍劈。這個格式化上下文既可以是塊級的,也可以是行級的寡壮,但不能兩者都是贩疙。塊級盒子在塊格式化上下文中,行級盒子在行格式化上下文中况既。
2.1 塊格式化上下文中盒子的定位
浮動的元素这溅、采用絕對定位的元素、不是塊盒子的塊容器(比如inline-block棒仍,table-cell和table-caption)以及設(shè)置了overflow且值不為visible(設(shè)置了visible的viewport除外)的塊盒子將會為他們的內(nèi)容建立新的塊格式化上下文悲靴。
在塊格式化上下文中,各個盒子從他們的包含塊的頂部開始莫其,豎直的順次放置癞尚。相鄰的兩個盒子的豎直距離有margin屬性決定耸三。在同一個格式化上下文中的兩個相鄰的塊級盒子的豎直外邊距將會合并。
在塊格式化上下文中浇揩,每個盒子的左外邊界與盒子的包含塊的左邊界相接(對于從右到左的情況仪壮,右外邊界與右邊界相接)。 即使當(dāng)有浮動元素存在是也依然使用胳徽,除非這個盒子產(chǎn)生了新的塊格式化上下文(這樣的話积锅,由于浮動,盒子的寬度將變心だ取)乏沸。
2.2 行內(nèi)格式化上下文中盒子的定位
在行內(nèi)格式化上下文中淫茵,每個盒子從他們的包含塊的頂部開始爪瓜,依據(jù)每個盒子的水平margin,border和padding匙瘪,水平的依次放置铆铆。這些盒子在豎直方向上,可能依據(jù)頂部或者底部對齊丹喻,也可能依據(jù)盒子內(nèi)部文本的基準線對齊薄货。包含這些盒子的來形成行的這個長方形區(qū)域就叫行盒子。
2.3 行級格式化上下文中盒子的定位
行盒子必須要有足夠的高度來包含它的所有后代盒子碍论。因此谅猾,它可能比它包含的最高的盒子還要高(比如,行盒子內(nèi)部的盒子都依據(jù)文本基準線對其)鳍悠。當(dāng)盒子B的高度比行盒子低的時候税娜,盒子B在行盒子里的對其方式就由vertical-align屬性決定。如果多個行內(nèi)級盒子無法在單一的行盒子中水平放置藏研,那么這些行內(nèi)級盒子將會被分放到多個行盒子中敬矩。因此,一個段落就是多個行盒子的豎直堆疊蠢挡。堆疊的行盒子之間沒有分隔(除非指定)弧岳,并且從不重疊。
通常业踏,行盒子的左邊界與包含塊的左邊界相接禽炬,右邊界與包含塊的右邊界相接。但是勤家,如果有浮動元素存在的話腹尖,那浮動元素將會介乎兩者之間。因此却紧,盡管在同一個行級格式化上下文中的行盒子通常都與包含塊同寬桐臊,但是他們的寬度也會因為受到浮動元素的影響而有所差異胎撤。在同一個行級格式化上下文中的行盒子高度可以不同(比如一個行盒子包含一個較高的圖片,而另一個僅僅包含文本断凶。)
當(dāng)行內(nèi)級盒子的寬度小于包含他們的行盒子時伤提,他們水平方向的對其方式將由text-align屬性決定。如果text-align屬性取值為justify认烁,那么瀏覽器可能拉伸盒子中的文字和間距肿男,但是inline-table和inline-block盒子除外。
如果一個行內(nèi)級盒子的寬度超出了行盒子的寬度却嗡,那它將被拆斷為多個行內(nèi)盒子舶沛,然后放到多個行盒子中。如果行內(nèi)盒子不能被拆斷(比如:行內(nèi)盒子僅包含單個字符窗价,或者規(guī)定語言單詞的截斷規(guī)則不允許截斷如庭,或者使用了white-space,且取值為nowrap或pre)撼港,那這個行內(nèi)級盒子將會溢出行盒子坪它。當(dāng)行內(nèi)級盒子被拆斷時,margin帝牡、border和padding對拆斷處沒有任何視覺上的影響往毡。
當(dāng)在行級格式化上下文中需要包含行內(nèi)級內(nèi)容時就會創(chuàng)建行盒子。不包含任何文本靶溜、任何保留的空白字符开瞭、任何擁有非零margin、padding和border的行內(nèi)元素以及任何其他在流中的內(nèi)容(例如圖片罩息、行內(nèi)塊或行內(nèi)表格)并且不以保留的換行符結(jié)束的行盒子嗤详,它將被視作沒有高度的行盒子,以此來保證盒子里的任何元素的的位置計算扣汪。
3. 相對定位
盒子一但被定位或者被浮動断楷,它可以相對于這個位置進行一定的偏移。這就叫做相對定位崭别。偏移的盒子(B1)對緊跟著它的盒子(B2)沒有任何影響(B2的位置就像B1沒有發(fā)生偏移一樣)冬筒。因此,相對定位可能導(dǎo)致盒子重疊茅主。但是舞痰,如果相對定位導(dǎo)致了設(shè)置有"overflow:auto"或者"overflow:scroll"的盒子溢出了,那么瀏覽器必須允許用戶(通過滾動條等)能夠訪問到盒子的內(nèi)容诀姚。
相對定位的盒子會保持原來的正常大小响牛,包括換行和一開始就保有的空間。
對于相對定位的元素:
在水平方向上:
left和right將盒子不改變大小的水平移動。left將盒子右移呀打,right將盒子左移矢赁。因為left或right的結(jié)果都不會導(dǎo)致盒子被分隔或拉伸,所以實際上最終使用的值總是: left=-right贬丛;具體規(guī)則如下:
- 如果left和right的取值都是auto撩银,那最終生效的值都為0(也就是說盒子呆在原來的位置);
- 如果left取值為auto豺憔,那么最終由right的值決定额获;
- 如果right取值為auto,那么最終由left的值決定恭应;
- 如果left和right都不是auto抄邀,那么二者之中必須要忽略一個。如果包含塊的direction屬性值為ltr昼榛,那么使用left境肾,忽略rightt;如果包含塊的direction為rtl褒纲,那么使用right准夷,忽略left;
在垂直方向上:
top和bottom屬性將盒子不改變大小的上下移動莺掠。top將盒子下移,bottom將盒子上移读宙。因為盒子不會被分隔或者拉伸彻秆,所有最終使用的值總是:top=-bottom。
- 如果兩個都是auto结闸,那么最終使用的值都為0唇兑;
- 如果其中之一為auto,那么最終由另一個屬性的值決定桦锄;
- 如果都不是auto扎附,那么使用top,忽略bottom;
4. 浮動
浮動的盒子會被移動到當(dāng)前行的左邊或者右邊结耀。浮動最有趣的特點就是其他內(nèi)容會在浮動的元素的旁邊依次放置(或者通過設(shè)置clear屬性禁止)留夜,或者說其他盒子會流動到浮動盒子的旁邊。也就是說图甜,其他盒子將沿著向左浮動的盒子的右邊碍粥、向右浮動的盒子的左邊依次放置。
浮動的盒子將會向左或向右移動黑毅,直到觸碰到包含塊的邊界或者其他浮動盒子的外邊界嚼摩。如果是行盒子的話,那么浮動盒子的外邊界的頂部將與當(dāng)前行盒子的頂部對其。如果沒有足夠的水平空間枕面,那么浮動的盒子將移至下一行直到有足夠的空間或者行內(nèi)已經(jīng)沒有其他浮動元素為止愿卒。
因為浮動盒子不在文檔流中,所以在浮動盒子前后的未定位的塊盒子將像浮動盒子不存在一樣的依次豎直放置潮秘。但是掘猿,浮動盒子所在的當(dāng)前行以及后面相鄰的行盒子都會根據(jù)浮動盒子縮短寬度來給浮動盒子留下空間。如果有個豎直的位置滿足如下四個條件:
- 在行盒子的頂部或者頂部之下唇跨;
- 在行盒子的底部或底部之上稠通;
- 在浮動盒子的外邊界的頂部或者頂部之下;
- 在浮動盒子的外邊界的底部或者底部之上买猖;
那么行盒子將會換行改橘。也就是說:如果浮動的盒子的外邊界高度為0或者為負,那么行盒子不會縮短玉控。
如果縮短的行盒子太短而不能包含任何內(nèi)容飞主,那么這個行盒子將會換行(并且其高度會重新計算)直到有足夠的空間或者沒有浮動盒子為止。當(dāng)前行內(nèi)的任何在浮動盒子之前的盒子都將重新流動到浮動盒子的另一邊高诺。換句話說:如果一個行內(nèi)盒子放在了一個向左浮動盒子的前面碌识,那么,向左浮動的盒子會被放在這一行的開始虱而,與行盒子的頂部對其筏餐,之前的行內(nèi)盒子將會移動到浮動盒子的右邊。對于rtl和向右浮動的盒子同理牡拇。
table魁瞪、塊級可替換元素或者正常文檔流中建立新的塊格式化上下文的元素的border盒不能與任何在同一個格式化上下文中的浮動盒子的margin盒重疊。
4.1 float屬性
float屬性的取值范圍是: left | right | none | inherit惠呼,初始值為none导俘。該屬性值決定元素向左移動還是向右移,或者根本不動剔蹋。float屬性可以被應(yīng)用于任何元素上旅薄,除了絕對定位的元素。float屬性的取值有如下含義:
- left:元素產(chǎn)生一個向左浮動的塊盒子泣崩;其他內(nèi)容流向盒子的右邊少梁;
- right:與left相似,盒子浮動到右邊律想,其他內(nèi)容流向盒子的左邊猎莲;
- none:不浮動;
如下9條規(guī)定了浮動元素的確切行為:
- 向左浮動的盒子的外左邊界不能超過包含塊的左邊界技即。同理應(yīng)用于向右浮動的盒子;
- 對于一個向左浮動的盒子著洼,如果在這個盒子之前還有其他向左浮動的盒子,那么,這個盒子的左外邊界不能超過其他任何向左浮動的盒子的右外邊界身笤,或者這個盒子的上邊界必須比其他盒子的下邊界低豹悬。同理應(yīng)用于向右浮動的盒子;
- 任何向左浮動的盒子的右外邊界不能超過任何與之相鄰的向右浮動的盒子的左外邊界。同理應(yīng)用于向右浮動的盒子;
- 浮動盒子的上外邊界不能比包含塊的上邊界高液荸。當(dāng)浮動發(fā)生在兩個合并的margin中時瞻佛,浮動的盒子根據(jù)一個假設(shè)的父的空匿名塊盒子定位;
- 浮動盒子的上外邊界不能比任何其他之前的塊盒子或浮動盒子的上外邊界高;
- 浮動盒子的上外邊界不能比任何之前的行盒子的上邊界高;
- 一個向左浮動的盒子,如果在他之前還有向左浮動的盒子娇钱,那么這個盒子的右外邊界不能超過包含塊的有邊界伤柄,除非這個盒子已經(jīng)盡可能的向左了。同理應(yīng)用于向右浮動的盒子;
- 浮動元素要盡可能的往高放置;
- 向左浮動的盒子要盡可能向左文搂,向右浮動的盒子要盡可能向右适刀。但是相對于盡可能向左或向右,更高的位置有更高的優(yōu)先級;
5. 絕對定位
在絕對定位模型中煤蹭,盒子被從正常文檔流中完全移除笔喉,并只相對于它的包含塊進行偏移定位。絕對定位的盒子會為它的正常文檔流后代盒子以及非fixed的絕對定位后代盒子建立一個包含塊硝皂。絕對定位的盒子可能會遮蓋其他元素常挚,具體取決于堆疊層次。
固定布局:
固定布局是絕對布局的一個子類稽物,唯一的不同在于固定布局的盒子的包含塊由視口產(chǎn)生奄毡。
6. display、position和float的關(guān)系
這三個屬性都影響盒子的產(chǎn)生以及定位姨裸,他們關(guān)系如下:
- 如果display的值為none秧倾,那么position和float不起作用。在這種情況下傀缩,元素不產(chǎn)生盒子;
- 否則农猬,如果position的值為absolute或者fixed赡艰,那么盒子就使用絕對定位,float的最終使用的值為none斤葱,display的取值依據(jù)如下表格來定慷垮。盒子的顯示位置根據(jù)top、right揍堕、bottom和left屬性決定料身;
- 否則,如果float的取值不會none衩茸,那么盒子將會浮動芹血,display的取值參照下表;
- 否則,如果元素是根元素幔烛,那么display的取值參照下表啃擦;
- 否則,display的取值就是指定的值饿悬。
display的轉(zhuǎn)換表
指定的值 | 最終使用的值 |
---|---|
inline-table | table |
inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block | block |
其他 | 與指定的值相同 |