fix(parallax): drive --parallax-pos via CSS scroll animation to kill SSR/hydration position pop
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
@property --parallax-pos {
|
||||
syntax: '<percentage>';
|
||||
inherits: true;
|
||||
initial-value: 0%;
|
||||
}
|
||||
|
||||
.parallax-window {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@@ -37,6 +43,39 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cascade interaction for --parallax-pos:
|
||||
*
|
||||
* Before WASM (SSR / hydration):
|
||||
* @property initial-value: 0%
|
||||
* → CSS animation (view timeline) overrides → correct position from scroll
|
||||
*
|
||||
* After WASM (JS running):
|
||||
* JS element.style.setProperty('--parallax-pos', ...) [inline style]
|
||||
* → inline style beats animation → JS takes over seamlessly
|
||||
*
|
||||
* prefers-reduced-motion:
|
||||
* animation: none → @property initial-value 0% used → static image
|
||||
* JS also skips scroll listener
|
||||
*/
|
||||
@supports (animation-timeline: view()) {
|
||||
@keyframes parallax-pan {
|
||||
from { --parallax-pos: var(--parallax-from, 0%); }
|
||||
to { --parallax-pos: var(--parallax-to, 0%); }
|
||||
}
|
||||
|
||||
.parallax-window {
|
||||
animation: parallax-pan linear both;
|
||||
animation-timeline: view();
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.parallax-window {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.parallax-window {
|
||||
--parallax-pos: 0%;
|
||||
|
||||
Reference in New Issue
Block a user