Subscribe to Our Mailing List and Stay Up-to-Date!
Subscribe
WordPress Development

Adding CSS Animations to Custom Gutenberg Blocks: Code Tutorial

Adding CSS animations to custom Gutenberg blocks enhances user experience without JavaScript overhead. CSS-only animations are faster, more performant, and easier to maintain than JavaScript alternatives.

This code tutorial walks you through implementing CSS animations in custom Gutenberg blocks, from basic transitions to complex keyframe animations. You’ll learn best practices for performant, accessible animations.

Basic CSS Animation Structure

CSS Transition approach:

.my-block {
	opacity: 0;
	transform: translateY(20px);
	transition: opacity 0.6s ease, transform 0.6s ease;
}

.my-block.visible {
	opacity: 1;
	transform: translateY(0);
}

CSS Keyframe approach:

@keyframes fadeUp {
	from {
		opacity: 0;
		transform: translateY(30px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

.my-block {
	animation: fadeUp 0.6s ease-out forwards;
}

Registering Block Styles

In block.json:

{
	"styles": [
		{ "name": "default", "label": "Default", "isDefault": true },
		{ "name": "fade-up", "label": "Fade Up" },
		{ "name": "slide-left", "label": "Slide Left" },
		{ "name": "zoom-in", "label": "Zoom In" }
	]
}

Corresponding CSS:

.is-style-fade-up {
	animation: fadeUp 0.6s ease-out;
}

.is-style-slide-left {
	animation: slideLeft 0.5s ease-out;
}

.is-style-zoom-in {
	animation: zoomIn 0.7s ease-out;
}

Dynamic Animation Attributes

Add duration, delay, and easing controls:

attributes: {
  animationDuration: {
    type: 'number',
    default: 600
  },
  animationDelay: {
    type: 'number',
    default: 0
  }
}

// In Edit component
style={{
  '--animation-duration': `${animationDuration}ms`,
  '--animation-delay': `${animationDelay}ms`
}}

CSS with custom properties:

.my-block {
	animation-duration: var(--animation-duration, 600ms);
	animation-delay: var(--animation-delay, 0ms);
}

Scroll-Triggered Animations

Enqueue frontend script:

function enqueue_animation_script() {
    wp_enqueue_script(
        'block-animations',
        get_template_directory_uri() . '/js/animations.js',
        array(),
        '1.0.0',
        true
    );
}
add_action('wp_enqueue_scripts', 'enqueue_animation_script');

animations.js:

const observer = new IntersectionObserver(
	(entries) => {
		entries.forEach((entry) => {
			if (entry.isIntersecting) {
				entry.target.classList.add("animate");
				observer.unobserve(entry.target);
			}
		});
	},
	{ threshold: 0.1 }
);

document.querySelectorAll("[data-animate]").forEach((el) => observer.observe(el));

Performance Optimization

Use GPU-accelerated properties only (transform, opacity), avoid layout-triggering properties (width, height, margin), implement will-change judiciously, and test on low-end devices.

Accessibility Implementation

Respect prefers-reduced-motion:

@media (prefers-reduced-motion: reduce) {
	.my-block {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

Conclusion

CSS animations in Gutenberg blocks provide: better performance than JavaScript animations, GPU acceleration with transform/opacity, scroll-triggered activation via Intersection Observer, custom property support for dynamic timing, and full accessibility compliance.

Start with Block Editor Animations for pre-built solutions, extend with custom CSS for unique needs.

Visit our support page for questions!

Leave a Reply

Your email address will not be published. Required fields are marked *