英文:
Z Index complexity - How to position a component inside of a div to have a higher z-index value against a component outside to its level?
问题
.App {
font-family: sans-serif;
text-align: center;
}
.section-01 {
position: relative;
z-index: 0;
background-color: red;
color: white;
padding: 2rem;
}
.section-02 {
position: fixed;
z-index: 1;
background-color: blue;
color: white;
padding: 1rem;
top: 25vh;
left: 30vh;
}
.div-01 {
z-index: 2;
position: absolute;
background-color: purple;
padding: 1rem;
top: 6vh;
left: 25vh;
}
<section class="section-01">
Section-01
<div class="div-01">Div-01</div>
</section>
<section class="section-02">
<div>Section - 02</div>
</section>
英文:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.App {
font-family: sans-serif;
text-align: center;
}
.section-01 {
position: relative;
z-index: 0;
background-color: red;
color: white;
padding: 2rem;
}
.section-02 {
position: fixed;
z-index: 1;
background-color: blue;
color: white;
padding: 1rem;
top: 25vh;
left: 30vh;
}
.div-01 {
z-index: 2;
position: absolute;
background-color: purple;
padding: 1rem;
top: 15vh;
left: 25vh;
}
<!-- language: lang-html -->
<section class="section-01">
Section-01
<div class="div-01">Div-01</div>
</section>
<section class="section-02">
<div>Section - 02</div>
</section>
<!-- end snippet -->
I have a component like this:
<section id='section-01' style={{zIndex: 0}}>
<div id='div-01' style={{zIndex: 2}}>Hello World</div>
</section>
<section id='section-02' style={{zIndex: 1}}>
</section>
Now my problem is that due to absolute positioning of #section-02
and #div-01
, #section-02
takes the precedence and shows above #div-01
. However I don't want that, I want #div-01
to show up above #section-02
and #section-02
show up above #section-01
.
Please note that I don't have access to alter code of #section-01
or #section-02
. I can only control the code of #div-01
.
I know that if parent element has lower z-index
then its child won't be able to show above any other entity in hierarchy of parent element and so no matter how high I set the value of div-01
it will always show below section-02
so I wanted to know how can I solve this problem?
Adding code sandbox for example: https://codesandbox.io/s/ecstatic-flower-u5plui?file=/src/styles.css
And here's how I want it to be:
Please note that you're only allowed to make changes in
.div-01 {
position: relative;
z-index: 2;
position: absolute;
background-color: purple;
padding: 1rem;
top: 6vh;
left: 25vh;
}
or in JSX part (HTML):
<div className="div-01">Div-01</div>
I don't have access to section-01 or section-02.
I cannot restructure the HTML as these comes from different App owners and I have only control to div and its inner content.
答案1
得分: 2
目标
给定两个兄弟定位元素(.section-01
和 .section-02
),其中第一个元素位于较低的堆叠上下文中,而第二个元素位于较高的堆叠上下文中。将第一个元素(.section-01 > .div-01
)的子定位元素放在第二个元素(.section-02
)的z轴上方。
条件
只能通过CSS(显然是通过样式表)和HTML(通过JSX)修改第一个元素(.section-01 > .div-01
)的子元素。这两个兄弟元素是由一个应用程序生成的,出于某种原因无法访问(请阅读XY问题)。
考虑到上述条件,我们不能:
- 添加、删除或修改HTML(
.div-01
是例外) - 添加、删除或修改CSS(
.div-01
是例外)
问题
存在两个堆叠上下文:
-
.section-01
位于z-index: 0
,没有扩展定位(top
、right
、bottom
和left
)也没有引用任何其他定位元素(position: relative
)。 -
.section-02
位于z-index: 1
,它的位置与视口相关(top
、left
和position: fixed
)。
自然地,堆叠上下文#2将占据前景。即使.section-02
具有z-index: 0
,它仍将位于前景,因为在HTML布局中,它位于.section-01
之前。影响堆叠上下文的唯一方法是更改启动它的元素(即.section-01
和.section-02
)。
解决方案
如果我们可以在不考虑条件下解决这个问题,我们可以通过将.section-01
恢复到文档的正常流程,给它分配position: static
(或完全删除position:
),从而将其从堆叠上下文的起点中移除,并允许它的子元素.div-01
成为其自己堆叠上下文的起点(参见图I)。
图I
.section-01 {
position: static;
/* 正如它最初那样,没有任何理由让它具有任何`position`属性 */;
}
.div-01 {
position: fixed /* 或`absolute` */;
z-index: 2;
/* ... */
}
抛开对条件是否真正成立的疑虑(也许难以定位应用程序的HTML/CSS,因为它分配了随机确定的#ids或.classes),还有一种以间接方式获得相同结果的解决方案。
由于我们完全控制的唯一元素是.div-01
,我们可以使用.has()
伪类来定位它的父元素(参见图II)。
图II
/* 这将定位任何直接祖先(即父元素)的内容
.div-01 */
:has(> .div-01) {
position: static
}
.div-01 {
position: fixed /* 或绝对定位 */;
z-index: 2;
}
示例
<!-- 开始片段:js 隐藏:false 控制台:true babel:false -->
<!-- 语言:lang-css -->
html,
body {
margin: 0;
padding: 0;
min-height: 100vh;
font: 2ch/1.15 "Segoe UI";
}
.section-01 {
position: relative;
z-index: 0;
padding: 2rem;
color: white;
background-color: red;
}
.section-02 {
position: fixed;
top: 10vh;
left: 30vw;
z-index: 1;
Width: 40vw;
height: 30vh;
padding: 6rem 1rem 1rem;
text-align: right;
color: white;
background-color: blue;
}
.div-01 {
position: fixed;
top: 5vh;
left: 25vw;
z-index: 2;
width: 30vw;
height: 30vh;
padding: 1rem;
color: white;
background-color: purple;
}
:has(> .div-01) {
position: static;
}
<!-- 语言:lang-html -->
<section class="section-01">
Section-01
<div class="div-01">Div-01</div>
</section>
<section class="section-02">
<div>Section - 02</div>
</section>
<!-- 结束片段 -->
英文:
Objective
Given 2 sibling positioned elements (.section-01
and .section-02
), of which the first element sits at a lower stacking context than the second element. Place the child positioned element of the first element (.section-01 > .div-01
) above the second element (.section-02
) in the z-axis.
Criterias
Only the child element of the first element (.section-01 > .div-01
) may be modified by CSS (apparently by stylesheet?) and HTML (by JSX). The 2 sibling elements are generated by an app and for some reason are beyond reach (please read the XY problem).
Taking the aforementioned criterias into consideration, we cannot:
- add, remove, or modify HTML (
.div-01
is the exception) - add, remove, or modify CSS (
.div-01
is the exception)
Problem
There are two stacking contexts:
-
.section-01
sits atz-index: 0
without any extended positioning (<del>top
,right
,bottom
, andleft
</del>) nor does it reference any other positioned elements (position: relative
). -
.section-02
sits above everything else atz-index: 1
and it's position references the viewport (top
,left
, andposition: fixed
).
Naturally #2 stacking context will occupy the foreground. Even if .section-02
had z-index: 0
it would still be in the foreground because in HTML layout it proceeds .section-01
. The only way to affect stacking context is to change the element that started it (ie. .section-01
and .section-02
).
Solutions
If we could just resolve this issue without having to consider the impossible restrictions mentioned under Criterias, we can simply place .section-01
back into the normal flow of the document by assigning it position: static
(or removing position:
all together), thereby removing it as an origin of a stacking context and allowing it's child element, .div-01
to be the origin of it's own stacking context. (see Figure I).
Figure I
.section-01 {
position: static;
/* As it was originally, there was no real reason for it to have any `position`
property */;
}
.div-01 {
position: fixed /* or `absolute` */;
z-index: 2;
/* ... */
}
Putting aside my doubts about the criterias being a genuine concern, (maybe it's too difficult to target the app's HTML/CSS because it assigns randomly determined #ids or .classes), there is a solution with the same result but in an indirect way.
Since the only element in our complete control is .div-01
, we can target it's parent by using the .has()
pseudo-class. (see Figure II)/
Figure II
/* This will target anything that is a direct ancestor (aka parent) of
.div-01 */
:has(> .div-01) {
position: static
}
.div-01 {
position: fixed /* or absolute */;
z-index: 2;
Example
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
html,
body {
margin: 0;
padding: 0;
min-height: 100vh;
font: 2ch/1.15 "Segoe UI";
}
.section-01 {
position: relative;
z-index: 0;
padding: 2rem;
color: white;
background-color: red;
}
.section-02 {
position: fixed;
top: 10vh;
left: 30vw;
z-index: 1;
Width: 40vw;
height: 30vh;
padding: 6rem 1rem 1rem;
text-align: right;
color: white;
background-color: blue;
}
.div-01 {
position: fixed;
top: 5vh;
left: 25vw;
z-index: 2;
width: 30vw;
height: 30vh;
padding: 1rem;
color: white;
background-color: purple;
}
:has(> .div-01) {
position: static;
}
<!-- language: lang-html -->
<section class="section-01">
Section-01
<div class="div-01">Div-01</div>
</section>
<section class="section-02">
<div>Section - 02</div>
</section>
<!-- end snippet -->
答案2
得分: 1
如果您希望 div-01 出现在 section-02 之上,同时保持 section-01 位于它们下方,您需要稍微调整HTML结构,通过添加一个具有相对位置的共同索引上下文,如下所示:
<div class="container">
<section class="section-01">
Section-01
</section>
<div class="div-01">Div-01</div>
<section class="section-02">
<div>Section - 02</div>
</section>
</div>
.container {
position: relative;
}
.section-01 {
width: 100vw;
position: relative;
z-index: 1;
background-color: red;
color: white;
padding: 2rem;
border: 1px solid red;
}
.section-02 {
position: absolute;
z-index: 2;
background-color: blue;
color: white;
padding: 1rem;
top: 4.6rem;
left: 11rem;
}
.div-01 {
z-index: 3;
position: absolute;
background-color: purple;
padding: 1rem;
top: 2.5rem;
left: 10rem;
}
英文:
If you want div-01 to appear on top of section-02 while maintaining section-01 below both, you will need to adjust the HTML structure slightly, by adding a common index context with position relative as shown below:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.container {
position: relative;
}
.section-01 {
width: 100vw;
position: relative;
z-index: 1;
background-color: red;
color: white;
padding: 2rem;
border: 1px solid red;
}
.section-02 {
position: absolute;
z-index: 2;
background-color: blue;
color: white;
padding: 1rem;
top: 4.6rem;
left: 11rem;
}
.div-01 {
z-index: 3;
position: absolute;
background-color: purple;
padding: 1rem;
top: 2.5rem;
left: 10rem;
}
<!-- language: lang-html -->
<div class="container">
<section class="section-01">
Section-01
</section>
<div class="div-01">Div-01</div>
<section class="section-02">
<div>Section - 02</div>
</section>
</div>
<!-- end snippet -->
答案3
得分: 0
你不能像这样将 section-02 的 z-index 改为 -1:
<section id='section-02' style={{zIndex: -1}}>
</section>
英文:
You cant change the z-index of section-02 to -1 like this
<section id='section-02' style={{zIndex: -1}}>
</section>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论