Search code examples
javascriptcssoverflowsticky

If overflow is set to hidden/scroll in html and body, sticky navbar doesn't work, otherwise, html/body is not filling the screen


I am building an website with nextJs framework and I have the following issue: my navbar is set to be sticky because I have a cover upon it that I want to be hidden when the user scrolls. But my html/body is acting strange and is not filling up the whole screen when overflow-x is not set to be hidden:

As you can see, there's a white-space in the right side of the screen, causing the cover and the images in the page not to be 100% width... (This is when html and body's overflow-x is set to unset/visible/revert/initial, and like this, the navbar is sticky as it should)

Image example...

On the other hand, when I set html and body's overflow-x to be hidden, auto, scroll or overlay, the body then fills up the entire screen, but the navbar doesn't stick to the page at scrolling anymore.

I would appreaciate some explaining on this issue because CSS sometimes seems so difficult to me and I fix things but do not really understand why they got fixed. For example, I don't understand why sometimes theres white-space on right side of the body, and sometimes not, what makes this happen? Also, the sticky bar is very useful, but is so buggy, should I use javascript to make it stick instead or stay with css?

Thanks for the attention.

Some css code, it might show what I'm doing wrong:

In the header:

.cover {
    background-color: black;
    position: relative;
    margin: auto;
    width: 100%;
    height: 120px;
}

.menu {
    display: inline-flex;
    flex-flow: row nowrap;
    justify-content: space-evenly;
    width: 100%;
  
    position: sticky;
    top: 0;
    z-index: 1;
    
    color: white;
    background-color: black;
  
    padding: 10px;
    font-size: 1.5rem;
}

In main:

.grid { //Is also the container
    display: grid;
    grid-template-columns: 2fr 2fr;
    margin: auto;
    max-width: 1200px;
  }

  .grid-image {
    position: relative;
    height: 400px;
    padding: 5px;
  }

  .grid-image img {
    object-fit: cover;
  }

  .grid-text {
    padding: 2em;
    font-size: 1.3rem;
    letter-spacing: 0.15rem;
    color: white;
  }

  .grid-title {
    color: var(--primary-red);
    font-size: 3rem;
  
    letter-spacing: 0.15rem;
    text-transform: uppercase;
    text-align: left;
  }
  
  @media only screen and (max-width: 1200px){
    .grid {
      grid-template-columns: 1fr;
      max-width: 800px;
    }

    .grid, .grid-title {
      text-align: center;
    } 

    .grid-item-3 { order: 1 }
  }

  @media only screen and (max-width: 600px){
    .rescue-button {
      display: inline-flex;
      flex-wrap: nowrap;
      justify-content: center;
      position: fixed;
      width: 80%;

      bottom: 50px;
      left: 0;
      right: 0;
      margin: auto;
      padding: .5em .8em;

      color: white;
      background-color: green;
      border-radius: 10px;
      opacity: 90%;

      animation: fade-in 3s;
    }
    .rescue-button-whatsapp-icon {
      position: absolute;
      bottom: .4em;
      left: 20px;
      width: 2rem;
    }
  }

  @keyframes fade-in {
    0% {
      opacity: 0%;
    }
    100% {
      opacity: 95%;
    }
  }

Solution

  • There are some best practices out there that will help you in this situation.

    Setup the document to take up the whole screen regardless of the content. And make sure images will never overflow the page.

    html {
        height: 100%;
    }
    body {
        min-height: 100%;
    }
    img {
        max-width: 100%;
    }
    

    To explain the box-sizing, setting it on an element like the navbar will cause that element to be border-box

    Setting it on html and body have no effect because they shouldn’t grow past the bounds of the screen.

    The current best practice is to set box-sizing like this:

    html {
        box-sizing: border-box;
    }
    *, *::before, *::after {
        box-sizing: inherit;
    }