Why is the purple text lower than the red text?

I’m expecting that this code would produce layered text, similar to text-shadow. But it seems that the purple text is twice as far from the top as the red text. To me, this is unexpected, since they have the same top:20px; property. This only happens when I nest the divs. Is there some sort of default property that is being applied twice here?

.data {position:absolute; color:red;}

.shadow {position:absolute; color: yellow;}

.shadow .data {position:absolute; color:purple; z-index:-1; left:1px;}
<div class="data" style="top:20px;">Hello</div>
<div class="shadow">
    <div class="data" style="top:20px;">Hello</div>
</div>

There are a lot of ways I could ask this question, but maybe this example will work. I suspect that there’s something I don’t understand about position:absolute; or maybe nesting elements.

Hi! Do you expect the result like this?

2024-02-22 22_25_28-W3Schools Tryit Editor — Mozilla Firefox
I expect a result like this. (I know how to achieve this in other ways, I’m just hoping to learn why my expectations don’t match reality here). Hopefully an image works ok, sorry it’s a bit boorish.

Pretty close, I suppose. Like this?

Yes, that’s it. Why is one 20px offset from the top, and the other is 12? I would expect that they are in the same vertical position, so they have the same top: property.

Because the second one is nested in a div element, which is adding margins.

I’ve changed the shadow positioning to relative, so the value of top propery is different now. If you change it to absolute again, they will be in the same position with the same properties

1 Like

What default property is the source of this margin? I have tried setting margin and padding to zero.

I suppose the crux of my confusion is, why can I not achieve this effect with nested div elements? Why does the top: property of .shadow .data not position the nested elements 20 pixels from the top the same way the top property of .data does?

The reason the top: 20px; property of .shadow .data doesn’t position the nested elements 20 pixels from the top like .data does is because the parent .shadow div doesn’t have a defined position. Without a positioning context, the top property won’t have an effect on the child elements.

To achieve the desired effect, you need to give the .shadow div a position, like relative, so that the .shadow .data elements can position themselves relative to it. Here’s how you can modify your CSS:

.data { position: absolute; color: red; }

.shadow { position: relative; } /* Change this to relative */

.shadow .data { position: absolute; color: purple; z-index: -1; left: 1px; top: 20px; } /* Add top: 20px; here */

With this modification, the .shadow .data elements should now be positioned 20 pixels from the top inside the .shadow div.

This might have clicked it for me. So the top: and left: properties, if undefined, do not default to zero? What is it doing by default, then? I thought defining position: absolute; would give it a “defined position”. If I define top: and left: values for each div in my original code (maintaining position: absolute; because my project requires some precise positioning), the text ends up looking as expected.

You’re correct that position: absolute; does give an element a defined position, but if you don’t explicitly set top and left properties, the element will be positioned where it would normally be in the document flow, which might not be where you expect it to be.

When an element is positioned absolutely without top and left properties defined, it’s positioned relative to its closest positioned ancestor or the initial containing block if none are found. If you want precise positioning, it’s a good practice to explicitly define top, left, right, or bottom properties to ensure the element appears where you want it to be. This way, you have full control over its placement on the page.

1 Like

Thank you very much. I’ve been having trouble communicating what exactly I don’t understand, been pretty stumped. I appreciate the explanations and the patience while I piece things together. Thank you!

BTW, The credit of the solution goes to chatgpt open ai. LoL! I just copied and pasted your questions to chatgpt.
@flome

1 Like