CSS Media Query
Responsive
CSS
- Between two screen sizes
<style>
@media screen and (min-width: 992px) and (max-width: 1200px) {
body { background-color: red; }
}
</style>- Desktop only
<style>
@media screen and (min-width: 992px) {
body { background-color: red; }
}
</style>- Tablet & below only
<style>
@media screen and (max-width: 991px) {
body { background-color: red; }
}
</style>- Non-touch devices only
<style>
@media (pointer: fine) {
body { background-color: red; }
}
</style>- Prefers reduced motion
<style>
@media screen and (prefers-reduced-motion: reduce) {
body { background-color: red; }
}
</style>- Prefers contrast
<style>
@media (prefers-contrast: more) {
body { background-color: red; }
}
</style>- Prefers dark mode
<style>
@media screen and (prefers-color-scheme: dark) {
body { background-color: red; }
}
</style>css-media-query
Code
Hide Scrollbars
Utility
Style
CSS
- Give element an attribute name of data-hide-scrollbar
<style>
[data-hide-scrollbar]::-webkit-scrollbar {
display: none;
}
[data-hide-scrollbar] {
-ms-overflow-style: none;
scrollbar-width: none;
}
</style>hide-scrollbars
Code
CSS Nth Child
Utility
Layout
CSS
<style>
/* Create a repeating pattern every 3 items */
.your-cms-item:nth-child(3n+1) { background-color: red; }
.your-cms-item:nth-child(3n+2) { background-color: blue; }
.your-cms-item:nth-child(3n+3) { background-color: green; }
/* Create a repeating pattern every 3 items while targeting the item's children */
.your-cms-item:nth-child(3n+1) .item-child { background-color: yellow; }
.your-cms-item:nth-child(3n+2) .item-child { background-color: green; }
.your-cms-item:nth-child(3n+3) .item-child { background-color: purple; }
/* Target the 1st, 2nd, and 3rd item with no repeating pattern */
.your-cms-item:nth-child(1) { background-color: red; }
.your-cms-item:nth-child(2) { background-color: blue; }
.your-cms-item:nth-child(3) { background-color: green; }
</style>css-nth-child
Code
GSAP Scroll Snap
Scroll
Utility
GSAP
ScrollTrigger
JS
- Give the section an attribute name of data-scroll-snap
- When we stop scrolling, the page will scroll to the nearest section with that attribute
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
gsap.registerPlugin(ScrollTrigger);
document.querySelectorAll("[data-scroll-snap]").forEach((component) => {
ScrollTrigger.create({
trigger: component,
start: "top top",
end: "bottom top",
scrub: true,
snap: {
snapTo: [0, 1],
duration: { min: 0.05, max: 0.3 },
delay: 0,
ease: "power1.inOut"
}
});
});
});
</script>gsap-scroll-snap
Code
GSAP matchMedia
Utility
Responsive
GSAP
JS
- Run GSAP code only for certain screen sizes
<script>
document.addEventListener("DOMContentLoaded", () => {
// only on the desktop breakpoint
gsap.matchMedia().add("(min-width: 992px)", () => {
// your gsap timeline here
});
});
</script>- Run GSAP code with multiple breakpoints
<script>
document.addEventListener("DOMContentLoaded", () => {
let mm = gsap.matchMedia();
// on desktop
mm.add("(min-width: 992px)", () => {
// your gsap timeline here
return () => {
// optional: clean up non-gsap code when leaving this breakpoint
};
});
// on tablet and below
mm.add("(max-width: 991px)", () => {
// your gsap timeline here
});
// on tablet only
mm.add("(max-width: 991px) and (min-width: 768px)", () => {
// your gsap timeline here
});
});
</script>gsap-matchmedia
Code
Refresh ScrollTrigger On Scroll Into View
Utility
Scroll
GSAP
ScrollTrigger
JS
- Give an element or section the attribute name of data-refresh-scrolltrigger
- When the element first enters view, it will refresh ScrollTrigger's markers
- This is helpful if ScrollTrigger's positions are getting out of sync from the page height changing.
<script>
document.addEventListener("DOMContentLoaded", () => {
if (typeof ScrollTrigger === "undefined") return;
document.querySelectorAll("[data-refresh-scrolltrigger]").forEach(target => {
const observer = new IntersectionObserver((entries, observerInstance) => {
entries.forEach(entry => {
if (!entry.isIntersecting) return;
ScrollTrigger.refresh();
observerInstance.unobserve(entry.target);
});
}, { threshold: 0.1 });
observer.observe(target);
});
});
</script>refresh-scrolltrigger-on-scroll-into-view
Code
Close Native Dropdown
Utility
Dropdown
JS
- Give any child of the dropdown an attribute name of data-dropdown-close to close the dropdown on click of that child
<script>
document.addEventListener("DOMContentLoaded", function () {
document.addEventListener("click", (e) => {
if (!e.target.closest("[data-dropdown-close]")) return;
const dropdown = e.target.closest(".w-dropdown");
dropdown?.dispatchEvent(new CustomEvent("w-close", { bubbles: true }));
dropdown?.dispatchEvent(new CustomEvent("w-dropdown", { bubbles: true }));
});
});
</script>close-native-dropdown
Code
Animate Item Based On Position Within Parent
Utility
GSAP
JS
- Animate item based on its horizontal position within parent
- When .item is horizontally centered within .your-section, it will be at the middle of the GSAP Timeline
- Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or horizontal scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".your-section").forEach((component) => {
component.querySelectorAll(".item").forEach((item) => {
gsap.context(() => {
let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
tl.to(item, { opacity: 0.1, scale: 0.5 });
tl.to(".item-image", { scale: 1.2 }, "<");
function animate() {
const rect = item.getBoundingClientRect();
const compRect = component.getBoundingClientRect();
let progress = Math.max(0, Math.min(1, (compRect.right - rect.left) / (rect.width + compRect.width)));
tl.progress(progress);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}, item);
});
});
});
</script>- Animate item based on its vertical position within parent
- When .item is vertically centered within .your-section, it will be at the middle of the GSAP Timeline
- Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".your-section").forEach((component) => {
component.querySelectorAll(".item").forEach((item) => {
gsap.context(() => {
let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
tl.to(item, { opacity: 0.1, scale: 0.5 });
tl.to(".item-image", { scale: 1.2 }, "<");
function animate() {
const rect = item.getBoundingClientRect();
const compRect = component.getBoundingClientRect();
let progress = Math.max(0, Math.min(1, (compRect.bottom - rect.top) / (rect.height + compRect.height)));
tl.progress(progress);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
}, item);
});
});
});
</script>animate-item-based-on-position-within-parent
Code
GSAP Context
Utility
GSAP
JS
- With GSAP Context, we can pass class names directly into our timeline, and it will only target children of the current component.
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".your-section").forEach((component) => {
gsap.context(() => {
let tl = gsap.timeline();
tl.from(component, { opacity: 0, y: "2rem" });
tl.from(".child-image", { scale: 1.2 }, "<");
}, component);
});
});
</script>- Without GSAP Context....
tl.from(component.querySelectorAll(".child-image"), { scale: 1.2 }, "<");- With GSAP Context....
tl.from(".child-image", { scale: 1.2 }, "<");gsap-context
Code
Hide Video In Low Power Mode
Video
Utility
CSS
JS
- Add attribute name of data-low-power-hidden to custom element with video tag
- Include code in site settings footer code
- Video will have opacity 0 until it starts playing. Since it never starts playing in lower power mode, it will remain hidden.
<style>
[data-low-power-hidden] { opacity: 0; transition: opacity .3s ease; }
</style>
<script>
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("[data-low-power-hidden]").forEach(video => {
const reveal = () => video.style.opacity = "1";
video.addEventListener("playing", reveal);
if (!video.paused && video.readyState >= 2) reveal();
});
});
</script>
hide-video-in-low-power-mode
Code
Prevent Flicker
Utility
CSS
- Include code in site settings head code
- Add class in style panel of u-prevent-flicker to your animated element or parent of the animated elements
- Remove class with JS or Webflow Interactions before the animation starts
- Element will only be hidden in browsers that support JS.
<style>.u-prevent-flicker { visibility: hidden; }</style>
<noscript><style>.u-prevent-flicker { visibility: visible; }</style></noscript>prevent-flicker
Code
Fix Cut Off Text When Using SplitText
Text Animation
Utility
CSS
- Add this CSS to an embed on your page
- Give your animated text element a class of u-split-fix
<style>
.u-split-fix div[style*="overflow: clip;"] { padding-block: 0.5em; margin-block: -0.5em; }
.u-split-fix div[style*="overflow: clip;"][style*="display: block"]:not(:first-child) { margin-top: -1em; }
.u-split-fix div[style*="overflow: clip;"][style*="display: block"]:not(:last-child) { margin-bottom: -1em; }
.u-split-fix div[style*="overflow: clip;"] { padding-inline: 0.2em; margin-inline: -0.2em; }
</style>fix-cut-off-text-when-using-splittext
Code
Lenis
Scroll
Lenis
JS
<link rel="stylesheet" href="https://unpkg.com/lenis@1.2.3/dist/lenis.css">
<script src="https://unpkg.com/lenis@1.2.3/dist/lenis.min.js"></script>
<script>
let lenis;
document.addEventListener("DOMContentLoaded", () => {
lenis = new Lenis({
lerp: 0.1,
wheelMultiplier: 0.7,
gestureOrientation: "vertical",
normalizeWheel: false,
smoothTouch: false,
});
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
});
</script>- Run lenis.stop() to disable scroll
- Run lenis.start() to enable scroll
lenis
Code
























