What are the default rules for overlapping elements in CSS?

276 views Asked by At

I am trying to teach myself html and CSS through w3schools, and it mentions there that if no z-values are specified, elements that are positioned last in the html code will be shown on top. However, in their example, if we comment out the z-index of images so that none is specified, the image still shows up on top. Shouldn't the order from bottom to top be the heading, then the image, then the paragraph since this is the order in which they are specified in the code? Are their special overlapping rules being applied that I am not aware of?

P.S. I found this question, which references another instance of images appearing on top of text even though the text comes last in the html, but no reason is given for this behavior (instead, only the proper z-index code is recommended). However, I want to know why this is happening, rather than how to make the text come on top with z-index.

3

There are 3 answers

0
Oriol On BEST ANSWER

That's because the image is absolutely positioned. From the spec,

Within each stacking context, the following layers are painted in back-to-front order:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. the child stacking contexts with positive stack levels (least positive first).

If you remove the z-index, the image is painted at step 6 in front of the paragraph at step 3 and the paragraph's text at step 5.

0
Andy Ray On

If both elements have default z-index (equivalent to 0), the absolutely positioned one will be on top of the one without positioning set.

2
Dan Fletcher On

Here is the section of the spec that I just finished reading: https://www.w3.org/TR/html5/embedded-content-0.html#the-img-element

My interpretation of this is that, although the browser will render elements from the top of the document to the bottom, the src for the image element has to be received after the document has been loaded, since it obviously requires an additional HTTP request. This would mean that the content of the image is rendered after your regular elements are, and thus without specifying a z-index, it renders on top.

So in other words, your browser first receives an HTML document via HTTP request to the server. That HTML document has an <img> tag with a src attribute, which then fires another HTTP request to the server for the actual file for that image tag. Without a z-index set, the browser will simply draw that image on top of the other elements.

This is my best guess. I tried playing with a few experiments and using the inspector to see if maybe there was a default z-index on images, but there's not.

EDIT:

As Oriol pointed to in the spec, that explains the w3schools example, as well as the other code snippet you linked to: Image overlapping over div

In that case, it looks like the <img> element would be in-line and so would be drawn at step 5, whereas the <div>s would be drawn at step 3.