深刻理解position屬性&containing block

1、包含塊(Containing Block)

要講position,首先就涉及到一個概念:包含塊。javascript

一、包含塊介紹

包含塊簡單理解就是一個定位參考塊,就是"大盒子裏套小盒子"中那個大盒子。元素有positon屬性就必然涉及到包含塊。先簡單總結一下。css

一、初始包含塊(Initial containing block),即根元素的包含框。 在瀏覽器中是原點與 canvas 原點重合、大小與 viewport 相同的矩形。html

二、position:static|relative 元素包含塊爲最近的級【block|list-item|table】父元素的內容框content-boxjava

三、positon:absolute 先找absolute最近已定位祖先元素【沒有的話包含塊就是初始包含塊】chrome

  • 若是祖先元素是塊級元素,則包含塊是祖先元素的padding框
  • 若是祖先元素是內聯元素,包含塊取決於祖先元素的direction屬性
    • dirrection:ltr,祖先元素的第一個盒子的上、左padding框邊界是包含塊的上和左,祖先元素最後一個盒子的下、右padding邊界是包含塊的下和右。
    • direction:rtl,祖先元素第一個盒子的上、右padding框邊界是包含塊的上右,祖先元素最後一個元素的下、左padding框邊界是包含塊的下、左。

四、positon:fixed 元素的包含塊是由viewport決定的,和根元素無關。canvas

二、static和包含塊

舉例:沒有設置postion,因此標籤position都是默認的static。瀏覽器

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>包含塊 by starof</title>
</head>
<body>
    <div id="div1">
        <p id="p1">第一段內容</p>
        <p id="p2">
            這些文字是
            <em id="em1"><strong id="strong1"></strong></em> 
            內容
        </p>
    </div>
</body>
</html>

產生盒子的元素——》包含塊ide

body——》initial C.B.(UA-dependent)佈局

div1——》bodypost

p1——》div1

p2——》div1

em1——》p2

strong1——》p2

三、absolute和包含塊

主要介紹一下祖先元素是內聯元素的狀況。

舉例:direction:ltr

包含塊的上,左是祖先元素span生成的第一個框的上,左padding 框,包含塊下右是祖先元素span的最後一個line box的下右padding框。

<p style="border:1px solid red; width:200px; padding:20px;">
    TTT
    <span style="background-color:#C0C0C0; position:relative;padding:10px;">
        這段文字從左向右排列,紅 XX 和 藍 XX 和黃 XX 都是絕對定位元素,它的包含塊是相對定位的SPAN。
 能夠經過它們絕對定位的位置來判斷它們包含塊的邊緣。 <em style="position:absolute; color:red; top:0; left:0;">XX</em> <em style="position:absolute; color:yellow; top:20px; left:0;">XX</em>
        <em style="position:absolute; color:blue; bottom:0; right:0;">XX</em>
    </span>
</p>

包含塊的寬度能夠爲負,行內元素的第一個框的起始位置位於最後一個框結束位置的右側,這時包含塊爲負值。

 我增刪幾個字符來看看效果以下

<p style="border:1px solid red; width:200px; padding:20px;">
    TTTTT
    <span style="background-color:#C0C0C0;position:relative;padding:10px;">
        這段文字從左向右排列,紅XX 和 藍 XX 和黃 XX 都是絕對定位元素,它的包含塊是相對定位的SPAN。
 能夠經過它們絕對定位的位置來判斷它們包含塊 <em style="position:absolute; color:red; top:0; left:0;">XX</em> <em style="position:absolute; color:yellow; top:20px; left:0;">XX</em>
        <em style="position:absolute; color:blue; bottom:0; right:0;">XX</em>
    </span>
</p>
View Code

舉例:direction:rtl

包含塊的上,右是祖先元素第一個框的上,右padding框,包含塊的下左是祖先元素最後一個line box的下左padding同理。

<p style="border:1px solid red; width:200px; padding:20px; direction:rtl;">
    T
    <span style="background-color:#C0C0C0; position:relative;padding:10px;">
        這段文字從右向左排列,紅 XX 和 藍 XX 和黃 XX 都是絕對定位元素,它的包含塊是相對定位的SPAN。
能夠經過它們絕對定位的位置來判斷它們 <em style="position:absolute; color:red; top:0; left:0;">XX</em> <em style="position:absolute; color:yellow; top:20px; left:0;">XX</em>
        <em style="position:absolute; color:blue; bottom:0; right:0;">XX</em>
    </span>
</p>
View Code

其餘狀況相對簡單,不作介紹。接下來是position各取值細節。

2、position:static

static是默認值,表示元素沒有別"positioned",position其它值表示元素被"positioned"。因此"已定位元素"表示的就是設置position屬性爲除static以外的值的元素。position:static元素的佈局就是按照盒子模型在正常流中來佈局。

使用:

通常不用顯示指定,除非想要覆蓋以前設置的定位,讓元素迴歸到正常流。

3、position:relative

relative表現和static同樣,除非添加了top|right|bottom|left屬性。//lxy能夠理解爲relative是從static到absolute的一個過渡屬性狀態。就像在inline和block中間過渡有一個inline-block。

相對定位元素屬性設置top|right|bottom|left偏離正常位置後,其餘元素不會調整位置來彌補偏離後剩下的空間。也能夠理解爲仍然佔據原來空間,因此不影響其餘元素佈局,可能會覆蓋別的元素。

總結:relative元素仍然處於正常流,且不改變display屬性,可能會覆蓋頁面其餘元素。

舉例:

<style>
div{
    display: inline-block;
}
.red{
    width: 100px;
    height: 100px;
    border:1px solid red;
    position: relative;
    background-color: yellow;
}
.green{
    width: 100px;
    height: 100px;
    border:1px solid green;
}
/*.left{
    left: -50px;
}*/
</style>
<body>
    <div class="red left">第一個元素</div>
    <div class="green">第二個元素</div>
    <div class="red left">第三個元素</div>
</body>

取消註釋查看設置偏移後的對比效果:

4、position:absolute

position:absolute相對於最近的"positioned" 祖先元素定位。若是沒有「positioned」祖先元素,那麼它是相對於文檔的 body 元素,而且它會隨着頁面滾動而移動。

絕對定位元素的定位值發生衝突時的解決方法:

  • 若是同時指定 top 和 bottom(非 auto),優先採用 top
  • 若是同時指定 left 和 right,若包含塊 direction 爲 ltr(英語、漢語等),則優先採用 left;若包含塊 direction 爲 rtl(阿拉伯語、希伯來語等),則優先採用right

總結幾點:

position:absolute和margin,padding都不衝突,可同時生效。

position:absolute會改變display值,因此會產生包裹性。

position:absolute的元素脫離正常流。因此會產生破壞性。

position:absolute存在時【不加top,right,bottom,left】,float不起做用,因此能夠用來去浮動。

一、包裹性

設置了position:absolute的元素,其尺寸會收縮正好容納內容。

由於position:absolute會改變元素的display屬性【相似浮動】,inline變成block,好比下面例子。

<style>
.container{
    border: 1px solid green;
    padding: 30px;
    background-color: green;
    background-clip: content-box;/*將背景裁剪到內容框,方便看絕對定位元素效果*/
    position: absolute;
}
</style>
<div class="container">內容</div>

塊狀元素設置position:absolute後,chrome下top,right,bottom,left變爲auto,而ff下直接是計算出的寬度。

補充:【update20170419】

chrome 55.0.2883.87 下設置了position:absolute的元素的top,right,bottom,left也變成了計算值。

下圖中盒模型中position盒子的值即爲top,right,bottom,left的值。

二、破壞性

舉例:子元素absolute,父元素高度塌陷。

<style>
.father{
border:1px solid red;
}
.son{
background-color: green;
position: absolute;
/*float: left;*/
}
</style>
</head>
<body>
    <div class="father">
        <div class="son" >元素內容</div>
    </div>
</body>

原理:和float同樣,position:absolute讓元素脫離正常流,而父元素還在正常流中,它們已是兩個世界的東東了,天然撐不起父元素高度。

Note:設置position:absolute後再設置float:left不生效,且最終計算的float值仍是none而不是設置的值。

三、不受relative控制的position:absolute舉例

不使用top,right,bottom,left中任何一個屬性或者使用auto做爲值。

通常都是用absolute加margin調整位置。

舉例:hot圖片始終在求課文字右上角。

<style type="text/css">
.icon-hot {
  position: absolute;
  width: 28px;
  height: 11px;
  margin: -6px 0 0 2px;
  background-color: red;
  background: url(img/new.jpg);
}
</style>
<body>
  <h3>
    <a href="#">
      新項目 <i class="icon-hot"></i>
    </a>
  </h3>
  <a href="#">新項目</a><img src="img/new.jpg" style="margin-bottom:15px;">
</body>
View Code

分析:由於position:absolute讓<i>標籤的display值從inline變成block,因此能夠設置寬高。經過margin調整位置。

相似例子:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>圖標定位二三事</title>
<style>
body { font: 14px/1.4 "Microsoft YaHei"; background-color: #EDEFF0; }
body, h3, h5 { margin: 0; }
img { border: 0 none; vertical-align: bottom; }
.l { float: left; }.r { float: right; }
.constr { width: 1200px; margin-left: auto; margin-right: auto; }

.course { padding-top: 10px; }
.course-list { float: left; width: 280px; height: 240px; margin: 5px 10px 15px; border-radius: 0 0 1px 1px; background-color: #F7FAF9; background-color: rgba(255,255,255,1); box-shadow: 0 1px 2px #c5c5c5; text-decoration: none; }
.course-list-img { background-color: #6396F1; }
.course-list-h { line-height: 50px; font-size: 14px; font-weight: 400; color: #363d40; text-align: center; }
.course-list-tips { margin: 0 14px; font-size: 12px; color: #b4bbbf; overflow: hidden; }

.icon-recom { position: absolute; line-height: 20px; padding: 0 5px; background-color: #f60; color: #fff; font-size: 12px; }
.icon-vip { position: absolute; width: 36px; height: 36px; margin-left: -36px; background: url(http://img.mukewang.com/5453048000015d8800360036.gif); text-indent: -9em; overflow: hidden; }
</style>
</head>

<body>

<div class="main">
    <div class="constr">
        <div class="course">
            <a href="http://www.imooc.com/view/121" class="course-list">
                <div class="course-list-img">
                    <span class="icon-recom">推薦</span>
                    <img width="280" height="160" alt="分享:CSS深刻理解之float浮動" src="http://img.mukewang.com/53d74f960001ae9d06000338-300-170.jpg"><!--
                    --><i class="icon-vip">vip</i>
                </div>
                <h5 class="course-list-h">分享:CSS深刻理解之float浮動</h5>
                <div class="course-list-tips">
                    <span class="l">已完結</span>
                    <span class="r">3514人學習</span>
                </div>
            </a>
        </div>
    </div>
</div>
</body>
</html>
View Code

四、無固定寬高容器內絕對定位元素拉伸

舉例:實現遮罩效果

<style>
body {
    background-color: #ddd;
}
img {
    vertical-align: bottom;
}
.container { 
    display: inline-block;
    position: relative;
}
.cover { 
    position: absolute; 
    left: 0; top: 0; right: 0; bottom: 0;
    background-color: blue;
    opacity: .5; filter: alpha(opacity=50);
}
</style>
<body>
<span class="container">
    <i class="cover"></i>
    <img src="img/wb.jpg">
</span>
</body>
View Code

一樣的原理實現:全屏自適應遮罩層效果,切加上margin:auto可實現水平且直居中。

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>沒有寬度和高度聲明實現的全屏自適應效果by starof</title>
<style>
html, body {
    height: 100%;
}
.overlay {
    display: none;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
}
.content {
    position: absolute;
    width: 300px;
    height: 200px;
    margin: auto;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: #fff;
}
</style>
</head>

<body>
    <div class="overlay" id="overlay">
        <div class="content">
            彈出層內容
            <a href="javascript:void(0);" id="close">關閉</a>
        </div>
    </div>
    <a href="javascript:void(0);" id="open">打開</a>
<script>
var  openA=document.getElementById("open");
var overlay=document.getElementById("overlay");
var  closeA=document.getElementById("close");
openA.onclick=function(){
overlay.style.display="block";
}
closeA.onclick=function(){
overlay.style.display="none";
}
</script>
</body>
</html>
View Code

5、position:fixed

fixed是absolute的特例,相對於視窗來定位,因此頁面滾動它仍是停靠在相對位置。

因此fixed也會改變元素的display屬性,會讓元素脫離正常流。

6、position和float的關係

一、position:static;position:relative和float屬性可共存。

三、同時設置position:absolute和float,float無效。

四、設置position:absolute的元素可能會覆蓋float元素。

舉例:

<style>
.float{
    width: 300px;
    height: 150px;
    background: green;
    float:left;
}
.abs{
    width: 150px;
    background-color: red;
    position: absolute;
    top:50px;
}
</style>
</head>
<body>
    <div class="float">我是float:left的DIV</div>
    <div class="abs">我是一個應用了position:absolute的DIV。</div>
</body>
View Code

爲何絕對定位元素可能會覆蓋浮動元素,由於瀏覽器渲染的時候相同堆疊上下文中,先渲染非定位元素,再渲染浮動元素,最後渲染已定位元素。

關鍵問題是,此時設置float元素的z-index來覆蓋absolute無效。由於z-index值只適用於已經定位的元素(即position:relative/absolute/fixed),對浮動元素不起做用的。

可將float元素的position屬性值設置爲relative,而後設置z-index。由於已定位元素而且z-index不是默認的auto的話會生成一個新的堆疊上下文。

若是上面說的還不是很懂,或者想更深刻了解z-index原理,可參考:z-index堆疊規則

7、資源連接

8 Box model

9 Visual formatting model

中文版CSS2/visuren

中文版CSS2/visudet/zh-hans

KB012: 絕對定位( Absolute positioning )

http://w3help.org/zh-cn/causes/RM1020

http://w3help.org/zh-cn/kb/008/

 

本文做者starof,因知識自己在變化,做者也在不斷學習成長,文章內容也不定時更新,爲避免誤導讀者,方便追根溯源,請諸位轉載註明出處:http://www.cnblogs.com/starof/p/4617776.html有問題歡迎與我討論,共同進步。

相關文章
相關標籤/搜索