天天看点

CSS中position详解

一些关于定位和叠加的理解

一、position属性

position有5个值,分别为static,relative,absolute,fixed,sticky。

1.1 static

static是position的默认属性,元素会按正常的文档流进行排序,不会受到top,bottom,left,right的影响。

1.2 relative

relative相对定位的元素会较正常文档流中的位置进行偏移,受top,bottom,left,right的影响。就是元素还在文档流中像static一样占着位置,但视觉上会有偏移,多用于absolute绝对定位的父元素。

1.3 absolute

absolute绝对定位会脱离正常的文档流,相对于最近的进行过定位的(非static)父级元素定位,若没有父级元素进行过定位,则相对于即浏览器窗口定位。

1.4 fixed

fixed固定定位同样是脱离正常的文档流,一直相对于浏览器窗口定位,无论页面如何滚动,此元素总在屏幕的同一个位置。

注:当fixed定位的父元素使用了transform的样式时,fixed定位会失效,变成和absolute一样的效果。

1.5 sticky

sticky粘性定位需要指定 top,right,bottom,left 四个阈值其中之一才会生效。

阈值为此元素在可视区域中与边界的距离,跨越特定阈值前为相对定位(relative),当页面滚动导致此元素跨越阈值则变为固定定位(absolute)。

注:此属性兼容性不是特别好,请根据业务场景进行选择。

附兼容性传送门:https://caniuse.com/#search=sticky

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <div class="box">
       <div>title</div>
       <div class="stickyBar">stickyBar</div>
       <p>this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!</p>
   </div>
</body>
</html>
<style>
    div.box{
        height: 2000px;
    }
    div.stickyBar {
        position: -webkit-sticky;
        position: sticky;
        top: 0;
        padding: 5px;
        background-color: #cae8ca;
        border: 2px solid #4CAF50;
        width: 200px;
    }
    div p {
        width: 200px;
    }
</style>
           

效果:

CSS中position详解
CSS中position详解

二、元素叠加时的几种状态

实际开发过程中免不了遇到元素的叠加问题,大都可以使用除static以外的定位方式(relative,absolute,fixed,sticky),配合z-index来控制叠加的展示方式(z-index只在position不为static时才生效)。

注:父级加transform、opacity会使子元素的z-index失效,因为它们会创建新的stacking context,然后子元素原来设置的z-index会作用到这个新的stacking context上。

以下是可能的几种情况:

2.1

同一级别的元素,定位方式相同且没有设置z-index,在html结构中靠后的元素在上面。

注:同级别的static元素也可以叠加。常见的方法有把margin设为负数或使用transform。用transform的话,需要把两个元素都加上transform,这样在html结构中靠后的元素会在上面,否则加了transform的会展示在没加transform的元素上面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="one">
        <p>divOne</p>
        <p>position: absolute;</p>
    </div>
    <div class="two">
        <p>divTwo</p>
        <p>position: absolute;</p>
    </div>
</body>
</html>
<style>
    p {
        margin: 0;
    }
    div {
        width: 200px;
        height: 200px;
        border: 1px solid black;
    }
    .one {
        position: absolute;
        background-color: red;
        top: 10px;
        left: 10px;
    }
    .two {
        position: absolute;
        background-color: blue;
        top: 100px;
        left: 100px;
    }
</style>
           
CSS中position详解

2.2

同一级别的元素使用了relative,absolute,fixed,sticky,那么z-index值大的元素在上面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="one">
        <p>divOne</p>
        <p>position: relative;</p>
    </div>
    <div class="two">
        <p>divTwo</p>
        <p>position: absolute;</p>
    </div>
</body>
</html>
<style>
    p {
        margin: 0;
    }
    div {
        width: 200px;
        height: 200px;
        border: 1px solid black;
    }
    .one {
        position: relative;
        background-color: red;
        top: 10px;
        left: 10px;
        z-index: 99;
    }
    .two {
        position: absolute;
        background-color: blue;
        top: 50px;
        left: 100px;
        z-index: 1;
    }
</style>
           
CSS中position详解

2.3

同级别的元素,relative,absolute,fixed,sticky定位会在static上面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="one">
        <p>absolute</p>
    </div>
    <div class="two">
        <p>static</p>
    </div>
</body>
</html>
<style>
    p {
        margin: 0;
    }
    div {
        width: 200px;
        height: 200px;
        border: 1px solid black;
        box-sizing: border-box;
    }
    .one {
        position: absolute;
        background-color: red;
        top: 0;
        left: 0;
    }
    .two {
        position: static;
        background-color: blue;
        margin: 100px 0 0 100px;
        padding-top: 100px;
    }
</style>
           
CSS中position详解

2.4

非同级别的使用了relative,absolute,fixed,sticky的元素,他们的叠加顺序是以非static的最上层的祖级元素的z-index进行比较的,没有非static的祖级则用自身进行比较,与此元素的子元素的z-index无关,再高都没用。

文字描述不是很清晰,举几个例子:

example1

CSS中position详解
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="one">
        <p>absolute</p>
        <p>z-index:2</p>
        <div class="child">
            <p style="padding-left: 28px">absolute</p>
            <p style="padding-left: 28px">z-index:1</p>
        </div>
    </div>
    <div class="two">
        <p style="padding-left: 100px">absolute</p>
        <p style="padding-left: 100px">z-index:1</p>
        <div class="child">
            <p style="padding-left: 28px">absolute</p>
            <p style="padding-left: 28px">z-index:99</p>
        </div>
    </div>
</body>
</html>
<style>
    p {
        margin: 0;
    }
    div {
        width: 200px;
        height: 200px;
        border: 1px solid black;
        box-sizing: border-box;
    }
    div .child {
        width: 100px;
        height: 100px;
        margin: 0 0 0 70px;
        position: relative;
        font-size: 14px;
    }
    .one {
        position: absolute;
        background-color: red;
        top: 0;
        left: 0;
        z-index: 2;
    }
    .one .child {
        background-color: palevioletred;
        z-index: 1;
    }
    .two {
        position: absolute;
        background-color: blue;
        top: 100px;
        left: 100px;
        z-index: 1;
    }
    .two .child {
        background-color: purple;
        z-index: 99;
    }
</style>
           

example2

可以实现父元素在底下,子元素在上面的情况。

CSS中position详解
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="one">
        <p>static</p>
        <div class="child">
            <p style="padding-left: 28px">relative</p>
            <p style="padding-left: 28px">z-index:1</p>
        </div>
    </div>
    <div class="two">
        <p style="padding-left: 100px">static</p>
        <div class="child">
            <p style="padding-left: 28px">static</p>
        </div>
    </div>
</body>
</html>
<style>
    p {
        margin: 0;
    }
    div {
        width: 200px;
        height: 200px;
        border: 1px solid black;
        box-sizing: border-box;
    }
    div .child {
        width: 100px;
        height: 100px;
        margin: 0 0 0 70px;
        font-size: 14px;
    }
    .one {
        position: static;
        background-color: red;
    }
    .one .child {
        position: relative;
        background-color: palevioletred;
        z-index: 1;
    }
    .two {
        position: static;
        background-color: blue;
        margin: -150px 0 0 75px;
    }
    .two .child {
        position: static;
        background-color: purple;
    }
</style>
           

example3

稍微复杂一点的情况

CSS中position详解

2.5

最后再来看一种被transform影响到的情况。

父级红色未加transform
CSS中position详解
父级红色加了transform
CSS中position详解
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div class="one">
        <div class="oneChild"></div>
    </div>
    <div class="two">

    </div>
</body>
</html>
<style>
    p {
        margin: 0;
    }
    div {
        width: 200px;
        height: 200px;
        border: 1px solid black;
    }
    .one {
        position: static;
        background-color: red;
        /*transform: translate(1px,1px);*/
    }
    .oneChild {
        width: 100px;
        height: 100px;
        background-color: pink;
        margin: 50px 0 0 50px;
        position: relative;
        z-index: 2;
    }
    .two {
        position: absolute;
        background-color: blue;
        top: 100px;
        left: 100px;
        z-index: 1;
    }
</style>