摘要:在確定頁面元素的準確位置時,需要細致地參考這些邊。它們的位置從下到上依次是為負的定位元素。本文只介紹了一部分有關位置的細節知識,如果你也曾對這些內容有所困惑,那么希望能有所幫助。
位置是個怎樣的概念
哎,這個元素怎么跑那里去了?
回想一下,在我們覺得“樣式崩了”,“頁面出bug了”的時候,是不是會有相當一部分情況都可以描述成上面這句話呢?
我們在寫css的時候,就會經常考慮“位置”這個事。理念就是,所有的頁面元素都應該被安排在為它預定的位置上。畢竟按照計劃預定的來,才能有條不紊,不容易出錯。
就像一本雜志的編輯,即便文稿都已準備好,但具體哪篇放在第幾頁的哪里,是要認真考慮的。好的雜志應該有好的排版。
下面,本文將介紹一些會影響到“位置”,但一般不太會知道的要點。
盒模型的再認識盒模型你一定很熟悉:
在content、padding、border、margin這些區域之外,請注意圖中的edge,也就是分隔盒模型各區域的邊。在確定頁面元素的準確位置時,需要細致地參考這些邊。它們按照范圍從小到大分別是:
content edge,也叫做inner edge(注意和JavaScript的innerWidth等區別開)。它圍成的區域代表內容區,一般由元素內的具體內容決定。它確定的范圍叫做content box,也是css屬性box-sizing的默認值content-box的范圍。
padding edge。它確定padding box的范圍。盡管w3c規范已經從box-sizing移除了這個值,但很容易類比理解。
border edge。它確定border box的范圍。
margin edge,也叫做outer edge。它確定margin box的范圍。box-sizing也沒有這個值。
為什么需要了解這些邊呢?想象一下你想要放置一個元素到你為它安排的位置上,但是,你拿的元素并不是一個點(比如物理學里的質點),而是一個盒子。一個占據一定空間的盒子,如果沒有邊作為參照,你能清楚地知道應該怎樣去對齊嗎?
背景的位置背景是很常用的樣式,但有好多地方可能不太會注意。
背景分為背景圖(background-image)和背景色(background-color),漸變(css gradients)也屬于背景圖。其中,背景圖位于背景色之上。如果使用多個背景圖(multiple backgrounds),聲明靠前的位于上方。
除background-clip之外的其他背景屬性,如background-position、background-size等,都只作用于背景圖,對背景色沒有作用。這是可以理解的,因為背景色很單純,它沒有起點和終點,總是鋪滿整個空間,要么有,要么沒有。
現在,一個元素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; }
這是一個同時有背景圖和背景色的元素,而且有內外邊距及邊框,其效果是:
可以看出,在默認情況下,背景圖的起始點為padding box的左上角,而背景色沒有起始點,將鋪滿整個border box(為了看到這一點,特意用了dashed邊框)。雖然這個例子中的背景圖好像限制在padding box范圍內,但實際上,它和背景色的可見范圍是一樣的,都是border box,用background-position或background-repeat稍作修改即可驗證:
這個背景可見范圍的概念,對應了css3新增屬性background-clip。這個屬性的默認值就是border-box。如果更改它,會是這樣:
無論怎么修改可見范圍,這個例子中的背景圖的起始點都是padding box左上角,這就是背景圖起始點的概念。它對應的是css3中新增的background-origin,其默認值正是padding-box。如果修改了background-origin,那么屬性background-position產生的位置偏移,包括right、bottom等關鍵字的情況,都會對應地改變參考的邊。
外邊距區域不會有背景。前文的盒模型的圖里,margin和transparent一起也是這個意思。
自設容器進行定位你一定用過這樣的定位搭配:position: relative;的父元素,加上position: absolute;的子元素。
這比較像建立一個xy平面坐標系,然后把元素放置在自己想要的坐標位置上。但是,x軸、y軸、原點、坐標點,它們分別在哪里呢?
請看這個例子:
.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; }
得到的結果是:
由于邊框是明顯的有視覺效果的部分,因此border edge的位置很容易確定。注意兩個元素都有完整的內外邊距和邊框,而此時div.pos-element的坐標是(0, 0),圖中間距為10px。經過分析可以得知,這個10px間距來自div.pos-element的margin。所以可以得到什么結論呢?結論如下:
首先,網頁的平面坐標系和通常的數學平面直角坐標系不同,y軸的正方向是朝下的。事實上,包括Photoshop、Flash等平面設計在內的界面,都使用這樣的坐標系。
這種搭配的情況下,構成坐標系xy軸的是用作容器的元素的padding edge。其中padding edge的左上角即為坐標系的原點。
絕對定位的元素設置的left、top所形成的坐標位置點,位于該元素的margin edge的左上角。也就是,定位元素是用margin edge的左上角這個點來對齊坐標的。
此外,構成定位參考坐標系的是包含塊,而不一定是直接父元素。
包含塊包含塊(containing block)是css規范的視覺格式化模型(visual formatting model)中的概念,它是一個邏輯的矩形框,用于css的定位及尺寸的計算,并不限制內部元素的位置,可以溢出。它和盒模型的關系可以這樣描述:一個DOM元素對應一個盒模型,盒模型的某一條邊(這不是固定的)將標明該DOM元素創建的包含塊范圍。
一般情況下,一個DOM元素的子元素(以及這些子元素的盒模型)以這個DOM元素的content edge作為包含塊的邊界。
特別地,在這種position: relative;的父元素及position: absolute;的子元素的搭配中,絕對定位的子元素以父元素的padding edge作為自己的包含塊的邊界。
更具體的包含塊的邊界判定可以參考W3C的說明。
普通流、浮動與絕對定位的三方糾葛在確定一個DOM元素的位置時,我們需要考慮它的定位方案(positioning schemes)。一個DOM元素可以選擇以下三個方案:
普通流(normal flow)。如果你對這個元素什么也沒干,那就是它了。
浮動(floats)。當元素的float屬性設置了left或right后。
絕對定位(absolute positioning)。當元素的position屬性設置了absolute或fixed后。
如果一個DOM元素既設置了浮動又設置了絕對定位,那么它是絕對定位(float會被重置為none的計算值)。
你也許聽說過“脫離文檔流”這樣的詞匯,它在css里是確實存在的概念,原詞是out of flow。如果一個元素的定位方案是浮動或絕對定位,又或者這個元素是根元素(root element),就稱這個元素是脫離文檔流(out of flow)的。
文檔流的問題同一層級的兄弟元素,同時有普通流、浮動、絕對定位這三種定位方案時,它們之間的相互關系是怎樣的?
要理清這個相互關系,需要理解脫離文檔流具體是什么意思。
css規范中這樣描述絕對定位:
In the absolute positioning model, a box is removed from the normal flow entirely and assigned a position with respect to a containing block.
請注意這里的entirely,這是在說,絕對定位是完全脫離文檔流的。為什么要強調完全呢?
因為,脫離文檔流是一個比較曖昧的概念,還有不完全的。請看浮動的描述:
In the float model, a box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible.
前文已經說過,浮動被歸類為out of flow,也就是脫離文檔流,但這里卻提到了先基于文檔流取得一次位置,然后再向左或向右移動。所以,浮動不是完全脫離文檔流的。
浮動的特性之前看到過別人的這樣一個提問:
對應html代碼(css省略):
normalfloat
按照傳統的“浮動元素是脫離文檔流的”的理解,為什么這個右浮動元素只是浮動到了它所在行的右邊,而不是整個容器的右上角呢?
答案就是,浮動不是完全脫離文檔流的。這有兩方面的意思。
一方面,浮動可以影響文檔流。你一定見過把一段文字里的某一個圖片浮動,來制造文字環繞圖片效果的用法:
這些位于文檔流內的文字,仍然會為浮動元素留出空間,而并非互不相干。這其實是浮動元素影響行框(line box)的寬度的結果。
另一方面,浮動會受到文檔流的影響。規范里列出的浮動元素的精確特性規則中有這樣一條:
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。意思是,浮動元素不可以高于任何在源文檔之前的塊元素或浮動元素。我們很熟悉浮動元素是會一個接一個地尋找空間排列的,但這一條卻告訴我們,如果前面還有塊元素,那么它們也會影響浮動元素的上邊緣位置。
請看這個例子:
如果一個浮動元素之前還有其他的浮動元素,那么會考慮到它們,而可能排列到一個更靠下的位置。那么,如果之前還有塊元素,而且占據了更大的位置呢?從上圖可以看到,浮動元素同樣會將其考慮在內。
這就是前面的提問的詳細解釋了。
絕對定位絕對定位大部分時候并不像浮動這樣讓人困惑。顯然,它被定義為“完全脫離文檔流”,就是說它和文檔流的關聯很弱,一般只根據包含塊和坐標來確定位置就可以了。
完全脫離文檔流,也仍然不是說和文檔流毫不相干,各自為政。它的意思是:這個元素在參與布局時,不會影響在它之后的兄弟元素。絕對定位元素,在left、top等定位屬性取值auto的時候,仍然會根據文檔流取得一個可用的計算值。
三者的覆蓋關系如果有重疊,就要考慮覆蓋關系了。它們的位置從下到上依次是:
z-index為負的定位元素。
普通流(normal flow)的非行內元素。
浮動元素。
普通流的行內元素。
z-index為auto或0的定位元素。
z-index為正值的定位元素。
結語想要讓元素穩定地待在為它預定的位置上,還是有很多功課要做的。本文只介紹了一部分有關位置的細節知識,如果你也曾對這些內容有所困惑,那么希望能有所幫助。
(重新編輯自我的博客,原文地址:http://acgtofe.com/posts/2015/10/xyz-in-css)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/111175.html
摘要:但是當時因為時間限制,沒有去深入學習的更多細節。每一位的對應含義第一位,表示這個位置在轉換后的壓縮文件的第幾列。第三位,表示這個位置屬于原始文件的第幾行。第五位,數組中的索引,表示這個位置屬于源文件中的哪一個變量。 在我的博客A debugging issue caused by source code mapping里我介紹了在我做SAP C4C開發時遇到的一個曾經困擾我很久的問題,...
摘要:但是當時因為時間限制,沒有去深入學習的更多細節。每一位的對應含義第一位,表示這個位置在轉換后的壓縮文件的第幾列。第三位,表示這個位置屬于原始文件的第幾行。第五位,數組中的索引,表示這個位置屬于源文件中的哪一個變量。 在我的博客A debugging issue caused by source code mapping里我介紹了在我做SAP C4C開發時遇到的一個曾經困擾我很久的問題,...
摘要:原創,基本上是界面,新加了七八個功能,解決了前輩閱讀器上的絕大部分,并成功添加路徑打包成。畢竟只是一個學習項目跨域問題本次開發使用的是代理追書神器,是不需要后臺認證直接可以跨域的接口,以實現在移動端顯示的效果。 應屆畢業生,目前正在找工作,簡歷需要所以開發了這個app。剛開始開發也是一臉懵逼,因為沒得后臺,一些邏輯功能也不知道怎么拓展。好在看到了追書神器api接口,頓時讓我決心做出這一...
摘要:最近項目用到谷歌地圖,但是看谷歌文檔,對于國人來說,還是比較吃力的,網上找資料也并沒有太多的資料,所以就想分享給大家。顯示了整個地球地圖的完全縮放。 最近項目用到谷歌地圖,但是看谷歌api文檔,對于國人來說,還是比較吃力的,網上找資料也并沒有太多的資料,所以就想分享給大家。但是因為本人太懶了,每次研究技術完事時間一久就忘了,更別提分享了,在朋友的鼓勵支持之下,重新開始寫博客,共享給大家...
閱讀 916·2021-11-25 09:43
閱讀 1283·2021-11-17 09:33
閱讀 2998·2019-08-30 15:44
閱讀 3301·2019-08-29 17:16
閱讀 472·2019-08-28 18:20
閱讀 1624·2019-08-26 13:54
閱讀 546·2019-08-26 12:14
閱讀 2166·2019-08-26 12:14