與容器查詢類似,但適用於卡住、固定和溢出的查詢。
發布日期:2025 年 1 月 15 日
Chrome 133 引進捲動狀態容器查詢,以此建構容器查詢。瀏覽器管理的固定位置、捲動對齊點和可捲動元素狀態,現在可透過 CSS 查詢及調整。
總覽
在捲動狀態查詢之前,您必須使用 JavaScript 瞭解元素是否卡住、固定或可捲動。標準版現在提供效能更佳的方法,可用來瞭解這項資訊並做出相應調整。我們也推出了新的動畫觸發方式,讓您可以透過 CSS 觸發捲動動畫。
以下簡要說明 Chrome 133 提供的狀態查詢:
好消息是,您從容器查詢中學到的所有知識,都將有助於您使用捲動狀態查詢。
捲動驅動動畫和捲動狀態容器查詢之間也有未知的領域,我們需要嘗試使用時間和情境,找出捲動驅動動畫或捲動觸發捲動狀態動畫的最佳方式。以下影片和示範說明瞭這個問題:固定觸發動畫與捲動驅動動畫的比較。
第一個捲動狀態查詢
第一步是使用 container-type
屬性的新值定義容器。如同容器查詢,您要查詢的元素是您提供 container-type
的元素,以及選用的 container-name
。使用捲動狀態查詢時,您可以為已對齊、卡住或溢出的元素提供 container-type: scroll-state
。
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
}
第二步是選取會回應狀態的容器子項,因為容器查詢中,這個元素不能包含 container-type
。
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
第三步:試用這項功能。以下 CSS 範例會在 .stuck-top
元素停留在 0
頂端時,將背景設為紅色。只要在已編寫的 CSS 中加入幾行程式碼,以及一個用於代理瀏覽器狀態的額外容器元素,元件就能更聰明地處理周遭環境。
漸進式增強
@supports
at-rule 和巢狀結構可讓您只需新增幾行程式碼,即可新增漸進式增強或條件式功能用法:
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
@supports (container-type: scroll-state) {
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
}
此外,如果您使用捲動狀態查詢來為網頁周圍的元素製作動畫,請務必在動作周圍使用 @media (prefers-reduced-motion: no-preference) {}
。
應用實例
停滯
或許這個部分應該稱為「棘手情況」?這是一小組黏性狀態用途,以及需要建構的額外構想。
@container scroll-state(stuck: top) {}
@container scroll-state(stuck: bottom) {}
在卡住時加入陰影
卡住的查詢最常見的用途之一,就是在導覽列卡住時新增 box-shadow
,讓導覽列浮在疊加的內容上方。
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
transition: box-shadow .3s ease;
@container scroll-state(stuck: top) {
box-shadow: var(--shadow-5);
}
}
}
啟用目前的卡住標頭
另一個常見的 UI 意見回饋情境是強調目前卡住的元素。在以字母排序的頻道清單中,這項功能可以提供實用且有助於提升使用體驗的功能。
.sticky-slide {
dt {
container-type: scroll-state;
position: sticky;
inset-block-start: 0;
inset-inline: 0;
> header {
transition:
background .3s ease,
box-shadow .5s ease;
@container scroll-state(stuck: top) {
background: hsl(265 100% 27%);
box-shadow: 0 5px 5px #0003;
}
}
}
}
以下是另一種變化版本,其中標題會顯示在清單項目旁邊。無限可能!
意見交流
以下列出一些黏滯式示範,或許能激發您運用捲動狀態查詢為示範增添一點趣味,或移除 JavaScript。建議您嘗試建構自己喜歡的內容,這樣有助於您記住語法和概念 😏?。
- https://codepen.io/BlogFire/pen/PoGMjaX - 便利貼變化版本
- https://codepen.io/mikegolus/pen/jOZzRzw - 在表格卡住時為其加入陰影
- https://codepen.io/MarcRay/pen/PomBeP - 觸發時顯示在標題下方的水平導覽列
- https://codepen.io/kevinpowell/pen/OqKJjK - 底部導覽列顯示
- https://codepen.io/abhisekz-the-decoder/pen/eKaLRd - 固定資訊卡標題
- https://codepen.io/tutsplus/pen/abojPjP - 觸發事件上的價格標頭陰影
- https://codepen.io/kevinpowell/pen/KEjMEv - 固定的版面區側欄標題
比對成功
透過固定狀態查詢,我們可以移除 JavaScript 和 Snap 事件的部分責任,並將處理工作移至 CSS。
@container scroll-state(snapped: x) {}
@container scroll-state(snapped: y) {}
@container scroll-state(snapped: inline) {}
@container scroll-state(snapped: block) {}
提醒您,如果您略過「第一個捲動狀態查詢」一節,請注意,用於貼齊查詢的容器是含有 scroll-snap-align
的元素,而可調整的元素必須是該元素的子項。也就是說,您需要設定三個元素:
a scroll container with `scroll-snap-type`
⤷ a snap target with both `scroll-snap-align` and `container-type: scroll-state`
⤷ a child of the snap target that can query the container for snap state
視覺上強化已固定的項目
在中心固定捲軸中,常見的做法是醒目顯示或突顯中心固定項目。在這個推薦評價範例中,我們使用了 not
關鍵字,因此所有未固定的推薦評價都會顯示低不透明度,而固定的推薦評價則會維持自然的呈現狀態。
.demo {
overflow: auto hidden;
scroll-snap-type: x mandatory;
> article {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
> * {
transition: opacity .5s ease;
@container not scroll-state(snapped: x) {
opacity: .25;
}
}
}
}
}
顯示已固定項目的標題
這是一個很好的範例,說明如何透過捲動狀態查詢啟用捲動觸發動畫。這也是在 CSS 中尊重減少動畫效果的價值所在。
.demo {
overflow-x: auto;
scroll-behavior-x: contain;
scroll-snap-type: x mandatory;
> .card {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
figcaption {
transform: translateY(100%);
@container scroll-state(snapped: x) {
transform: translateY(0);
}
}
}
}
}
}
在投影片元素中加入動畫
在演講時,動畫投影片或簡報元素是很常見的做法。過去,為此編寫交集觀察器相當麻煩,因為這麼做只會在投影片上設定一個類別。我們現在不需要任何 JavaScript。
html {
scroll-snap-type: y mandatory;
}
section {
container-type: scroll-state;
scroll-snap-align: start;
scroll-snap-stop: always;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
> h1 {
transition: opacity .5s ease, transform .5s var(--ease-spring-3);
transition-delay: .5s;
opacity: 0;
transform: scale(1.25);
@container scroll-state(snapped: block) {
opacity: 1;
transform: scale(1);
}
}
}
}
}
您可能會發現,所有已固定的 CSS 狀態查詢都會像 scrollsnapchanging
一樣運作,而非 scrollsnapchange
。這樣一來,您就能盡早提供固定元素的視覺回饋。如果太過積極,建議您改用 JavaScript 事件。
可捲動
當捲動區域可實際捲動時,捲動狀態查詢會非常實用,可顯示視覺提示。在推出捲動狀態查詢之前,這項資訊很難掌握。
@container scroll-state(scrollable: top) {}
@container scroll-state(scrollable: right) {}
@container scroll-state(scrollable: bottom) {}
@container scroll-state(scrollable: left) {}
使用陰影表示捲動
Lea Verou 曾經介紹過一項 CSS 技巧,使用 background-attachment: local
就能達到類似的效果,也可以透過捲動驅動動畫實現這項效果。每種技術都有取捨,我們需要探索每種技術最適合的使用時機和地點。
以下範例使用單一橫跨捲動區的黏滯元素。當上下兩個漸層都套用內容相關捲動狀態查詢 @container scroll-state(scrollable: top)
時,頂端漸層和底部漸層的透明度會以 @property
進行動畫效果:@container scroll-state(scrollable: top)
。
請注意,這是第一個同時具備 size
和 scroll-state
容器的容器。
.scroll-container {
container-type: scroll-state size;
overflow: auto;
&::after {
content: " ";
background: var(--_shadow-top), var(--_shadow-bottom);
transition:
--_scroll-shadow-color-1-opacity .5s ease,
--_scroll-shadow-color-2-opacity .5s ease;
@container scroll-state(scrollable: top) {
--_scroll-shadow-color-1-opacity: var(--_shadow-color-opacity, 25%);
}
@container scroll-state(scrollable: bottom) {
--_scroll-shadow-color-2-opacity: var(--_shadow-color-opacity, 25%);
}
}
}
箭頭提示
有時顯示箭頭有助於使用者發現某個區域可捲動。這些元素通常會指向捲動方向,並在不再需要時消失。您可以使用下列程式碼執行這項操作。
@container scroll-state((scrollable: top) or (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
}
@container scroll-state((scrollable: top) and (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
rotate: .5turn;
}
返回頁首
另一個常見的捲動狀態互動是「捲動至頂端」便利按鈕。下列程式碼會在沒有向上捲動的情況下,讓「捲動至頂端」按鈕消失。
這個解決方案有點反向,但可讓您減少 CSS 的用量。按鈕的自然停留位置是在檢視畫面中,因此您需要在沒有向上捲動的情況下,指示按鈕隱藏。
@container not scroll-state(scrollable: top) {
translate: 0 calc(100% + 10px);
}
持續研究
如需更多資訊,請參考以下幾項資源,從規格詳細資料到其他相關文章都有:
- 我們還能對哪些項目進行容器查詢?https://github.com/w3c/csswg-drafts/issues/5989
- scroll-state() 說明 - https://drafts.csswg.org/css-conditional-5/scroll_state_explainer.md
- scroll-state() CSS 規格 - https://www.w3.org/TR/css-conditional-5/#scroll-state-container
- 在 HTML 事件迴圈中快照版面配置
- 關於狀態查詢的 Podcast 節目 - https://nerdy.dev/the-css-podcast-on-state-queries
- 更多文章