CSS 定位
- CSS有三種基本的定位機(jī)制:普通流,浮動,絕對定位(absolute, fixed):
- 普通流是默認(rèn)定位方式,在普通流中元素框的位置由元素在html中的位置決定,這也是我們最常見的方式,其中 position: static 與 position: relative 屬于普通流的定位方式
- 浮動定位機(jī)制
- 絕對定位包括 absolute和 fixed
position: static(默認(rèn)) | relative | absolute | fixed | sticky | inherit
// 應(yīng)用于所有元素。無繼承性
/*
static:
元素框正常生成。塊級元素生成一個矩形框,作為文檔流的一部分,行內(nèi)元素則會創(chuàng)建一個或多個行框,置于其父元素中。
元素出現(xiàn)在正常的流中(忽略 top, bottom, left, right 或者 z-index 聲明)
relative:
生成相對定位的元素,相對于元素本身正常位置進(jìn)行定位。
元素仍保持其未定位前的形狀,它原本所占的空間仍保留。
常用于對其自身進(jìn)行細(xì)微調(diào)整。
相對定位實(shí)際上被看作普通流定位模型的一部分,因?yàn)樵氐奈恢孟鄬τ谒谄胀髦械奈恢?
absolute:
生成絕對定位的元素,元素框從文檔流完全刪除,相對于 static 定位以外的第一個祖先元素(offset parent)進(jìn)行定位。
元素原先在正常文檔流中所占的空間會關(guān)閉,就好像該元素原來不存在一樣。元素定位后生成一個塊級框,而不論原來它在正常流中生成何種類型的框
fixed:
元素框的表現(xiàn)類似于將 position 設(shè)置為 absolute,不過其包含塊是視窗本身(或者說是瀏覽器窗口)
常用于需要一直停留在窗口的元素
sticky:
CSS3新屬性,兼容性較差,一般用JS實(shí)現(xiàn)。表現(xiàn)類似 position: relative 和 position: fixed 的合體,
在目標(biāo)區(qū)域在屏幕中可見時,它的行為就像 position: relative;
而當(dāng)頁面滾動超出目標(biāo)區(qū)域時,它的表現(xiàn)就像 position: fixed,它會固定在目標(biāo)位置
inherit:規(guī)定應(yīng)該從父元素繼承 position 屬性的值。一般不使用
*/
// 三種定位機(jī)制使用了4個屬性來描述定位元素各邊相對于其包含塊的偏移。這4個屬性被稱為偏移屬性
top/right/bottom/left = <length> | <percentage> | auto(默認(rèn)) | inherit
/*
應(yīng)用于:定位元素(也就是 position 值不是 static 的元素)。無繼承性
百分?jǐn)?shù):對于top和bottom,相對于包含塊的 clientHeight;對于right和left,相對于包含塊的 clientWidth
這些屬性描述了距離包含塊最近邊的偏移。top描述了定位元素上外邊界離其包含塊的頂端有多遠(yuǎn)。如果top為正值,會把定位元素的上外邊距邊界下移,若為負(fù)值,則會把定位元素的上外邊距移到其包含塊的頂端之上。
類似地,left描述了定位元素的左外邊距邊界在其包含塊左邊界右邊(正值)或左邊(負(fù)值)有多遠(yuǎn)。如果是正值,會把定位元素的外邊距邊界移到包含塊左邊界右邊,而負(fù)值則將其移到包含塊左邊界左邊。
所以,正值會導(dǎo)致向內(nèi)偏移,使邊界朝著包含塊的中心移動,而負(fù)值會導(dǎo)致向外偏移
偏移定位元素的外邊距邊界時,帶來的影響是元素的所有一切(包含外邊距、邊框、內(nèi)邊距和內(nèi)容)都會在定位的過程中移動
注意:
定位元素的邊界是指定位元素 margin 外側(cè)的邊界;包含塊的包含區(qū)域是指包含塊的 border 內(nèi)側(cè)的 padding + content 區(qū)域
如果同時定義了 left 和 right 值,且 width 和 height 有值,那么 left 生效, right 無效,同樣,同時定義了 top 和 bottom,top 生效。
*/
絕對定位(absolute)
定義
- 相對定位可以看作特殊的普通流定位,元素位置是相對于它在普通流中位置發(fā)生變化,而絕對定位使元素的位置與文檔流無關(guān),也不占據(jù)文檔流空間,普通流中的元素布局就像絕對定位元素不存在一樣
-
當(dāng)元素絕對定位時,會從文檔流中完全刪除。絕對定位的元素的位置是相對于距離最近的非static祖先元素位置決定的。如果元素沒有已定位的祖先元素,那么他的位置就相對于初始包含塊html來定位,其邊界根據(jù)偏移屬性放置。元素定位后生成一個塊級框,而不論原來它在正常流中生成何種類型的框。定位元素不會流入其他元素的內(nèi)容,反之亦然
- 因?yàn)榻^對定位與文檔流無關(guān),所以絕對定位的元素可以覆蓋頁面上的其他元素,可以通過 z-index 屬性控制疊放順序,z-index 越高,元素位置越靠上
- 注意:如果文檔可滾動,絕對定位元素會隨著它滾動,因?yàn)樵刈罱K會相對于正常流的某一部分定位
寬度
- 絕對定位寬度是收縮的,如果想撐滿父容器,可以設(shè)置 width: 100%
- 注意:當(dāng)父容器里有 絕對定位 的子元素時,子元素設(shè)置 width: 100% 實(shí)際上指的是相對于父容器的 padding+content 的寬度。當(dāng)子元素是非絕對定位的元素時,width: 100% 才是指子元素的 content 等于父元素的 content寬度
特性
- absolute 和 float都可以觸發(fā)元素的BFC屬性,且都具有包裹性和破壞性,所以對于一些應(yīng)用場景,這兩個屬性可以進(jìn)行替換
- 包裹性
- 元素絕對定位后,會為其后代元素建立一個包含塊。且若該絕對定位元素不設(shè)置寬度,寬度由內(nèi)容撐開,也就是默認(rèn)寬度為內(nèi)容寬度
- 注意:浮動的包含塊會延伸,進(jìn)而包含所有后代浮動元素,但絕對定位的包含塊并不會包含后代的定位元素,只是作為后代定位元素的定位父級
- 破壞性
- 元素絕對定位后,會脫離文檔流,若父級不設(shè)置高度,則父級高度塌陷;若父級為行內(nèi)元素,無其他內(nèi)容,則父級寬度也將塌陷
- 去浮動
- 偏移特性
- 如果使用top、right、bottom、left這4個偏移特性來描述元素4個邊的放置位置,那么元素的高度和寬度將由這些偏移隱含確定,元素將會拉伸
- 使用偏移屬性拉伸的絕對定位元素,其內(nèi)部元素支持百分比 width/height 值。通常情況下,元素高度百分比要想起作用,需要父級窗口的高度值不是 auto;但是如果容器由絕對定位拉伸形成,百分比高度值也是支持的
display 解析
- 當(dāng)元素絕對定位后,元素可以改變display屬性,但各瀏覽器解析不一致
- IE8+瀏覽器解析正常
- firefox和safari瀏覽器只有切換為
display: none;時才會重新渲染,其他值相互切換時無效
- chrome瀏覽器切換到
display: inline;時渲染無效,其他值相互切換時渲染正常
- IE7-瀏覽器將絕對定位的元素全部渲染為
inline-block元素,只有切換為display: none;時才會重新渲染,其他值相互切換時無效
- 解決IE7-瀏覽器絕對定位元素渲染為
inline-block元素的bug很簡單,只需要在絕對定位的元素外面套一個空的<div>即可
clip
- 絕對定位或固定定位元素才可以使用clip屬性。絕對定位元素常配合clip屬性達(dá)到元素隱藏的效果
.hide{
position: absolute;
clip: rect(0, 0, 0, 0);
}
靜態(tài)位置
- 當(dāng)元素絕對定位后,若該元素的格式化屬性不發(fā)生變化,則該元素處于靜態(tài)位置
- 元素的靜態(tài)位置是指元素在正常流中原本的位置,更確切的講,頂端的靜態(tài)位置是從包含塊的上邊界到假想框的上外邊距邊界之間的距離。假想框是假設(shè)元素position 屬性 為static 時元素的第一個框
- 但對于居中對齊的行內(nèi)元素(個人:還包括行內(nèi)塊狀元素)來說,將元素設(shè)置為 absolute 或 fixed 會發(fā)生靜態(tài)位置跳動問題。而 relative 或 static 則不會有此問題。這是因?yàn)樵啬J(rèn)的居中對齊是元素的內(nèi)容中線對應(yīng)父級塊級元素中線,而當(dāng)元素絕對定位或固定定位之后,定位元素左邊界將與其父級塊級元素的中線對齊。除了居中對齊,左對齊、右對齊都是利用元素自身的左邊界去對齊
<style type="text/css">
* {
padding: 0;
margin: 0;
}
.box1 {
width: 300px;
height: 200px;
margin: 20px;
text-align: center;
/*text-align: right;*/
background-color: lightsalmon;
}
span {
/*display: inline-block;*/
position: absolute;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="box1">
<span>居中行內(nèi)元素</span>
</div>
</body>
overflow
- 當(dāng)overflow在絕對定位元素和其包含塊之間時,絕對定位元素不會被父級overflow屬性剪裁
- 比如:可以應(yīng)用絕對定位元素的overflow屬性失效實(shí)現(xiàn)按鈕外置的效果
<style type="text/css">
.box {
/*position: relative;*/
width: 200px;
height: 200px;
margin: 30px;
overflow: hidden;
background-color: pink;
}
.close {
position: absolute;
margin: -30px 0 0 185px;
width: 20px;
line-height: 20px;
text-align: center;
border: 2px solid;
border-radius: 50%;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box">
<div class="in">測試內(nèi)容</div>
<span class="close">×</span>
</div>
</body>
絕對定位的應(yīng)用
自適應(yīng)位置的跟隨圖標(biāo)
- 圖標(biāo)使用不依賴定位父級的absolute和margin屬性進(jìn)行定位,這樣,當(dāng)文本的字符個數(shù)改變時,圖標(biāo)的位置可以自適應(yīng)
<style type="text/css">
div {
width: 500px;
height: 20px;
margin: 30px;
line-height: 20px;
}
i {
position: absolute;
width: 28px;
height: 11px;
margin: -6px 0 0 2px;
background: url(http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/hot.gif);
}
</style>
</head>
<body>
<div>改變文字長度不影響<i></i></div>
</body>
視頻圖片上的小圖標(biāo)提示
- 一般在視頻圖片上的邊角上都會有“自制”、“最新”、“1080p”等諸如此類的提示。使用不依賴的絕對定位屬性,可以讓父級元素不設(shè)置relative,拓展性更強(qiáng)
<style type="text/css">
i {
position: absolute;
width: 50px;
height: 18px;
padding: 2px;
text-align: center;
line-height: 18px;
font-style: normal;
color: white;
background-color: orange;
}
.box {
height: 200px;
width: 200px;
margin: 50px;
border: 2px solid gray;
}
.in {
display: inline-block;
width: 100%;
height: 100%;
line-height: 100px;
background-color: pink;
}
.rt {
margin-left: -54px;
}
.lb {
margin-top: -22px;
}
.rb {
margin-top: -22px;
margin-left: -54px;
}
</style>
</head>
<body>
<div class="box">
<i class="lt">自制</i>
<div class="in">測試內(nèi)容</div><i class="rt">獨(dú)家</i>
<i class="lb">1080p</i>
<span style="display: inline-block; width: 100%;"></span><i class="rb">最新</i>
</div>
</body>
下拉菜單
- 一般地,下拉菜單作為一個組件需要使用在各種場景中,如果給組件添加 relative屬性,則降低了其利用率
<style type="text/css">
* {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
input {
border: none;
}
.box {
width: 250px;
height: 35px;
margin: 50px;
border: 1px solid #ccc;
}
.box > .con {
overflow: hidden;
margin-bottom: 10px;
}
.con > .input {
width: 215px;
height: 35px;
}
.con > .search {
float: right;
width: 35px;
height: 35px;
background: url('http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/search.png') -2px -40px;
}
.box > .list {
display: none;
/* 這里absolut的作用是什么? 設(shè)置絕對定位,完全脫離文本流,也就不會影響到其它元素的布局 */
position: absolute;
width: 212px;
overflow: hidden;
border: 1px solid #ccc;
background-color: #fff;
}
.list > .in {
line-height: 40px;
text-indent: 1em;
cursor: pointer;
}
.list > .in + .in {
border-top: 1px solid lightblue;
}
.list > .in:hover {
background-color: #f9f9f9;
}
</style>
</head>
<body>
<div class="box">
<div class="con">
<input class="input" id="input">
<a href="#" class="search"></a>
</div>
<ul class="list" id="list">
<li class="in">選項(xiàng)一</li>
<li class="in">選項(xiàng)二</li>
<li class="in">選項(xiàng)三</li>
</ul>
<div>其它文本內(nèi)容其它文本內(nèi)容其它文本內(nèi)容其它文本內(nèi)容</div>
</div>
<script type="text/javascript">
input.onfocus = function(){
list.style.display = 'block';
}
input.onblur = function(){
list.style.display = 'none';
}
</script>
</body>
邊緣對齊
- 很多網(wǎng)站都使用了邊緣對齊,但好多都是用頁面寬度計(jì)算出來的,當(dāng)寬度變化時需要重新計(jì)算。而無依賴的絕對定位利用靜態(tài)位置,無需計(jì)算就可將其位置確定,且拓展性好
<style type="text/css">
* {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.box {
width: 300px;
height: 200px;
margin: 50px;
border: 2px solid black;
background-color: lightgreen;
}
.box > .out {
text-align: right;
}
.out > .list {
/* 未設(shè)置絕對定位前,元素右邊界與其父級塊級元素的右邊界線對齊 */
position: absolute;
/* 定位元素左邊界將與其父級塊級元素的右邊界線對齊 */
/* 設(shè)置固定定位 osition: fixed; 也可以,但是可能會影響其它元素的布局 */
display: inline-block;
margin: 10px 0 0 2px;
}
.list > .in {
text-align: center;
width: 30px;
line-height: 30px;
margin-top: 10px;
border-radius: 50%;
background-color: pink;
}
</style>
</head>
<body>
<div class="box">
<div class="out">
<!-- 對于safari瀏覽器需要添加空格 來觸發(fā)右對齊,其他瀏覽器則不需要-->
<!-- -->
<ul class="list">
<li class="in">一</li>
<li class="in">二</li>
<li class="in">三</li>
</ul>
</div>
</div>
</body>
星號
- 在很多注冊或登錄頁面中,存在用 * 表示的必填項(xiàng)。* 和 * 號對齊,文字和文字對齊。這種情況使用靜態(tài)位置的絕對定位比較合適
<style type="text/css">
* {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.list {
width: 100px;
padding-left: 20px;
margin: 50px;
border: 2px solid black;
line-height: 2em;
}
.in > i {
/* 設(shè)置絕對定位,完全脫離文檔流,<span> 中的文字自然也就左對齊了 */
position: absolute;
margin-left: -10px;
color: red;
font-style: normal;
}
</style>
</head>
<body>
<ul class="list">
<li class="in">
<i>*</i><span>手機(jī)號</span>
</li>
<li class="in">
<span>用戶名</span>
</li>
<li class="in">
<i>*</i><span>密碼</span>
</li>
</ul>
</body>
偏移屬性
- 當(dāng)使用偏移屬性時,絕對定位元素將相對于包含塊進(jìn)行定位。一般地,我們僅僅使用偏移屬性中的兩個,且這兩個屬性不對立。但實(shí)際上,對立的偏移屬性如left和right可以同時使用,甚至4個偏移屬性都可以同時使用,并且可以達(dá)到一些意想不到的效果。以下基于絕對定位偏移屬性的應(yīng)用
全屏自適應(yīng)
- 實(shí)現(xiàn)一個距離屏幕右側(cè)200px的全屏自適應(yīng)的容器層
<style type="text/css">
.box {
position: absolute;
top: 0;
left: 0;
right: 200px;
bottom: 0;
background-color: pink;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
左右半?yún)^(qū)翻圖
- 一些選項(xiàng)卡中存在左右半?yún)^(qū)的翻圖效果,點(diǎn)擊左覆蓋區(qū)切換到上一張圖片,點(diǎn)擊右覆蓋區(qū)切換到下一張圖片
<style type="text/css">
* {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.box {
position: relative;
width: 300px;
height: 200px;
overflow: hidden;
margin: 50px;
border: 2px solid lightgray;
text-align: center;
font: 40px/200px '宋體';
color: white;
}
.box > .list{
position: absolute;
width: 400%;
left: 0;
top: 0;
bottom: 0;
transition: left 1s;
}
.list > .in{
float: left;
width: 25%;
background-color: lightgreen;
}
.box > .l,
.box > .r{
position: absolute;
opacity: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.box > .l {
left: 0;
right: 50%;
}
.box > .r {
left: 50%;
right: 0;
}
.box > .l:hover,
.box > .r:hover{
opacity: 1;
transition: 1s;
}
</style>
</head>
<body>
<div class="box">
<ul class="list" id="list">
<li class="in">第1個</li>
<li class="in">第2個</li>
<li class="in">第3個</li>
<li class="in">第4個</li>
</ul>
<div class="l" id="l"><</div>
<div class="r" id="r">></div>
</div>
<script type="text/javascript">
var index = 0;
var children = list.children;
l.onclick = function(){
if(index > 0){
index--;
move(index);
}
}
r.onclick = function(){
if(index < children.length - 1){
index++;
move(index);
}
}
function move(index){
list.style.left = '-' + index * 100 + '%';
}
</script>
</body>
九宮格
- 利用絕對定位的偏移屬性可以制作寬高自適應(yīng)的九宮格效果
<style type="text/css">
* {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
.list {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.list > .in {
/* 這里設(shè)置:相對定位,因?yàn)橄旅媸褂昧?偽元素,在 .in 的內(nèi)容之前及之后插入了新內(nèi)容 */
position: relative;
float: left;
height: 33.3%;
width: 33.3%;
background-color: pink;
}
.list > .in:before {
content: "";
position: absolute;
left: 10px;
right: 10px;
top: 10px;
bottom: 10px;
border-radius: 10px;
background-color: lightblue;
}
.list > .in:after {
content: attr(data-value);
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
height: 30px;
margin: auto;
text-align: center;
font:bold 24px/30px '宋體';
}
</style>
</head>
<body>
<ul class="list">
<li class="in" data-value='1'></li>
<li class="in" data-value='2'></li>
<li class="in" data-value='3'></li>
<li class="in" data-value='4'></li>
<li class="in" data-value='5'></li>
<li class="in" data-value='6'></li>
<li class="in" data-value='7'></li>
<li class="in" data-value='8'></li>
<li class="in" data-value='9'></li>
</ul>
</body>
相對定位(relative)
定義
- 當(dāng)元素相對定位時,它會從其正常位置移走,不過,原來所占的空間并不會因此消失。相對定位元素,會為其所有子元素建立一個新的包含塊。這個包含塊對應(yīng)于該元素原本所在的位置
- 相對定位完成的過程首先是按static(float)方式生成一個元素(并且元素像層一樣浮動了起來),然后相對于自身原有位置進(jìn)行偏移,移動的方向和幅度由
left、right、top、bottom屬性確定,偏移前的位置保留不動
-
position: relative; 和 負(fù)margin 都可以使元素位置發(fā)生偏移,二者有什么區(qū)別?
-
position: relative; 相對自己原本的位置偏移,不影響其它普通流中元素的位置
- margin:除了讓元素自身發(fā)生偏移還影響其它普通流中的元素
<style type="text/css">
* {
padding: 0;
margin: 0;
}
.box {
width: 600px;
height: 300px;
margin: 30px;
background-color: pink;
}
.box > .box1 {
position: relative;
top: 50px;
left: 100px;
/* .box1 元素相對于以前的位置向右移動100px,向下移動50px */
/* 雖然 .box1 元素相對于以前的位置產(chǎn)生了偏移,但是 .box1 元素以前的位置還是保留著,所以span元素實(shí)際顯示的區(qū)域是在 .box1 元素以前位置的后面 */
width: 100px;
height: 100px;
background-color: lightsalmon;
}
</style>
</head>
<body>
<div class="box">
<div class="box1">相對定位</div>
<span>你好世界你好世界你好世界你好世界你好世界你好世界</span>
</div>
</body>
- 注意:
- 元素仍然處于標(biāo)準(zhǔn)文檔流中
- 如果相對定位元素遇到過度受限的問題,一個值會重置為另一個值的相反數(shù)。bottom 總是等于 -top,right 總是等于 -left
百分比
- 非常奇怪的是,雖然相對定位的數(shù)值型偏移屬性是相對于自身的,但其百分比卻是相對于包含塊的。top 和 bottom 百分比相對于包含塊的高度(只是高度height,不包括縱向 padding 和 border),left 和 right 百分比相對于包含塊的寬度(只是寬度 width,不包括橫向 padding 和 border)
- 注意:對于IE7-和firefox瀏覽器來說,若包含塊的高度 height 為 auto,則百分比的 top 和 bottom 設(shè)置有效果,而其他瀏覽器則都沒有效果
<style type="text/css">
* {
padding: 0;
margin: 0;
}
.box {
width: 400px;
height: 400px;
background-color: pink;
}
.box > .box1{
position: relative;
left: 40px;
top: 40px;
/* 數(shù)值型相對于自身 */
width: 100px;
height: 100px;
background-color: lightsalmon;
}
.box > .box2{
position: relative;
left: 10%;
top: 10%;
/* 百分比相對于包含塊,這里移動 10% * 400 = 40px */
width: 100px;
height: 100px;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="box">
<div class="box1"></div>
<div class="box2"></div>
</div>
</body>
特性
- 限制范圍
- 般地,給絕對定位元素限制范圍時,為其父級元素設(shè)置相對定位relative,因?yàn)橄鄬Χㄎ辉夭幻撾x文檔流
- 注意:相對定位元素可以限制絕對定位,但不能限制固定定位,因?yàn)楣潭ǘㄎ皇窍鄬τ谝暣岸ㄎ坏?/li>
- 提升層級
- 當(dāng)想要提升元素層級,又不想脫離文檔流時,使用相對定位是一個好主意
行內(nèi)元素
- 不同于絕對定位元素可以使元素具有塊級元素屬性,相對定位應(yīng)用于 inline 元素后,由于無法改變其行內(nèi)元素的屬性,不具備塊級元素屬性,無法設(shè)置寬高,其上下 margin 也依然存在問題
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.box {
width: 600px;
height: 300px;
margin: 30px;
background-color: pink;
}
.box > .inline1 {
position: absolute;
width: 100px;
height: 100px;
margin: 100px 0 0 100px;
background-color: lightsalmon;
}
.box > .inline2 {
position: relative;
width: 100px;
height: 100px;
margin: 20px 0 0 20px;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="box">
<span class="inline1">行內(nèi)元素1</span>
<span class="inline2">行內(nèi)元素2</span>
</div>
</body>
IE兼容
- 在IE6瀏覽器下,haslayout下的元素 負(fù)margin 超出父元素的部分會被隱藏掉。這個問題可以通過設(shè)置margin負(fù)值元素的 position 屬性值為 relative 來解決
固定定位(fixed)
- 固定定位是絕對定位的一種,元素會完全從文檔流中去除,但固定元素的偏移是相對于視窗,或者說它的相對移動的坐標(biāo)是視圖(屏幕內(nèi)的網(wǎng)頁窗口)本身。由于視圖本身是固定的,它不會隨瀏覽器窗口的滾動條滾動而變化,除非我們在屏幕中移動瀏覽器窗口的屏幕位置,或改變?yōu)g覽器窗口的顯示大小,因此固定定位的元素會始終位于瀏覽器窗口內(nèi)視圖的某個位置,不會受文檔流動影響,這與
background-attachment: fixed;屬性功能相同
- 注意:IE7-瀏覽器不支持
特性
- 固定定位與絕對定位的很多特性都類似,具有包裹性、破壞性及去浮動的特性,關(guān)于各瀏覽器中 display 屬性的 bug、clip屬性的隱藏功能、靜態(tài)位置跳動以及overflow失效的表現(xiàn)都相同,在此就不再贅述
全屏遮罩
- 當(dāng)頁面內(nèi)容超出頁面容器大小出現(xiàn)滾動條時,此時使用 absolute 全屏遮罩會出現(xiàn)滾動條以外部分沒有遮住的情況。因?yàn)楦豩tml的父級是document,document的高度和可視區(qū)域一致,也就是與視窗一致,是不包括滾動條以外部分的
- 這時,只能使用fixed固定定位來實(shí)現(xiàn)全屏遮罩效果
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.page {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: pink;
z-index: -1;
}
.test {
width: 2000px;
height: 200px;
margin: 20px;
background-color: lightblue;
}
</style>
</head>
<body>
<div class="page" id="page"></div>
<div class="test"></div>
<button type="button">absolute</button>
<button type="button">fixed</button>
<script type="text/javascript">
// 分別點(diǎn)擊兩個按鈕,并拖動橫向滾動條查看效果
var btns = document.getElementsByTagName('button');
for(var i = 0; i < btns.length; i++){
btns[i].onclick = function(){
page.style.position = this.innerHTML;
console.log('.page 當(dāng)前的定位方式為 ' + this.innerHTML)
}
}
</script>
</body>
CSS定位中的堆疊 z-index
- 對于所有定位,最后都不免遇到兩個元素試圖放在同一位置上的情況。顯然,其中一個必須蓋住另一個。但,如何控制哪個元素放在上層,這就引入了屬性 z-index
- 參考: 深入理解CSS中的層疊上下文和層疊順序
z-index 的作用
- 利用z-index,可以改變元素相互覆蓋的順序。這個屬性的名字由坐標(biāo)系統(tǒng)得來,其中從左向右是x軸,從上到下是y軸。從屏幕到用戶是z軸。在這個坐標(biāo)系中,較高z-index值的元素 比 較低z-index值的元素 離用戶更近,這會導(dǎo)致較高z-index值的元素覆蓋其他元素,這也稱為堆疊或疊放
- z-index 僅在設(shè)置了position 非 static 屬性的元素生效,且 z-index 的值只能在兄弟元素之間比較
- 注意:z-index默認(rèn)值為 auto,不會建立層疊上下文。但為 0 時則會建立層疊上下文
z-index: <integer> | auto(默認(rèn)) | inherit
// 應(yīng)用于:定位元素。無繼承性
// z-index 應(yīng)用于定位元素是CSS2的規(guī)范,到了CSS3標(biāo)準(zhǔn),z-index 的應(yīng)用范圍擴(kuò)大了不少
// 所有整數(shù)都可以作為 z-index 的值,包括負(fù)數(shù)。如果為元素指定一個負(fù)z-index值,會將其移到離讀者更遠(yuǎn)的位置,會移到疊放棧的更低層
堆疊規(guī)則
- 對于CSS2.1來說,頁面元素的堆疊規(guī)則如下:
- 定位元素的堆疊規(guī)則:
- 對于定位元素(position不是static的元素)來說,不設(shè)置z-index或z-index相同時,后面元素覆蓋前面元素
- 對于處于同一堆疊上下文中的同一層次的元素來說,默認(rèn)z-index較大值覆蓋z-index較小值
<style type="text/css">
.clearfix:after {
content: " ";
display: table;
clear: both;
}
.parent {
border: 10px solid green;
background-color: rgba(0, 255, 0, 0.5);
/*overflow: hidden;*/
}
.parent > div{
height: 80px;
}
.block {
border: 1px solid green;
color: white;
background-color: pink
}
/*
行內(nèi)框與一個浮動元素重疊時,其邊框、背景和內(nèi)容都在該浮動元素之上顯示
塊框與一個浮動元素重疊時,其邊框和背景在該浮動元素之下顯示,而內(nèi)容在浮動元素之上顯示
*/
.float {
float: left;
font-weight: bolder;
background-color: yellow
}
.inline {
margin-left: -40px;
background-color: lightcoral;
}
.position {
position: relative;
background-color: rgba(0, 0, 255, 0.8);
}
.positive-zindex {
position: relative;
z-index: 10;
top: -10px;
background-color: rgba(255, 0, 0, 0.8);
}
.negative-zindex {
position: relative;
z-index: -1;
top: -20px;
background-color: lightcoral;
}
</style>
</head>
<body>
<div class="parent">
文字內(nèi)容
<div class="block">塊狀元素塊狀元素塊狀元素<br>塊狀元素塊狀元素塊狀元素<br>塊狀元素塊狀元素塊狀元素</div>
<div class="float clearfix">浮動元素浮動元素浮動元素</div>
<span class="inline">行內(nèi)元素行內(nèi)元素行內(nèi)元素</span>
<div class="position">定位元素定位元素定位元素</div>
<div class="positive-zindex">正z-index正z-index正z-index</div>
<div class="negative-zindex">負(fù)z-index負(fù)z-index負(fù)z-index</div>
</div>
</body>
堆疊上下文
- 一旦為一個元素指定了z-index值(不是auto),該元素會建立自己的局部堆疊上下文。這意味著,元素的所有后代相對于該祖先元素都有其自己的疊放順序
- auto值指當(dāng)前堆疊上下文中生成的棧層次與其父框的層次相同,這個框不會建立新的局部疊放上下文。
z-index: auto;與z-index: 0;的值相等,但z-index: 0;會建立新的局部堆疊上下文
- 元素不會疊放在其堆疊上下文(即定位父級z-index為數(shù)字值)的背景之下,但可以疊放在其內(nèi)容之下;當(dāng)元素沒有處于堆疊上下文中,元素不會疊放在
<body>元素的背景之下,但可以疊放在其內(nèi)容之下
<style type="text/css">
* {
padding: 0;
margin: 0;
}
.box1 {
position: relative;
/*z-index: 0;*/
width: 150px;
height: 150px;
padding: 10px;
margin: 50px;
background-color: lightsalmon;
}
.box1 > .box2 {
position: relative;
z-index: -1;
width: 100px;
height: 100px;
margin-top: -10px;
background-color: lightblue;
}
.box3 {
width: 200px;
height: 200px;
padding: 10px;
margin: -100px 50px 0;
background-color: lightgreen;
}
</style>
</head>
<body>
<div class="box1">
<p>box1</p>
<div class="box2">box2</div>
</div>
<div class="box3">box3</div>
<script type="text/javascript">
var divs = document.getElementsByTagName('div'),
box1 = divs[0],
box2 = divs[1],
box3 = divs[2];
console.log(getComputedStyle(box1, false)['z-index']); // 0
console.log(getComputedStyle(box2, false)['z-index']); // -1
console.log(getComputedStyle(box3, false)['z-index']); // auto
</script>
</body>
兼容
- IE7-瀏覽器 z-index 的默認(rèn)值是 0
- 一般地,定位元素的 z-index 的默認(rèn)值是 auto,而IE7-瀏覽器定位元素的 z-index 的默認(rèn)值是 0,二者的區(qū)別是IE7-瀏覽器的定位元素會自動生成堆疊上下文
- IE6-瀏覽器關(guān)于z-index的一個怪異bug
- 當(dāng)元素本身浮動且不是定位元素(position是static),元素父級是relative,則在IE6-瀏覽器在無論該元素的父級的z-index如何設(shè)置都不起作用
- 解決辦法:
- 元素去除浮動
- 父級元素的相對定位改成絕對定位
- 元素添加position屬性(static除外)
- 以上三個方法任一方法都可以,其實(shí)就是在破壞bug成立的條件
- IE6-瀏覽器下select的z-index無效而遮擋div
- IE6-瀏覽器下select元素(下拉列表)設(shè)置z-index無效,且默認(rèn)會堆疊在div上
- 解決辦法:在IE6-瀏覽器中,雖然div無法覆蓋select,但是iframe可以覆蓋select。所以可以設(shè)置一個與div寬高相同的iframe。讓div覆蓋iframe,iframe覆蓋select,最終達(dá)到select被div覆蓋的效果