Div doesn't have height - html

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?

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

Why does absolute positioning of child makes parent's height collapse?

please don't mark this question as duplicate because I don't think anyone asked this before. I know that position:absolute takes the element out of the flow, but that doesn't explain why its parent's height collapses to 0. If I have this markup:
<div class="container">
<div class="inside">
some content
</div>
</div>
Then I add these styles:
.container {
background-color: red;
position: relative;
}
.inside {
background-color: green;
position: absolute;
}
Applying absolute positioning to the child will make the container's height collapse to 0. The only way to make it visible is to apply height, but not in percentages.
Does anyone know why this happens?
And is there a way to make it not happen?
Thanks in advance

CSS ignore child element's dimensions when calculating parent element height

I have a container element that is automatically resizing according to its children, while maintaining its assigned padding and margin values.
If i adjust the dimensions of a child element then the parent resizes.
I wish to exclude a specific child element from this resizing process.
The following snippet illustrates the problem:
<div id="div1">
<button id="button1">Dummy</button>
<span>My parent div has increased in height</span>
</div>
With the following CSS:
#div1 {
background-color: red;
padding: 15px;
}
#button1 {
vertical-align: super;
height: 30px;
}
Here is also a plunker.
I wish the height of #div1 to be unaffected by the position of #button1.

Two Absolute child divs inside relative parent div are hidden with overflow:hidden, expected to hover over eachother

When I use float, childs pop out of parents.
I just put overflow:hidden on the parent and the child pops back into its parent.
However, I can't do the same with an absolute div and a relative div.
.parent {
position: relative;
overflow: hidden;
}
.child {
position: absolute;
}
<div class="parent">
<div class="child">First</div>
<div class="child">Second</div>
</div>
The goal is to float 2 images one over another to create a slideshow, but still make the page respect the slideshow as an item.
Expected: "First" hovers above "Second" inside parent
Behavior: "First" and "second" are hidden, parent is 0px in height.
Upon removing overflow:hidden;, they appear outside the parent.
Since you have only absolute div inside a relevant parent div there is effectively no content in the parent div. You can set a preferred height to the parent div but also need to set html and body height to 100%.
Note: You would likely set your parent div to the size of your images to be displayed
I have colored the parent black and the children red for visual point of view.
Is this what you are trying to achieve? Sorry if I have miss understood your question.
html, body {
height:100%;
width:100%;
}
.parent {
position: relative;
height:50%;
width:50%;
background-color:Black;
}
.child {
position: absolute;
background-color:red;
width:20%;
height:20%;
}
<div class="parent">
<div class="child">First</div>
<div class="child">Second</div>
</div>

Does every div needs a set height?

I'm stressing out because of a mindbreaker and I'm probably missing some essential, but easy thing.. And although I've done this many times before.. it's going wrong now.
So I'm creating a web app and always my starting point is
html, body {
height:100%;
width:100%;
}
And some of my inner elements have a set height in percentages and some in pixels.
However, to have some structure in my code, I'm setting up div's without a set height. Let's set up the following situation.
HTML
<div class="wrapper">
<div class="thisIsAStructureItem">
<div class="innerElement">
And just some untagged piece of text
</div>
</div>
</div>
CSS
.wrapper {
height:100%;
width:100%;
}
.thisIsAStructureItem {
/* nothing, not even height */
}
.innerElement {
height: 17.5%;
}
But in any editor or browser, because I haven't set a specific (%/px) height on the second element, it shows up as 0px, including all the inner elements.
So stupid as this might be.. What am I doing wrong?
UPDATE: See this JSFiddle
The situation makes it appear a set height is necessary, therefor so my title. Feel free to adjust to something more suitable
The situation above is a replica of a to-build-situation and using exact pixels is (at that above part) not an option. Please don't advice 'use X pixels'.
Original: http://jsfiddle.net/o0Lfyt0m
Updated: http://jsfiddle.net/o0Lfyt0m/1/ (from code sample below)
The innerElement is trying to display as 17.5% as tall as the parent element. The problem is that the parent element does not have a defined height. As a fall back to calculating 17.5% of undefined, the div's height is essentially defaulting to "auto" and assuming the height of it's content, which is based on the size of the font, line-height, padding etc.
Edit: A nice feature of CSS is that an elements styles can be inherited from it's parents. You can add a structure class which will inhert the height from it's parent element, which seems to be your intent.
You could even add this class to the body element, since it's height and width are identical to html... just not certain if the HTML element can be styled in all browsers, so I didn't do that.
html, body {
height: 100%;
width: 100%;
}
.wrapper {
height: 100%;
width: 100%;
}
.struct {
height: inherit;
width: inherit;
}
.innerElement {
height: 17.5%;
}
<div class="wrapper">
<div class="struct"> <!-- .struct inherits height/width from .wrapper -->
<div class="innerElement"> <!-- height calculated based on .wrapper -->
And just some untagged piece of text
</div>
</div>
</div>
Yes, you need to set the height 100% for that div too. Otherwise it's height is unknown and will not be able to take exactly the 100% height and innerElement height is not calculated accordingly.
To make sure, you must use the height 100% for that div too.
.wrapper {
height:100%;
width:100%;
}
.thisIsAStructureItem {
height: 100%;
}
.innerElement {
height: 17.5%;/* calc from it's parent div height i.e. thisIsAStructureItem*/
}
You are, in effect, asking the browser to calculate a height from an undefined value. Since that would equal a null-value, the result is that the browser does nothing.