定位在我们的布局中常常会用,巧妙的利用定位,会在部分业务中帮助我们实现很多功能。通俗来讲,定位是脱离文档流,不占用父级高度,且会存在层级关系。
本文主要会从以下几点认识定位
- relative,absolute,fixed,sticky,static的应用理解
- 如何理解relative,absolute,一个元素中设置absolute,它是绝对定位,相对于谁?
- fixed失效问题
- sticky吸顶
相对定位
首先我们问自己一个问题,relative是相对哪个元素定位,相对自身?还是相对父级?,还是相对相邻元素?
我们先看一段简单的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
h1 {
font-size:50px;
}
.app {
position: relative;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<div class="app">
<h1 class="text">Web技术学苑</h1>
</div>
</body>
</html>
从结果来看如果一个元素设置相对定位,那么它的参照是相对父级元素body
如果我们在app上方再加一个相邻元素
<body>
<h1>Hello</h1>
<div class="app">
<h1 class="text">Web技术学苑</h1>
</div>
</body>
我们会发现app元素相对定位与顶部最初位置的Y轴偏距多了50px,offsetTop= 150(加上了文字的高度)
我们继续给.text设置相对定位试试
.text {
position: relative;
top: 100px;
left: 100px;
}
我们发现text文本元素相对原有位置xy方向分别偏移了100个像素
我们再来看一段代码,假设app不设置相对定位,相对定位只作用在text元素中呢
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.text {
position: relative;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<h1>Hello</h1>
<div class="app">
<h1 class="text">Web技术学院</h1>
</div>
</body>
</html>
所以我们可以确定,当一个元素设置相对定位,这个元素是相对它父级最近的一个元素,父元素本身的高度由子元素决定,offetTop会作用在父级元素上,如果父级有设置relative,那么子元素的offsetTop就是当前定位的偏移值,如果父级元素没有设置relative,那么offetTop会包含元素自身高度
绝对定位
当一个元素我设置绝对定位时,这个元素到底是相对于谁?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>absolute</title>
<style>
* {
padding: 0;
margin: 0;
}
.text {
position: absolute;
top: 100px;
left: 100px;
}
.app {
background: red;
}
</style>
</head>
<body>
<h1>Hello</h1>
<div class="app">
<h1 class="text">Web技术学院</h1>
</div>
</body>
</html>
我们发现text元素是相对body的
如果我们在.app设置relative,那么这个text元素就是相对.app
absolute相对谁?
如果我在.app中设置absolute,那么子元素text也是设置absolute,那么text元素会怎么样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>absolute</title>
<style>
* {
padding: 0;
margin: 0;
}
.app {
background: red;
width: 100px;
height: 100px;
position: absolute;
top: 100px;
left: 100px;
}
.text {
position: absolute;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<h1>Hello</h1>
<div class="app">
<h1 class="text">Web技术学院</h1>
</div>
</body>
</html>
你发现.text的absolute是相对最近的父级元素,而父级设置的absolute是相对它本身最近的父级元素。
如果一个absolute元素设置的外边距会怎么样
.text {
position: absolute;
top: 100px;
left: 100px;
margin-top: 100px;
}
从以上现象来看,外边距会相对它父级元素偏移,并且边距并不会被合并
fixed
当我们对一个元素设置fixed时,该元素是相对视图窗口的。当我们在它父元素上添加transform,perspective、filter、backdrop-filter会导致fixed失效,主要是因为fixed产生了层叠上下文
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>fixed</title>
<style>
* {
padding: 0;
margin: 0;
}
.text {
width: 100px;
height: 100px;
background-color: red;
position: fixed;
top: 100px;
left: 100px;
}
.app {
backdrop-filter: blur(10px);
}
</style>
</head>
<body>
<div class="app">
<div class="text">Web技术学苑</div>
</div>
<div style="height: 3000px; background-color: yellow">Maic</div>
</body>
</html>
sticky
粘性定位,可以理解成相对定位与固定定位的混合,元素在特定阀值就是相对定位,之后为固定定位
比如我给一个元素加上sticky之后
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>sticky</title>
<style>
* {
padding: 0;
margin: 0;
}
.header {
position: sticky;
top: 10px;
width: 100%;
height: 50px;
background-color: red;
}
.main {
height: 2000px;
}
</style>
</head>
<body>
<div class="app">
<div class="header">header</div>
<div class="main"></div>
</div>
</body>
</html>
在可视区域范围内,header距离顶部10px,但是超过可视区域后,header就固定在10px位置了
当我们对一个元素使用fixed时,有时会失效,为什么?
fixed失效
由于我们对一个元素使用了fixed,此时会产生层叠上下文,当我们它的父元素上添加transfrom,perspective,filter,backdrop-filter属性会导致fixed失效。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>fixed</title>
<style>
* {
padding: 0;
margin: 0;
}
.header {
position: fixed;
top: 10px;
width: 100%;
height: 50px;
background-color: red;
}
.main {
height: 2000px;
}
.app {
filter: blur(5px);
}
</style>
</head>
<body>
<div class="app">
<div class="header">header</div>
<div class="main"></div>
</div>
</body>
</html>
static
当我们对一个元素使用static时,此时这个元素就相当于一个普通文档流,top,right,bottom,left,以及zIndex就会失效。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>static</title>
<style>
* {
padding: 0;
margin: 0;
}
h1 {
position: static;
top: 100px;
left: 100px;
}
</style>
</head>
<body>
<div class="app">
<h1>公众号: Web技术学苑</h1>
</div>
</body>
</html>
总结
-
当我们对元素设置relative,absolute,fixed时,该元素会脱离文档流
-
定位的元素不会占用父级高度,当一个元素设置absolute,width与height会相对父级
-
当一个元素设置relative时,它相对的是它的父级元素,如果父级没有设置relative,当前元素的offestTop会包含父级本身的高度,offetTop = Y + parentHeight,如果父级设置了relative,此时offsetTop = Y
-
当我们在一个多级结构,多层定位,比如一个父级元素加了absolute绝对定位,它的子元素继续绝对定位,那么该子元素设置的绝对定位只会相对它最近的父级元素
-
sticky是吸顶定位,是相对定位与固定定位的结合体,当一个元素在可视区域时,它是相对的,当内容区域超过可视区域时,它就变成了固定定位
-
fixed是相对可视窗口的,fixed会产生css层级堆叠上下文,如果在该元素的父级设置transfrom,filter,backdrop-filter,perspective,那么fixed就会失效
-
static设置会导致left,right,top,bottom,zIndex失效
-
[code example] github.com/maicFir/les…