Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sticky header input scrolls on input

Tags:

html

css

I have a sticky header with a search input. To ensure anchor tags (<a href='#section'>) doesn't hide the contents behind the top of the header, I added the following CSS.

html {
    scroll-padding-top: 48px
}

However, if the sticky header includes an input, the entire page will scroll when a user types into the input.

Is there a way to preserve the current scroll-padding behavior and prevent the auto-scrolling in when using the input? Preferably with HTML and CSS only.

html {
  scroll-padding-top: 48px;
}

body {
  margin: 0;
}

header {
  position: sticky;
  top: 0;
  background: #eeeeee;
  padding: 8px 16px;
}

main {
  padding: 8px 16px;
}

main article,
main div {
  padding: 32px 0;
  border-bottom: 1px solid lightgray;
}

main div {
  background: #ddddff;
}
<html>

<body>
  <header>
    <input type='text' placeholder='type here, page scrolls' />
  </header>
  <main>
    <article>
      <p><a href='#anchor-point'>click me to skip down to the lower section</a></p>
    </article>
    <article>
      <p>some useless text just to fill up vertical space and allow for scrolling</p>
    </article>
    <article>
      <p>some useless text just to fill up vertical space and allow for scrolling</p>
    </article>
    <div id='anchor-point'>
      I also want to link to here. This section should not get cut off by the sticky header. The entire thing should be visible.
    </div>
    <article>
      <p>some useless text just to fill up vertical space and allow for scrolling</p>
    </article>
    <article>
      <p>some useless text just to fill up vertical space and allow for scrolling</p>
    </article>
    <article>
      <p>some useless text just to fill up vertical space and allow for scrolling</p>
    </article>
  </main>
</body>

</html>

Related post

Editing a sticky input element in Chrome causes the page to scroll to the top — solutions use JS to intercept the input. I'd rather not use JS in this case if possible. Furthermore, the original bug described in that post seems to be fixed.

like image 629
Nick Avatar asked Jan 28 '21 00:01

Nick


1 Answers

The problem is being caused by a combination of causes:

In the first place because if the content of input is changed outside of the current viewing page, by default the web browser will scroll to that input.

And in second place because by adding the property scroll-padding-top: 48px to the HTML tag you are kinda 'reducing' the size of the available visible page.

So for the combination of these two reasons is like your input is always just some pixels adobe the current viewing page, so the browser scrolls up a little bit to make it 'visible' (and that are the jumps that we can see when we write or delete anything in the input).

You can try the following:

    html {
      /* scroll-padding-top: -48px; */
    }
    
    body {
      margin: 0;
    }
    
    header {
      position: sticky;
      top: 0;
      background: #eeeeee;
      padding: 8px 16px;
    }
    
    main {
      padding: 8px 16px;
    }
    
    main article,
    main div {
      padding: 32px 0;
      border-bottom: 1px solid lightgray;
    }
    
    main div {
      background: #ddddff;
    }

    #anchor-point {
        background: none;
        z-index: -1;
        position: relative;
        padding: 0;
        height: 48px;
        margin-top: -48px;
    }
    <html>
    
    <body>
      <header>
        <input type='text' placeholder='type here, page scrolls' />
      </header>
      <main>
        <article>
          <p><a href='#anchor-point'>click me to skip down to the lower section</a></p>
        </article>
        <article>
          <p>some useless text just to fill up vertical space and allow for scrolling</p>
        </article>
        <article>
          <p>some useless text just to fill up vertical space and allow for scrolling</p>
        </article>
        <div id="anchor-point"></div>
        <div>
          I also want to link to here. This section should not get cut off by the sticky header. The entire thing should be visible.
        </div>
        <article>
          <p>some useless text just to fill up vertical space and allow for scrolling</p>
        </article>
        <article>
          <p>some useless text just to fill up vertical space and allow for scrolling</p>
        </article>
        <article>
          <p>some useless text just to fill up vertical space and allow for scrolling</p>
        </article>
      </main>
    </body>
    
    </html>

I hope it works for you!

like image 92
maurogandulfo Avatar answered Oct 20 '22 17:10

maurogandulfo