CSS滚动对齐,垂直不工作

uubf1zoe  于 2022-12-15  发布在  其他
关注(0)|答案(3)|浏览(142)

我使用this article作为参考点,特别是this working snippet,但是在我的页面(下面的脚本)中垂直对齐滚动不起作用,为什么?

.parent {
  height: 100vh;
  scroll-snap-type: mandatory;
  scroll-snap-points-y: repeat(100vh);
  scroll-snap-type: y mandatory;
}

section {
  height: 100vh;
  scroll-snap-align: start;
  position: relative;
}

.one {
  background-color: red;
}

.two {
  background-color: blue;
}

.three {
  background-color: grey;
}

.four {
  background-color: green;
}
<div class="parent row">
  <section class="one">
  </section>
  <section class="two">
  </section>
  <section class="three">
  </section>
  <section class="four">
  </section>
</div>
ijnw1ujt

ijnw1ujt1#

代码片段中的主要问题是显示的滚动条属于主体,主体中没有定义scroll-snap属性,这就是滚动时没有任何对齐行为的原因。
要实现预期结果,您需要
1.确保显示的滚动条属于父 div
1.将overflow对父容器的行为定义为scroll
下面是一个工作示例
需要注意的是,捕捉属性(适用于Chrome)已经发生了变化,并且您正在使用弃用的功能。
还要注意的是,这个答案只涉及Chrome,没有polyfill部分,这里涉及的只是主滚动条的概念。

html,
body {
  height: 100vh;
  overflow: hidden;
}

.parent {
  overflow: scroll;
  height: 100vh;
  scroll-snap-points-y: repeat(100vh);
  scroll-snap-type: y mandatory;
}

section {
  height: 100vh;
  scroll-snap-align: start;
  position: relative;
}

.one {
  background-color: red;
}

.two {
  background-color: blue;
}

.three {
  background-color: grey;
}

.four {
  background-color: green;
}
<div class="parent row">
  <section class="one"></section>
  <section class="two"></section>
  <section class="three"></section>
  <section class="four"></section>
</div>
8qgya5xd

8qgya5xd2#

最初的答案是将overflow: hidden直接放在htmlbody元素上,这会把很多事情搞砸,即使用position: sticky的头部,这是一个非常常见的概念。
另一种方法是将scroll-snap-type属性放在主体上,然后将scroll-snap-align属性放在需要滚动对齐行为的元素上。

body, html {
  scroll-snap-type: proximity;
  scroll-snap-points-y: repeat(100vh);
  scroll-snap-type: y proximity;
}

section {
  height: 100vh;
}

.row section {
  scroll-snap-align: start;
}

.one {
  background-color: red;
}

.two {
  background-color: blue;
}

.three {
  background-color: grey;
}

.four {
  background-color: green;
}
<div class="row">
  <section class="one">
  </section>
  <section class="two">
  </section>
  <section class="three">
  </section>
  <section class="four">
  </section>
</div>
<section>
  <h2>This will not have sticky</h2>
</section>
lp0sw83n

lp0sw83n3#

下面是我目前最好的尝试,使用JavaScript来解决前面评论中提到的Chrome bug。全屏运行它。我想在浏览器中滚动永远不会像在文件管理器中那样流畅。这就是生活。

let adjusted = false

function snapscroll(event) {
    let snappable = null; {
        let hovered = document.elementsFromPoint(event.clientX, event.clientY)
        for (elem of hovered) {
            if (elem.classList.contains('snapme')) {
                snappable = elem
                break
            }
        }
    }

    let prev = null
    let next = null
    if (snappable !== null) {
        prev = snappable.previousElementSibling; if (prev !== null && !prev.classList.contains('snapme')) {prev = null}
        next = snappable.nextElementSibling; if (next !== null && !next.classList.contains('snapme')) {next = null}
    }

    if (event.deltaY > 0) {
        if (next === null) {
            snappable = null
            adjusted = false
        } else {
            if (adjusted) {
                snappable = next
            }
        }
    } else {
        if (prev === null) {
            snappable = null
            adjusted = false
        } else {
            if (adjusted) {
                snappable = prev
            }
        }
    }

    if (snappable !== null) {
        snappable.scrollIntoView({behavior: "smooth"})
        adjusted = true
        event.preventDefault()
        event.stopPropagation()
    }
}

let doit
document.addEventListener('wheel', function(event) {
    clearTimeout(doit)
    doit = setTimeout(() => snapscroll(event), 25)
})
body {padding:1em;}
section { height: 100vh; }
.snapme {cursor:move;}
.one { background-color: red; }
.two { background-color: blue; }
.three { background-color: grey; }
.four { background-color: green; }
<section>
    <h2>No snapping here</h2>
</section>

<section class='snapme one'></section>
<section class='snapme two'></section>
<section class='snapme three'></section>
<section class='snapme four'></section>

<section>
    <h2>No snapping here</h2>
</section>

相关问题