10.2 positition属性

属性position表示盒子的定位方式,可选值包括:static、relatvie相对定位、absolute、fixed固定定位、sticky粘性定位。结合坐标属性(top、bottom、left、right)一起使用。


position属性值根据是否脱离流分为两种:static级别定位、绝对级别定位。

(1)static-level(static级别)定位。包括static、relative、sticky,它们属于正常流、in-flow。

(2)absolute-level(绝对级别)定位。包括absolute、fixed,它们属于脱离流。

position属性值英文翻译说明。static没有翻译中文,意义不大,直接用英文。

绝对定位(w3c、MDN) = 绝对级别定位(小步教程) = position : absolute与fixed

值absolute属于不能翻译成中文,一旦翻译就发生术语冲突,假设翻译成“绝对定位”,可是w3c、MDN的术语“绝对定位”指position: absolute、fixed,两者相冲突。为避免“绝对定位”术语的尴尬,本教程使用absolute-level绝对级别定位表示,且不使用“绝对定位”这一术语。官方文档查看资料时,“绝对定位”与本教程的“绝对级别定位”一致。官方并没有static级别这一术语,因为它们具有重大相同点,所以设置此级别。


position属性值字面意思说明。不要从字面意思理解它们的含义,例如“相对”、“绝对”,没有意义。坐标总是相对的,只是相对于谁(即定位基准元素)的区别,理解各属性值的两个关键:它的定位基准是谁,它对后代元素的影响。


10.2.1 static

static示意图

img

position默认值static属于正常流定位,它是运用最多的定位方式。

属性无效规则Invalid003:position没有设置(或指定默认值position:static)时,坐标属性(top、bottom、left、right)无效。

示例:为box1显示设置position: static,等于没有设置;然后设置top与left坐标。

<!DOCTYPE html>
<html style="display: block flow-root;">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        body{
            display: block flow;
            margin: 0;
        }

        .box1{            
            padding: 5px;
            border: 5px solid #0aaa76;            
            margin: 5px;

            display: inline flow;

            position: static;
            top: 20px;
            left: 20px;
        }

        .box2{
            border: 5px solid #4aa6fc;
            padding: 5px;
            margin: 5px;

            display: inline flow;
        }
    </style>
</head>
<body >    
    <span class="box1">box1</span>
    <span class="box2">box2</span>
    <div class="box3">小步教程 xiaobuteach.com</div>
</body>
</html>

运行效果:top与left设置无效。开发者工具提示错误:“position: static 属性可防止 top 产生影响。不妨尝试将 position 设为除 static 之外的某个值。”。

img

底层逻辑。static表示盒子占据区域的坐标由浏览器自动计算,且显示区域的坐标与占据区域的坐标完全一致。


10.2.2 relative

relative示意图

img

posistion: relative表示盒子占位与static相同,盒子显示根据坐标设置进行偏移,也就是自己的显示相对于自己的占位进行移动,即“移形换影”。偏移不影响后续元素的坐标位置。

relative定位属于正常流定位,而且元素的显示与占位不一致。

示例代码

<!DOCTYPE html>
<html style="display: block flow-root;">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        body{
            display: block flow;
            margin: 0;
        }

        .box1{            
            padding: 5px;
            border: 5px solid #0aaa76;            
            margin: 5px;

            display: inline flow;

            position: relative;
            top: 20px;
            left: 20px;
        }

        .box2{
            border: 5px solid #4aa6fc;
            padding: 5px;
            margin: 5px;

            display: inline flow;
        }
    </style>
</head>
<body >    
    <span class="box1">box1</span>
    <span class="box2">box2</span>
    <div class="box3">小步教程 xiaobuteach.com</div>
</body>
</html>

运行效果

img

box1坐标偏移使盒子显示发生变化,而占位没有变化,所以box2与box3的位置未发生变化。

试一试。设置3个box的背景色,查看谁在上方谁在下方。


10.2.3 absolute

absolute示意图

img

position: absolute表示当前元素相对于坐标基准元素进行定位。坐标基准元素是当前元素最近的非static的祖先元素,如果全部是static元素则是body元素。坐标基准元素是不严格的说法,严格说法称为包含块containing block,详情见下节。

值absolute属于脱离流定位,属于absolute-level定位,元素在所在流式布局没有占位。

属性被自动修改规则Update001:脱离流定位的盒子需要在内部新建BFC(流式布局),所以自动转化成block-level盒子。


场景1:定位基准元素是爷元素。注:关键属性设置在style属性。

<!DOCTYPE html>
<html style="display: block flow-root;">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        body {
            display: block flow;
            margin: 0;
        }

        .box1 {
            padding: 5px;
            border: 5px solid #0aaa76;
            margin: 5px;

            display: inline flow;

        }

        .box2 {
            border: 5px solid #4aa6fc;
            padding: 5px;
            margin: 5px;

            display: inline flow;
        }

        .box1-wrap{
            border: 1px solid #ddd;
            height: 120px;
           
        }

        .box1-inner{
            border: 1px solid #666;
            height: 60px;
        }

      
    </style>
</head>

<body>
    <div class="box1-wrap" style="position: relative;">
        <div class="box1-inner">
            <span class="box1" style="position: absolute;right: 0;bottom: 0;">box1</span>
            <span class="box2">box2</span>
        </div>
    </div>
    <div class="box3">小步教程 xiaobuteach.com</div>
</body>

</html>

运行结果

img

box1设置absolute,爷元素box1-wrap设置非static(relative),则坐标right、bottom相对爷元素。计算样式面板查看box1的display值,被自动修改成block,体现了CSS特性的计算性。


场景2:定位基准元素是父元素。

    <div class="box1-wrap">
        <div class="box1-inner"  style="position: relative;">

运行效果

img

box1设置absolute,父元素box1-inner设置非static(relative),则坐标right、bottom相对父元素。假设父元素与爷元素同时设置非static,按照最近原则,会以父元素作为坐标基准元素。


场景3:所有祖先元素都是static元素。相对body元素定位。

img

absolute元素的代码位置。只要在坐标基准元素的内部,任意位置无差别。考虑代码可读性,通常放在开头与结尾。


10.2.4 fixed

fixed示意图1:无滚动

img

fixed示意图2:滚向滚动

img

viewport。viewport指浏览器窗口的内容区域,也就是窗口去除标题栏、地址栏、任务栏等的内容区域,如上图桔色区域。中文翻译为视口区域。

position:fixed表示当前元素相对于viewport定位。当页面有或水平或垂直滚动条进行滚动时,fixed元素不随滚动条变化而变化。fixed定位属于脱离流定位,绝对级别定位,元素在所在流式布局没有占位。

示例代码

<!DOCTYPE html>
<html style="display: block flow-root;">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小步教程</title>

    <style>
        body {
            display: block flow;
            margin: 0;
        }

        .div2{
            position: fixed;
            top: 50px;
            left: 120px;
        }

      
    </style>
</head>

<body>
    <div class="div1">
        <div>第1行</div>
        <div>第2行</div>
        <!-- 省略中间行 -->
        <div>第49行</div>
        <div>第50行</div>
    </div>

    <div class="div2">
        <div>小步教程</div>
        <div>xiaobuteach.com</div>
    </div>
</body>

</html>

fixed元素代码位置。通常作为body的子元素放在最前或最后,提高代码可读性。


注:sticky属性涉及滚动模型,后续介绍滚动模型时再讲解。