CSS height property doesn`t work on iframe? [duplicate] - html

This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Closed 6 years ago.
How come a percentage value for height doesn’t work but a percentage value for width does?
For example:
<div id="working"></div>
<div id="not-working"></div>
#working{
width:80%;
height:140px;
background:orange;
}
#not-working{
width:80%;
height:30%;
background:green;
}
The width of #working ends up being 80% of the viewport, but the height of #not-working ends up being 0.

The height of a block element defaults to the height of the block's content. So, given something like this:
<div id="outer">
<div id="inner">
<p>Where is pancakes house?</p>
</div>
</div>
#inner will grow to be tall enough to contain the paragraph and #outer will grow to be tall enough to contain #inner.
When you specify the height or width as a percentage, that's a percentage with respect to the element's parent. In the case of width, all block elements are, unless specified otherwise, as wide as their parent all the way back up to <html>; so, the width of a block element is independent of its content and saying width: 50% yields a well defined number of pixels.
However, the height of a block element depends on its content unless you specify a specific height. So there is feedback between the parent and child where height is concerned and saying height: 50% doesn't yield a well defined value unless you break the feedback loop by giving the parent element a specific height.

A percentage value in a height property has a little complication, and the width and height properties actually behave differently to each other. Let me take you on a tour through the specs.
height property:
Let's have a look at what CSS Snapshot 2010 spec says about height:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'. A percentage height on the root element is relative to the initial containing block. Note: For absolutely positioned elements whose containing block is based on a block-level element, the percentage is calculated with respect to the height of the padding box of that element.
OK, let's take that apart step by step:
The percentage is calculated with respect to the height of the generated box's containing block.
What's a containing block? It's a bit complicated, but for a normal element in the default static position, it's:
the nearest block container ancestor box
or in English, its parent box. (It's well worth knowing what it would be for fixed and absolute positions as well, but I'm ignoring that to keep this answer short.)
So take these two examples:
<div id="a" style="width: 100px; height: 200px; background-color: orange">
<div id="aa" style="width: 100px; height: 50%; background-color: blue"></div>
</div>
<div id="b" style="width: 100px; background-color: orange">
<div id="bb" style="width: 100px; height: 50%; background-color: blue"></div>
</div>
In this example, the containing block of #aa is #a, and so on for #b and #bb. So far, so good.
The next sentence of the spec for height is the complication I mentioned in the introduction to this answer:
If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
Aha! Whether the height of the containing block has been specified explicitly matters!
50% of height:200px is 100px in the case of #aa
But 50% of height:auto is auto, which is 0px in the case of #bb since there is no content for auto to expand to
As the spec says, it also matters whether the containing block has been absolutely positioned or not, but let's move on to width.
width property:
So does it work the same way for width? Let's take a look at the spec:
The percentage is calculated with respect to the width of the generated box's containing block.
Take a look at these familiar examples, tweaked from the previous to vary width instead of height:
<div id="c" style="width: 200px; height: 100px; background-color: orange">
<div id="cc" style="width: 50%; height: 100px; background-color: blue"></div>
</div>
<div id="d" style=" height: 100px; background-color: orange">
<div id="dd" style="width: 50%; height: 100px; background-color: blue"></div>
</div>
50% of width:200px is 100px in the case of #cc
50% of width:auto is 50% of whatever width:auto ends up being, unlike height, there is no special rule that treats this case differently.
Now, here's the tricky bit: auto means different things, depending partly on whether its been specified for width or height! For height, it just meant the height needed to fit the contents*, but for width, auto is actually more complicated. You can see from the code snippet that's in this case it ended up being the width of the viewport.
What does the spec say about the auto value for width?
The width depends on the values of other properties. See the sections below.
Wahey, that's not helpful. To save you the trouble, I've found you the relevant section to our use-case, titled "calculating widths and margins", subtitled "block-level, non-replaced elements in normal flow":
The following constraints must hold among the used values of the other properties:
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
OK, so width plus the relevant margin, border and padding borders must all add up to the width of the containing block (not descendents the way height works). Just one more spec sentence:
If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
Aha! So in this case, 50% of width:auto is 50% of the viewport. Hopefully everything finally makes sense now!
Footnotes
* At least, as far it matters in this case. spec All right, everything only kind of makes sense now.

I think you just need to give it a parent container... even if that container's height is defined in percentage.
This seams to work just fine: JSFiddle
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.wrapper {
width: 100%;
height: 100%;
}
.container {
width: 100%;
height: 50%;
}

You need to give it a container with a height. width uses the viewport as the default width

Another option is to add style to div
<div style="position: absolute; height:somePercentage%; overflow:auto(or other overflow value)">
//to be scrolled
</div>
And it means that an element is positioned relative to the nearest positioned ancestor.

Without content, the height has no value to calculate the percentage of. The width, however, will take the percentage from the DOM, if no parent is specified. (Using your example) Placing the second div inside the first div, would have rendered a result...example below...
<div id="working">
<div id="not-working"></div>
</div>
The second div would be 30% of the first div's height.

Related

what is the behavior of percentage height with min height? [duplicate]

This question already has an answer here:
Height Calculation By Browsers : Containing Blocks and Children
(1 answer)
Closed 3 years ago.
When you give min-height to parent and percentage height to the child, the child doesn't get any height.
.p {
min-height: 50vh;
background-color:beige;
}
.c {
height: 50%;
background-color: red;
}
<div class="p">
<div class="c"> hi </div>
</div>
But if you give explicit height to parent, even if it is smaller than min-height, the child gets a height, but it is relative to min-height and not height provided( when height < min-height)
.p {
min-height: 50vh;
height: 1px;
background-color:beige;
}
.c {
height: 50%;
background-color: red;
}
<div class="p">
<div class="c"> hi </div>
</div>
First, I want to understand this behaviour
How can I give the height in percentage to the child with min-height only on the parent
Here is how percentage height works https://developer.mozilla.org/en-US/docs/Web/CSS/height I am using this link because it was much easier to find, as mentioned in the other answer, spec link https://www.w3.org/TR/CSS22/syndata.html#value-def-percentage
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to auto. A percentage height on the root element is relative to the initial containing block.
You will have to scroll down to find this (Specifications section)
In your case, since you did not specify the height of the parent, your child percentage height computes to auto which is what you saw in your example
here is how you can get percentage height to work without specifying a height of the parent, with position absolute
.p {
min-height: 50vh;
background-color:beige;
position: relative;
}
.c {
height: 50%;
background-color: red;
position: absolute;
}
<div class="p">
<div class="c"> hi </div>
</div>
Note - the height of your parents = the greater value between min-height and height, which is why your second case works
Honestly, adding a height of 1px as a work around to get the percentage to work for a child without defining a fixed height (since min-height overrides) is a pretty good work around.
In the first case, you do not specify a height for the parent so according to the specs height doc the height of the child will be set to auto instead of the percentage.
If the height of the containing block is not specified explicitly , and this element is not absolutely positioned, the value computes to auto.
In the second case you set a specific height and a min-height. According to another spec regarding min-height
The element's height is set to the value of min-height whenever min-height is larger than max-height or height.
So just by setting height:1px on the parent ( so setting a specific height ) the value of height:50% of the child will compute to 50% of the parent's height. Now, the parents height is not computed to 1px but to the value of min-height . So the child 50% height will be 1/2 of min-height of parent.

Why did HTML 5 drop support for setting iframe height in %?

In HTML 4.01, the height could be defined in pixels or in % of the containing element. In HTML5, the value must be in pixels.
Why was this decision made? Is there some concern that setting height: 100%; will have some negative consequence? It's not like people can't set height: 100000px; (obviously, not a good work around).
Is there some sort of reference someone can give me to the reasoning behind this?
I'm not sure this will be regarded as a good question for this forum, if you think this question isn't appropriate here, please recommend a better place to ask.
I suppose one might phrase this differently, What are the disadvantages of applying height as a percent to an iframe in HTML 4.01? (other than the fact that HTML 4.01 is obsolete)
The 'dropped support' that you are referencing is only through use of the inline height attribute. This was dropped because inline attributes mix content and styling, which is bad practice; your markup should be completely separated from its presentation.
<iframe> elements can indeed take up 100% of the height of their parent, although they are inline elements by default.
What's important to remember is that with percentage-driven values, these are relative to the immediate parent. If the immediate parent doesn't have a height, the element won't inherit their height automatically from a grandparent (or higher):
div.outer {
background: cyan;
height: 300px;
}
iframe {
border: 5px solid red;
height: calc(100% - 10px);
}
<div class="outer">
<div class="inner">
<iframe></iframe>
</div>
</div>
This can be resolved by ensureing that every element in between the element with a fixed height and the target element with the percentage-based height all have height: 100% set as well:
div.outer {
background: cyan;
height: 300px;
}
div.inner {
height: 100%;
}
iframe {
border: 5px solid red;
height: calc(100% - 10px);
}
<div class="outer">
<div class="inner">
<iframe></iframe>
</div>
</div>
The HTML5 Section 4.7.19. Dimension attributes says
Author requirements: The width and height attributes on img, iframe, embed, object, video, and, when their type attribute is in the Image Button state, input elements may be specified to give the dimensions of the visual content of the element (the width and height respectively, relative to the nominal direction of the output medium), in CSS pixels. The attributes, if specified, must have values that are valid non-negative integers.
[...]
The two attributes must be omitted if the resource in question does not have both an intrinsic width and an intrinsic height.
That is, it is only valid to use height and width in pixels when the resource in the iframe has an intrinsic width and an intrinsic height. And the height and width should reflect those intrinsic dimensions. So it makes no sense for them to be specified in percentages because intrinsic dimensions aren't in percentages.
Percentages are always just styling. So they should be specified in CSS, not HTML.

CSS increase width using calc() does not affect parent container

Take a look at the following snippet. How can I increase the width of the red container with 10px?
Is there a way to increase the width of an element in CSS, still affecting the parent container? Or do I have to use a pseudo-element placeholder to accomplish this instead?
<div style="
background:blue;
display:inline-block;
height:50px">
<div style="
font-size:30px;
width:calc(100% + 20px);
background:red">
Inner container</div>
</div>
In the snippet above the blue container is not affected, and the red overflows.
Is there a way to increase width of an element by a certain amount, where the width of the element itself is not known until runtime?
You can only reliably do this using padding; however, padding will affect the layout of the element's contents, which may not be what you want. In your example, padding the child element will affect the layout of the text inside it; the content width is never really increased at all.
You can't change an element's content width by a definite amount when it is not known in advance and depends on external factors such as the amount of content it actually has, which is usually the case with floats, absolutely positioned elements, and inline-blocks. The closest you can get is an auto width, and that only has a meaningful effect on in-flow block boxes — which are none of the above — with respect to their parents, not their children.
In fact, the behavior that you see with calc(100% + 20px) is not governed by the spec, although it's as far as browsers generally go without falling into the cyclic dependency trap:
<percentage>
Specifies a percentage width. The percentage is calculated with respect to the width of the generated box's containing block. If the containing block's width depends on this element's width, then the resulting layout is undefined in CSS 2.1.
(calc() is CSS3, but the box model hasn't changed much from CSS2.1.)
If I understood correctly, you want to increase the child's initial width and add another 10px.
But when you set this property:
The width: 100% will always be relative to its parent, so if you add another 10px in relation to the 100% it will always be 10px bigger than its parent.
You may want to set just a min-width and a max-width instead of setting explicitly its width so that the child will be within some specified ranges, but to increase the width by 10px from the starting witdh using JUST CSS its not possible.
Note: Keep in min that using calc you have to add the according browser-engine property extension i.e:
-webkit-calc()
-moz-calc()
calc()
<div style="
background:blue;
display:inline-block;
height:50px">
<div style="
font-size:30px;
width: 100%;
background:red">
Inner container</div>
</div>
Hope this helps in some way, gl.

In CSS, how to compute the percentage height within a `height:auto` parent?

CSS
#parent {
height: auto;
}
#child {
height: 10%;
width: 75%;
}
HTML
<div id="parent">
<div id="child">
<span>I'm one tenth the height of my parent.</span>
</div>
</div>
Is this a forbidden or wrong usage? This is a bit confusing because child relies on the parent's height to calculate its own height, and the parent also relies on the child's height to calculate the height:auto..
How will the browser compute the height for the child and parent element for the above codes?
This is a bit confusing because child relies on the parent's height to calculate its own height, and the parent also relies on the child's height to calculate the height:auto..
Exactly, so the browser doesn't bother with the percentage at all. From the spec:
<percentage>
[...] If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
So the computed height for both elements is auto.

height and width on html and body elements

If I have the following markup
<html>
<body>
<div id="wrapper">
<div id="container">
<p>Lots of pragraphs here</p>
</div>
</div>
</body>
</html>
with the following styles
html, body, #wrapper
{
width: 100%;
height: 100%;
}
#container
{
width: 960px;
margin: 0 auto;
}
why does not my html, body and wrapper elements extend to 100% height of the browser/view port in FF13. The html, body and wrapper stop vertically about some distance from the bottom when looking in Firebug. The container div extends to the full height as it's height is determined by the content.
(1263px X 558px for html, body, wrapper) and (960px X 880px for container)
Looking at default 100% the above happens as the first image below shows. But when I zoom to the last poosible zoom in, the above does not happen as the second image below shows and the html, body, wrapper extends to the full height.
(4267px X 1860px for html, body, wrapper) - (960px X 1000px for container)
Your html actually exactly extends to 100% height of your viewport cause viewport here is the browser window, not the inner content.
Consider this (jsfiddle):
<div id="div1">
<div id="div2">
<div id="div3">
very much content
</div>
</div>
</div>
#div1 {
height:300px;
overflow-y:scroll;
border: 1px solid black;
}
#div2 {
height:100%;
}
#div3 {
height:600px;
}
div1 here has the height of 300px and is scrolled. When you scroll content you simply move inner div but height remains untouched that is 300px. Exactly the same happens when you set height:100% to html. Your browser's height remains the same.
When you zoomed out your viewport then you have not scroll, so inner content's height is less than the height of viewport.
Shortly, html {height:100%} relates to parent's height not to the height of the inner content
UPDATE:
you can specify 3 types of values to the block-element's height:
length - set fixed height (i.g. '200px', '50em'). That's all, I can say nothing more about that.
percentage - from W3C spec:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'. A percentage height on the root element is relative to the initial containing block.
auto - The height depends on the values of other properties. (Generally on the height of inner content: text, other inline elements, block elements etc.)
What is happening when browser shows your page:
it gets height: 100% for <html>. That means that the resulting height is calculated with respect to the height of the generated box's (html-element in that case) containing block (initial containing block, i.e. browser window in that case). Let's say 1024px.
then it takes height: 100% for <body>. It will set body's height to the already calculated height of the html, that is 1024px.
then browser applies height:auto to the #wrapper and then the #container and the <p>. I don't know how it does that exactly but can suppose that it postpones the height setting (and respectively all other styles which depend on that i.e. backgrounds, borders etc.) and proceeds to the inner content.
next point is text content. Browser takes related properties specified or it's own, that is default styles, like font-family, font-size and the height of the text.
after that it will set height to the <p>-element so the <p> will stretch down to contain all content (the text in that case). The same then happens to the #container and the #wrapper.
If it happens that the height of the #wrapper is greater than the body's one (1024 px as it were agreed) than the overflow should be applied to the body. That is visible which is the default. Then overflow: visible is applied to the html. Then browser shows scroll for the entire window. Honestly, I don't know whether this is specified by the W3C spec, but can suppose it is.
So when you scroll the window your html and body are moved as are all the other elements. This is the same behavior as is with any other elements (like in jsfiddle I posted above):
Note that the background is set on the body element, but it extends to the entire canvas i.e. far beyond of the body element itself. This is towards your concern of the possible necessity of setting bg-property on the body. This is 100% compliant with the W3C spec which states (cutted):
For documents whose root element is an ... "html" element that has computed values of 'transparent' for 'background-color' and 'none' for 'background-image', user agents must instead use the computed value of the background properties from that element's first ... "body" element child when painting backgrounds for the canvas, and must not paint a background for that child element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element.
When you zoom out your page then browser recalculates all dimensions. Let's say, with each Ctrl + - click page shrinks, for example, for 20 %. Then all your text is reduced, cause its height depends on the font-size, which is affected by the Ctrl + - click, correspondingly <p>, #container and #wrapper all are reduced cause their height depends on text's height. But body and html both have height which depends on the window's height which is not affected by the Ctrl + - click. That is why you finally get this:
There is no difference here between width and height behavior in that case. You don't see the same issue with horizontal dimension simply because you've set width: 960px; for the #container which turned out to be less than your browser window's width, so no overflowing occurs. If the width of the #container were exceeding body's width you would see this:
This all is a normal and expected behavior and there is nothing to solve here.
Because you can never set the height to 100% if the element is relative to the browser window. The reason for this is that because of scrolling, your browser window could potentially be infinitely big. You will have to set a fixed height, or you will just have to set the height to expand to whatever is inside of it.
However width: 100%; is perfectly valid.
You will also need to use valid html tags. what I would do is, instead of using <wrapper> and <container>, I would make a class in your css. Class names are declared by starting them with a period.
.container{
width: 100%;
}
<div class="container"></div>
Good Luck,
-Brian