css position 對於初學者來說觀念很容易混淆,我在剛學習時也很常搞不清楚relative和absolute之間的關係,但只要抓到幾個訣竅重點,其實可以很輕鬆的掌握它,這篇是紀錄我自己學習css position的心得,搭配幾個簡單易懂的範例,讓大家一起成長

Start

首先,css position 屬性共有四個值,分別為 staticrelativeabsolutefixed,其中,當你沒有設定position時,預設為static,下面就來介紹這四個值的差別

static

就如剛剛所提到的,static是預設值,意思是說,就算你沒宣告position這個屬性,默認還是為static,而通常這時候會影響到元素的位置,就是看它本身是 block 或是 inline,例如兩個<div>因為是block的關係,所以會上下各占據一行,那如果是兩個<span>,因為是inline,所以會在同一行裡面呈現
css
#d1{
    width: 100px;
    height: 100px;
    background: blue;
}
#d2{
    width: 100px;
    height: 100px;
    background: red;
}
#s1{
        background: blue;
    }
#s2{
        background: red;
    }
html
<div id="d1">
div1
</div>
<div id="d2">
div2
</div>
<span id="s1">span1</span><span id="s2">span2</span>


特別注意的是,static並不會受 topbottomleftright 這些屬性值影響

relative

假如元素的position屬性值設為relative,就會受到 topbottomleftright 這些值影響所在位置,利用剛剛的範例,我們增加position屬性值和一些位移看看結果
css
#d1{
    width: 100px;
    height: 100px;
    background: blue;
    position: relative;
    top: 20px;
    left: 20px;
}
#d2{
    width: 100px;
    height: 100px;
    background: red;
}
我們在id為d1的<div>裡面加上了 position: relativetop:20px 還有 left:20px,會看到下面如圖的結果

藍色的div從原本的位置往右下角位移了,從原始位置的左上角為起點,遠離左邊(left)20px的差距,遠離上面(top)也是20px的差距,但還是保留原本位置的空間,並且覆蓋到d2,注意我這邊特別註明是原本的位置,因為這會跟等下介紹的 absolute 有所不同,那有些人或許會有疑問,可以用 margin 取代嗎?我們來實驗一下
#d1{
    width: 100px;
    height: 100px;
    background: blue;
    margin-top: 20px;
    margin-left: 20px;
}
#d2{
    width: 100px;
    height: 100px;
    background: red;
}

有明顯的發現,利用屬性margin做位移,元素並沒有覆蓋堆疊的問題,但會影響到其它的元素位置,這是要特別注意小心的地方,不可不慎

absolute

absolute 跟relative很像,差別在於位移時是從哪個起始點開始算起,剛剛的relative是從原本的位置開始算,而absolute是從整個頁面的視窗開始算起(感謝網友底下留言補充,這邊應該講從最近一個有 "position: relative" 的 parent node 開始算),並且並不會保留它原本的空間,範例如下
#d1{
    width: 100px;
    height: 100px;
    background: blue;
    position: absolute;;
    top: 20px;
    left: 20px;
}
#d2{
    width: 100px;
    height: 100px;
    background: red;
}

有發現藍色的<div>完全無視其它的元素存在,也不會干擾到其它的元素,因為它的原始空間也消失了,自己獨立起來自成一格,看起來還 蠻容易了解的,不過有一個地方是初學者很容易混淆的,就是當relative和absolute一起使用時,那情形就會跟我們設想的不太一樣,範例如下
css
#d1{
    width: 100px;
    height: 100px;
    background: blue;
    position: absolute;;
    top: 20px;
    left: 20px;
}
#d2{
    width: 100px;
    height: 100px;
    background: red;
}

#d3{
    position: relative;
    width: 300px;
    height: 300px;
    border: solid 1px orange;
}
html
<div id="d3">
    <div id="d1">
    div1
    </div>
    <div id="d2">
    div2
    </div>
</div>
這裡多用一個id為d3的<div>包住兩個<div>,d3的position屬性值為relative,此時會看到藍色的<div>屬性值position雖然一樣是absolute,但會看到位移不太一樣了

會發現藍色的<div>是從id為d3的<div>左上角開始定位,這代表是說,如果屬性值為absolute的<div>,上面還有被其它元素包住,就要注意位移計算的起始值會有所不同,那如果將relative移除的話呢?

嗯!定位又從頁面視窗的左上角當作起始點囉,如果覺得範例感覺不到效果,可以將top和left的值加大,會更明顯

fixed

最後講到的是fixed,它常被用於在Menu bar,位置也是受到 topbottomleftright 這些值影響,跟absolute類似,但有兩個不一樣的地方
1.它的位移起始的依據永遠都是視窗頁面,也就是說就算它有relative的父元素,並不會受到影響
2.它會跟著scroll移動,也就是說當畫面被往下拉時,該元素會跟隨著移到相對的位置
基於以上兩點的特色,我們就可以做出永遠固定在視窗某個地方的元素

像是 pinterest 就有用到類似的效果,不過記得要搭配 * z-index* 來做元素堆疊

結論

其實網路上有很多很好的文章在討論關於css position的用法和觀念,也有很多很漂亮的排版,但只要掌握好基本觀念,我相信對於那些複雜的layout也可以輕鬆的理解
另外除了上面討論的四個屬性值以外,CSS3其實還有新增另外兩個,分別叫做 position: centerposition: page,不過因為非主流且各瀏覽器支援程度很低,有興趣的人在自行研究即可

參考資料:

CSS Positioning: A Comprehensive Look
Learn CSS Positioning in Ten Steps(10個步驟學習CSS Position)
CSS Position 位置
內容如有錯誤,歡迎指正