导航栏下滑隐藏上滑显现,我用了八年 JS,今天 CSS 自己会判断滚动方向了——scroll-state(scrolled) 把我那个滚动事件全删了

这个需求你肯定写过:导航栏往下滑就藏起来,往上滚就让它出现。以前要监听 scroll 事件、记录上次滚动位置、算差值判断方向,一套下来大几十行 JS,还时不时在快速滚动时判断错。

Chrome 144 推出的 scroll-state(scrolled) 把这件事彻底原生化了。

原理很简单:给滚动容器加一个 container-type: scroll-state,然后用 @container 查询最后一次滚动的方向。浏览器自己记录方向,CSS 直接读。

/* 1. 父容器开启滚动状态查询 */
html {
  container-type: scroll-state;
  overflow-y: auto;
  height: 100vh;
}

/* 2. 导航栏:向下滚时藏起来 */
nav {
  position: fixed;
  top: 0;
  transition: transform 0.3s ease;
}

/* 3. 向下滚 50px,导航栏往上滑出 */
nav {
  @container scroll-state(scrolled: bottom) {
    transform: translateY(-100%);
  }
}

/* 4. 往上滚一点,导航栏滑回来 */
nav {
  @container scroll-state(scrolled: top) {
    transform: translateY(0);
  }
}

超过阈值才触发,这是关键。以前用 JS 算差值,阈值控制要自己写;现在 scrolled 支持 top / right / bottom / left 四个方向值,还可以用 x / y 的逻辑方向。

/* 阈值控制:滚动超过 50px 才触发 */
nav {
  @container scroll-state(scrolled: bottom) {
    transform: translateY(-100%);
  }
}

/* 也可以用逻辑方向,和书写模式无关 */
nav {
  @container scroll-state(scrolled: block-end) {
    transform: translateY(-100%);
  }
}

不只方向——四种滚动状态全包了

scrolled 只是 Chrome 144 新增的一个值。scroll-state() 这个容器查询家族从 Chrome 133 就有了,另外三个早就能用了:

stuck:元素被边缘粘住时的状态

这是 sticky 定位的 CSS 查询接口。以前想知道一个元素当前是否处于粘附状态,只能靠 JS 拿 getBoundingClientRect 算。现在直接读:

.banner {
  @container scroll-state(stuck: top) {
    /* 粘在顶部时的样式 */
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  }
}

snapped:滚动吸附完成后的状态

轮播图场景最常用。以前想知道当前显示的是哪一张,要自己维护状态;现在 CSS 自己知道:

.carousel-item {
  @container scroll-state(snapped: block) {
    /* 这张卡片是当前显示的那一张 */
    opacity: 1;
    transform: scale(1);
  }
}

scrollable:内容溢出的状态

可以用来判断这个容器是否值得显示滚动条:

.panel {
  @container scroll-state(scrollable: block) {
    /* 有溢出内容,可以显示滚动条 */
    scrollbar-gutter: auto;
  }
}

浏览器兼容性:Chrome 133+ 支持 stuck / snapped / scrollable,Chrome 144 追加 scrolled。Firefox 和 Safari 还没上。生产环境用之前记得查一下 caniuse,不过用在内部工具或者移动端 Web 场景,Chrome 独占也完全没问题。

以前这套交互要 60 行 JS 才能写清楚,现在 20 行 CSS,而且逻辑全部内聚在样式文件里,不用再维护一个独立的状态管理模块。下一个项目里,这种「监听滚动方向」的需求,直接上 scroll-state() 就完事了。

评论区

0 条评论

登录后可评论。

小鹿·界面实验室 660 阅读