跳过到内容

CSS 元素定位

标准流 (Normal Flow)

默认情况下,元素都是按照标准流进行布局的。

标准流中的元素按照文档的顺序从上到下从左到右依次排列。

且在默认情况下,互相之间不存在层叠现象

在标准流中,使用 marginpadding 进行元素的定位。

但是会存在一些明显的问题:

  1. 设置一个元素时会影响到其他元素的位置。
  2. 不便于实现元素层叠的效果

如果需要某些元素跳出标准六,可以使用 position 属性对某个元素进行定位。

position 属性

position 属性用于指定一个元素在文档中的定位方式。

position 属性有以下值:

  • static:默认值。元素遵循正常的文档流。
  • relative:元素相对于其正常位置进行定位。
  • fixed:元素相对于浏览器窗口进行定位。
  • absolute:元素相对于其最近的已定位父元素进行定位。
  • sticky:元素在跨越特定阈值前为相对定位,之后为固定定位。

静态定位 static

staticposition 属性的默认值,static 元素遵循正常的文档流。

lefttoprightbottom 属性对 static 元素无效。

相对定位 relative

relative 元素相对于其正常位置进行定位。

lefttoprightbottom 属性用于指定元素相对于其正常位置的偏移量。

html
<style>
  strong {
    position: relative;
    left: 30px;
    top: 30px;
  }
</style>
<div>
  <span>span 标签内容</span>
  <strong>strong 标签内容</strong>
  <a href="#">a 标签内容</a>
  <p>p 标签内容</p>
</div>

应用场景

在不影响其他元素位置的前提下,对当前元素位置进行微调。

图片居中案例:将 1920px × 489px 的图片居中。
html
<style>
  body {
    margin: 0;
    padding: 0;
  }
  .box {
    height: 489px;
    background: url(./images/mhxy.jpg) no-repeat;
    background-position: center; /* 居中 */
  }
</style>

<div class="box"></div>

固定定位 fixed

fixed 元素相对于浏览器窗口进行定位,当画布滚动时,固定不动。

lefttoprightbottom 属性用于指定元素相对于浏览器窗口的偏移量。

html
<style>
  .fixed {
    position: fixed; /* 固定定位 */
    right: 30px; /* 距离右侧 30px */
    bottom: 30px; /* 距离底部 30px */
  }
</style>

<div>
  <span>span 标签内容</span>
  <strong class="fixed">strong 标签内容</strong>
  <a href="#">a 标签内容</a>
  <p>p 标签内容</p>
</div>

绝对定位 absolute

absolute 元素相对于其最近的定位祖先元素(position值为relativefixedabsolute)进行定位,如果没有找到符合条件的祖先元素,相对的是窗口。

lefttoprightbottom 属性用于指定元素相对于其最近的已定位父元素的偏移量。

在大多数情况下,字元素的绝对定位都是相对于父元素进行定位。

当期望子元素相对于父元素进行定位,又不希望父元素脱标,常用解决方案是:

  • 父元素设置position: relative(让父元素成为定位元素,而且父元素不脱离标准流)
  • 子元素设置position: absolute
html
<style>
  .container {
    position: relative; /* 让父元素成为定位元素 */
    width: 600px;
    height: 500px;
    border: 1px solid red;
  }
  .box {
    position: absolute; /* 子元素绝对定位 */
    bottom: 0;
    right: 0;
    width: 500px;
    height: 300px;
    border: 1px solid blue;
  }
  strong {
    position: absolute; /* 子元素绝对定位 */
    left: 0;
    bottom: 0;
  }
</style>

<div class="container">
  <div class="box">
    <span>span 标签</span>
    <strong>strong 标签</strong>
    <p>p 标签</p>
  </div>
</div>

粘性定位 sticky

sticky 元素在跨越特定阈值前为相对定位,之后为固定定位。

它可以看作是相对定位和固定(绝对)定位的结合体,它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点时,就会变成固定(绝对)定位。

lefttoprightbottom 属性用于指定元素相对于其最近的已定位父元素的偏移量。

html
<style>
  .nav {
    background-color: #f00;
    color: #fff;
    position: sticky; /* 粘性定位 */
    top: 0; /* 距离顶部的距离 */
  }
</style>
<h1>标题</h1>
<div class="nav">
  <span>手机</span>
  <span>电脑</span>
  <span>衣服</span>
  <span>鞋子</span>
</div>

<ul>
  <li>列表数据01</li>
  <li>......</li>
</ul>

提示

position: sticky; 是相对于最近的滚动祖先包含滚动视口的。

position 定位总结

定位方式脱离标准流定位元素绝对定位元素定位参照对象
静态定位 static
相对定义 relative元素自己原来的位置
绝对定位 absolute最邻近的定位祖先元素
(不存在则相对浏览器窗口)
固定定位 fixed浏览器窗口

绝对定位元素

将绝对定位元素(元素的 position 属性设置为 absolutefixed 元素)的特点:

  • 可以随意设置宽高,如果不设置宽高,默认大小是内容的大小

  • 不再受标准流的约束

    • 不再严格按照从上到下、从左到右排布
    • 不再严格区分块级(block)、行内级(inline),行内块级(inline-block)的很多特性都会消失
  • 不再给父元素汇报宽高数据

    html
    <style>
      .container {
        background-color: red;
      }
      .container strong {
        position: absolute; /* 开启绝对定位后,父元素 .container 的高度没有了 */
      }
    </style>
    
    <div class="container">
      <strong>strong 元素</strong>
    </div>
  • 脱标元素内部默认还是按照标准流布

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

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

  • 如果需要设置绝对定位元素的宽高和定位参照对象一样,可以给绝对定位元素设置以下属性:left: 0; right: 0; top: 0; bottom: 0; margin:0

  • 如果需要设置绝对定位元素在定位参照对象中居中显示,可以给绝对定位元素设置以下属性: left: 0; right: 0; top: 0; bottom: 0; margin: auto

html
<style>
  .container {
    width: 800px;
    height: 400px;
    background-color: #eee;
    position: relative;
  }
  /* 水平居中定位方案 */
  .container .box {
    width: 200px;
    height: 200px;
    background-color: #f00;
    position: absolute;
    left: 0;
    right: 0;
    margin: 0 auto;
  }
</style>
<div class="container">
  <div class="box"></div>
</div>