“位置”在CSS里的細(xì)節(jié)

作者:ACGTOFE
原文地址:http://acgtofe.com/posts/2015/10/xyz-in-css/

位置是個(gè)怎樣的概念

哎涌献,這個(gè)元素怎么跑那里去了屯断?

回想一下氛堕,在我們覺(jué)得“樣式崩了”,“頁(yè)面出bug了”的時(shí)候尼斧,是不是會(huì)有相當(dāng)一部分情況都可以描述成上面這句話呢竣稽?

我們?cè)趯?xiě)css的時(shí)候,就會(huì)經(jīng)彻σǎ考慮“位置”這個(gè)事萍倡。理念就是,所有的頁(yè)面元素都應(yīng)該被安排在為它預(yù)定的位置上辟汰。畢竟按照計(jì)劃預(yù)定的來(lái)列敲,才能有條不紊,不容易出錯(cuò)帖汞。

就像一本雜志的編輯戴而,即便文稿都已準(zhǔn)備好,但具體哪篇放在第幾頁(yè)的哪里翩蘸,是要認(rèn)真考慮的所意。好的雜志應(yīng)該有好的排版。

下面催首,本文將介紹一些會(huì)影響到“位置”扶踊,但一般不太會(huì)知道的要點(diǎn)。

盒模型的再認(rèn)識(shí)

盒模型你一定很熟悉:

content郎任、padding秧耗、bordermargin這些區(qū)域之外涝滴,請(qǐng)注意圖中的edge绣版,也就是分隔盒模型各區(qū)域的邊。在確定頁(yè)面元素的準(zhǔn)確位置時(shí)歼疮,需要細(xì)致地參考這些邊杂抽。它們按照范圍從小到大分別是:

  • content edge,也叫做inneredge(注意和JavaScript的innerWidth等區(qū)別開(kāi))韩脏。它圍成的區(qū)域代表內(nèi)容區(qū)缩麸,一般由元素內(nèi)的具體內(nèi)容決定。它確定的范圍叫做contentbox赡矢,也是css屬性box-sizing的默認(rèn)值content-box的范圍杭朱。
  • padding edge。它確定padding box的范圍吹散。盡管w3c規(guī)范已經(jīng)從box-sizing移除了這個(gè)值弧械,但很容易類(lèi)比理解。
  • border edge空民。它確定border box的范圍刃唐。
  • margin edge羞迷,也叫做outer edge。它確定margin box的范圍画饥。box-sizing也沒(méi)有這個(gè)值衔瓮。

為什么需要了解這些邊呢?想象一下你想要放置一個(gè)元素到你為它安排的位置上抖甘,但是热鞍,你拿的元素并不是一個(gè)點(diǎn)(比如物理學(xué)里的質(zhì)點(diǎn)),而是一個(gè)盒子衔彻。一個(gè)占據(jù)一定空間的盒子薇宠,如果沒(méi)有邊作為參照,你能清楚地知道應(yīng)該怎樣去對(duì)齊嗎艰额?

背景的位置

背景是很常用的樣式昼接,但有好多地方可能不太會(huì)注意。

背景分為背景圖(background-image)和背景色(background-color)悴晰,漸變(css gradients)也屬于背景圖慢睡。其中,背景圖位于背景色之上铡溪。如果使用多個(gè)背景圖(multiple backgrounds)漂辐,聲明靠前的位于上方。

background-clip之外的其他背景屬性棕硫,如background-position髓涯、background-size等,都只作用于背景圖哈扮,對(duì)背景色沒(méi)有作用纬纪。這是可以理解的,因?yàn)楸尘吧軉渭兓猓鼪](méi)有起點(diǎn)和終點(diǎn)包各,總是鋪滿整個(gè)空間,要么有靶庙,要么沒(méi)有问畅。

現(xiàn)在,一個(gè)元素div.bg-element定義了這樣的css:

.bg-element{
    width: 100px;
    height: 100px;
    margin: 20px;
    padding: 20px;
    border: 5px dashed #386365;
    background: #2aace9 url(pattern.png) no-repeat;
}

這是一個(gè)同時(shí)有背景圖和背景色的元素六荒,而且有內(nèi)外邊距及邊框护姆,其效果是:

可以看出,在默認(rèn)情況下掏击,背景圖的起始點(diǎn)為padding box的左上角卵皂,而背景色沒(méi)有起始點(diǎn),將鋪滿整個(gè)border box(為了看到這一點(diǎn)砚亭,特意用了dashed邊框)灯变。雖然這個(gè)例子中的背景圖好像限制在padding box范圍內(nèi)豺旬,但實(shí)際上,它和背景色的可見(jiàn)范圍是一樣的柒凉,都是border box,用background-positionbackground-repeat稍作修改即可驗(yàn)證:

這個(gè)背景可見(jiàn)范圍的概念篓跛,對(duì)應(yīng)了css3新增屬性background-clip膝捞。這個(gè)屬性的默認(rèn)值就是border-box。如果更改它愧沟,會(huì)是這樣:

無(wú)論怎么修改可見(jiàn)范圍蔬咬,這個(gè)例子中的背景圖的起始點(diǎn)都是padding box左上角,這就是背景圖起始點(diǎn)的概念沐寺。它對(duì)應(yīng)的是css3中新增的background-origin林艘,其默認(rèn)值正是padding-box。如果修改了background-origin混坞,那么屬性background-position產(chǎn)生的位置偏移狐援,包括rightbottom等關(guān)鍵字的情況究孕,都會(huì)對(duì)應(yīng)地改變參考的邊啥酱。

外邊距區(qū)域不會(huì)有背景。前文的盒模型的圖里厨诸,margintransparent一起也是這個(gè)意思镶殷。

自設(shè)容器進(jìn)行定位

你一定用過(guò)這樣的定位搭配:position: relative;的父元素,加上position: absolute;的子元素微酬。

這比較像建立一個(gè)xy平面坐標(biāo)系绘趋,然后把元素放置在自己想要的坐標(biāo)位置上。但是颗管,x軸陷遮、y軸、原點(diǎn)垦江、坐標(biāo)點(diǎn)拷呆,它們分別在哪里呢?

請(qǐng)看這個(gè)例子:

<div class="pos-container">
    <div class="pos-element"></div>
</div>
.pos-container{
    position: relative;
    width: 140px;
    height: 140px;
    margin: 20px;
    padding: 20px;
    border: 5px dashed #789;
}
.pos-element{
    position: absolute;
    width: 70px;
    height: 70px;
    margin: 10px;
    padding: 20px;
    border: 5px dashed #a74;
    background: #e5c5a5;
    left: 0;
    top: 0;
}

得到的結(jié)果是:

由于邊框是明顯的有視覺(jué)效果的部分疫粥,因此border edge的位置很容易確定茬斧。注意兩個(gè)元素都有完整的內(nèi)外邊距和邊框,而此時(shí)div.pos-element的坐標(biāo)是(0, 0)梗逮,圖中間距為10px项秉。經(jīng)過(guò)分析可以得知,這個(gè)10px間距來(lái)自div.pos-elementmargin慷彤。所以可以得到什么結(jié)論呢娄蔼?結(jié)論如下:

首先怖喻,網(wǎng)頁(yè)的平面坐標(biāo)系和通常的數(shù)學(xué)平面直角坐標(biāo)系不同,y軸的正方向是朝下的岁诉。事實(shí)上锚沸,包括Photoshop、Flash等平面設(shè)計(jì)在內(nèi)的界面涕癣,都使用這樣的坐標(biāo)系哗蜈。

這種搭配的情況下,構(gòu)成坐標(biāo)系xy軸的是用作容器的元素的padding edge坠韩。其中padding edge的左上角即為坐標(biāo)系的原點(diǎn)距潘。

絕對(duì)定位的元素設(shè)置的left、top所形成的坐標(biāo)位置點(diǎn)只搁,位于該元素的margin edge的左上角音比。也就是,定位元素是用margin edge的左上角這個(gè)點(diǎn)來(lái)對(duì)齊坐標(biāo)的氢惋。

此外洞翩,構(gòu)成定位參考坐標(biāo)系的是包含塊,而不一定是直接父元素焰望。

包含塊

包含塊(containing block)是css規(guī)范的視覺(jué)格式化模型(visual formatting model)中的概念菱农,它是一個(gè)邏輯的矩形框,用于css的定位及尺寸的計(jì)算柿估,并不限制內(nèi)部元素的位置循未,可以溢出。它和盒模型的關(guān)系可以這樣描述:一個(gè)DOM元素對(duì)應(yīng)一個(gè)盒模型秫舌,盒模型的某一條邊(這不是固定的)將標(biāo)明該DOM元素創(chuàng)建的包含塊范圍的妖。

一般情況下,一個(gè)DOM元素的子元素(以及這些子元素的盒模型)以這個(gè)DOM元素的content edge作為包含塊的邊界足陨。

特別地嫂粟,在這種position: relative;的父元素及position: absolute;的子元素的搭配中,絕對(duì)定位的子元素以父元素的padding edge作為自己的包含塊的邊界墨缘。

更具體的包含塊的邊界判定可以參考W3C的說(shuō)明星虹。

普通流、浮動(dòng)與絕對(duì)定位的三方糾葛

在確定一個(gè)DOM元素的位置時(shí)镊讼,我們需要考慮它的定位方案(positioning schemes)宽涌。一個(gè)DOM元素可以選擇以下三個(gè)方案:

  • 普通流(normal flow):如果你對(duì)這個(gè)元素什么也沒(méi)干,那就是它了蝶棋。
  • 浮動(dòng)(floats):當(dāng)元素的float屬性設(shè)置了left或right后卸亮。
  • 絕對(duì)定位(absolute positioning):當(dāng)元素的position屬性設(shè)置了absolutefixed后。

如果一個(gè)DOM元素既設(shè)置了浮動(dòng)又設(shè)置了絕對(duì)定位玩裙,那么它是絕對(duì)定位(float會(huì)被重置為none的計(jì)算值)兼贸。

你也許聽(tīng)說(shuō)過(guò)“脫離文檔流”這樣的詞匯段直,它在css里是確實(shí)存在的概念,原詞是out of flow溶诞。如果一個(gè)元素的定位方案是浮動(dòng)或絕對(duì)定位鸯檬,又或者這個(gè)元素是根元素(root element),就稱(chēng)這個(gè)元素是脫離文檔流(out of flow)的螺垢。

文檔流的問(wèn)題

同一層級(jí)的兄弟元素喧务,同時(shí)有普通流、浮動(dòng)甩苛、絕對(duì)定位這三種定位方案時(shí),它們之間的相互關(guān)系是怎樣的俏站?

要理清這個(gè)相互關(guān)系讯蒲,需要理解脫離文檔流具體是什么意思。

css規(guī)范中這樣描述絕對(duì)定位:

In the absolute positioning model, a box is removed from the normalflow entirely and assigned a position with respect to a containingblock.

請(qǐng)注意這里的entirely肄扎,這是在說(shuō)墨林,絕對(duì)定位是完全脫離文檔流的。為什么要強(qiáng)調(diào)完全呢犯祠?

因?yàn)樾竦龋撾x文檔流是一個(gè)比較曖昧的概念,還有不完全的衡载。請(qǐng)看浮動(dòng)的描述:

In the float model, a box is first laid out according to the normalflow, then taken out of the flow and shifted to the left or right asfar as possible.

前文已經(jīng)說(shuō)過(guò)搔耕,浮動(dòng)被歸類(lèi)為out of flow,也就是脫離文檔流痰娱,但這里卻提到了先基于文檔流取得一次位置弃榨,然后再向左或向右移動(dòng)。所以梨睁,浮動(dòng)不是完全脫離文檔流的鲸睛。

浮動(dòng)的特性

之前看到過(guò)別人的這樣一個(gè)提問(wèn):

對(duì)應(yīng)html代碼(css省略):

<div class="scheme-container">
    <div class="scheme-element-normal">normal</div>
    <div class="scheme-element-float">float</div>
</div>

按照傳統(tǒng)的“浮動(dòng)元素是脫離文檔流的”的理解,為什么這個(gè)右浮動(dòng)元素只是浮動(dòng)到了它所在行的右邊坡贺,而不是整個(gè)容器的右上角呢官辈?

答案就是,浮動(dòng)不是完全脫離文檔流的遍坟。這有兩方面的意思拳亿。

一方面,浮動(dòng)可以影響文檔流愿伴。你一定見(jiàn)過(guò)把一段文字里的某一個(gè)圖片浮動(dòng)风瘦,來(lái)制造文字環(huán)繞圖片效果的用法:

文字環(huán)繞圖片

這些位于文檔流內(nèi)的文字,仍然會(huì)為浮動(dòng)元素留出空間公般,而并非互不相干万搔。這其實(shí)是浮動(dòng)元素影響行框(line box)的寬度的結(jié)果胡桨。

另一方面,浮動(dòng)會(huì)受到文檔流的影響瞬雹。規(guī)范里列出的浮動(dòng)元素的精確特性規(guī)則中有這樣一條:

The outer top of a floating box may not be higher than the outer top of any block or floated box generated by an element earlier in the source document.

這里的outer top就是margin edge (outer edge)的top edge昧谊。意思是,浮動(dòng)元素不可以高于任何在源文檔之前的塊元素或浮動(dòng)元素酗捌。我們很熟悉浮動(dòng)元素是會(huì)一個(gè)接一個(gè)地尋找空間排列的呢诬,但這一條卻告訴我們,如果前面還有塊元素胖缤,那么它們也會(huì)影響浮動(dòng)元素的上邊緣位置尚镰。

請(qǐng)看這個(gè)例子:

如果一個(gè)浮動(dòng)元素之前還有其他的浮動(dòng)元素,那么會(huì)考慮到它們哪廓,而可能排列到一個(gè)更靠下的位置狗唉。那么,如果之前還有塊元素涡真,而且占據(jù)了更大的位置呢分俯?從上圖可以看到,浮動(dòng)元素同樣會(huì)將其考慮在內(nèi)哆料。

這就是前面的提問(wèn)的詳細(xì)解釋了缸剪。

絕對(duì)定位

絕對(duì)定位大部分時(shí)候并不像浮動(dòng)這樣讓人困惑。顯然东亦,它被定義為“完全脫離文檔流”杏节,就是說(shuō)它和文檔流的關(guān)聯(lián)很弱,一般只根據(jù)包含塊和坐標(biāo)來(lái)確定位置就可以了典阵。

完全脫離文檔流拢锹,也仍然不是說(shuō)和文檔流毫不相干,各自為政萄喳。它的意思是:這個(gè)元素在參與布局時(shí)卒稳,不會(huì)影響在它之后的兄弟元素。絕對(duì)定位元素他巨,在left充坑、top等定位屬性取值auto的時(shí)候,仍然會(huì)根據(jù)文檔流取得一個(gè)可用的計(jì)算值染突。

三者的覆蓋關(guān)系

如果有重疊捻爷,就要考慮覆蓋關(guān)系了。它們的位置從下到上依次是:

  • z-index為負(fù)的定位元素份企。
  • 普通流(normal flow)的非行內(nèi)元素也榄。
  • 浮動(dòng)元素。
  • 普通流的行內(nèi)元素。
  • z-indexauto0的定位元素甜紫。
  • z-index為正值的定位元素降宅。

結(jié)語(yǔ)

想要讓元素穩(wěn)定地待在為它預(yù)定的位置上,還是有很多功課要做的囚霸。本文只介紹了一部分有關(guān)位置的細(xì)節(jié)知識(shí)腰根,如果你也曾對(duì)這些內(nèi)容有所困惑,那么希望能有所幫助拓型。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末额嘿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子劣挫,更是在濱河造成了極大的恐慌册养,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件压固,死亡現(xiàn)場(chǎng)離奇詭異球拦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)邓夕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)刘莹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)阎毅,“玉大人焚刚,你說(shuō)我怎么就攤上這事∩鹊鳎” “怎么了矿咕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)狼钮。 經(jīng)常有香客問(wèn)我碳柱,道長(zhǎng),這世上最難降的妖魔是什么熬芜? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任莲镣,我火速辦了婚禮,結(jié)果婚禮上涎拉,老公的妹妹穿的比我還像新娘瑞侮。我一直安慰自己,他們只是感情好鼓拧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布半火。 她就那樣靜靜地躺著,像睡著了一般季俩。 火紅的嫁衣襯著肌膚如雪钮糖。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天酌住,我揣著相機(jī)與錄音店归,去河邊找鬼阎抒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛娱节,可吹牛的內(nèi)容都是我干的挠蛉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼肄满,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谴古!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起稠歉,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤掰担,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后怒炸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體带饱,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年阅羹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勺疼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捏鱼,死狀恐怖执庐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情导梆,我是刑警寧澤轨淌,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站看尼,受9級(jí)特大地震影響递鹉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜藏斩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一躏结、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狰域,春花似錦媳拴、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至拓颓,卻和暖如春语婴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工砰左, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留匿醒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓缠导,卻偏偏與公主長(zhǎng)得像廉羔,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子僻造,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案憋他? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,754評(píng)論 1 92
  • 1.CSS基本概念 1.1 CSS的定義 CSS(Cascading Style Sheets)層疊樣式表,主要用...
    寥寥十一閱讀 1,836評(píng)論 0 6
  • 當(dāng)在這一個(gè)頁(yè)面上實(shí)現(xiàn)布局和定位有幾種不同的技術(shù)髓削。使用哪種技術(shù)竹挡,很大程序上取決于內(nèi)容和目標(biāo)頁(yè)面,因?yàn)橛泻芏嗉夹g(shù)比別人...
    lulu_c閱讀 1,060評(píng)論 0 5
  • 一、文檔流的概念指什么宝泵?有哪種方式可以讓元素脫離文檔流? 1好啰、文檔流指的是元素在排列布局中所占用的位置,具體的說(shuō)是...
    鴻鵠飛天閱讀 782評(píng)論 0 0
  • 每當(dāng)看到當(dāng)?shù)毓计骄べY水平的時(shí)候儿奶,我們經(jīng)常覺(jué)得自己的工資又在托后腿了框往,工資的上漲水平趕不上物價(jià)的上漲水平,抱怨老...
    君利閱讀 137評(píng)論 1 0