Home > database >  Question on a width property of a fixed positioned element
Question on a width property of a fixed positioned element

Time:12-13

I understand setting a width property of a fixed positioned element to 100% makes it as wide as a viewport and it works as expected with the following code:

<!DOCTYPE html>

<html lang="en">
    <head>
        <title>TEST</title>
        <meta name="viewport" content="initial-scale=1, width=device-width">

        <style>

            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            nav {
                position: fixed;
                background-color: black;
                width: 100%;
                height: 70px;
            }
        </style>
    </head>

    <body>

        <nav></nav>

    </body>

</html>

No matter how I resize the viewport in the Chrome devtools, the nav element assumes the width of the screen-size:

Result of the above code

Now, let's add main element and set it's min-width property to 700px like below:

<!DOCTYPE html>

<html lang="en">
    <head>
        <title>TEST</title>
        <meta name="viewport" content="initial-scale=1, width=device-width">
        <style>

            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            nav {
                position: fixed;
                background-color: black;
                width: 100%;
                height: 70px;
            }

            main {
                
                min-width: 700px;
                background-color: red;
                height: 500px;
            }
        </style>
    </head>
    <body>

        <nav></nav>

        <main></main>

    </body>
</html>

Now, the nav element only assumes the width of the viewport up until the screen-size is greater than 700px:

Result of the above code

As soon as the screen-size is less than 700px, the nav element stays at width of 700px, same as main element:

Like here

This gives me a lot of head scratching. Why nav element assumes the min-width property of 700px (same as main element) while never explicitly configured with it and also not being the child of the main element?

CodePudding user response:

position: fixed sets the containing block of the element to the initial containing block, so when you set 100% width on it, it takes 100% of the width of the containing block, which is the viewport. This is working correctly. Your main element, however, is set to a min-width of 700px... which is wider than the containing block (or viewport) of the snippet in your question... which means a scrollbar appears. But you are only scrolling the main element, not the nav element.

To illustrate, here's the same styles but with content in both the nav and main elements. If both were scrolling, you'd see the "This is a header" text shifting to the left as you scroll to the right. Since you don't, you know that it must be fixed. (For reference, the width of the viewport in these snippets here on Stack Overflow is 616px, at least for me. If it were 700px or wider, you wouldn't see a scrollbar. If you had set width: 700px instead of min-width: 700px on main, you could set the snippet to fullscreen mode to see the scrollbar disappear and further illustrate the situation)

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
nav {
    position: fixed;
    background-color: black;
    color: white;
    width: 100%;
    height: 70px;
}
main {
    min-width: 700px;
    background-color: red;
    height: 500px;
}
<nav>This is a header</nav>
<main>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. </main>

As it happens, you also don't have any top spacing applied to your main element, so much of it is being overlapped by the nav element, due to position: fixed taking the nav element out of the normal document flow. Here's a demo of that issue taken care of, as well:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
nav {
    position: fixed;
    background-color: black;
    color: white;
    width: 100%;
    height: 70px;
}
main {
    padding-top: 70px; /* Pushes the contents of the main element down by the same height as the nav element */
    min-width: 700px;
    background-color: red;
    height: 500px;
}
<nav>This is a header</nav>
<main>Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet. </main>

CodePudding user response:

Using the * CSS selector is discouraged. It selects every element. If you want to remove the default margin and/or padding from html and body use:

body, html {
  margin: 0;
  padding 0;
}

In terms of % based sizing, it is percentage of it's parent element, not the entire viewport. You generally want to avoid fixed or absolute positioning and instead use grid (and it's 1fr filler) or flex (and it's flex 1 1 auto filler) display styles to create your overall layouts.

  • Related