Blog-Archiv

Sonntag, 15. Mai 2016

CSS Width 100% and Position Absolute or Fixed

The CSS statement "width: 100%;" does not always do what it's expected. In case of CSS position: absolute or fixed it does not.

The Symptom

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>


Test Panel

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


This DIV is a block element, having by default 100% width.


Learning by Try and Error


Position absolute and fixed dismiss default width

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.

Width 100% hangs out on the right

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% !


Fix by box-sizing border-box?

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.

Fix by attach to right?

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.

Combine fixes?

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.

Replace width 100% by left and right zero

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%.




Keine Kommentare: