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.
Related
How do you fill the height when the website is zoomed 100%? When zoomed out i don't want the element to keep filling the screen. To be more clear, when a user enters the website and the website is zoomed by the default 100% the whole screen should be filled with a color. But when the user scrolls down or zooms the fill should not dynamically change its height.
From comments i edit the code to get a better result, but now there is gaps around the element:
header.mainHeader {
background-color: #282828;
width: 100%;
height: 100vh;
box-sizing: border-box;
}
First, you're setting the position: fixed of the .mainHeader class. This causes the element to always be at the same position in the viewport, regardless of zoom-level or scrolling position.
Remove this position: fixed, and its corresponding top and left properties.
You're currently setting the height to 100% of its parent element, so it would always be as big as that.
To set the height using the viewport's (visible page area) height, you can use vh units, equivalent to percentage of the viewport height (vh) - likewise for width and vw.
So, to set the height of the element to 100% of the viewport height, you can simply do:
height: 100vh;
EDIT - NOTE: the vh unit isn't supported by all browsers (I've found some, trust me). So I would recommend setting a fallback value, above the vh one, to prevent incompatibility. For example:
height: 500px; // fallback value if browser doesn't support vh
height: 100vh; // this value overrides the above one, if the browser supports vh
You might then need to remove padding and/or margin from the body or other elements, if you're seeing whitespace around the element. Have a play about to get the right effect.
For example:
body {
padding: 0;
margin: 0;
... other properties
}
Please find a JSFiddle of this in action: https://jsfiddle.net/s49p6Laj/
Sample code:
HTML
<div class="header">
I fill the viewport!
</div>
<div class="other-stuff">
// All your other content here...
</div>
CSS
// Set the body's margin and padding to 0
body {
margin: 0;
padding: 0;
}
// Make the container fill the viewport
.header{
width: 100%;
height: 100vh;
For some reason, min-height is not working on Firefox. I tried setting min-height on the body, but Firefox totally ignored it. Since my page is dynamic, I cannot just set the height to 100%. What should I do?
body {
border: 1px solid black;
width: 100%;
min-height: 100%;
}
<body>
This is the body.
</body>
height percentages are inherited (that includes min-height and max-height, too). From the CSS spec:
Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box's containing block.
What most people don't realize is that body is just an element like any other, and so is html. What people also don't realize is that these elements don't have an inherent height set. The parent of html is the viewport, and it does have an inherent height of 100%. The viewport is--more or less--the browser window, minus any menu or title bars.
Since height percentages inherit from their parent, and you don't have a height set for your html element, your CSS of min-height: 100%; doesn't have a value to take 100% of. So your body is taking min-height: 100% of 0, basically.
To fix this, simply tell your html element to be 100% the height of the viewport:
html {
height: 100%; /* this is the important bit */
}
body {
border: 1px solid black;
width: 100%;
min-height: 100%;
margin: 1px; /* I added this to make the border around the body a little easier to see. Normally you want to set it to 0 or leave it alone completely */
}
<body>
This is the body.
</body>
However, if you don't want to set your entire document to be as tall as the viewport (I strongly recommend that you do), you can also use position: absolute; on your body element so that the percentage height will always resolve, regardless of the height of its parent element. This is what Saqib was trying to get at in the comments above. From the CSS Spec on min-height and height, respectively:
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 percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').
-
Note that the height of the containing block of an absolutely positioned element is independent of the size of the element itself, and thus a percentage height on such an element can always be resolved.
body {
border: 1px solid black;
width: 100%;
min-height: 100%;
position: absolute;
margin: 1px; /* I added this to make the border around the body a little easier to see. Normally you want to set it to 0 or leave it alone completely */
}
<body>
This is the body.
</body>
(I don't know what code of yours is working in Chrome, but the code in your question has the same behavior in Chrome as it does in Firefox.)
I've set my html body tag heigth to be 100% but in Firefox that shows as a few more pixels than the screen has, so a nav scroll bar appears. How can I adjust that other than specifiying an arbitrary height :98%? I've set padding and margin to zero.
I'm using only bootstrap for css, if that's of any importance.
Check elements inside the body. One of it probably has margins or even content goes outside the body element. Just try to delete all inner elements one by one in Firefox's dev.tools and notice what element deletion will solve the problem.
Just to follow up the answer above, I noticed that padding can cause the same effect, but can only be noticed when inspecting the elements.
<button class="sbtn">
<span class="text">
my btn
</span>
</button>
.sbtn {
height: 5vh;
background-color: red;
}
.text {
padding: 10vh;
color: white;
}
Try adding this to your main CSS file.
/* CSS */
* {
box-sizing: border-box;
}
border-box tells the browser to account for any border and padding in the values you specify for an element's width and height. If you set an element's width to 100 pixels, that 100 pixels will include any border or padding you added, and the content box will shrink to absorb that extra width. This typically makes it much easier to size elements.
CSS box sizing
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.
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.