Why does height 100% work on absolutely positioned element? - html

As far as I know for the height to work as percentage the container element must have a specific height mentioned. But this doesn't hold true for absolutely positioned element with the ancestor being relatively positioned. Here is a working example of what I meant:
.container {
width: 400px;
background: cyan;
text-align: right;
position: relative;
color: white;
}
.child {
width: 90%;
height: 100%;
background: blue;
}
.absolute {
position: absolute;
}
.second {
margin-top: 30px;
}
<div class="container">
<div class="child absolute">Absolute</div>
one <br> two <br> three <br> one <br> two <br> three <br>
</div>
<div class="container second">
<div class="child">Static</div>
one <br> two <br> three <br> one <br> two <br> three <br>
</div>
As you can see the absolutely placed div applied 100% height onto it but not the statically positioned div. Why?

From MDN
relative
This keyword lays out all elements as though the element were not positioned, and then adjusts the element's position, without changing layout (and thus leaving a gap for the element where it would have been had it not been positioned). The effect of position:relative on table-*-group, table-row, table-column, table-cell, and table-caption elements is undefined.
Read more. Is very nicely described.

Here is a great read about the different position types:
Absolute is relative to the parent element and is not affected by other elements and are removed from the flow of the page i.e. you can see the list with one, two, three unaffected.
It's height is 100% as .child specifies.

Related

What's the standard of width % for child positioned: absolute [duplicate]

This question already has answers here:
Pseudo element not full container width when border used
(3 answers)
Closed 1 year ago.
As I know, child's width percentage's standard is parent's content box(only the content, without padding or margin.). So if there's a padding in parent and child's width is 100%, child's width is smaller than parents. But If I position child as a absolute and parent as a relative, child's width is just equal to the parent's no matter padding and margin in parents. Like this:
<div class="first">HI
<div class="second">
HELLO
</div>
</div>
css code
.first{
background-color: yellow;
width:100px;
height:100px;
padding:10%;
position:relative;
}
.second{
background-color: blue;
position:absolute;
width: 100%;
height:100%;
opacity:40%;
}
Eventhough parent's position and relative so Child is totally dependent on '.first'. What's the standard of child's width in this case?
This snippet shows the result of setting the second div to have position relative and then position absolute. You can see that the absolutely positioned element takes on the width of its parent including the padding.
.first {
background-color: yellow;
width: 100px;
height: 100px;
padding: 10%;
position: relative;
}
.second {
background-color: blue;
width: 100%;
height: 100%;
opacity: 40%;
}
.relative {
position: relative;
}
.absolute {
position: absolute;
}
<h2>The blue square has relative position</h2>
<div class="first">HI
<div class="second relative">
HELLO
</div>
</div>
<h2>The blue square has absolute position</h2>
<div class="first">HI
<div class="second absolute">
HELLO
</div>
</div>
The reason seems to be that:
when a box has position: absolute its containing box is the parent's padding box.
See the accepted answer to: Absolute positioning ignoring padding of parent though I am struggling to find the exact description of that in the actual standard documents and it would be good if someone could point out a primary reference.
UPDATE: thanks to Temani Afif who has pointed out this SO answer which has info. from an actual specification:
The standard of the % for position:absolute is of the nearest positioned ancestor block and if no ancestor is positioned, it is relative to body element. In your case since the first is positioned relative the second will be relative to first and if u remove the position attribute of first, second will be positioned relative to body.
You can also check this - https://www.w3schools.com/css/css_positioning.asp

Absolutely positioned element is scrolled with content, why?

I have the following setup: (try scrolling the content)
HTML
<div class="wrapper">
<div class="backdrop"></div>
<div class="content">
1<br>
2<br>
3<br>
4<br>
5<br>
6<br>
7<br>
</div>
</div>
CSS:
.wrapper {
height: 100px;
overflow: auto;
border: 1px solid black;
position: relative;
}
.backdrop {
position: absolute;
top:0;
left: 0;
bottom:0;
right: 0;
background: red;
}
The problem is that backdrop for some reason is scrolled top with the content. Why is this happening? I was expecting the backdrop to remain still since it's positioned relative to the wrapper borders, not content's.
The scrollable area is defined by the wrapper via its overflow: auto declaration. Since wrapper serves as the containing block for both the content and the backdrop (due to position: relative), this causes both elements to scroll together. In other words, this is due to both overflow: auto and position: relative on the same parent element, working in tandem.
Note that absolute positioning does not make an element immune to scrolling; when an absposed element does not appear to scroll, that is simply because its containing block does not scroll, and whatever is scrolling apart from the absposed element is some other element that is not its containing block. That is not the case in your setup. See the last example in section 11.1.1 of the spec for another example of this.

Div doesn't have height

Why does wrapper div not have a height? If I set the height (height:200px) the green background appears but how to set with auto height?
Here is my code (JSFiddle):
HTML:
<div class="wrapper">
<div class="effect"></div>
<div class="content">
...content
</div>
</div>
CSS:
.content {
position: absolute;
background-color:red;
}
.wrapper, .effect {
background: green;
}
.wrapper {
position: relative;
width: 630px;
}
.effect {
width:100%;
position: absolute;
}
It is not working (i.e. parent element not having any height) because all the immediate descendant of the .wrapper element is absolutely positioned — this will have the effect of taking them out of the flow of the document, therefore causing the parent's dimension to collapse to nothing.
You will also notice that the effect is the same when you float all
descendants of the parent wrapper, because float also has the
effect of taking normal elements out of the document flow.
There are only two ways to prevent this from happening, both of which involving declaring a certain height for the parent .wrapper element:
Either you explicitly state a height for the parent (see example fiddle)
Or use a relative height (say, in percentages or viewport units) that is not dependent on its own content.
You should reconsider your design strategy, and what you're trying to achieve. There is probably other ways to achieve what you intend to do, will you mind showing us?

Positioning Elements in Tableless Layout

I am trying to do a tableless
layout, and I have the following
HTML snippet:
<div class="slider-inner">
<div class="slider-pane">
<div class="container">
<p>...</p>
<div class="did-you-knoow">
<div class="facts">
</div>
<div class="marquee-container">
</div>
</div>
</div>
</div>
</div>
Which is styled w/ this CSS:
div.slider-pane {
width: 1024px;
}
div.container {
display: block;
}
div.facts {
margin-right: 60%;
}
div.marquee-container {
position: absolute;
top: 0;
right: 0;
margin-left: 0;
margin-right: 0;
padding: 10px;
width: 60%;
}
I want the div.facts to occupy the left-40% , and the div.marquee-container
to occupy the right-60% of the div.did-you-know (their immediate parent). I
expect the div.marquee-container to be positioned relative to its parent, and
its width to be 60% of its parent, but its positioning and width are relative
to div.slider-inner, which is 2 levels above its parent.
How do I set the position and width of div.marquee-container relative to
its parent, and not the div three levels above it?
add position:relative to div.container
#locrizak's answer is correct, I needed to add 'position:relative' to the div.container, but I needed to add it to the div.did-you-know as well. In other words, I needed to set all of the containing div's to position:relative in order for the elements in question to be positioned relative to the immediate parent.
I found this was also answered in the MDN page for css position under the 'absolute' definition:
[The browser will] position [the element] at a specified position relative to its closest positioned ancestor or to the containing block
However the W3C reference was not as helpful.

How to use 100% height with css

Attempt #3.
Using css, with a strict doctype, can someone please draw 4 div boxes to meet these requirements.
The wrapper or outermost div will scale in height. That means that it could be any height.
The middle div should always be 100% high to match the outer/parent div (#1 in my list)
The next div should be positioned inside, and at the top of div #2
The last div should be positioned inside, and at the bottom of div #2
NOTES:
If you use absolute positioning for this, you will put divs 3 and 4 outside of div #1 and that won't work. The key is to keep divs 3 and 4 within div #2
<div id="wrapper">
<div id="middle">
<div id="top">top</div>
<div id="bottom">bottom</div>
</div>
</div>
#wrapper { height: 200px; position: relative; }
#middle { height: 100%; }
#bottom { position: absolute; bottom: 0; }
It should work for any height you give the #wrapper.
you can play with it here: http://jsfiddle.net/dmBsa/