元素定位
默认情况下,元素都是按照 normal flow,
从左到右、从上到下按顺序摆放好, 互相之间不存在层叠现象

在标准流中,可以使用 margin、 padding 对元素进行定位
缺点:
- 设置一个元素的 margin 或者 padding,通常会影响到标准流中其他元素的定位效果
- 不便于实现元素层叠的效果
如果我们希望一个元素可以跳出标准流, 单独的对某个元素进行定位
常用取值有 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>
|
标准流: 各个元素按照从上到下, 从左到右依次排布, 结果如下:

strong { position: absolute;
right: 0; top: 0; }
|
开始找祖先定位元素
- 父元素依次是: div. box –> div. container –> body –> html
- 都不是定位元素
- 于是参照物为: 视口

.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 属性用来设置定位元素的层叠顺序(仅对定位元素有效)
<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>
|

取值:
比较原则
如果是兄弟关系
- z-index 越大,层叠在越上面
- z-index 相等,写在后面的那个元素层叠在上面
如果不是兄弟关系
- 各自从元素自己以及祖先元素中,找出最邻近的 2 个定位元素进行比较
- 而且这 2 个定位元素必须有设置 z-index 的具体数值
z-index: -1;

z-index: 1;
