3

I had this situation in CSS which I never saw before, where an element sits between the background and the text of another element. I know that what is happening here is not best practice (element is larger than its given height), but to further my CSS knowledge, I'd be interested in understanding what is exactly going on (in terms of stacking context, etc.):

.search {
  width: 2rem;
  height: 10rem;
  background: red;
  margin-left: 2rem;
}
.header__top {
  display: flex;
  height: 2rem;
  background: blue;
}
.header__bottom {
  font-size: 2rem;
  background: green;
}
<div class="header__top"><div class="search"></div></div>
<div class="header__bottom">Hello!</div>

Theoretically, anything related to stacking without a given z-index (as is the case here) should be described in stacking without the z-index property but I can't find the situation being mentioned there.

EDIT

I don't know if this is weird, but I post questions like this not to get a solution (there are many in this case), but because I want to understand the theory of CSS better. My goal is to see some CSS code and know how it will be rendered. Whenever something happens which I cannot explain using what I learned so far (stacking context, box model, etc.) and I can't find some documentation explaining the theory behind the phenomena, I post it somewhere.

fweth
  • 631
  • 6
  • 16
  • 1
    I would guess, that it isn't mentioned there, because you change the `display` of `header_top` to `flex`. If you don't do that, the stacking behaves as explained in the article and as expected. I am not sure, why `display: flex;` behaves that way, though. – Geshode Sep 27 '22 at 07:02
  • @Geshode the duplicate explain in detail how the painting order behave + this quote from the Flexbox Spec to explain what flexbox is doing: *Flex items paint exactly the same as inline blocks* (https://www.w3.org/TR/css-flexbox-1/#painting). If you remove `display: flex` and use `display: inline-block` on the red element you will still get the same output – Temani Afif Sep 27 '22 at 10:36
  • Thanks for linking the question with really interesting answers! Should I delete mine now or is it helpful to leave it here? – fweth Sep 27 '22 at 10:37

1 Answers1

-1

the red panel is display under green panel due to green panel have no position define so it's take the default value static and in this case no z-index rule is apply

https://developer.mozilla.org/fr/docs/Web/CSS/z-index

you can use a relative position to have green panel above red panel

.search {
  width: 2rem;
  height: 10rem;
  background: red;
  margin-left: 2rem;
}

.header__top {
  display: flex;
  height: 2rem;
  background: blue;
}

.header__bottom {
  font-size: 2rem;
  background: green;
  position: relative
}
<div class="header__top">
  <div class="search"></div>
</div>
<div class="header__bottom">Hello!</div>
jeremy-denis
  • 6,368
  • 3
  • 18
  • 35
  • Thanks, yes, I know how to solve it, I was just curious about how it comes that there is some layer between background and text. I never saw this before, what is the theory behind it, when can it happen exactly? Is it always related to flexbox and overflow? – fweth Sep 27 '22 at 07:14
  • no it's link to `position: static` and z-index : https://developer.mozilla.org/fr/docs/Web/CSS/z-index by default in your case green panel have a static position and for these element no z-index rule is apply – jeremy-denis Sep 27 '22 at 07:16
  • 1
    Yes, but what logic makes just the text of the green panel go over the red panel? My understanding was that every element in the dom has some computed z-index, I never had a situation where background and text seem to have seperated z-indices. So I don't wonder so much about why the green panel sits below or above the other one, but why the text of the green panel sits not at the same z-index than the (green) background, which belong both to the same element. – fweth Sep 27 '22 at 07:19
  • by default text is always place above his container. here the red panel go on green panel due to his overflow but with no z-index rule define. it's y-overflow issue where browser don't know how to deal with z-index, y-overflow and position. like no rule are define it's browser who try do there best. I test your sample on safari and have another behaviour for overflow and z-index where red panel is place – jeremy-denis Sep 27 '22 at 07:37
  • Ah, that is super interesting, thanks a lot! So it's just undefined behaviour then, and best practice to avoid such cases is to avoid overflow, is that correct? – fweth Sep 27 '22 at 07:39
  • yes or you can define position and z-index to choose/force how element are displayed – jeremy-denis Sep 27 '22 at 07:40
  • OK, but apart from this specific case, what do I have to do to not encounter undefined behaviour? Just in general, is there some rule of thumb? (Because even when it looks right, as you mentioned, it might look different in a different browser, so I think it would be good to know in advance what constructs to avoid.) – fweth Sep 27 '22 at 07:44
  • when no rule is apply on an html element browsers add a lot of default one explain in there doc for sample for chrome it's here https://chromium.googlesource.com/chromium/blink/+/master/Source/core/css/html.css you don't have to know all rules but if you see a behaviour you don't specify it's often a default rules apply inspect element and see in computed tab (for chrome and firefox) rules apply can help you understand and see what happen – jeremy-denis Sep 27 '22 at 08:00