Go to comments

HTML+CSS宝典 CSS进阶[扩展] 堆叠上下文(z-index)

堆叠上下文(stack context),它是一块区域

这块区域由某个元素创建,它规定了该区域中的内容在 Z 轴上排列的先后顺序。


stack 翻译过来是,如果直接翻译栈上下文,又感觉怪怪的,

有些教程翻译层叠上下文层叠的这个词又和之前的课程重复,袁老师的翻译是堆叠上下文


一、创建堆叠上下文的元素

创建堆叠上下文有两种

第一:html元素(根元素)会创建堆叠上下文

第二:设置 z-index(值非auto)值是数值的定位元素。给普通元素设置 z-indx 没有用,一定是定位元素 postition 的值是 relaitve、absolute、fixed


看例子,下面有两个堆叠上下文

1. 根元素 HTML 创建的

2. .container 元素创建的

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  .container{
    position: relative;
    z-index: 1;
  }
</style>
</head>
<body>

  <div class="container">
    <div>
      <p></p>
    </div>
  </div>

</body>
</html>


.container 元素本身在 html 根元素创建的堆叠上下文里面,

.container 元素里面的内容,在它创建的堆叠上下文里面,按照 .container 元素创建的堆叠上下文独立排列


二、同一个堆叠上下文中的元素在 z 轴上的排列

HTML 根元素创建的堆叠上下文是一个整体,.container 元素创建的堆叠上下文又是一个整体


从后到前的排列顺序

第一层:创建堆叠上下文的元素的背景和边框

第二层:堆叠级别为负值的堆叠上下文

第三层:常规流非定位块盒

第四层:非定位的浮盒子

第五层:常规流非定位行盒

第六层:任何 z-index 是 auto 的定位子元素,以及 z-index 是 0 的堆叠上下文

第七层:堆叠级别为正值的堆叠上下文


1、创建堆叠上下文的元素的背景边框

HTML根元素创建堆叠上下文,它的背景边框永远是排在最后面的

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
  }
</style>
</head>
<body>

  <div class="container"></div>

</body>
</html>

HTML元素是堆叠上下文,它的背景永远在最后


刷墙总结

第一层:html 根元素背景

第二层:?


2、堆叠级别为负值的堆叠上下文

什么是堆叠级别?

z-index 属性就是堆叠级别(stack level),z-index 属性只要为数字就创建堆叠上下文,负值也创建堆叠上下文


"的堆叠上下文",这五个字的意思?

堆叠上下文是一个整体,比如如果 .container 元素是堆叠上下文,它里面按照自己的堆叠来排列,但它整体上出现在 HTML 根元素的背景前


示例,

父级 .container 元素不是堆叠上下文,子元素 .item 是堆叠上下文

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1; /* 设置堆叠上下文 */
  }
</style>
</head>
<body>

  <div class="container">
    <div class="item"></div>
  </div>

</body>
</html>

所以先排列在 HTML 根元素,在排列堆叠层级为负数的 .item 元素(红色的方块)


如果出现两个 .item 元素都是一样的负数值 z-index: -1,后面的覆盖前面的(后面的在前,前面的在后)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1; /* 设置堆叠上下文 */
  }
</style>
</head>
<body>

  <div class="container">
    <div class="item"></div>
    <div class="item" style="background-color:chocolate;left:-35px;top:-35px;"></div>
  </div>

</body>
</html>

后面的巧克力色,覆盖前面的红色

默认情况下 z-index 的值越大越靠前,值越小越靠后,值相同后面的覆盖前面


刷墙总结

第一层:html 根元素背景

第二层:z-index 属性负数值

第三层:?


3、常规流非定位块盒

常规流非定位块盒,就是没有设置 position 属性的是块盒(position 的默认值是 static)


.normal 元素是常规流(巧克力色)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1;
  }
  .normal{
    width: 200px;
    height: 200px;
    background-color: chocolate;
    margin-top: -200px;
  }
</style>
</head>
<body>

  <div class="container">
    <div class="item"></div>
  </div>
  <div class="normal"></div>

</body>
</html>

非定位常规流 .normal 元素巧克力色方块排在倒数第三的位置(倒数第一个是 html 背景,倒数第二是红色的 z-inedex 为负数的 .item元素)


刷墙总结

第一层:html根元素背景

第二层:z-index属性负数值

第三层:常规流盒子(正常的盒子)

第四层:?


4、非定位的浮盒子

非定位就是 postiton 默认值为 static 的盒子


增加一个浮动盒子float元素,会看到浮动盒子排倒数第四的位置,浮动盒子在巧克力盒子上面

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1;
  }
  .normal{
    width: 200px;
    height: 200px;
    background-color: chocolate;
    margin-top: -200px;
  }
  /* 浮动盒子 */
  .float{
    width: 200px;
    height: 200px;
    background-color: brown;
    float: left;
    margin-left: 100px;
    margin-top:-180px;
  }
</style>
</head>
<body>

  <div class="container">
    <div class="item"></div>
  </div>

  <div class="float">浮动盒子</div>

  <div class="normal"></div>

  <!-- <div class="float">浮动盒子</div> -->

</body>
</html>

浮动盒子排在巧克力色盒子上面与位置无关,把浮动盒子放到巧克力色 .normal 元素上面的位置,也是覆盖 .normal 元素


为什么浮动盒子覆盖巧克力色的常规流盒子呢?

因为之前说过:常规流盒子无视浮动盒子( Ps:但是浮动盒子覆盖不了定位盒子 )


刷墙总结

第一层:html 根元素背景

第二层:z-index 属性负数值

第三层:常规流盒子(正常的盒子)

第四层:浮动盒子

第五层:?


5、常规流 非定位行盒

常规流非定位行盒,

常规流写 span 元素也行,这里写 p 元素,因为 p 元素里面会生成匿名行盒


设置常规流盒子 .normal,margin-top: -330px 负数

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1;
  }
  .normal{
    width: 200px;
    height: 200px;
    background-color: chocolate;
    margin-top: -330px;
    margin-left: 60px;
  }
  .float{
    width: 200px;
    height: 200px;
    background-color: brown;
    float: left;
    margin-left: 100px;
    margin-top:-180px;
  }
</style>
</head>
<body>

  <p style="background-color:lightyellow; height:40px; width:300px;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!
  </p>
  <div class="container">
    <div class="item"></div>
  </div>
  <div class="float">浮动盒子</div>
  <div class="normal"></div>
  <!-- <div class="float">浮动盒子</div> -->

</body>
</html>

常规流块盒 .normal 覆盖了p元素,但是没有覆盖 p 元素里面的文字,

因为文字是行盒,相当于 p 元素里写了一个 span 元素

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!


如果把 p 元素换成 span 元素,span 元素就不能被覆盖了,因为 span 元素本身就是行盒

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1;
  }
  .normal{
    width: 200px;
    height: 200px;
    background-color: chocolate;
    margin-top: -330px;
    margin-left: 60px;
  }
  .float{
    width: 200px;
    height: 200px;
    background-color: brown;
    float: left;
    margin-left: 100px;
    margin-top:-180px;
  }
</style>
</head>
<body>

  <span style="background-color:lightyellow; height:40px; width:300px;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!
  </span>
  <div class="container">
    <div class="item"></div>
  </div>
  <div class="float">浮动盒子</div>
  <div class="normal"></div>

</body>
</html>

整个 span 元素都不能被覆盖

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!

如果是图片,图片也是在前面(因为图片也是行盒)


到现在还没有到定位元素,马尔斯绿色(normal)定位元素可以覆盖很多元素,设置定位元素top值向上移动

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  /* container是定位元素 */
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
    top: -70px; /* 设置top值向上移动 */
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1;
  }
  .normal{
    width: 200px;
    height: 200px;
    background-color: chocolate;
    margin-top: -330px;
    margin-left: 60px;
  }
  .float{
    width: 200px;
    height: 200px;
    background-color: brown;
    float: left;
    margin-left: 100px;
    margin-top:-180px;
  }
</style>
</head>
<body>

  <span style="background-color:lightyellow; height:40px; width:300px;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!
  </span>
  <div class="container">
    <div class="item"></div>
  </div>
  <div class="float">浮动盒子</div>
  <div class="normal"></div>

</body>
</html>

都开始有文字了,还没有到定位元素,定位元素在显示上非常非常靠前



Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!


第五步,都开始在墙上写文字了,还没有到定位元素

到了第六部开始涉及定位元素,之前第二步涉及到的定位元素是负数值


刷墙总结

第一层:html根元素背景

第二层:z-index属性负数值

第三层:常规流盒子(正常的盒子)

第四层:浮动盒子

第五层:行盒(文字、span元素…)

第六层:?


6、任何 z-index 是 auto 的定位子元素,以及 z-index 是 0 的堆叠上下文

这一层排列的是 z-index 值为 auto 或为 0 的堆叠上下文


.container 元素没有设置 z-index 属性,默认属性值为 auto( 代码与上面一样,效果也一样 )

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  /* container是定位元素,z-index属性默认值为auto */
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
    top: -70px; /* 设置top值向上移动 */
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: -1;
  }
  .normal{
    width: 200px;
    height: 200px;
    background-color: chocolate;
    margin-top: -330px;
    margin-left: 60px;
  }
  .float{
    width: 200px;
    height: 200px;
    background-color: brown;
    float: left;
    margin-left: 100px;
    margin-top:-180px;
  }
</style>
</head>
<body>

  <span style="background-color:lightyellow; height:40px; width:300px;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!
  </span>
  <div class="container">
    <div class="item"></div>
  </div>
  <div class="float">浮动盒子</div>
  <div class="normal"></div>

</body>
</html>


刷墙总结

第一层:html 根元素背景

第二层:z-index 属性负数值

第三层:常规流盒子(正常的盒子)

第四层:浮动盒子

第五层:行盒(文字、span元素…)

第六层:z-index 值为 auto 或 0

第七层:?


7、堆叠级别为正值的堆叠上下文

堆叠级别为正值的堆叠上下文的意思是,z-index 值为正数,大于 0 的堆叠上下文


设置 .item 红色盒子 z-index 属性值为 1 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .container{
    background-color: #008c8c;
    width: 200px;
    height: 200px;
    position: relative;
    margin: 50px;
    top: -70px;
  }
  .item{
    width:100px;
    height:100px;
    background-color: red;
    position: absolute;
    left:-30px;
    top:-30px;
    z-index: 1;/* 设置属性值为1 */
  }
  .normal{
    width: 200px;
    height: 200px;
    background-color: chocolate;
    margin-top: -330px;
    margin-left: 60px;
  }
  .float{
    width: 200px;
    height: 200px;
    background-color: brown;
    float: left;
    margin-left: 100px;
    margin-top:-180px;
  }
</style>
</head>
<body>

  <span style="background-color:lightyellow; height:40px; width:300px;">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!
  </span>
  <div class="container">
    <div class="item"></div>
  </div>
  <div class="float">	浮动盒子 </div>
  <div class="normal"></div>

</body>
</html>

没什么好说的了



Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus dolor!


刷墙总结

第一层:html 根元素背景

第二层:z-index 属性负数值

第三层:常规流盒子(正常的盒子)

第四层:浮动盒子

第五层:行盒(文字、span元素…)

第六层:z-index 值为 auto 或 0

第七层:z-index 值为正数


以上全是在一个堆叠上下文里面的,就是 HTML 根元素,

虽然 .item 元素是堆叠上下文,但是 .item 内部没有东西


三、每一个堆叠上下文都是一个整体(三明治)

每个堆叠上下文,独立于其它堆叠上下文,它们之间不能穿插,

意思是一个堆叠上下文,一定要看做一个整体,一个堆叠上下文相当一个三明治(或千层面包),整个三明治是一个整体,和其它堆叠上下文进行排列

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>堆叠上下文</title>
<style>
  html{
    background-color: lightblue;
  }
  .sandwich1{
    position: relative;
    z-index: 0;
    width: 200px;
    height: 200px;
    background-color: #008c8c;
  }
  .sandwich2{
    position: absolute;
    z-index: -1;
    width: 200px;
    height: 200px;
    background-color: chocolate;
    left:100px;
    top:100px;
  }
  .item{
    position: absolute;
    width: 100px;
    height: 100px;
    line-height: 100px;
    text-align: center;
    color: #fff;
    right: -50px;
    bottom:-50px;
  }
</style>
</head>
<body>

  <div class="sandwich1">
    <div class="item" style="background-color: red;">马尔斯绿</div>
  </div>

  <div class="sandwich2">
    <div class="item" style="background-color: rgb(145,0,0);">chocolate</div>
  </div>

</body>
</html>


马尔斯绿chocolate



Leave a comment 0 Comments.

Leave a Reply

换一张