That's the 10^6 $ question!
I've searched and read a lot about this, but is there a state-of-the-art method that would respond to the following problematic :
if height(block content) < height(viewport):
height(block) = height(viewport)
else:
height(block) = height(block content)
The bottom of the block should always touch the bottom of the page. I'm looking for the most simple, clean and cross-browser way to do this.
Thank you!
The most common way is to do this:
html, body { height:100%; }
Then set any elements which are to also fill the vertical space to height:100%.
Note: For this to work the item needs to be block-level and have content, even a &nsbp; would do and don't forget that padding adds to the height of the element so be sure to compensate accordingly if you absolutely have to have padding on that element.
min-height is what you're describing. Just know you'd have to give html, body, and all parent tags a height for percentage heights to work:
html, body, #someBlockId {
margin: 0;
padding: 0;
min-height: 100%;
}
Note: I had to remove the margin and padding, because those are added after the height is calculated. box-sizing can change this behavior, but it isn't quite cross-browser.
Considering that :
The bottom of the block should always touch the bottom of the page
I would go like :
.block {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
Then set the height if height(block content) > height(viewport).
If no height is set, it will take all the space of the offset parent.
If height is set, it will override top:0; bottom:0;.
Then if height is set and you remove top (remove, no set it to 0), it will stick to the bottom of the offset parent.
Related
I have the following html:
<style>
body {
margin: 0;
height: 100vh;
}
div {
margin: 1px;
}
</style>
<body>
<div>feck</div>
</body>
The div's margin causes scroll bars, even tho the div itself is nowhere near the height of the page. Without the div's margin, there is no scroll bar. What's going on? Is this a browser bug?
Collapsing margins. Because the div is the topmost element in the body, the div's margin is collapsed with the body's margin. That is, the body gets the same margin too.
You may think that "collapsing" isn't the right word for this behaviour, and you'd be right, but that's the word they've chosen. Sorry.
There are several solutions:
Sean's solution of simply moving the div a pixel downwards
Your own solution of using calc for the body height
Set a padding on the body, and use box-sizing:border-box for it.
Because a div is a block element. It has positioning in the Dom, therefore takes up space. When you add a margin to the top, you are pushing its space down, therefore increasing the overall amount of space it occupies.
If you want to push the div down, without changing the overall container (body) height, you can give the div a position of relative, and a top of 1px.
div {
position: relative;
top: 1px;
}
Check out this answer it should be clear enough.
The main point is that margins of adjacent elements (in this case your div and body) are collapsing taking the maximum value of the two margins.
I'm trying to set a div the width of the screen but without using:
div {
position: relative;
left: 0;
right: 0;
}
because this breaks the template.
It that possible?
As mentioned in the Bootstrap documentation, you have two different types of container classes to work with. One with a fixed width called "container" and one called "container-fluid" which is spanning the entire width of your viewport.
Link to the bootstrap documentation: http://getbootstrap.com/css/#overview-container
Code:
<div class="container-fluid">
...
</div>
You did not submit any code though I'll answer your question sans Twitter.
Even if the parent element is statically defined all the child elements will dynamically flow (within the parent's limitations) until you put static limitations on those child elements.
main {bottom: 0; left: 0; overflow: auto; position: absolute; right: 0; top: 0;}
All the elements in the main element in this example will still dynamically expand to use 100% of the width of the screen, regardless of what kind of screen.
Without using the position property if you don't set a width a block element like a div will automatically use 100% of the available width of it's parent unless it is set to float; adding margin or padding will subtract from the content width unless you specify a width (other than inherent or auto).
I'm going to presume that there is existing content on the page you're working with so unless you can edit the entire (X)HTML of the page then there is a chance you'll be forced to use the position property.
Can anyone tell me why position:fixed cause the element to be wider than the browser or other content on the page and causing horizontal scrolling?
Here is the code
HTML
<header>
this is a header
</header>
<div class="container">
this is a container
</div>
CSS
header {
width: 90%;
height: 100px;
background: blue;
position: fixed;
z-index: 100;
}
.container {
width: 90%;
height: 500px;
background: red;
position: relative;
z-index: -2;
}
Here is a link to the codepen http://codepen.io/colbydodson/pen/wcgua
Width is differently applied to relative and fixed elements, the ancestors margin and the style property that are parent-inheritable in respect to their position property.
The body tag will have it's default User Agent Style Sheet 8px margins (http://www.w3.org/TR/CSS2/sample.html),
header 90% width, being fixed, without any top, left, right or bottom value will be positioned to the nearest available place, but will inherit the original document/viewport size, making it in reality 90% wide, but positioned at the 10px 'body' margin offset.
To test add top:0; left:0; for the fixed header http://jsbin.com/ETAqADu/1/edit
.container being a block-level DIV element set to relative position, will be 90% width of the available parent usable width, which is the body innerWidth (not counting the 10 + 10 px margins on the X axis)
Unwanted result:
logically header will be 20px wider than .container because position fixed moves your element out of body flow.
Fix:
control your parent (body) element default margin by setting to 0
body { margin: 0; }
Or a small but heavy CSS reset like:
/* QuickReset */
*, *::before, *::after { margin: 0; box-sizing: border-box; }
Read also CSS Box Model - Margin collapsing
I was having a similar problem only on mobile. Despite having no margins, borders, padding on any of the parents, my fixed element was still wider than the viewport, and I didn't have the option of using width: auto.
If you're willing to not support IE8 and below, you can use
width: 100vw
Can I use Viewport units: vw, vh, vmin, vmax
The accepted answer is fine but in my case, I was seeing a fixed header that was wider than the rest of the page only on a mobile device. It happened to be caused by some element in the footer that had a width in pixels wider (width: 750px in my case) than the viewport of the browser.
If you want to know if some element on your page is causing this problem for you? Just open your browser console and remove some elements further down. At some point, you may notice the header becoming the correct width again. Chances are that the element you just removed or some element in it has a width in pixels wider than the viewport of the browser.
The solution, in that case, is to either set that element to a lesser width or make it flexible.
By default the body tag have margin.
Try this in your stylesheet:
body{
margin: 0;
}
As Salaw mentioned, using body { margin: 0; } will solve the issue, since <body> has default margin/padding (depending on the browser). position: fixed; removes an element completely from the flow of the document and makes it relative only to the viewport, while position: relative; does not.
Given this fact, and given that width: 90% means "make this element take up 90% of parent element's available space", and given that the parent of a fixed element is the viewport while the parent of this relative element is the body with its margin, you have the discrepancy in sizes.
See http://codepen.io/anon/pen/exzpC
Because position:fixed behave as the element is detached from document, and placed in the nearest top/left corner of the document, adding default body's margin. That's why it will take the same amount of space, as your second div, if you reset body margin.
At this fiddle, you can see a header-bar with a title on the left and some text on the right. The problem should be obvious,
the header-bar does not scale with the full site, only with the visible part
The right-floated text sticks to the top of the header and is not on the same baseline as the title.
How can I fix this? Is there a better way to achieve what I want to do?
Clarification: With "the header does not scale" I mean that it does not have a width of 750px as defined in #header because the page is too small.
A few things:
No need for a float-clearing element. Just add overflow: auto; to the container.
Use max-width instead of width, as it scales nicely.
Try this: http://jsfiddle.net/PkkU8/7/
For 1) As Blender has mentioned, setting max-width: 750px should give you the flexible header width that you are looking for. This way, your header will never be larger than 750px, but can shrink if the window gets smaller than that size.
For 2) If you aren't adverse to it, you can absolutely position the right block instead of floating it. You'd be less prone to issues that float may cause, especially when you can guarantee the right block is going to be smaller than the header itself:
.fr {
position: absolute;
bottom: 0;
right: 0;
}
This also requires that its parent div be positioned either absolutely or relatively to work properly:
#head {
position: relative;
}
add padding to class fr
.fr {
float: right;
padding: 9px 60px 0 0;
}
Has anyone heard of a bug that occurs with IE8 when applying height as a percentage to the html and body using CSS? I'm seeing a white background when a tile pattern should be applied.
html, body {
margin: 0;
padding: 0;
height: 100%;
}
body {
background-color: #666;
background-image: url('../images/body/bg_pattern.gif');
}
IE8 interprets the height element closer to the standards than IE7 did. The statement
`Height: 100%
Is pretty much ignored. Percentage heights are based upon the height of their parent element. If the parent element doesn't have an explicit height, the percentage is ignored and set to Auto. You can see more about this on w3.org.
If the page you are displaying is empty, body will have a height of 0 and you will see the default background.
To prevent the generated height:0 when you're floating the child elements, set
overflow:hidden;
position: relative;
on the parent.