In the quest for better user engagement, we’ve collectively moved past the flashy animations of the early web (farewell, Flash) to embrace more considered, purpose-driven motion design. As we navigate the challenges of 2020’s remote-first world, keeping users engaged with our interfaces has never been more critical. Let’s explore how to implement effective motion UI with current tools and techniques that won’t tank your performance.
The Psychology Behind Motion
Before diving into implementation, it’s worth understanding why we’re adding motion in the first place. Motion isn’t just eye candy—it creates cognitive anchors that help users understand what’s happening in your interface.
Disney figured this out decades ago with their famous 12 principles of animation. Many of these principles translate surprisingly well to UI design. As dribbble.com notes, “Most of the objects in the real world follow motions which are eased.” This natural movement creates interfaces that feel alive rather than mechanical.
The key, however, is subtlety. I’ve seen too many sites lately where developers went overboard with animations, creating experiences that feel like navigating through molasses.
Popular Motion Libraries in 2020
Several libraries have emerged as front-runners this year:
- Framer Motion - React’s golden child for animations
- GSAP - The venerable animation platform for complex sequences
- Motion UI by ZURB - Built on Sass, perfect for Foundation users
- Anime.js - Lightweight JavaScript animation library
- React Spring - Physics-based animations for React
For this post, I’ll focus on Motion UI by ZURB, which is particularly well-suited for scroll-triggered animations and micro-interactions using Sass.
Setting Up Motion UI with Sass
If you’re using Foundation, Motion UI might already be part of your workflow. If not, installation is straightforward:
npm install motion-ui --save
Then in your main Sass file:
@import 'motion-ui';
@include motion-ui-transitions;
@include motion-ui-animations;
What’s great about Motion UI is how it leverages Sass mixins to create transition classes that you can apply directly in your markup:
.fade-in-element {
@include mui-hinge(
$state: in,
$from: top,
$fade: true,
$timing: 0.5s
);
}
Scroll-Triggered Animations: The Right Way
Scroll-triggered animations have become ubiquitous, but implementing them efficiently is another story. Here’s a pattern I’ve found effective:
// Using Intersection Observer API (now widely supported)
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
observer.unobserve(entry.target); // Stop observing once triggered
}
});
}, {
threshold: 0.1 // Trigger when 10% of element is visible
});
// Target all elements with animation classes
document.querySelectorAll('.animate-on-scroll').forEach(element => {
observer.observe(element);
});
Paired with your Motion UI classes:
.animate-on-scroll {
opacity: 0;
transition: opacity 0.3s ease-out;
&.is-visible {
opacity: 1;
}
}
This approach is vastly superior to scroll event listeners which fire constantly and can cripple performance.
Micro-Interactions for Feedback
Micro-interactions provide immediate feedback to user actions. Consider this example for a form button:
@mixin button-interaction {
transition: transform 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
&:active {
transform: translateY(0);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
}
.submit-button {
@include button-interaction;
}
These subtle cues mimic physical interactions, making interfaces feel more responsive and tangible.
Performance Considerations
Animation performance is a critical concern, especially for mobile users who might be on slower devices or metered connections.
Here are my rules of thumb:
- Stick to opacity and transform properties - They’re GPU-accelerated in modern browsers
- Avoid animating layout properties - Things like
width,height, andmarginforce costly reflows - Use the
will-changeproperty sparingly - It’s powerful but can backfire if overused
.performant-animation {
transform: translateZ(0); // Hardware acceleration hack
transition: transform 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
&:hover {
transform: scale(1.05);
}
}
Real-World Example: Navigation Transition
Let’s build a practical example. Here’s a responsive main navigation with scroll-triggered behavior:
// Main Sass file
@import 'motion-ui';
// Custom transitions
@include motion-ui-transitions;
@include motion-ui-animations;
// Navigation styles
.main-nav {
position: fixed;
top: 0;
left: 0;
right: 0;
padding: 20px;
transition: background-color 0.3s ease, padding 0.3s ease;
&.scrolled {
background-color: rgba(255, 255, 255, 0.95);
padding: 10px 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
.nav-link {
color: #333;
}
}
.nav-link {
color: white;
transition: color 0.3s ease;
&:hover {
@include mui-zoom(
$from: 1,
$to: 1.1,
$duration: 0.2s
);
}
}
}
// JavaScript to handle scroll behavior
const nav = document.querySelector('.main-nav');
let scrollThreshold = 100;
window.addEventListener('scroll', () => {
if (window.scrollY > scrollThreshold) {
nav.classList.add('scrolled');
} else {
nav.classList.remove('scrolled');
}
}, { passive: true }); // Performance optimization
This creates a navigation that subtly transforms as the user scrolls down the page, providing context about their position while maintaining access to navigation controls.
Where Do We Go From Here?
Several design systems have begun treating motion as a first-class citizen. Carbon and Lightning have considered motion as an important aspect of design and formulated specifications for timing, easing and other transition parameters.
This standardization helps create consistent experiences across products and reduces the cognitive load on both designers and developers.
Finding Inspiration
If you’re looking to level up your animation game, there are countless inspirational sources. For animated backgrounds specifically, Prototypr.io recently published “5 CSS Animated Backgrounds to Inspire Your Next Project,” showcasing some creative approaches from simple to complex.
Conclusion
Effective motion design is about enhancing the user experience rather than distracting from it. Some users might appreciate subtle animations, while others might prefer more pronounced effects."
The tools available to us today make implementing thoughtful animations more accessible than ever. Whether you’re using Motion UI with Sass, Framer Motion with React, or vanilla CSS transitions, the principles remain the same: be intentional, be performant, and above all, serve the user’s needs.