一些关于定位和叠加的理解
position有5个值,分别为static,relative,absolute,fixed,sticky。
static是position的默认属性,元素会按正常的文档流进行排序,不会受到top,bottom,left,right的影响。
relative相对定位的元素会较正常文档流中的位置进行偏移,受top,bottom,left,right的影响。就是元素还在文档流中像static一样占着位置,但视觉上会有偏移,多用于absolute绝对定位的父元素。
absolute绝对定位会脱离正常的文档流,相对于最近的进行过定位的(非static)父级元素定位,若没有父级元素进行过定位,则相对于即浏览器窗口定位。
fixed固定定位同样是脱离正常的文档流,一直相对于浏览器窗口定位,无论页面如何滚动,此元素总在屏幕的同一个位置。
注:当fixed定位的父元素使用了transform的样式时,fixed定位会失效,变成和absolute一样的效果。
sticky粘性定位需要指定 top,right,bottom,left 四个阈值其中之一才会生效。
阈值为此元素在可视区域中与边界的距离,跨越特定阈值前为相对定位(relative),当页面滚动导致此元素跨越阈值则变为固定定位(absolute)。
注:此属性兼容性不是特别好,请根据业务场景进行选择。
附兼容性传送门:https://caniuse.com/#search=sticky
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div class="box">
<div>titlediv>
<div class="stickyBar">stickyBardiv>
<p>this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!this is a paragraph!p>
div>
body>
html>
<style>
div.box{
height: 2000px;
}
div.stickyBar {
position: -webkit-sticky;
position: sticky;
top: 0;
padding: 5px;
background-color: #cae8ca;
border: 2px solid #4CAF50;
width: 200px;
}
div p {
width: 200px;
}
style>
实际开发过程中免不了遇到元素的叠加问题,大都可以使用除static以外的定位方式(relative,absolute,fixed,sticky),配合z-index来控制叠加的展示方式(z-index只在position不为static时才生效)。
注:父级加transform、opacity会使子元素的z-index失效,因为它们会创建新的stacking context,然后子元素原来设置的z-index会作用到这个新的stacking context上。
以下是可能的几种情况:
同一级别的元素,定位方式相同且没有设置z-index,在html结构中靠后的元素在上面。
注:同级别的static元素也可以叠加。常见的方法有把margin设为负数或使用transform。用transform的话,需要把两个元素都加上transform,这样在html结构中靠后的元素会在上面,否则加了transform的会展示在没加transform的元素上面。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div class="one">
<p>divOnep>
<p>position: absolute;p>
div>
<div class="two">
<p>divTwop>
<p>position: absolute;p>
div>
body>
html>
<style>
p {
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid black;
}
.one {
position: absolute;
background-color: red;
top: 10px;
left: 10px;
}
.two {
position: absolute;
background-color: blue;
top: 100px;
left: 100px;
}
style>
同一级别的元素使用了relative,absolute,fixed,sticky,那么z-index值大的元素在上面。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div class="one">
<p>divOnep>
<p>position: relative;p>
div>
<div class="two">
<p>divTwop>
<p>position: absolute;p>
div>
body>
html>
<style>
p {
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid black;
}
.one {
position: relative;
background-color: red;
top: 10px;
left: 10px;
z-index: 99;
}
.two {
position: absolute;
background-color: blue;
top: 50px;
left: 100px;
z-index: 1;
}
style>
同级别的元素,relative,absolute,fixed,sticky定位会在static上面。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div class="one">
<p>absolutep>
div>
<div class="two">
<p>staticp>
div>
body>
html>
<style>
p {
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid black;
box-sizing: border-box;
}
.one {
position: absolute;
background-color: red;
top: 0;
left: 0;
}
.two {
position: static;
background-color: blue;
margin: 100px 0 0 100px;
padding-top: 100px;
}
style>
非同级别的使用了relative,absolute,fixed,sticky的元素,他们的叠加顺序是以非static的最上层的祖级元素的z-index进行比较的,没有非static的祖级则用自身进行比较,与此元素的子元素的z-index无关,再高都没用。
文字描述不是很清晰,举几个例子:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div class="one">
<p>absolutep>
<p>z-index:2p>
<div class="child">
<p style="padding-left: 28px">absolutep>
<p style="padding-left: 28px">z-index:1p>
div>
div>
<div class="two">
<p style="padding-left: 100px">absolutep>
<p style="padding-left: 100px">z-index:1p>
<div class="child">
<p style="padding-left: 28px">absolutep>
<p style="padding-left: 28px">z-index:99p>
div>
div>
body>
html>
<style>
p {
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid black;
box-sizing: border-box;
}
div .child {
width: 100px;
height: 100px;
margin: 0 0 0 70px;
position: relative;
font-size: 14px;
}
.one {
position: absolute;
background-color: red;
top: 0;
left: 0;
z-index: 2;
}
.one .child {
background-color: palevioletred;
z-index: 1;
}
.two {
position: absolute;
background-color: blue;
top: 100px;
left: 100px;
z-index: 1;
}
.two .child {
background-color: purple;
z-index: 99;
}
style>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div class="one">
<p>staticp>
<div class="child">
<p style="padding-left: 28px">relativep>
<p style="padding-left: 28px">z-index:1p>
div>
div>
<div class="two">
<p style="padding-left: 100px">staticp>
<div class="child">
<p style="padding-left: 28px">staticp>
div>
div>
body>
html>
<style>
p {
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid black;
box-sizing: border-box;
}
div .child {
width: 100px;
height: 100px;
margin: 0 0 0 70px;
font-size: 14px;
}
.one {
position: static;
background-color: red;
}
.one .child {
position: relative;
background-color: palevioletred;
z-index: 1;
}
.two {
position: static;
background-color: blue;
margin: -150px 0 0 75px;
}
.two .child {
position: static;
background-color: purple;
}
style>
最后再来看一种被transform影响到的情况。
父级红色未加transform
父级红色加了transform
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div class="one">
<div class="oneChild">div>
div>
<div class="two">
div>
body>
html>
<style>
p {
margin: 0;
}
div {
width: 200px;
height: 200px;
border: 1px solid black;
}
.one {
position: static;
background-color: red;
/*transform: translate(1px,1px);*/
}
.oneChild {
width: 100px;
height: 100px;
background-color: pink;
margin: 50px 0 0 50px;
position: relative;
z-index: 2;
}
.two {
position: absolute;
background-color: blue;
top: 100px;
left: 100px;
z-index: 1;
}
style>