Sticky Nav - Width Changing When Position Fixed

- 1 answer

i have a sticky nav that when it sticks (position: fixed being applied) the width is changing to push the right of the navbar off the screen.

a screen recording example

a codesandbox eample

Using react/hooks and styled components. a hook is applying the prop of sticky: true (see code below).

I have tried a few different combinations of setting width: 100% or width: 100vw in both the non-sticky and sticky styles.

in the video you can see 2 things happening when the nav becomes "sticky". the border-radius-bottom-right is disappearing and the content of the nav is being pushed to the right. When not sticky, the nav has a width of 808px, when sticky it grows to 840px. To be clear I'm not saying the border radius style is being removed, but the border right is now off screen.

the code for the nav:

const Wrapper = styled.div`
  padding: 1rem;
  display: flex;
  justify-content: center;
  font-size: 1.5rem;
  background-color: white;
  color: black;
  /* width: auto; */
  /* width: 100%; */
  z-index: 1;
  margin: 0;
  box-shadow: 0px 2px 10px #273136;
  height: 30px;
  border-radius: 0 0 10px 10px;
  ${props => props.sticky && css`
    position: fixed;
    top: 0;
    width: 100vw;

This is being rendered inside of another wrapper component, wrapping the entire app, with the following styles:

text-align: center;
font-size: 10px; 
color: black;
display: flex;
flex-direction: column;
max-width: 100vw;


You set widht:100vw to the fixed element which makes wider than the body because vw doesn't care about the scrollbar it will be difficult to work with, i suggest you use width:100%

Also because you have box-sizing set to content-box the padding and border won't be considered as content so they will influence the width, and let's not forget about the default margin:8px on the body

to accommodate for all this we can use calc()

instead of 100vw you should use 100% because 100% gives us the exact width of the parent excluding the width of the scrollbar.


After you set position:fixed

You also add

left:8px; // to push it 8px from the left because of the default margins on the body
width:calc(100% - 48px);

Why 48x ?

left padding (16p) + right padding(16px) + left body margin(8px) + right body margin(8px) = 48px

Why left body margin ? didn't we use left:8px to deal with it ?

Yes we did and by pushing it we simply added it the other end.