Skip to content

Instantly share code, notes, and snippets.

@linuz90
Created November 4, 2025 14:23
Show Gist options
  • Select an option

  • Save linuz90/c5d095c4012beed1461781edc1f59db9 to your computer and use it in GitHub Desktop.

Select an option

Save linuz90/c5d095c4012beed1461781edc1f59db9 to your computer and use it in GitHub Desktop.
Tailwind Scroll Masking Utils
/* ----------------------------- Scroll Masking ----------------------------- */
/* Custom properties for scroll-driven mask animations */
@property --mask-up-fade {
syntax: "<length>";
inherits: false;
initial-value: 0;
}
@property --mask-down-fade {
syntax: "<length>";
inherits: false;
initial-value: 0;
}
@property --mask-left-fade {
syntax: "<length>";
inherits: false;
initial-value: 0;
}
@property --mask-right-fade {
syntax: "<length>";
inherits: false;
initial-value: 0;
}
/* Keyframes for vertical scroll masking */
@keyframes mask-vertical-scroll {
0% {
--mask-up-fade: 0;
}
10%,
100% {
--mask-up-fade: var(--mask-fade-distance, 1rem);
}
0%,
90% {
--mask-down-fade: var(--mask-fade-distance, 1rem);
}
100% {
--mask-down-fade: 0;
}
}
/* Keyframes for horizontal scroll masking */
@keyframes mask-horizontal-scroll {
0% {
--mask-left-fade: 0;
}
10%,
100% {
--mask-left-fade: var(--mask-fade-distance, 1rem);
}
0%,
90% {
--mask-right-fade: var(--mask-fade-distance, 1rem);
}
100% {
--mask-right-fade: 0;
}
}
/* Scroll mask utilities with progressive enhancement */
@utility scroll-mask-up {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: 1rem;
mask-image: linear-gradient(to bottom, transparent, black var(--mask-up-fade, 1rem), black);
animation: mask-vertical-scroll linear;
animation-timeline: scroll(self block);
}
}
}
@utility scroll-mask-up-* {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: --value([ *]);
mask-image: linear-gradient(to bottom, transparent, black var(--mask-up-fade, --value([ *])), black);
animation: mask-vertical-scroll linear;
animation-timeline: scroll(self block);
}
}
}
@utility scroll-mask-down {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: 1rem;
mask-image: linear-gradient(to top, transparent, black var(--mask-down-fade, 1rem), black);
animation: mask-vertical-scroll linear;
animation-timeline: scroll(self block);
}
}
}
@utility scroll-mask-down-* {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: --value([ *]);
mask-image: linear-gradient(to top, transparent, black var(--mask-down-fade, --value([ *])), black);
animation: mask-vertical-scroll linear;
animation-timeline: scroll(self block);
}
}
}
@utility scroll-mask-vertical {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: 1rem;
mask-image: linear-gradient(
to bottom,
transparent,
black var(--mask-up-fade, 1rem),
black calc(100% - var(--mask-down-fade, 1rem)),
transparent
);
animation: mask-vertical-scroll linear;
animation-timeline: scroll(self block);
}
}
}
@utility scroll-mask-vertical-* {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: --value([ *]);
mask-image: linear-gradient(
to bottom,
transparent,
black var(--mask-up-fade, --value([ *])),
black calc(100% - var(--mask-down-fade, --value([ *]))),
transparent
);
animation: mask-vertical-scroll linear;
animation-timeline: scroll(self block);
}
}
}
@utility scroll-mask-left {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: 1rem;
mask-image: linear-gradient(to right, transparent, black var(--mask-left-fade, 1rem), black);
animation: mask-horizontal-scroll linear;
animation-timeline: scroll(self inline);
}
}
}
@utility scroll-mask-left-* {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: --value([ *]);
mask-image: linear-gradient(to right, transparent, black var(--mask-left-fade, --value([ *])), black);
animation: mask-horizontal-scroll linear;
animation-timeline: scroll(self inline);
}
}
}
@utility scroll-mask-right {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: 1rem;
mask-image: linear-gradient(to left, transparent, black var(--mask-right-fade, 1rem), black);
animation: mask-horizontal-scroll linear;
animation-timeline: scroll(self inline);
}
}
}
@utility scroll-mask-right-* {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: --value([ *]);
mask-image: linear-gradient(to left, transparent, black var(--mask-right-fade, --value([ *])), black);
animation: mask-horizontal-scroll linear;
animation-timeline: scroll(self inline);
}
}
}
@utility scroll-mask-horizontal {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: 1rem;
mask-image: linear-gradient(
to right,
transparent,
black var(--mask-left-fade, 1rem),
black calc(100% - var(--mask-right-fade, 1rem)),
transparent
);
animation: mask-horizontal-scroll linear;
animation-timeline: scroll(self inline);
}
}
}
@utility scroll-mask-horizontal-* {
@media (prefers-reduced-motion: no-preference) {
@supports (animation-timeline: scroll()) {
--mask-fade-distance: --value([ *]);
mask-image: linear-gradient(
to right,
transparent,
black var(--mask-left-fade, --value([ *])),
black calc(100% - var(--mask-right-fade, --value([ *]))),
transparent
);
animation: mask-horizontal-scroll linear;
animation-timeline: scroll(self inline);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment