固定头部输入框随着输入滚动

12

我有一个带搜索输入框的固定头部。为了确保锚标签 (<a href='#section'>) 不会被头部遮挡,我添加了以下 CSS。

html {
    scroll-padding-top: 48px
}

然而,如果置顶的标题栏中包含输入框,用户在输入时整个页面都会滚动。

是否有一种方法可以保持当前的滚动填充行为并在使用输入框时防止自动滚动?最好只使用HTML和CSS实现。

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>

相关文章

在Chrome中编辑粘性输入元素会导致页面滚动到顶部 - 解决方案使用JS拦截输入。如果可能的话,我不想在这种情况下使用JS。此外,该文章中描述的原始错误似乎已经得到修复。

3个回答

4

这可能不是一个完整的答案,因为它没有回答“为什么”的问题。

然而,如果你从html样式中删除scroll-padding-top: 48px,并在目标锚点上添加scroll-margin-top,你将得到预期的结果。

#anchor-point{
 scroll-margin-top: 48px;
}

还有一种避免使用id选择器的方法,就是使用:target伪类选择器。

:target {
 scroll-margin-top: 48px;
}

自我记录:只有当“header”的“top”值设置为<= 36px时,页面才会滚动; - lastr2d2
使用:target伪选择器真是太聪明了!这意味着它适用于您滚动到的每个单独元素,而不仅仅是由特定类或ID定义的那些元素。 - Nick
1
这太奇怪了!对我来说解决方案是将 scroll-padding-top 切换为 scroll-margin-top。谢谢! - Lionel T

3
问题的原因是由多个因素共同造成的:
首先,如果输入内容在当前查看页面之外被更改,默认情况下,Web浏览器将滚动到该输入位置。
其次,通过向HTML标签添加scroll-padding-top: 48px属性,您可以“减少”可见页面的大小。
因此,由于这两个原因的组合,就好像您的输入始终只是在当前查看页面的一些像素之后,因此浏览器会向上滚动一小部分以使其“可见”(这就是我们在输入时写入或删除任何内容所能看到的跳跃)。
您可以尝试以下操作:

    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>

希望对你有用!


2

我认为scroll-margin-top应该放到#anchor-point中。

html {
    scroll-behavior: smooth;
}
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 {
    scroll-margin-top: 48px;
}
<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>

在我的情况下,它运行良好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接