The CSS statement "width: 100%;"
does not always do what it's expected. In case of CSS position: absolute
or fixed
it does not.
Elements that have position: fixed
, or position: absolute
, and have padding
, margin
, or border
, are too wide. See screenshot below.
Here is the HTML source code:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Fixed Position with 100% Width</title>
</head>
<body>
<div style="position: fixed; left: 0; top: 0; width: 100%; border: 1em solid red;">
style = "position: fixed; width: 100%;"
</div>
</body>
</html>
This is a test panel that lets style the red-blue DIV
element on bottom. That element has been given z-index: -1
to avoid it covering any input-field. As parent for position: absolute
I have defined this chapter, enclosed by the dotted border. The parent for position: fixed
is always the browser window. A DIV
element is a block-element and has by default 100% width when positioned static
or relative
.
Set position
to absolute
or fixed
, and then try to achieve a precise 100% width of the element. When you think you are done, add a margin and see whether it holds. Should you find a solution here, you don't need to work through this Blog :-)
position | |
width 100% (explicit) | |
box-sizing |
top | em |
left | em |
bottom | em |
right | em |
margin | em |
border-width | em |
padding | em |
Set position
to absolute
. The element loses its default width of 100%, because it goes out of the document layout flow. Mind that when one of top
or bottom
is set to an explicit value, the element would go there, relatively to its next non-static
parent (the Test Panel chapter).
The same happens when you set position
to fixed
. Mind that, in this case, the element disappears when none of top
or bottom
and left
or right
is set. So enter 0 for top
and left
, and the element should be in view again.
Now, with one of position: absolute
or fixed
, set width
to 100% by activating the according checkbox. The test element should have full width now, but it hangs out on the right (thus it has more than 100% width).
This is the problem this Blog is about. How can we fix it? Mind that you should not fix it by setting width
to something like 96%
!
Try to set border-width
to zero. Now the element fits into its parent. Most likely, because there is no problem when border is zero, we could fix the problem by setting box-sizing
to border-box
, because then the browser lays it out like paddings and borders were inside the element. Try to do that. You see that the element fits nearly into space now:
But it still hangs out to the right. And it also shows a scrollbar when position
is absolute
.
Let's say it is a half-fix. Now add a margin
of 1
to the element. The half-fix breaks, the element is hanging out to the right again. Reason is that box-sizing: border-box
does not include margins.
Can we fix it by setting the right
coordinate, attaching the element to the right bound of its parent container?
To try this out, first reset box-sizing
to content-box
, and also set margin
to zero again. Then set both left
and right
to zero to attach the elements between the bounds of its layout-parent.
When you are in position: absolute
, the browser shows a scrollbar:
In position: fixed
, the browser shows no scrollbar:
In both cases the bug is not fixed, not even without margin
.
Try to set the box-sizing
field value to border-box
now, while left
and right
is set to zero:
Looks good. But the final test is setting margin
to 1. See what happens:
So this is not a solution! Learning by try & error is hard.
Get rid of width: 100%
. Leave the work to left
and right
. Here is the solution that works, and we don't even need box-sizing: border-box
for it:
Elements that have position: fixed
or position: absolute
can be brought to a real 100% width by setting their left
and right
to zero, and NOT explicitly set width: 100%
.
ɔ⃝ Fritz Ritzberger, 2016-05-15