1 Box positioning in CSS

從今天開(kāi)始學(xué)習(xí)CSS Layout
ps: 十分可怕,寫了近2個(gè)月,后面的章節(jié)應(yīng)該會(huì)快一些。

主要跟著這本書學(xué)習(xí)Learn CSS Layout

1 Box positioning in CSS

CSS布局的核心就是把HTML的元素映射一些rectangular boxes,這些盒子又分布在x、y、z三個(gè)軸上,x,y方向上的位置是由positioning scheme定義的,在CSS 2.1中定義了三種:normal flowfloats,absolute positioning。

Positioning Scheme

  • normal flow:包括三種fomatting context,block, inline, relativeformatting context。
  • floats:以自己的方式和normal flow進(jìn)行交互,并形成了大多數(shù)現(xiàn)代CSS grid框架。
  • absolute positioning:作用是相對(duì)于normal flow的絕對(duì)位置和固定的元素。

涉及這些的CSS的屬性是display,positionfloat。float和absolute定位可以看做是和normal flow的交互,也比較復(fù)雜,所以首先了解normal flow。從設(shè)計(jì)角度layout主要做了兩件事:

  • 元素盒子的尺寸和對(duì)齊是如何處理的,這些一般是通過(guò)display的屬性(width,height,margin)來(lái)完成的
  • 有相同父元素的的子元素是如何相互定位的

這章主要討論第二件事。

標(biāo)準(zhǔn)是這樣定義formatting context,即塊級(jí)元素就在一個(gè)block formatting context,行級(jí)元素就在inline formatting context。

Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.

從視覺(jué)上看block formatting context就是一個(gè)垂直的棧布局,inline formatting context就是一個(gè)水平的棧布局。

Anonymous box generation

當(dāng)一個(gè)父級(jí)元素同時(shí)包含inline和block元素時(shí),會(huì)進(jìn)行Anonymous box的生成,具體規(guī)則是:

  • 當(dāng)同時(shí)有inline和block元素存在時(shí),會(huì)生成Anonymous block boxes,并將inline元素放進(jìn)去。
  • 當(dāng)有inline元素且這個(gè)元素被text包裹時(shí),會(huì)生成Anonymous inline boxes,并將text放進(jìn)去。

需要注意的是,這些Anonymous box是不會(huì)再chrome等瀏覽器的布局中顯示的,參考這個(gè)問(wèn)題。

Normal flow positioning

block formatting

block formatting 規(guī)則比較簡(jiǎn)單,如圖它遵循這樣一些規(guī)則

block-box.png
  • 每個(gè)block box在父盒子的左外邊緣
  • float不會(huì)影響左外邊緣的位置,但會(huì)影響文字的位置
  • 沒(méi)有設(shè)置寬度的block box會(huì)填充滿整個(gè)父盒子的寬度
  • 設(shè)置了寬度的會(huì)從左邊開(kāi)始計(jì)算
  • 寬度即使沒(méi)有充滿父盒子,block box也不會(huì)同一行

inline formatting

inline formatting 就比較復(fù)雜了,因?yàn)樗婕暗綄?nèi)容分割成line box(將那些在一行的boxes的長(zhǎng)方形區(qū)域稱為line box),正常來(lái)說(shuō)inline的元素時(shí)在一行中平行布局,當(dāng)一行放不下時(shí)(這里的行寬度由它的父元素決定)會(huì)進(jìn)行垂直布局,此時(shí)是以line box為單位垂直布局。

inline box的另一個(gè)特點(diǎn)是給它設(shè)置widthheight這些屬性時(shí)會(huì)被忽略,通常情況下inline元素的寬度由它的父元素決定。當(dāng)通過(guò)設(shè)置position:absolute使它成為block時(shí)才會(huì)使這些屬性生效。

對(duì)于line box,它的高度可以由line-height控制,以絕對(duì)高度或者相對(duì)高度的形式,絕對(duì)高度就是一個(gè)固定的值,或者以倍數(shù)于當(dāng)前元素設(shè)置的字體尺寸來(lái)決定,可大可小,默認(rèn)情況下根據(jù)字體的尺寸來(lái)決定行高。line box的高度是在計(jì)算所有inline box之后進(jìn)行的,然后設(shè)置除過(guò)vertical-align:top/bottom之外的其它vertical-align屬性。例子。

當(dāng)container有width時(shí),inline的布局像是block元素,實(shí)際上只是因?yàn)閣idth太小,導(dǎo)致每一個(gè)inline元素變成了上一段說(shuō)的line box。

vertical-align屬性

直觀了解vertical-align在和誰(shuí)對(duì)齊

垂直居中是一個(gè)常見(jiàn)的需求,這個(gè)例子通過(guò)將需要垂直居中的元素設(shè)為display:inline-boxvertical-align:middle解決了水平方向居中的問(wèn)題,配合一個(gè)container后面的樣式為height:100%的偽元素將line box的高度和container一致,這樣該元素就可以和這個(gè)偽元素對(duì)齊,解決了垂直方向居中的問(wèn)題。

display:inlinedisplay:inline-box的區(qū)別可以見(jiàn)這個(gè)問(wèn)題。簡(jiǎn)單說(shuō)就是inline-box可以設(shè)置width和height,但又不會(huì)像block一樣獨(dú)占一行。

這個(gè)例子介紹了當(dāng)兩個(gè)元素中間存在空格時(shí)會(huì)生成一個(gè)匿名的inline box導(dǎo)致兩個(gè)本該在一行的inline box分別在兩行。
有幾種辦法可以解決:

  • 手動(dòng)去掉那個(gè)空格,但這樣做會(huì)影響代碼可讀性
  • 將父盒子的font-size:0,再單獨(dú)給兩個(gè)子元素設(shè)置font-size,這可以使那個(gè)空格不再占用任何空間
  • 父盒子設(shè)置white-space: nowrap,雖然兩個(gè)子元素在一行了,但是空格依舊存在
  • CSS3的text-space-collapse屬性,缺點(diǎn)是目前許多瀏覽器暫不支持
不那么直觀的vertical-align:middle

middle的值不像baseline、top、bottom那么直觀,由定義它是將盒子(子盒子,一般是inline)的垂直中點(diǎn)和父盒子的baseline+x-height的一半對(duì)齊。

  • 父盒子的baseline:這里的父盒子不是指包含它的container,而是它所在的line box。這個(gè)例子,可以看到parent是有固定高度60px的,但是"<"卻沒(méi)有那么高
  • x-height:就是指'x'字符的高度,這個(gè)例子表明line box的高度也不影響布局。

Normal flow: relative positioning

position:relative依舊算在文檔流中,然后根據(jù)top/left/bottom/right等屬性進(jìn)行位置的offset。

這個(gè)例子可以看出,4個(gè)div區(qū)域,沒(méi)有任何樣式的情況下是每個(gè)div垂直布局的,第一個(gè)div增加float之后跳出文檔流;第二個(gè)div加了10px的padding-top,增加了自己的高度;第三個(gè)div將position設(shè)置為relative,然后向上移動(dòng)了20px,向右移動(dòng)了10px,width成為原來(lái)的30%,這里注意,向上移動(dòng)是通過(guò)-20px完成的,而向右移動(dòng)又是通過(guò)10px完成的,兩個(gè)方向的正負(fù)數(shù)值代表的含義并不相同;第四個(gè)div只減少了寬度,但是它的位置并沒(méi)有隨著第三個(gè)div位置的變化而變化。

float position scheme

float布局本意是將文字環(huán)繞在圖片周圍,但現(xiàn)在已經(jīng)成為CSS里grid布局的基礎(chǔ)。

float將塊級(jí)元素從布局的文檔流中取出來(lái),這不會(huì)影響那些塊級(jí)盒子但是會(huì)影響line boxes。標(biāo)準(zhǔn)的描述說(shuō)"float是一個(gè)在當(dāng)前行上向左或向右移動(dòng)的盒子,最有趣的特性是內(nèi)容可以沿著一側(cè)流動(dòng)(flow along its side)。"

float有這些特殊的行為:

  • float 跳出文檔流,因此它不會(huì)影響塊級(jí)元素的垂直布局
  • float 和容器的左或者右外邊緣對(duì)齊
  • float 從左邊或者右邊堆疊,當(dāng)有兩個(gè)right-float元素時(shí),第一個(gè)在容器的右外邊緣,第二個(gè)在第一個(gè)的左邊
  • float 會(huì)影響當(dāng)前和隨后的inline元素,所有當(dāng)前和隨后的line boxes都需要縮短以給float留出空間
  • float 不在文檔流中,所以它通常不會(huì)影響父元素的高度,這也是為什么開(kāi)發(fā)"clearfix"技術(shù)的原因之一
  • float 可以使用clear屬性清除

下面逐條解釋這些特性:

caes 1

浮動(dòng)的框向左或向右移動(dòng),直到它的外邊緣接觸父容器的的邊緣或者另一個(gè)浮動(dòng)框。如果存在line box則浮動(dòng)框的頂部與當(dāng)前l(fā)ine box的頂部對(duì)齊。以左浮動(dòng)為例,如果在一個(gè)左浮動(dòng)盒子生成時(shí)已經(jīng)有其他的左浮動(dòng)盒子存在,對(duì)每一個(gè)生成的左浮動(dòng)盒子來(lái)說(shuō)要么它的左邊框在已生成的盒子的右邊框右邊,要么top屬性小于已生成盒子的bottom,右浮動(dòng)同理。

caes 2

如果水平空間不夠,float會(huì)向下移動(dòng)直到空間足夠或者沒(méi)有更多的float出現(xiàn)。因?yàn)閒loat不在文檔流中,所以浮動(dòng)框之前或之后創(chuàng)建的未定位框垂直流動(dòng),就像浮動(dòng)不存在。例子里就是三個(gè)div區(qū)域正常垂直布局。但是當(dāng)前和隨后的line box就需要縮短寬度為float留出區(qū)域,例子中就是綠色和橙色div區(qū)域中的文本組成的line box移動(dòng)了float區(qū)域中文本的寬度以便為它留出空間。

case 3

float不會(huì)影響文檔流中用于建立新塊級(jí)上下文元素內(nèi)的line box,對(duì)應(yīng)例子中綠色區(qū)域的文本組成的line box,這些元素要么放在float的側(cè)面或者任何前面float的下面。

case 4

clear屬性比較好理解,就是去除左邊或右邊的浮動(dòng)元素,默認(rèn)不去除,橙色區(qū)域清除了左邊的浮動(dòng)元素,無(wú)色區(qū)域去除了兩邊的浮動(dòng)元素。

case 5

float的另一個(gè)需要關(guān)注的特性是父元素高度的計(jì)算不考慮浮動(dòng)元素,也就是說(shuō)當(dāng)父容器只有float元素時(shí),它的高度為0。原因是在計(jì)算塊級(jí)元素高度時(shí)需要考慮一個(gè)屬性overflow,它的默認(rèn)值為visible,這種情況下不考慮float元素,當(dāng)你將他設(shè)置為其它值時(shí)就會(huì)將那些float元素計(jì)算在內(nèi)了。

case 6

claerfix技術(shù)是對(duì)基本浮動(dòng)清除的增強(qiáng),case 6想把將三組float元素塞進(jìn)他們對(duì)應(yīng)的父容器中,以目前的知識(shí)有三種做法:

  • 在父元素的兩個(gè)float元素之后增加一個(gè)clear:both的元素,也就是例子中的.hide。
  • 在父元素后增加一個(gè)具有clear:both的偽元素,也就是例子中的.clearfix:after。
  • 改變父元素的overflow屬性的值

這三個(gè)方法一般使用后兩個(gè)方法,這其中又比較推薦偽元素方法,這個(gè)例子體現(xiàn)了偽元素方法的優(yōu)勢(shì),如果是修改overflow屬性值,會(huì)將溢出內(nèi)容可滾動(dòng)而不是可見(jiàn)。

Absolute / fixed positioning scheme

Absolute / fixed 定位是比較簡(jiǎn)單直觀的一種模式,boxes相對(duì)于它的父容器以絕對(duì)偏移量定位。文檔流計(jì)算定位的時(shí)候會(huì)忽略絕對(duì)定位,同時(shí)絕對(duì)定位也不與它的兄弟元素交互,絕對(duì)定位元素中的float元素只與絕對(duì)定位元素中的其它元素交互。這兩種定位模式都與width,heighttop,left,bottomright屬性有關(guān)系,如果這些屬性都明確定義了,計(jì)算結(jié)果是非常直觀的,但只是部分指定,計(jì)算過(guò)程就復(fù)雜很多。

  • fix定位與viewport有關(guān)
  • absolute定位與父元素有關(guān)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,168評(píng)論 1 92
  • 1. 前言 前端圈有個(gè)“梗”:在面試時(shí),問(wèn)個(gè)css的position屬性能刷掉一半人,其中不乏工作四五年的同學(xué)。在...
    YjWorld閱讀 4,924評(píng)論 5 15
  • 以下文章是我在網(wǎng)上收集的內(nèi)容,為了記錄自己的學(xué)習(xí)以及為了以后不到處找而記錄下來(lái),如果對(duì)你有用,請(qǐng)感謝寫這些文章的前...
    DCbryant閱讀 1,031評(píng)論 0 2
  • 先前在學(xué)習(xí)CSS float時(shí),有同學(xué)提到了BFC這個(gè)詞,作為求知好問(wèn)的好學(xué)生,哪里不懂查哪里,那么今天就來(lái)研究一...
    這名字真不對(duì)閱讀 6,695評(píng)論 3 19
  • 一直都覺(jué)得,愛(ài)讀書的女孩子有一種獨(dú)特的魅力,也一直想培養(yǎng)自己喜歡讀書的愛(ài)好,而最近,發(fā)現(xiàn)確實(shí)已經(jīng)愛(ài)上了看書,或許是...
    糾結(jié)的女漢子閱讀 246評(píng)論 0 2

友情鏈接更多精彩內(nèi)容