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?

huangapple go评论40阅读模式
英文:

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 -->

&lt;section class=&quot;section-01&quot;&gt;
        Section-01
        &lt;div class=&quot;div-01&quot;&gt;Div-01&lt;/div&gt;
      &lt;/section&gt;
      &lt;section class=&quot;section-02&quot;&gt;
        &lt;div&gt;Section - 02&lt;/div&gt;
&lt;/section&gt;

<!-- end snippet -->

I have a component like this:

&lt;section id=&#39;section-01&#39; style={{zIndex: 0}}&gt;
    &lt;div id=&#39;div-01&#39; style={{zIndex: 2}}&gt;Hello World&lt;/div&gt;
&lt;/section&gt;
&lt;section id=&#39;section-02&#39; style={{zIndex: 1}}&gt;
&lt;/section&gt;

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

Here's how it shows atm:
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?

And here's how I want it to be:
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?

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):

&lt;div className=&quot;div-01&quot;&gt;Div-01&lt;/div&gt;

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 &gt; .div-01)的子定位元素放在第二个元素(.section-02)的z轴上方。

条件

只能通过CSS(显然是通过样式表)和HTML(通过JSX)修改第一个元素(.section-01 &gt; .div-01)的子元素。这两个兄弟元素是由一个应用程序生成的,出于某种原因无法访问(请阅读XY问题)。

考虑到上述条件,我们不能:

  • 添加、删除或修改HTML(.div-01是例外)
  • 添加、删除或修改CSS(.div-01是例外)

问题

存在两个堆叠上下文:

  1. .section-01位于z-index: 0,没有扩展定位(toprightbottomleft)也没有引用任何其他定位元素(position: relative)。

  2. .section-02位于z-index: 1,它的位置与视口相关(topleftposition: 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(&gt; .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(&gt; .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 &gt; .div-01) above the second element (.section-02) in the z-axis.

Criterias

Only the child element of the first element (.section-01 &gt; .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:

  1. .section-01 sits at z-index: 0 without any extended positioning (<del>top, right, bottom, and left</del>) nor does it reference any other positioned elements (position: relative).

  2. .section-02 sits above everything else at z-index: 1 and it's position references the viewport (top, left, and position: 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(&gt; .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 &quot;Segoe UI&quot;;
}

.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(&gt; .div-01) {
  position: static;
}

<!-- language: lang-html -->

&lt;section class=&quot;section-01&quot;&gt;
        Section-01
        &lt;div class=&quot;div-01&quot;&gt;Div-01&lt;/div&gt;
      &lt;/section&gt;
      &lt;section class=&quot;section-02&quot;&gt;
        &lt;div&gt;Section - 02&lt;/div&gt;
&lt;/section&gt;

<!-- 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 -->

&lt;div class=&quot;container&quot;&gt;
  &lt;section class=&quot;section-01&quot;&gt;
    Section-01
  &lt;/section&gt;
  &lt;div class=&quot;div-01&quot;&gt;Div-01&lt;/div&gt;
  &lt;section class=&quot;section-02&quot;&gt;
    &lt;div&gt;Section - 02&lt;/div&gt;
  &lt;/section&gt;
&lt;/div&gt;

<!-- 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

&lt;section id=&#39;section-02&#39; style={{zIndex: -1}}&gt;
&lt;/section&gt;

huangapple
  • 本文由 发表于 2023年6月1日 22:49:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383164.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定