Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于层叠上下文 #37

Open
lovelmh13 opened this issue Jun 14, 2020 · 0 comments
Open

关于层叠上下文 #37

lovelmh13 opened this issue Jun 14, 2020 · 0 comments

Comments

@lovelmh13
Copy link
Owner

lovelmh13 commented Jun 14, 2020

引子

在使用z-index的时候,发现怎么也不管用,不管多高的和多低的值,总是不能满足想要的效果。后来才知道这个是层叠上下文的锅。之前有看过,但是直到遇到它,并且解决了它,才知道原来是这个样子。

层叠上下文是什么

层叠上下文是什么呢? 网上随便一搜就出来很多。 这里就不再去重复记录了。

简单说,就是一个压一个的元素所在的那个z轴的空间

image

正常的话,如果我们设置了z-index,值越大,就会越在前面,压住值小的那个元素。但是也有不行的时候,就是因为创建了层叠上下文。

就像这样:

image

当我们创建了2个层叠上下文,B在A的上面,如果我们要把A里面的元素让它出现在B层叠上下文中的元素的上面,不管我们把z-index设多大,都是不管用的,因为他们压根不在一个空间里面。

怎么创建一个层叠上下文

不了解的话,可能我们无意之中创建了层叠上下文,然后还拼命的设置z-index想让某个元素盖在它上面。

因为网上太多了,直接从mdn上抄来一份:

在本篇之前的部分——运用 z-index,(我们认识到)某些元素的渲染顺序是由其 z-index 的值影响的。这是因为这些元素具有能够使他们形成一个层叠上下文的特殊属性。
文档中的层叠上下文由满足以下任意一个条件的元素形成:
文档根元素(<html>);
position 值为 absolute(绝对定位)或 relative(相对定位)且 z-index 值不为 auto 的元素;
position 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
flex (flexbox) 容器的子元素,且 z-index 值不为 auto;
grid (grid) 容器的子元素,且 z-index 值不为 auto;
opacity 属性值小于 1 的元素(参见 the specification for opacity);
mix-blend-mode 属性值不为 normal 的元素;
以下任意属性值不为 none 的元素:
transform
filter
perspective
clip-path
mask / mask-image / mask-border
isolation 属性值为 isolate 的元素;
-webkit-overflow-scrolling 属性值为 touch 的元素;
will-change 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
contain 属性值为 layout、paint 或包含它们其中之一的合成值(比如 contain: strict、contain: content)的元素。
在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。 重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。
总结:
层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。
每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。

太多了,记不住,那就想想一下能把元素给单独包起来的属性,大概就可能给它创建一个新的层叠上下文,把它区分开来

如果出现了层叠上写文,怎么让我们希望的元素在上面?

真的在上面是不行了,但是我们可以让他们看起来是在上面的。

说一下我遇到的问题:

我需要这么一个样式:
image

::after::before做橘红色的三角,在不写z-index的情况下长这样:
image

写了z-index: -1长这样: 橘色三角没有了,实际上它是跑到了背景的后面去了
image

html 结构是这样的:
image

示例代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<style>
body {
	background-color:#d0e4fe;
}
h1 {
	color:orange;
	text-align:center;
}
	.box {
		background-color: blue;
		padding: 50px;
	}
	.section {
		position: relative;
		width: 150px;
		height: 150px;
		background-color: white;
	}
	.child {
		content: "";
		width: 50px;
		height: 50px;
		background-color: orange;
		position: absolute;
		left: -20px;
		z-index: 1;
	}
</style>
</head>

<body style="">
	<div class="box">
		<div class="section">
			<div class="child"></div>
		</div>
	</div>
</body>
</html>

为什么会这样呢?因为我用了transform translateX(-50%)让白色的开黑榜居中了,这样就创造出了 层叠上下文

怎么解决

既然做不到让橘红色的三角正确的出现,那么用障眼法。可以看到上图有个<section class='list'>::after::before是在它上面的,然后<section>里面是内容。

改一下结构,弄个一样样式的<section class='list0'> 把它放在刚才的<section class='list'>的前面,不写内容,只是把::after::before加在list0上。内容依然写在刚才的list上面。

这样利用list0的伪元素添加橘红色三角背景,然后用list展示内容,盖在list0上面。这样listlist0之上,就能挡住不需要被看见的橘红色三角了

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant