Search code examples
cssflexboxcss-positionsticky

Making an element sticky at both the top and center


I have a page that overflows the viewport both horizontally and vertically, and I'd like to sticky a nav so that it is always at the top and horizontally centered.

Right now, I can get sticky top working, but the centering does not work. Can anyone help?

body {
  text-align: center;
}

#header {
  background-color: yellow;
  width: max-content;
  position: sticky;
  top: 0;
  left: 50%;
  translate: -50%
}

#container {
  background-color: black;
  color: white;
  width: 200vw;
  height: 200vh;
  display: flex;
  justify-content: center;
  align-content: center;
  flex-direction: column;
}
<div id="header">
  I should always be at the top and centered
</div>
<div id="container">
  <span>
  I am extremely large and wide
  </span>
</div>

CodePen: https://codepen.io/hbchin/pen/bGjpQLJ


Solution

  • After doing some digging I found this:

    Why is my element not sticking to the left when using position sticky in css?

    Essentially, it's not sticking because the body is automatically expanding to the width of the size of the very big box.

    Putting it in an inline-block container will make the width not auto-expand to children, and thus allow sticking behavior.

    So this works:

    body {
        text-align: center;
    }
    
    #header {
        background-color: yellow;
        width: max-content;
        position: sticky;
        top: 0;
        left: 50%;
        translate: -50%
    }
    
    #container {
        background-color: black;
        color: white;
        width: 200vw;
        height: 200vh;
        display: flex;
        justify-content: center;
        align-content: center;
        flex-direction: column;
    }
    
    #whole-thing {
        display: inline-block;
    }
    
    <div id="whole-thing">
        <div id="header">
            I should always be at the top and centered
        </div>
        <div id="container">
            <span>
                I am extremely large and wide
            </span>
        </div>
    </div>