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
Related
I'm confused as to what making a html element "height: 100%;" does exactly.
I've made both html and body 100% height
I've added a few 100% height sections inside
The content displays correctly.
But then I looked at the page with Inspect Elements and I noticed that even though the contents displayed are above 100vh, the html, the body and the wrapper are all exactly 100vh.
Is this normal behaviour? Should I refrain from changing the height of the html and body element unless I want a site that's strictly 100vh?
height is always relative to its parent.
If you have html's height as 100vh, and then body as height: 100%, then body will also be 100vh, because body's parent is html, and the height is always relative to its parent.
The 100% is covering 100% of the parent. What the % corresponds to is determined by what modifier it is included with. If a height is set to 100% it will scale linearly with vh. If a width is set to 100% it will scale with vw. So yes, it is normal to see 100% height correspond to 100vh;
The vh unit means "Viewport Height". Setting the html or body height to 100vh is essentially redundant since a page will always want to fit within the height of the viewport in the first place.
Should I refrain from changing the height of the html and body element
unless I want a site that's strictly 100vh?
I can't think of any scenario where you'd want to set the html or body height at all. It is much more common to set the height of elements "within" the body, not the body itself.
I have two child elements inside a parent element:
<div id="registration">
<div id="left-panel"></div>
<div id="right-panel"></div>
</div>
Styling:
#registration{
#include l {
flex-direction: column;
}
#left-panel, #right-panel{
width: 50%;
min-height: 100vh;
#include l {
width: 100%;
}
}
For simplicity, let's assume that there is no content in left-panel and there is content in right-panel (not shown)
I have made it responsive such that when the width is > l (i.e. 1025px), the two panels are side by side. When the width is < l, however, the panels will stack on top of each other.
I noticed that when they stack, the height of one, let's say left-panel, remains the same whereas the other one will increase to ensure that the contents don't 'spill out' of the element. Is this because I've set the height to min-height: 100vh? I ask because if I change 'min-height: 100vh' instead to 'height: 100vh', the content spills out.
So, it seems like min-height causes the parent element (i.e. right-panel) to change in height to contain all its contents. Can anyone confirm this?
Any help is appreciated!
There's nothing special about either flex or l in this regard.
min-height just sets the minimum height for the element - it's still allowed to expand in height of the content would exceed the height of the element, but never shrinks below the specified value:
The min-height CSS property sets the minimum height of an element. It prevents the used value of the height property from becoming smaller than the value specified for min-height.
Conversely, height is a fixed height where the element is not allowed to expand, and content will simply get cut off if there is more content than the element can accommodate:
The height CSS property specifies the height of an element. By default, the property defines the height of the content area.
If no height is specified, the default height: auto is used, which gives the element a flexible height based on the height of the content. The element will only be as high as is needed to accommodate the content, and will indefinitely expand to contain it.
I want to make <body> with 100% of the page height.
When I use 100% or 100vh on both <html> and <body>, they don't extend when the page content overflows the viewport.
html {
height: 100%;
}
body {
height: 100%;
}
When I use min-height: 100%; for <body> instead of height: 100%;, it does extend, but then I cannot use percentage height for divs inside the body, since the body does not have the height set.
How to make the body "infinite" and still be able to use divs with percentage inside it?
What you want isn't possible and more precisely not logical. let's ask a trivial question:
What will define the height of the body?
1) you want your body to be height:100% of the screen: You can either use a cascading height:100% or height:100vh and your body will have an explicit specified height thus you can use percentage height inside it but the body won't grow more than 100%.
2) you want your body to be min-height:100% of the screen: You can use either min-height:100vh or min-height:100% while having height:100% set to html. In this case, the content of the body will define the real height as you simply added a min-height constraint. If you have a lot of content, the body will grow beyond the 100% limit, if not you will have it at 100%. In this situation, it's clear that the content cannot use percentage value within height since the content is defining the body height.
You can have either (1) or (2) but you cannot have both since there is no logical way to define a min-height to the body, allow it to grow (depending on its content) and allow its content to use percentage values within height.
There is an inline-block element with 100% height and width :
<div style="width: 100%; height: 100%; background: red; display: inline-block">Y</div>
Why doesn't this div take up whole height, but takes up full width?
An auto width on a block box causes it to be as wide as its containing block allows. An auto height, on the other hand, causes it to only be as tall as its contents.
The block box in question is body, and by extension, html. Neither element has an intrinsic height (even though the initial containing block does), so the height of both elements defaults to auto.
The 100% width and height of the inline-block respect the used width and height of its containing block, which in this case is body. If you specify any arbitrary height on body, or height: 100% on both html, body, then the inline-block will be adjusted accordingly.
Note that because an inline-block is essentially the same as a block box except laid inline, percentage width and height are calculated the same way as if the element were block-level.
It takes height of its parent
try:
html,body {
height: 100%;
}
That's because a div by default takes full width, unless specified otherwise.
Making it inline-block, just allows it to be inline, but preserving its block nature such as setting width and height, top and bottom margins and paddings.
And the height of every element(not-null) in html markup is same as height of a line.. which can be changed by line-height property.
And if you wish it to take all-height, follow the above answers.
Because your html and body tags don't take full height.
Unless specified otherwise, block elements take full width, but only as much height as needed - it is only natural, since HTML was originally meant as a way to format text documents. You wouldn't want, say, a paragraph to take the full window height.
You must set their height to 100% to get it work - stretch them to the window height:
html, body {
margin: 0;
padding:0;
height:100%;
}
http://jsfiddle.net/gdyLs/1/
You need to specify height to html and body then only that div will take 100% height
html, body{
height: 100%;
}
I know that position: fixed makes an element relative to the viewport instead of it's offsetParent however I have an issue where I have a side element which takes x amount of space and then some fixed position heading elements which I want to take up a percentage of the remaining viewport width.
See fiddle: http://jsfiddle.net/U5DSZ/
Now I could put all the h1 element's into their own container but then they lose their semantic meaning as they are no longer associated with their content.
I understand JavaScript could do this but I am against using JavaScript for page structure.
Is there a way to do this in a purely HTML or CSS way? I don't mind moving the h1 element's as long as they retain their relationship with the content and the content remains statically positioned.
You can get the effect that you want as follows.
Your HTML snippet is good as is:
<div id="content">
<section>
<h1>Heading 1</h1>
<p>...</p>
</section>
<section>
<h1>Heading 2</h1>
<p>...</p>
</section>
</div>
and the CSS is good but just requires some explanation:
#content {
overflow: visible; /* default, but important to notice */
}
section {
float: left;
width: 25%;
}
h1 {
position: fixed;
width: 25%;
background: #00FF00;
text-align: center;
}
and the demo fiddle: http://jsfiddle.net/audetwebdesign/4zLMq/
How This Works
Your #content block takes up the remaining width to the right of your 200px left floated sidebar.
Within #content, you have two left-floated section elements that take up 25% of the parent container, which in this case, is the width of the view port panel.
Your child h1 elements have position: fixed, which means that their width of 25% is also computed based on the width of the viewport (not #content).
Case 1
If you want h1 and #content to have the same width, they need to have the same relative (25%) computed from the same containing block (view port in this case).
However, the value of 25% is not 25% of the remaining space after you account for the floated sidebar. However, maybe you can live with this.
Case 2
You could make the width values a bit easier to determine if you set the sidebar width to be a relative value. Using mixed units is always an issue.
tldr; Shorter and cleaner solution:
h1 {
width: inherit;
...
I stumbled upon this question, with a similar issue : my container's size can be user defined through resize:both (and moveable too!).
If I followed the accepted solution, it implied I had to apply the same props to my fixed header inside my container (top, left, width and height…).
Instead, inheriting the width from the parent container works properly. I found this way much simpler, and it makes more sense too, tested on major browsers and mobiles (demo).