Lightweight
No JavaScript library. Pure CSS animations + a minimal IntersectionObserver. The default for every mockup.
Lightweight No JavaScript library. Every effect in this tier runs on CSS transitions, CSS animations using the BDS keyframe library, and a minimal IntersectionObserver snippet to toggle .is-visible. This is the default for all mockups.
Files to load
<!-- 1. Semantic motion tokens — --duration-*, --ease-*, --stagger-* -->
<link rel="stylesheet" href="tokens/gap-fills.css">
<!-- 2. Keyframe library — bds-fade-in, bds-slide-up, etc. -->
<link rel="stylesheet" href="tokens/animations.css">
<!-- 3. Motion utility classes — .bds-enter-*, .bds-anim-*, .bds-stagger-* -->
<link rel="stylesheet" href="tokens/motion-classes.css">
<!-- 4. Scroll reveal + hover classes -->
<link rel="stylesheet" href="css/animations.css">If you already load the bds-tokens bundle, gap-fills.css and animations.css are included — link the individual files only when consuming motion standalone.
Scroll observer
All .is-visible-triggered classes (reveals, text highlights) need an IntersectionObserver to apply the class when the element enters the viewport. The Lightweight tier does not include a bundled JS file — add this inline or in a small module:
// Trigger .is-visible when elements enter the viewport
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
observer.unobserve(entry.target); // fire once
}
});
},
{ threshold: 0.15 }
);
document.querySelectorAll('[data-reveal]').forEach((el) => observer.observe(el));Mark elements with data-reveal:
<div class="animate-fade-up" data-reveal>Content enters here</div>
<div class="animate-fade-left" data-reveal>
<img src="photo.jpg" alt="...">
</div>Entrance animations
The token-layer utility classes apply named keyframes with BDS duration tokens. They animate once on mount — ideal for page-load sequences or component entry.
| Class | Effect |
|---|---|
.bds-enter-fade | opacity + scale(0.98 → 1) |
.bds-enter-slide-up | translateY(8px → 0) + fade |
.bds-enter-pop | scale(0 → 1) with spring overshoot |
Effects in this tier
Class tables, code, and live demos live on the effect pages. This page owns what the tier loads and when to escalate off it.
| Effect | Classes | Reference |
|---|---|---|
| Fade / slide scroll reveals | .animate-fade-up and siblings | Scroll reveals |
| Stagger | .bds-stagger-1 through .bds-stagger-6 | Scroll reveals |
| Hover micro-interactions | .hover-lift and siblings, .click-press | Hover |
Stagger delays read --stagger-1 through --stagger-6 from gap-fills.css, so a static item count needs no JS. Escalate to the GSAP tier when the count is dynamic, the sequence reverses on exit, or the stagger is non-linear. Magnetic cursor and cursor-spotlight hover variants are Premium — see Hover.
Attention animations
Draw the eye to a changed state without motion sickness risk. These loop continuously or fire on a single event.
<!-- Notification dot that breathes -->
<span class="bds-anim-pulse">3</span>
<!-- Bell shake on new message -->
<svg class="bds-anim-shake">...</svg>
<!-- Loading spinner -->
<div class="bds-anim-spin">...</div>Reduced motion
tokens/animations.css includes a prefers-reduced-motion override that disables all animations and transitions for users who have enabled this OS preference. No additional work needed.
Related
- Tiers Overview — when to escalate
- Scroll Reveals — full reference
- Hover Effects