position 屬性的基礎概念

Sandy
UI/UX練功坊
Published in
8 min readDec 3, 2018

好好運用position屬性就能做出自由度更高更靈活的排版

先來看 css 的 position 屬性有哪些值:
static (預設值)、absolute (絕對配置)、relative (相對配置)、fixed (固定配置),以及 css3 才加入的新屬性值 sticky

position: absolute 絕對配置

將某個區塊設定 position: absolute 之後,這個區塊就像在白板上貼便利貼一樣,可以脫離原本預設的版面配置,重新以「基準元素」為起點,可以自由指定配置位置。而原本應該顯示這個區塊的位置,由於這個區塊移到新的圖層(便利貼)了,後續的元素會自動遞補上去。

若沒有指定基準元素的話,預設是以 body 元素(整個視窗)為基準。我們來看下列這個範例,設定好 Box1 的屬性之後,它就從原本應該出現的位置,位移到目前的位置了(距離視窗上方80px、左方200px)

.box1 {
position: absolute;
top: 80px;
left: 200px;
}
基準元素預設為 body

查看範例一

但假如我們將 #wrap 設定為「基準元素」:position 屬性必須是relative (且必須為絕對配置元素的父元素或祖先元素),我們配置的位置數值就會以 #wrap 的範圍來做計算。指定好基準元素後,它又從剛剛的位置,位移到距離 #wrap 區塊上方80px、左方200px 的位置。

#wrap {
border: 3px solid #00f;
position: relative; /*表示它是基準元素*/
}
設定父元素 #wrap 為基準元素後

查看範例一修改後

● 補充說明1:left、top、right、bottom 這個語法只有當 position 屬性值不是 static (預設值) 時才有效,當指定的數值為「負值」時,可以將配置位置拉到基準元素外側。下圖為指定 left: -120px 的結果。

當位移的數值為負數時,可以配置到基準元素的外側

● 補充說明2:z-index (元素在 z 軸的方向順序)這個語法同樣也是只有當 position 屬性值不是 static (預設值) 時才有效,預設版面的 z-index 值視為 0 ,要讓區塊顯示於下方時,必須將 z-index 的數值設為「負數」,例如以下範例:

.box1 {
position: absolute;
top: 80px;
left: -70px;
z-index: -1;
}
設定 z-index 為負值,讓 Box1 顯示在 #wrap 的下方(下一層)

※ 註:當有多個屬性值不為 static(預設值)的元素重疊時,若不做 z-index 的設定,預設顯示時會依「 HTML 的撰寫順序,順序越後者顯示在越上層」

position: relative 相對配置

剛剛介紹的 position: absolute 是可以設定父層元素為基準元素作絕對位移,而 position: relative 則會以「自己原本顯示的位置為基準位置」來指定上下左右的偏移,且區塊原本的空間仍會保留不會消失

這個屬性值大多會用在:
(1) 設定絕對配置( position: absolute )的基準元素時
(2) 希望元素偏移重疊 or 指定圖層上下順序且同時保留原本的空間

(✓) 例如當我們希望做一個色塊重疊的效果,但是又不希望底下的介紹文字浮上來被色塊遮住時,就可以這樣設定:

.box3 {
position: relative;
top: -20px;
left: 160px;
}
將 Box3 設定為 position: relative; 時,原本的區塊空間會被保留,所以文字不會自動填補上來

查看範例二

(✖) 但假如使用 position: absolute 的話,雖然同樣也可以達到偏移的效果,但是區塊原本佔的空間消失了,後續的文字就自動填補上來了。

.box3 {
position: absolute;
top: 370px;
left: 190px;
}
若將 Box3 設定為 position: absolute; ,原本的區塊空間會消失,文字就自動填補上來了

查看範例二修改後

position: fixed 固定配置

position: fixed 和 position: absolute 一樣,都是以絕對位置配置元素區塊,不同的是,fixed 是以整個視窗( body 元素)為基準,就算拉動捲軸,區塊仍然會顯示在同一個位置。

這種特性可以使用在 go top (回到頁面頂端)按鈕 或是 固定顯示於頁面上方的 header 等,我們來做一個返回頁面頂端的按鈕試試看,先設定好按鈕的樣式後,加入 position: fixed 的設定,固定顯示在頁面右下方:

#gotop_btn {
position: fixed;
bottom: 10px;
right: 20%;
}
按鈕設定為 position: fixed 的絕對位置,不管頁面捲動到哪,都固定顯示在頁面的右下方

查看 position: fixed; 範例

position: sticky

最後來看 sticky 這個新屬性值的效果,它是 relative 及 fixed 兩種 position 的混合,默認的情況下,元素會被當作 position: relative; ,捲動頁面時元素會跟著父元素一起捲動,但是當元素與視窗的距離小於指定的數值時(例如下列範例是 top: 15px ),元素則會轉換為 position: fixed;,固定黏著( sticky )在指定的數值上,距離不會再縮小。

我們來寫一個 sticky sidemenu 看看實際效果:

.sidemenu {
width: 20%;
float: left;
padding-top: 15px;
position: sticky;
top: 15px;
}
一開始 sidemenu 的位置是在距離上方 header 15px 的地方
往下捲動之後,sidemenu 就會一直黏著( sticky )在距離視窗上方 15px 的地方,不會往上捲出去

查看 sticky sidemenu 範例

另外,也可以達成像索引文字開頭這樣的黏著 menu 效果,我們來看這個 MDN 提供的範例:→ MDN 範例連結

一開始文字開頭索引看起來跟靜態的沒什麼差別
往下捲動後,文字開頭會黏著在頁面的最上方
當捲動超出父元素的範圍時,上一個文字開頭會捲出畫面,繼續黏著下一個文字開頭

以上這兩種範例的效果,用 sticky 這個屬性值只需要純 CSS 就能實現,原本沒有這個屬性時,我們需要撰寫 JS 的滾動監聽才能實現。

但最重要的是,這個屬性的支援度到底如何,我們來看 MDN 提供的資訊:

支援的瀏覽器有 Chrome 版本 56 以上, Edge, Firefox, Safari 等,IE 不支援。但要注意的是 Chrome 跟 Opera 都不支援 table 元素使用 sticky 這個屬性

總結:
position 屬性雖然很好用,但是在大小不固定的區塊(基準元素)使用絕對配置時,內容很可能會超出區域外出現 bug,因此在使用時一定要慎重考慮如何設計並多加測試,儘量以用在較簡化的地方為佳。

--

--