元素定位

默认情况下,元素都是按照 normal flow,

从左到右、从上到下按顺序摆放好, 互相之间不存在层叠现象

在标准流中,可以使用 margin、 padding 对元素进行定位

  • 其中 margin 还可以设置负数

缺点:

  • 设置一个元素的 margin 或者 padding,通常会影响到标准流中其他元素的定位效果
  • 不便于实现元素层叠的效果

如果我们希望一个元素可以跳出标准流, 单独的对某个元素进行定位

  • 可以通过 position 属性来进行设置

常用取值有 5 个:

  • static:默认值, 静态定位
  • relative:相对定位
  • absolute:绝对定位
  • fixed:固定定位
  • sticky:粘性定位

static

  • 默认值
  • 元素按照 normal flow 布局
  • left 、 right、 top、 bottom 没有任何作用

relative

  • 元素按照 normal flow 布局
  • 可以通过 left、 right、 top、 bottom 进行定位
    • 定位参照对象是元素自己原来的位置

应用场景:

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

小练习:

  <style>
div {
font-size: 20px;
}

span {
font-size: 12px;
position: relative;
bottom: 8px;
}
</style>
-------------------------------------
<div>
3<span>2</span> + 2<span>3</span> = 17
</div>

fixed

固定定位

  • 元素脱离 normal flow(脱离标准流、脱标)
  • 可以通过 left、 right、 top、 bottom 进行定位
  • 定位参照对象是视口(viewport)
  • 当画布滚动时,固定不动
  <style>
.handle {
position: fixed;
right: 30px;
bottom: 30px;
}

.handle .item {
width: 80px;
height: 40px;
text-align: center;
line-height: 40px;
background-color: brown;
color: #fff;
border-radius: 8px;
cursor: pointer;
}

.handle .item:hover {
background-color: red;
}

.top {
margin-bottom: 10px;
}
</style>
-------------------------------------
<body>

<div class="handle">
<div class="item top">顶部</div>
<div class="item bottom">反馈</div>
</div>

<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>
<br><br><br><br><br>

</body>

画布和视口

  • 视口(Viewport)
    • 文档的可视区域
    • 如图红框所示
  • 画布(Canvas)
    • 用于渲染文档的区域
    • 文档内容超出视口范围,可以通过滚动查看
    • 如图黑框所示
  • 宽高对比
    • 画布 >= 视口

absolute

  • 元素脱离 normal flow(脱离标准流、脱标)
  • 可以通过 left、 right、 top、 bottom 进行定位
    • 定位参照对象是最邻近的定位祖先元素
    • 如果找不到这样的祖先元素,参照对象是视口
  • 定位元素(positioned element)
    • position 值不为 static 的元素
    • 也就是 position 值为 relative、 absolute、 fixed 的元素

案例演示

  • 默认情况:
<style>
.container {
width: 600px;
height: 300px;
background-color: #f00;

top: 0;
}

.box {
width: 400px;
height: 200px;
background-color: #0f0;
}

strong {
right: 0;
top: 0;
}

img {
width: 100px;
height: 80px;
}
</style>
--------------------------------------------------
<body>
<div>哈哈哈啊</div>
<div class="container">
<div class="box">
<span>我是span元素</span>
<strong>我是strong元素</strong>
<img src="../images/diqiu.jpg" alt="">
<div>我是div元素</div>
</div>
</div>
<div>呵呵呵呵</div>
</body>

标准流: 各个元素按照从上到下, 从左到右依次排布, 结果如下:

  • 设置 absolute
strong {
/* 脱离标准版 */
position: absolute;

/* 设置的四个值 */
/* 在没有祖先元素定位的情况下, 相对于的是谁? 视口 */
right: 0;
top: 0;
}

开始找祖先定位元素

  • 父元素依次是: div. box –> div. container –> body –> html
  • 都不是定位元素
  • 于是参照物为: 视口
  • 设置父元素 div. box 为定位元素
.box {
position: relative;

width: 400px;
height: 200px;
background-color: #0f0;
}

  • 只设置祖先元素 div. container 为定位元素

子绝父相

  • 在绝大数情况下,子元素的绝对定位都是相对于父元素进行定位
  • 如果希望子元素相对于父元素进行定位,又不希望父元素脱标,常用解决方案是:
    • 父元素设置 position: relative(让父元素成为定位元素,而且父元素不脱离标准流)
    • 子元素设置 position: absolute
    • 简称为“子绝父相”
  <style>
.container {
width: 600px;
height: 300px;
background-color: #f00;

position: relative;
}

.box {
width: 400px;
height: 200px;
background-color: #0f0;

position: absolute;
right: 0;
bottom: 0;
}

strong {
position: absolute;
left: 0;
bottom: 0;
}

img {
width: 100px;
height: 80px;
}
</style>
--------------------------------------
<body>

<div class="container">
<div class="box">
<span>我是span元素</span>
<strong>我是strong元素</strong>
<img src="../images/diqiu.jpg" alt="">
<div>我是div元素</div>
</div>
</div>
</body>

将 position 设置为 absolute/fixed 元素的特点

  • 可以随意设置宽高
    • 宽高默认由内容决定
  • 不再给父元素汇报宽高数据
    • 父元素没有设置宽高时, 会消失
  <style>
.box {
background-color: #f00;
}
.box strong {
position: absolute;
width: 200px;
height: 200px;
background-color: #0f0;
}
</style>
------------------------------
<body>

<div class="box">
<strong>我是strong元素</strong>
</div>

</body>

不再受标准流的约束

  • 不再严格按照从上到下、从左到右排布
  • 不再严格区分块级 (block)、行内级 (inline),行内块级 (inline-block) 的很多特性都会消失

脱标元素内部默认还是按照标准流布局

  <style>
.box {
background-color: #f00;
}
.box strong {
position: absolute;
width: 200px;
height: 200px;
background-color: #0f0;
}
</style>
-----------------------------------
<body>
<div class="box">
<strong>
<span>我是strong元素</span>
<i>我是i元素</i>
</strong>
</div>
</body>

对于绝对定位元素来说

  • position 值为 absolute 或者 fixed 的元素
  • 定位参照对象的宽度 = 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
  • 另外,还得设置具体的宽高值(宽高小于定位参照对象的宽高)

sticky

sticky 是相对于最近的滚动祖先包含滚动视口的 (the nearest ancestor scroll container’s scrollport )

可以看做是相对定位和固定 (绝对) 定位的结合体

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

  • 当达到这个阈值点时, 就会变成固定 (绝对) 定位的结合体
  <style>
.box {
width: 500px;
height: 500px;
margin: 100px auto 0;
overflow: scroll;
background-color: #ccc;
}

.nav {
background-color: #f00;
color: #fff;
position: sticky;
top: 0;
}
</style>
===============================
<body>

<div class="box">
<h1>我是标题</h1>
<div class="nav">
<span>电脑</span>
<span>手机</span>
<span>衣服</span>
<span>鞋子</span>
</div>
<ul>
<li>电脑列表1</li>
<li>电脑列表2</li>
<li>电脑列表3</li>
<li>电脑列表4</li>
<li>电脑列表5</li>
<li>电脑列表6</li>
<li>电脑列表7</li>
<li>电脑列表8</li>
<li>电脑列表9</li>
<li>电脑列表10</li>
<li>电脑列表11</li>
<li>电脑列表12</li>
..............
</ul>
</div>
</body>

小结

CSS 属性 z-index

z-index 属性用来设置定位元素的层叠顺序(仅对定位元素有效)

  • 取值可以是正整数、负整数、 0
  <style>
.item {
position: fixed;
width: 100px;
height: 100px;
left: 0;
top: 0;
background-color: #f00;
}

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

.box3 {
left: 40px;
top: 40px;
background-color: #00f;
}
</style>
-----------------------------------
<body>
<div class="item box1">1</div>
<div class="item box2">2</div>
<div class="item box3">3</div>
</body>

取值:

  • 默认 auto , 浏览器解析成 0

比较原则

  • 如果是兄弟关系

    • z-index 越大,层叠在越上面
    • z-index 相等,写在后面的那个元素层叠在上面
  • 如果不是兄弟关系

    • 各自从元素自己以及祖先元素中,找出最邻近的 2 个定位元素进行比较
    • 而且这 2 个定位元素必须有设置 z-index 的具体数值
  • z-index: -1;

  • z-index: 1;