CSS 定位(postion、z-index)

CSS 定位

  • CSS有三種基本的定位機制:普通流,浮動,絕對定位(absolute, fixed):
    • 普通流是默認定位方式,在普通流中元素框的位置由元素在html中的位置決定,這也是我們最常見的方式,其中 position: static 與 position: relative 屬于普通流的定位方式
    • 浮動定位機制
    • 絕對定位包括 absolute和 fixed
position: static(默認) | relative | absolute | fixed | sticky | inherit
// 應用于所有元素。無繼承性
/*
static:
元素框正常生成。塊級元素生成一個矩形框,作為文檔流的一部分,行內元素則會創建一個或多個行框,置于其父元素中。
元素出現在正常的流中(忽略 top, bottom, left, right 或者 z-index 聲明)

relative:
生成相對定位的元素,相對于元素本身正常位置進行定位。
元素仍保持其未定位前的形狀,它原本所占的空間仍保留。
常用于對其自身進行細微調整。
相對定位實際上被看作普通流定位模型的一部分,因為元素的位置相對于它在普通流中的位置

absolute:
生成絕對定位的元素,元素框從文檔流完全刪除,相對于 static 定位以外的第一個祖先元素(offset parent)進行定位。
元素原先在正常文檔流中所占的空間會關閉,就好像該元素原來不存在一樣。元素定位后生成一個塊級框,而不論原來它在正常流中生成何種類型的框

fixed:
元素框的表現類似于將 position 設置為 absolute,不過其包含塊是視窗本身(或者說是瀏覽器窗口)
常用于需要一直停留在窗口的元素

sticky:
CSS3新屬性,兼容性較差,一般用JS實現。表現類似 position: relative 和 position: fixed 的合體,
在目標區域在屏幕中可見時,它的行為就像 position: relative; 
而當頁面滾動超出目標區域時,它的表現就像 position: fixed,它會固定在目標位置

inherit:規定應該從父元素繼承 position 屬性的值。一般不使用
*/


// 三種定位機制使用了4個屬性來描述定位元素各邊相對于其包含塊的偏移。這4個屬性被稱為偏移屬性
top/right/bottom/left = <length> | <percentage> | auto(默認) | inherit
/*
應用于:定位元素(也就是 position 值不是 static 的元素)。無繼承性

百分數:對于top和bottom,相對于包含塊的 clientHeight;對于right和left,相對于包含塊的 clientWidth

這些屬性描述了距離包含塊最近邊的偏移。top描述了定位元素上外邊界離其包含塊的頂端有多遠。如果top為正值,會把定位元素的上外邊距邊界下移,若為負值,則會把定位元素的上外邊距移到其包含塊的頂端之上。
類似地,left描述了定位元素的左外邊距邊界在其包含塊左邊界右邊(正值)或左邊(負值)有多遠。如果是正值,會把定位元素的外邊距邊界移到包含塊左邊界右邊,而負值則將其移到包含塊左邊界左邊。
所以,正值會導致向內偏移,使邊界朝著包含塊的中心移動,而負值會導致向外偏移
偏移定位元素的外邊距邊界時,帶來的影響是元素的所有一切(包含外邊距、邊框、內邊距和內容)都會在定位的過程中移動

注意:
    定位元素的邊界是指定位元素 margin 外側的邊界;包含塊的包含區域是指包含塊的 border 內側的 padding + content 區域
    如果同時定義了 left 和 right 值,且 width 和 height 有值,那么 left 生效, right 無效,同樣,同時定義了 top 和 bottom,top 生效。
*/

絕對定位(absolute)

定義
  • 相對定位可以看作特殊的普通流定位,元素位置是相對于它在普通流中位置發生變化,而絕對定位使元素的位置與文檔流無關,也不占據文檔流空間,普通流中的元素布局就像絕對定位元素不存在一樣
  • 當元素絕對定位時,會從文檔流中完全刪除。絕對定位的元素的位置是相對于距離最近的非static祖先元素位置決定的。如果元素沒有已定位的祖先元素,那么他的位置就相對于初始包含塊html來定位,其邊界根據偏移屬性放置。元素定位后生成一個塊級框,而不論原來它在正常流中生成何種類型的框。定位元素不會流入其他元素的內容,反之亦然
  • 因為絕對定位與文檔流無關,所以絕對定位的元素可以覆蓋頁面上的其他元素,可以通過 z-index 屬性控制疊放順序,z-index 越高,元素位置越靠上
  • 注意:如果文檔可滾動,絕對定位元素會隨著它滾動,因為元素最終會相對于正常流的某一部分定位
寬度
  • 絕對定位寬度是收縮的,如果想撐滿父容器,可以設置 width: 100%
  • 注意:當父容器里有 絕對定位 的子元素時,子元素設置 width: 100% 實際上指的是相對于父容器的 padding+content 的寬度。當子元素是非絕對定位的元素時,width: 100% 才是指子元素的 content 等于父元素的 content寬度
特性
  • absolute 和 float都可以觸發元素的BFC屬性,且都具有包裹性和破壞性,所以對于一些應用場景,這兩個屬性可以進行替換
  • 包裹性
    • 元素絕對定位后,會為其后代元素建立一個包含塊。且若該絕對定位元素不設置寬度,寬度由內容撐開,也就是默認寬度為內容寬度
    • 注意:浮動的包含塊會延伸,進而包含所有后代浮動元素,但絕對定位的包含塊并不會包含后代的定位元素,只是作為后代定位元素的定位父級
  • 破壞性
    • 元素絕對定位后,會脫離文檔流,若父級不設置高度,則父級高度塌陷;若父級為行內元素,無其他內容,則父級寬度也將塌陷
  • 去浮動
    • 元素絕對定位后,元素原來的浮動效果將失效
  • 偏移特性
    • 如果使用top、right、bottom、left這4個偏移特性來描述元素4個邊的放置位置,那么元素的高度和寬度將由這些偏移隱含確定,元素將會拉伸
    • 使用偏移屬性拉伸的絕對定位元素,其內部元素支持百分比 width/height 值。通常情況下,元素高度百分比要想起作用,需要父級窗口的高度值不是 auto;但是如果容器由絕對定位拉伸形成,百分比高度值也是支持的
display 解析
  • 當元素絕對定位后,元素可以改變display屬性,但各瀏覽器解析不一致
    • IE8+瀏覽器解析正常
    • firefox和safari瀏覽器只有切換為display: none;時才會重新渲染,其他值相互切換時無效
    • chrome瀏覽器切換到display: inline;時渲染無效,其他值相互切換時渲染正常
    • IE7-瀏覽器將絕對定位的元素全部渲染為inline-block元素,只有切換為display: none;時才會重新渲染,其他值相互切換時無效
      • 解決IE7-瀏覽器絕對定位元素渲染為inline-block元素的bug很簡單,只需要在絕對定位的元素外面套一個空的<div>即可
clip
  • 絕對定位或固定定位元素才可以使用clip屬性。絕對定位元素常配合clip屬性達到元素隱藏的效果
.hide{
    position: absolute;
    clip: rect(0, 0, 0, 0);
}  
靜態位置
  • 當元素絕對定位后,若該元素的格式化屬性不發生變化,則該元素處于靜態位置
  • 元素的靜態位置是指元素在正常流中原本的位置,更確切的講,頂端的靜態位置是從包含塊的上邊界到假想框的上外邊距邊界之間的距離。假想框是假設元素position 屬性 為static 時元素的第一個框
  • 但對于居中對齊的行內元素(個人:還包括行內塊狀元素)來說,將元素設置為 absolute 或 fixed 會發生靜態位置跳動問題。而 relative 或 static 則不會有此問題。這是因為元素默認的居中對齊是元素的內容中線對應父級塊級元素中線,而當元素絕對定位或固定定位之后,定位元素左邊界將與其父級塊級元素的中線對齊。除了居中對齊,左對齊、右對齊都是利用元素自身的左邊界去對齊
    <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>居中行內元素</span>
</div>
</body>
overflow
  • 當overflow在絕對定位元素和其包含塊之間時,絕對定位元素不會被父級overflow屬性剪裁
  • 比如:可以應用絕對定位元素的overflow屬性失效實現按鈕外置的效果
    <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">測試內容</div>           
    <span class="close">×</span>
</div>
</body>

絕對定位的應用

自適應位置的跟隨圖標
  • 圖標使用不依賴定位父級的absolute和margin屬性進行定位,這樣,當文本的字符個數改變時,圖標的位置可以自適應
    <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>
視頻圖片上的小圖標提示
  • 一般在視頻圖片上的邊角上都會有“自制”、“最新”、“1080p”等諸如此類的提示。使用不依賴的絕對定位屬性,可以讓父級元素不設置relative,拓展性更強
    <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">測試內容</div><i class="rt">獨家</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的作用是什么? 設置絕對定位,完全脫離文本流,也就不會影響到其它元素的布局 */
        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">選項一</li>
        <li class="in">選項二</li>
        <li class="in">選項三</li>
    </ul>
    <div>其它文本內容其它文本內容其它文本內容其它文本內容</div>        
</div>
<script type="text/javascript">
input.onfocus = function(){
    list.style.display = 'block';
}

input.onblur = function(){
    list.style.display = 'none';
}
</script>
</body>
邊緣對齊
  • 很多網站都使用了邊緣對齊,但好多都是用頁面寬度計算出來的,當寬度變化時需要重新計算。而無依賴的絕對定位利用靜態位置,無需計算就可將其位置確定,且拓展性好
    <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 {
        /* 未設置絕對定位前,元素右邊界與其父級塊級元素的右邊界線對齊 */
        position: absolute;
        /* 定位元素左邊界將與其父級塊級元素的右邊界線對齊 */
        /* 設置固定定位 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瀏覽器需要添加空格   來觸發右對齊,其他瀏覽器則不需要-->
        <!--   -->
        <ul class="list">
            <li class="in">一</li>
            <li class="in">二</li>
            <li class="in">三</li>
        </ul>        
    </div>
</div>
</body>
星號
  • 在很多注冊或登錄頁面中,存在用 * 表示的必填項。* 和 * 號對齊,文字和文字對齊。這種情況使用靜態位置的絕對定位比較合適
    <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 {
        /* 設置絕對定位,完全脫離文檔流,<span> 中的文字自然也就左對齊了 */
        position: absolute;

        margin-left: -10px;
        color: red; 
        font-style: normal;
    }
    </style>
</head>
<body>
<ul class="list">
    <li class="in">
        <i>*</i><span>手機號</span>
    </li>
    <li class="in">
        <span>用戶名</span>
    </li>
    <li class="in">
        <i>*</i><span>密碼</span>
    </li>
</ul>
</body>
偏移屬性
  • 當使用偏移屬性時,絕對定位元素將相對于包含塊進行定位。一般地,我們僅僅使用偏移屬性中的兩個,且這兩個屬性不對立。但實際上,對立的偏移屬性如left和right可以同時使用,甚至4個偏移屬性都可以同時使用,并且可以達到一些意想不到的效果。以下基于絕對定位偏移屬性的應用
全屏自適應
  • 實現一個距離屏幕右側200px的全屏自適應的容器層
    <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>
左右半區翻圖
  • 一些選項卡中存在左右半區的翻圖效果,點擊左覆蓋區切換到上一張圖片,點擊右覆蓋區切換到下一張圖片
    <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>
九宮格
  • 利用絕對定位的偏移屬性可以制作寬高自適應的九宮格效果
    <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 {
        /* 這里設置:相對定位,因為下面使用了 偽元素,在 .in 的內容之前及之后插入了新內容 */
        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)

定義
  • 當元素相對定位時,它會從其正常位置移走,不過,原來所占的空間并不會因此消失。相對定位元素,會為其所有子元素建立一個新的包含塊。這個包含塊對應于該元素原本所在的位置
  • 相對定位完成的過程首先是按static(float)方式生成一個元素(并且元素像層一樣浮動了起來),然后相對于自身原有位置進行偏移,移動的方向和幅度由leftrighttopbottom屬性確定,偏移前的位置保留不動
  • position: relative; 和 負margin 都可以使元素位置發生偏移,二者有什么區別?
    • position: relative; 相對自己原本的位置偏移,不影響其它普通流中元素的位置
    • margin:除了讓元素自身發生偏移還影響其它普通流中的元素
    <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 元素相對于以前的位置產生了偏移,但是 .box1 元素以前的位置還是保留著,所以span元素實際顯示的區域是在 .box1 元素以前位置的后面 */

        width: 100px;
        height: 100px;
        background-color: lightsalmon;
    }
    </style>
</head>
<body>
<div class="box">
    <div class="box1">相對定位</div>
    <span>你好世界你好世界你好世界你好世界你好世界你好世界</span>
</div>
</body>
  • 注意:
    • 元素仍然處于標準文檔流中
    • 如果相對定位元素遇到過度受限的問題,一個值會重置為另一個值的相反數。bottom 總是等于 -top,right 總是等于 -left
百分比
  • 非常奇怪的是,雖然相對定位的數值型偏移屬性是相對于自身的,但其百分比卻是相對于包含塊的。top 和 bottom 百分比相對于包含塊的高度(只是高度height,不包括縱向 padding 和 border),left 和 right 百分比相對于包含塊的寬度(只是寬度 width,不包括橫向 padding 和 border)
  • 注意:對于IE7-和firefox瀏覽器來說,若包含塊的高度 height 為 auto,則百分比的 top 和 bottom 設置有效果,而其他瀏覽器則都沒有效果
    <style type="text/css">
    * {
        padding: 0;
        margin: 0;
    }
 
    .box {
        width: 400px;
        height: 400px;
        background-color: pink;
    }

    .box > .box1{
        position: relative;
        left: 40px;
        top: 40px;
        /* 數值型相對于自身 */

        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>
特性
  • 限制范圍
    • 般地,給絕對定位元素限制范圍時,為其父級元素設置相對定位relative,因為相對定位元素不脫離文檔流
    • 注意:相對定位元素可以限制絕對定位,但不能限制固定定位,因為固定定位是相對于視窗定位的
  • 提升層級
    • 當想要提升元素層級,又不想脫離文檔流時,使用相對定位是一個好主意
行內元素
  • 不同于絕對定位元素可以使元素具有塊級元素屬性,相對定位應用于 inline 元素后,由于無法改變其行內元素的屬性,不具備塊級元素屬性,無法設置寬高,其上下 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">行內元素1</span>
    <span class="inline2">行內元素2</span>
</div>
</body>
IE兼容
  • 在IE6瀏覽器下,haslayout下的元素 負margin 超出父元素的部分會被隱藏掉。這個問題可以通過設置margin負值元素的 position 屬性值為 relative 來解決

固定定位(fixed)

  • 固定定位是絕對定位的一種,元素會完全從文檔流中去除,但固定元素的偏移是相對于視窗,或者說它的相對移動的坐標是視圖(屏幕內的網頁窗口)本身。由于視圖本身是固定的,它不會隨瀏覽器窗口的滾動條滾動而變化,除非我們在屏幕中移動瀏覽器窗口的屏幕位置,或改變瀏覽器窗口的顯示大小,因此固定定位的元素會始終位于瀏覽器窗口內視圖的某個位置,不會受文檔流動影響,這與background-attachment: fixed;屬性功能相同
  • 注意:IE7-瀏覽器不支持
特性
  • 固定定位與絕對定位的很多特性都類似,具有包裹性、破壞性及去浮動的特性,關于各瀏覽器中 display 屬性的 bug、clip屬性的隱藏功能、靜態位置跳動以及overflow失效的表現都相同,在此就不再贅述
全屏遮罩
  • 當頁面內容超出頁面容器大小出現滾動條時,此時使用 absolute 全屏遮罩會出現滾動條以外部分沒有遮住的情況。因為根元素html的父級是document,document的高度和可視區域一致,也就是與視窗一致,是不包括滾動條以外部分的
  • 這時,只能使用fixed固定定位來實現全屏遮罩效果
    <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">
// 分別點擊兩個按鈕,并拖動橫向滾動條查看效果
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 當前的定位方式為 ' + this.innerHTML)
    }
}  
</script>
</body>

CSS定位中的堆疊 z-index

  • 對于所有定位,最后都不免遇到兩個元素試圖放在同一位置上的情況。顯然,其中一個必須蓋住另一個。但,如何控制哪個元素放在上層,這就引入了屬性 z-index
  • 參考: 深入理解CSS中的層疊上下文和層疊順序
z-index 的作用
  • 利用z-index,可以改變元素相互覆蓋的順序。這個屬性的名字由坐標系統得來,其中從左向右是x軸,從上到下是y軸。從屏幕到用戶是z軸。在這個坐標系中,較高z-index值的元素 比 較低z-index值的元素 離用戶更近,這會導致較高z-index值的元素覆蓋其他元素,這也稱為堆疊或疊放
  • z-index 僅在設置了position 非 static 屬性的元素生效,且 z-index 的值只能在兄弟元素之間比較
  • 注意:z-index默認值為 auto,不會建立層疊上下文。但為 0 時則會建立層疊上下文
z-index: <integer> | auto(默認) | inherit
// 應用于:定位元素。無繼承性
// z-index 應用于定位元素是CSS2的規范,到了CSS3標準,z-index 的應用范圍擴大了不少
// 所有整數都可以作為 z-index 的值,包括負數。如果為元素指定一個負z-index值,會將其移到離讀者更遠的位置,會移到疊放棧的更低層
堆疊規則
  • 對于CSS2.1來說,頁面元素的堆疊規則如下:
  • 定位元素的堆疊規則:
    • 對于定位元素(position不是static的元素)來說,不設置z-index或z-index相同時,后面元素覆蓋前面元素
    • 對于處于同一堆疊上下文中的同一層次的元素來說,默認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
    }

    /*
    行內框與一個浮動元素重疊時,其邊框、背景和內容都在該浮動元素之上顯示
    塊框與一個浮動元素重疊時,其邊框和背景在該浮動元素之下顯示,而內容在浮動元素之上顯示
    */
    .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">
    文字內容
    <div class="block">塊狀元素塊狀元素塊狀元素<br>塊狀元素塊狀元素塊狀元素<br>塊狀元素塊狀元素塊狀元素</div>
    <div class="float clearfix">浮動元素浮動元素浮動元素</div>
    <span class="inline">行內元素行內元素行內元素</span>
    <div class="position">定位元素定位元素定位元素</div>
    <div class="positive-zindex">正z-index正z-index正z-index</div>
    <div class="negative-zindex">負z-index負z-index負z-index</div>
</div>
</body>
堆疊上下文
  • 一旦為一個元素指定了z-index值(不是auto),該元素會建立自己的局部堆疊上下文。這意味著,元素的所有后代相對于該祖先元素都有其自己的疊放順序
  • auto值指當前堆疊上下文中生成的棧層次與其父框的層次相同,這個框不會建立新的局部疊放上下文。z-index: auto;z-index: 0;的值相等,但z-index: 0;會建立新的局部堆疊上下文
  • 元素不會疊放在其堆疊上下文(即定位父級z-index為數字值)的背景之下,但可以疊放在其內容之下;當元素沒有處于堆疊上下文中,元素不會疊放在<body>元素的背景之下,但可以疊放在其內容之下
    <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 的默認值是 0
    • 一般地,定位元素的 z-index 的默認值是 auto,而IE7-瀏覽器定位元素的 z-index 的默認值是 0,二者的區別是IE7-瀏覽器的定位元素會自動生成堆疊上下文
  • IE6-瀏覽器關于z-index的一個怪異bug
    • 當元素本身浮動且不是定位元素(position是static),元素父級是relative,則在IE6-瀏覽器在無論該元素的父級的z-index如何設置都不起作用
    • 解決辦法:
      • 元素去除浮動
      • 父級元素的相對定位改成絕對定位
      • 元素添加position屬性(static除外)
      • 以上三個方法任一方法都可以,其實就是在破壞bug成立的條件
  • IE6-瀏覽器下select的z-index無效而遮擋div
    • IE6-瀏覽器下select元素(下拉列表)設置z-index無效,且默認會堆疊在div上
    • 解決辦法:在IE6-瀏覽器中,雖然div無法覆蓋select,但是iframe可以覆蓋select。所以可以設置一個與div寬高相同的iframe。讓div覆蓋iframe,iframe覆蓋select,最終達到select被div覆蓋的效果
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,796評論 1 92
  • CSS 是什么 css(Cascading Style Sheets),層疊樣式表,選擇器{屬性:值;屬性:值}h...
    崔敏嫣閱讀 1,509評論 0 5
  • 1.CSS基本概念 1.1 CSS的定義 CSS(Cascading Style Sheets)層疊樣式表,主要用...
    寥寥十一閱讀 1,874評論 0 6
  • 一:在制作一個Web應用或Web站點的過程中,你是如何考慮他的UI、安全性、高性能、SEO、可維護性以及技術因素的...
    Arno_z閱讀 1,212評論 0 1
  • relative:生成相對定位的元素,通過top,bottom,left,right的位置相對于其正常位置進行定位...
    zx9426閱讀 965評論 0 2