【问题标题】:Scroll snap css property with overflow y is causing page scroll带有溢出 y 的滚动快照 css 属性导致页面滚动
【发布时间】:2018-07-13 04:16:45
【问题描述】:

我正在使用 css 属性 scroll-snap-type 来让溢出的 div 快照的内容放置在滚动条上。

很容易应用:

.container {
  height: 400px;
  overflow-y: scroll;
  scroll-snap-type: mandatory;
}

.contents {
  scroll-snap-align: start;
}

桌面版 Safari 11+ 中查看此页面以获取示例 - https://codepen.io/fionnbharra/full/PQZmav/ 滚动页面左侧的 div。请注意,当滚动完成时,div 是如何与容器顶部对齐的。这是按预期运行的。

我的问题是当我们有一个长页面时它会中断 - https://codepen.io/fionnbharra/full/oEbWeq/

尝试滚动相同的溢出 div。请注意页面正文如何同时滚动,这意味着很难看到原始内容滚动。

这是一个错误吗?我做错了吗?

【问题讨论】:

    标签: css safari


    【解决方案1】:

    这是实验性技术,仅部分支持。 Chrome 现在不支持它(2018-02-07)。 https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type

    您现在应该使用其他样式。 scroll-snap 系列可以用相对定位的附加容器替换。

    https://caniuse.com/#feat=css-snappoints

    浏览器通常不实现它或部分实现它。使用其他 CSS 样式。

    顺便说一句。如果您想确保正确支持该样式,请使用 caniuse.com。

    【讨论】:

    • 感谢您的回答,我知道浏览器支持。我是在专门询问 Safari。可悲的是,看起来即使在那里它的实施也很糟糕。
    • 是的,实验性技术是实验性的。不要使用实验性技术和制作跨浏览器网站。作为最后的排序:您可以使用 JS 来获得所需的效果,但如果它不是“候选推荐”或推荐或生活标准,请不要使用 DHTML。您可以先使用 MDN。如果有可见的“烧瓶” - 这意味着实验。以下是实验技术的副作用(主要由 Safari/Chrome 创建):github.com/w3c/csswg-drafts/issues/2156。没有人知道在这种情况下该怎么做。
    【解决方案2】:

    看起来 Safari 就是这样做的,当它捕捉 div 时,它将滚动事件向上传播,导致整个窗口滚动,但考虑到这是一项实验性技术,我并不感到惊讶。解决此问题的一种方法是在我们使用 JavaScript 滚动时将 html 元素的 overflow 设置为 hidden,并在完成后将其重置:

    const container = document.getElementsByClassName('container')[0];
    const html = document.documentElement;
    
    let scrollTimer = -1;
    let locked = false;
    
    function lock() {
      if (!locked) {
        locked = true;
        html.style.overflow = 'hidden';
      }
    }
    
    function unlock() {
      if (locked) {
        locked = false;
        html.style.overflow = '';
      }
    }
    
    container.addEventListener('scroll', () => {
      if (scrollTimer !== -1) {
        clearTimeout(scrollTimer);
      }
    
      if (container.scrollTop <= 0 ||
          container.scrollTop >= container.scrollHeight - container.offsetHeight) {
        // if scrollbar reaches top or bottom, unlock
        unlock();
      } else {
        lock();
        // defer unlocking scroll
        scrollTimer = setTimeout(unlock, 150); // consider 150ms of inactivity to be the end of a scroll
      }
    }, false);
    main {
      background: #D7FCD4;
      display: flex;
    }
    
    .container {
      height: 400px;
      flex: 1;
      overflow-y: scroll;
      scroll-snap-type: mandatory;
    }
    
    .contents {
      display: block;
      height: 100px;
      margin-bottom: 10px;
      width: 100%;
      scroll-snap-align: start;
    }
    
    .contents:nth-child(even) {background: #B68F40}
    .contents:nth-child(odd) {background: #545454}
    
    .more-stuff {
      background: linear-gradient(#30011E, #fff);
      border-left: 10px solid white;
      display: block;
      height: 2000px;
      flex: 1;
    }
    <main>
    
    <div class="container">
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
      <div class="contents"></div>
    </div>
    
    <div class="more-stuff">
     </div>
      
    </main>

    由于目前大多数浏览器不支持此功能,因此您现在希望在生产环境中使用基于 JavaScript 的解决方案。

    【讨论】:

      猜你喜欢
      • 2019-09-15
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 2011-09-19
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多