要講position,首先就涉及到一個概念:包含塊。javascript
包含塊簡單理解就是一個定位參考塊,就是"大盒子裏套小盒子"中那個大盒子。元素有positon屬性就必然涉及到包含塊。先簡單總結一下。css
一、初始包含塊(Initial containing block),即根元素的包含框。 在瀏覽器中是原點與 canvas 原點重合、大小與 viewport 相同的矩形。html
二、position:static|relative 元素包含塊爲最近的塊級【block|list-item|table】父元素的內容框content-boxjava
三、positon:absolute 先找absolute最近已定位祖先元素【沒有的話包含塊就是初始包含塊】chrome
四、positon:fixed 元素的包含塊是由viewport決定的,和根元素無關。canvas
舉例:沒有設置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
主要介紹一下祖先元素是內聯元素的狀況。
舉例: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>
舉例: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>
其餘狀況相對簡單,不作介紹。接下來是position各取值細節。
static是默認值,表示元素沒有別"positioned",position其它值表示元素被"positioned"。因此"已定位元素"表示的就是設置position屬性爲除static以外的值的元素。position:static元素的佈局就是按照盒子模型在正常流中來佈局。
使用:
通常不用顯示指定,除非想要覆蓋以前設置的定位,讓元素迴歸到正常流。
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>
取消註釋查看設置偏移後的對比效果:
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而不是設置的值。
不使用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>
分析:由於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>
舉例:實現遮罩效果
<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>
一樣的原理實現:全屏自適應遮罩層效果,切加上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>
fixed是absolute的特例,相對於視窗來定位,因此頁面滾動它仍是停靠在相對位置。
因此fixed也會改變元素的display屬性,會讓元素脫離正常流。
一、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>
爲何絕對定位元素可能會覆蓋浮動元素,由於瀏覽器渲染的時候相同堆疊上下文中,先渲染非定位元素,再渲染浮動元素,最後渲染已定位元素。
關鍵問題是,此時設置float元素的z-index來覆蓋absolute無效。由於z-index值只適用於已經定位的元素(即position:relative/absolute/fixed),對浮動元素不起做用的。
可將float元素的position屬性值設置爲relative,而後設置z-index。由於已定位元素而且z-index不是默認的auto的話會生成一個新的堆疊上下文。
若是上面說的還不是很懂,或者想更深刻了解z-index原理,可參考:z-index堆疊規則
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有問題歡迎與我討論,共同進步。