CSS - Layout - Element Positioning

Standard Flow - Normal Flow

Get into the habit of writing together! This is the 12th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event

By default, elements are arranged according to normal flow (standard flow, normal flow, normal flow, document flow)

  1. Block-level elements occupy a single line, and multiple inline elements or inline block-level elements can be displayed on the same line
  2. Elements are placed in order from left to right and top to bottom
  3. By default, elements do not stack with each other

LhYZHy.png

In the standard flow, you can use margin, padding to position the element

But in the standard flow, setting the margin or padding of an element usually affects the positioning effect of other elements in the standard flow

In addition, in the standard flow, it is not convenient to achieve the effect of element stacking

For this CSS provides positionproperties to help us implement an element out of the standard flow (off-label) and position it

The optional value of the position property

value illustrate
static Static positioning,
default value,
no off-label, that is, the layout is normal flow
relative relative positioning
absolute absolute positioning
fixed Fixed positioning
sticky sticky positioning

If an element has a value other staticthanposition

Then we think that this element has achieved de-labeling and is a 定位元素(positioned element)

For positioning elements, we can set left 、right、top、bottomequal attribute values ​​to achieve position adjustment

Relative positioning - relative

.box {
  /*
  	通过将position的值设置为relative
  	来为某个元素开启相对定位
  */
  position: relative;
}
复制代码
  • Relative positioning does not break away from the standard flow, so the elements themselves remain占位

  • Can be positioned by left, right, top, bottom

  • For elements with relative positioning turned on, left、right、top、bottomthe effect it sets

    similar tomargin-left, margin-right, margin-top, margin-bottom

  • The positioning reference object is the original position of the element itself

The application scenarios of relative positioning are:在不影响其他元素位置的前提下,对当前元素位置进行微调

示例

LhrSIL.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    span {
      position: relative;
      font-size: 12px;
      bottom: 5px;
    }
  </style>
</head>
<body>
  2<span>3</span> + 3<span>2</span> = 17
</body>
</html>
复制代码

fixed positioning - fixed

.box {
  /*
  	通过将position的值设置为fixed
  	来为某个元素开启相对定位
  */
  position: fixed;
}
复制代码
  • Elements are out of normal flow (out of standard flow, out of label)
  • Can be positioned by left, right, top, bottom
  • 定位参照对象是视口(viewport),
    • 当画布滚动时,因为viewport是固定不动,所以开启了固定定位的元素也会固定不动

示例:

LhrYcf.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .operate {
      position: fixed;
      right: 30px;
      bottom: 30px;
    }

    .btn {
      width: 60px;
      height: 30px;
      line-height: 30px;
      text-align: center;
      background-color: gray;
      color: #fff;
      border-radius: 5px;
    }

    .top {
      margin-bottom: 5px;
    }
  </style>
</head>
<body>
  <div class="operate">
    <div class="btn top">顶部</div>
    <div class="btn feedback">反馈</div>
  </div>
</body>
</html>
复制代码

绝对定位 - absolute

  1. 开启了绝对定位的元素脱离normal flow (脱离标准流、脱标)
  2. 可以通过left、right、top、bottom进行定位
    • 定位参照对象是最邻近的定位祖先元素
    • 如果找不到这样的祖先元素,参照对象是视口

开启了绝对定位的元素的定位参照元素是最近的那个定位元素,也就是最近的那个position不是fixed的元素

而我们绝大多数情况下,都希望父元素不脱标,只是作为绝对定位元素的定位参照元素,

所以在绝大多数情况下,绝对定位元素的定位参照元素开启的都是相对定位

因为相对定位成为了定位元素,但不脱标,此时我们可以简称为 子绝父相

绝对定位元素特点

  1. 可以随意设置宽高且 元素宽高默认由内容决定
    • 此时看上去 特性和行内块级元素的特性是一致的,但是它不是行内块级元素
    • 当一个元素的position值为absolute或者fixed的时候,这个元素就被称之为 绝对定位元素(absolutely positioned element)
  2. 不再受标准流的约束
  • 不再严格按照从上到下、从左到右排布
  • 不再严格区分块级(block)、行内级(inline),行内块级(inline-block)
  1. 不再给父元素汇报自己的宽度或高度
  2. 脱标元素内部默认还是按照标准流布局

此外,对于绝对定位元素来说,存在如下计算方式

定位参照对象的宽度 = left + right + margin-left + margin-right + 绝对定位元素的实际占用宽度

定位参照对象的高度 = top + bottom + margin-top + margin-bottom + 绝对定位元素的实际占用高度

利用上边的特性,我们可以实现如下效果:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 300px;
      height: 300px;
      background-color: red;
      position: relative;
    }

    /*
      此时div.child的参照定位元素为box.father

      fatherWidth = childWidth + left + right + marginLeft + marginRight
			因为 marginLeft 和 marginRight的默认值是0
      得到300 = auto + 0 + 0 + 0 + 0
			虽然默认情况下 相对定位元素的width为auto,其表现为宽高为包含的内容的宽高
			但是auto的本质是 由浏览器来确定需要显示的具体值
      所以在这里 auto的值为 300

      高度同理
    */
    .child {
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background-color: blue;
    }
  </style>
</head>
<body>
  <!-- 绝对定位元素的宽高和定位参照对象一样 -->
  <div class="father">
    <div class="child"></div>
  </div>
</body>
</html>
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father {
      width: 300px;
      height: 300px;
      background-color: red;
      position: relative;
    }

    /*
      此时div.child的参照定位元素为box.father
      tips:
    		1. 一定要设置元素的宽度和高度
    		2. margin四个方向的值都需要设置为auto

      fatherWidth = childWidth + left + right + marginLeft + marginRight
      此时设置childWidth的值为100
      得到 300 = 100 + 0 + 0 + 0 + 0
      公式不成立 => 默认情况下,浏览器会把剩余的值全部赋值给marginRight
      但是这里设置margin各个方向上的值为auto
      => 300 = 100 + 0 + auto + auto
      => 2auto = 300
      => auto = 150
      => marginLeft = marginRight = 150
      => div.child相对于div.father 水平居中

      垂直方向同理
    */
    .child {
      width: 100px;
      height: 100px;
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      margin: auto;
      background-color: blue;
    }
  </style>
</head>
<body>
  <!-- 绝对定位元素在定位参照对象中居中显示 --- 同时满足水平居中和垂直居中 -->
  <div class="father">
    <div class="child"></div>
  </div>
</body>
</html>
复制代码

粘性定位 - sticky

另外还有一个定位的值是position: sticky,比起其他定位值要新一些.

sticky可以看做是相对定位和固定(绝对)定位的结合体 --- 在展示效果上

它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点

当达到这个阈值点时, 就会变成固定(绝对)定位

sticky是相对于最近的滚动祖先元素,也就是sticky是相对于滚动视口( scrollport )的

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      body {
        height: 200vh;
      }

      .scrollview {
        width: 300px;
        height: 300px;
        margin: 100px auto;
        border: 1px solid red;
        overflow: auto;
      }

      h2 {
        margin: 10px 0;
        padding: 0;
        text-align: center;
      }

      .box {
        background-color: #f00;
        color: #fff;
        /*
        距离最近的滚动父元素
        在这里就是div.scrollview
        */
        position: sticky;
        /*
        当当前元素的上边框和最近的父级滚动元素重合的时候
        由相对定位转变为固定定位
        */
        top: 0;
      }
    </style>
  </head>
  <body>
    <div class="scrollview">
      <h2>lorem</h2>
      <div class="box">this is navbar</div>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Ea, aperiam.
      Fuga recusandae laboriosam cumque quasi eum molestias asperiores a minima?
      Consequatur alias quam placeat hic neque esse nisi voluptate quas!
      Eveniet doloremque enim ducimus quas tempora vel sit iure facere.
      Quis blanditiis quibusdam, explicabo qui dolores possimus dignissimos modi dolorum.
      Debitis, ex quo! Similique aut, impedit est eos qui molestiae.
      Ipsa explicabo voluptate expedita dolor obcaecati! Natus libero corrupti excepturi?
      Rerum optio quas cum eaque architecto cumque itaque veniam sit?
      Ad itaque aliquid quaerat error ipsum accusantium nesciunt minus et.
      Iste vitae non vero dicta cupiditate dolorem maiores. Dolorum, obcaecati.
    </div>
  </body>
</html>
复制代码

postiton各值比较

LhZQAk.png

sticky在效果上是在多个定位状态之间进行切换,所以没有列在表中

对于定位元素,当脱标后,不设置left,right,top,bottom的时候,他们的默认值皆为auto

表现形式为

  1. 尽可能到达父级定位元素的左上角(也就是left和top值为0)
  2. 定位元素后边的元素上移
  3. 定位元素之前的元素不动,且不会被定位元素覆盖

LhZ4eH.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      span {
        position: absolute;
        width: 50px;
        height: 50px;
        background-color: rgba(0, 0, 0, 0.5);
      }
    </style>
  </head>
  <body>
    <div class="before"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui, consequatur. </div>
    <!--
      在定位元素的left,top,rignt,bottom都不设置的情况下
      默认情况下,会尽可能实现left和top的值为0
      但定位元素不会覆盖其之前的元素,所以span元素不会覆盖div.before
      定位元素后边的元素会上移,所以span元素会和div.after元素发生层叠
			所以会发现示意图中,灰色的盒子和第二行文本有重叠
    -->
    <span></span>
    <div class="after">Animi, cum! Itaque numquam rem modi nisi perferendis dolores praesentium!</div>
  </body>
</html>
复制代码

z-index

For positioned elements, by default, the element written in the back will be stacked on the element written in front

if we需要调整定位元素的层叠顺序,我们可以使用z-index

z-index可以取正整数、负整数、0

The default value of z-index is auto, and the performance is the same as when the value of z-index is 0.

LhZYK6.png

z-index comparison principle

  1. For sibling positioned elements
    • The larger the z-index, the higher it is stacked
    • The z-index is equal, and the element written at the back is stacked on top
  2. if not brotherhood
    • 最邻近Compare the positioning elements found from the element itself and its ancestor elements.
    • And these two positioning elements must have specific values ​​for setting z-index

LhZJaX.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
      .box {
        width: 100px;
        height: 100px;
        color: #fff;
        position: absolute;
      }

      .box1 {
        background-color: #f00;
        z-index: 1;
      }

      .box2 {
        background-color: #0f0;
        left: 20px;
        top: 20px;
        z-index: 2;
      }

      .inner-box {
        width: 50px;
        height: 50px;
        background-color: yellow;
        color: red;
        position: absolute;
        /*
          在这里虽然div.inner-box的z-index为999
          但是其没有兄弟定位元素
          因此找到最邻近的定位元素进行比较
          分别为 div.box1 div.box2 div.box3
          此时div.box2的层级在div.box3下
          所以即使div.inner-box的z-index的值再大
          其还是会被div.box3元素覆盖
        */
        z-index: 999;
      }

      .box3 {
        background-color: #00f;
        left: 40px;
        top: 40px;
        z-index: 3;
      }
    </style>
  </head>
  <body>
    <div class="box box1">1</div>
    <div class="box box2">
      <div class="inner-box">2</div>
    </div>
    <div class="box box3">3</div>
  </body>
</html>
复制代码

Guess you like

Origin juejin.im/post/7085658788270702628