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>
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.
This may not be a complete answer because it doesn't answer to the question "why?".
However, if you remove the scroll-padding-top: 48px
from the html style, and add scroll-margin-top
on the target anchor point you will get the expected result.
#anchor-point{
scroll-margin-top: 48px;
}
It's also possible to avoid using the id selector, with the :target
pseudo-class selector
:target {
scroll-margin-top: 48px;
}