Master the responsive carousel block that gives you complete control over your WordPress content displays
Getting Started
The Groundworx Carousel Block transforms any WordPress content into beautiful, responsive carousels. Built with Splide.js and deeply integrated with Gutenberg, it offers professional templates and granular responsive control.
What You’ll Learn
By the end of this tutorial, you’ll know how to:
- Set up and configure a carousel with any content
- Choose and customize from 9 professional templates
- Control carousel behavior across 8 responsive breakpoints
- Style your carousel using theme.json
- Write custom CSS for unique designs
- Create your own reusable templates
- Build custom block variations for your team
Prerequisites
- WordPress 6.5 or higher
- PHP 8.2 or higher
- A block theme (recommended) or classic theme with Gutenberg support
- Basic understanding of the WordPress block editor
Basic Setup & Configuration
Installing the Plugin
Via WordPress Admin:
- Navigate to Plugins → Add New
- Search for “Groundworx Carousel”
- Click Install Now, then Activate
Manual Installation:
- Download the plugin from WordPress.org
- Upload via Plugins → Add New → Upload Plugin
- Activate the plugin
Creating Your First Carousel
Step 1: Add the Carousel Block
- Create or edit a post/page
- Click the + icon to insert a block
- Search for “Carousel” or browse to Design → Carousel
- Insert the block
Step 2: Add Slides
The carousel automatically creates one slide. To add more:
- Click Add Slide in the block toolbar
- Or click the + icon inside the carousel
- Add as many slides as you need
Step 3: Add Content to Slides
Each slide is a container that accepts any WordPress block:
Inside each slide, you can add:
✓ Images (single or galleries)
✓ Text (paragraphs, headings, lists)
✓ Buttons and links
✓ Groups and containers
✓ Cover blocks with overlays
✓ Custom blocks from plugins
Step 4: Configure Basic Settings
Open the Block Settings panel (sidebar) and configure:
Type Tab:
- Type: Choose slide, loop, or fade
- Focus: Enable center mode if desired
- Carousel Item Position: Manual (slides to show) or Auto (fixed width)
- Slides to Show: Number of slides visible at once
Navigation Tab:
- Arrows: Enable/disable navigation arrows
- Arrow Style: Choose from 11 styles
- Pagination: Enable/disable pagination dots
- Pagination Style: Choose from 9 styles
- Progress Bar: Show progress indicator
- Counter: Display slide count (e.g., “3 / 10”)
Behavior Tab:
- Autoplay: Enable automatic sliding
- Interval: Time between slides (milliseconds)
- Speed: Transition speed
- Rewind: Return to start after last slide
- Auto Height: Adjust height to current slide
Understanding Templates
Groundworx Carousel 2.0 includes 9 professionally designed templates:
Template Overview
Version 2.0 includes 9 template variations that change the positioning and layout of slide content and navigation elements:
Default – Arrows outset of the carousel carousel
Default Alt – Arrows outset and outset pagination
Simple – Arrows positioned center
Simple Left – Arrows positioned left
Simple Right – Arrows positioned right
Overlay – Arrows overlay
Overlay Alt – Arrows overlay and outset pagination
Partial Overlay – Arrows partial overlay
Partial Overlay Alt – Arrows partial overlay and outset pagination
Each template positions elements differently to suit various design needs. Try different templates to see which layout works best for your content.
Choosing a Template
Select your template in the Settings → General panel:
Template: [Dropdown selection]
Tips:
- Try different templates to see how they position your content
- Templates are purely visual – they don’t change carousel functionality
- All templates work with any carousel configuration
- You can switch templates anytime without losing content
Template Customization
Each template can be customized with:
- Colors: Text, background, and UI element colors
- Spacing: Padding and gaps via block spacing controls
- Typography: Font size, weight, and family
- Borders: Radius and styles
Block Philosophy
Before customizing the carousel, it’s important to understand the design philosophy behind Gutenberg blocks.
Blocks Should Be Flexible
Blocks are meant to be:
- Customizable – Users should be able to adjust colors, spacing, and appearance
- Modular – They work independently and fit into any design system
- Adaptable – They don’t impose rigid constraints
Blocks are NOT meant to be:
- Opinionated – Don’t force specific colors or heavy styling
- Rigid – Don’t lock users into fixed dimensions or layouts
- Restrictive – Don’t prevent the block settings from working
Best Practices for Styling
When using theme.json or custom CSS:
- Less is more – Avoid setting too many default values
- Don’t override user controls – If the block has color settings, don’t force colors in CSS
- Keep specificity low – Use
:where()so users can override your styles - Test thoroughly – Always verify that block settings still work after adding custom styles
- Preserve flexibility – Don’t set fixed heights, widths, or padding that prevents responsive behavior
What NOT To Do
❌ Don’t set colors that prevent the UI controls from working:
/* Bad - breaks color controls */
.wp-block-groundworx-carousel {
--gwx--color--arrows: #ffffff !important;
}
❌ Don’t set rigid dimensions:
/* Bad - prevents responsive behavior */
.wp-block-groundworx-carousel {
height: 500px;
width: 1200px;
}
❌ Don’t use high specificity:
/* Bad - users can't override */
.wp-block-groundworx-carousel .splide__slide {
padding: 2rem;
}
What TO Do
✅ Use :where() for low specificity:
/* Good - easy to override */
:where(.wp-block-groundworx-carousel) {
--gwx--color--arrows: var(--wp--preset--color--contrast);
}
✅ Provide sensible defaults that enhance, don’t restrict:
/* Good - adds style without forcing it */
:where(.wp-block-groundworx-carousel) {
border-radius: 8px;
}
✅ Let the block’s settings control behavior:
/* Good - respects user choices */
:where(.wp-block-groundworx-carousel.template-my-custom) {
/* Only template-specific positioning */
> .splide.is-active .splide__wrapper {
display: grid;
/* Grid layout only */
}
}
The Golden Rule
“Least is best” – Only add styling that genuinely improves the default experience. When in doubt, leave it out.
Users chose this block because it gives them control. Respect that by keeping your customizations minimal and non-invasive.
Responsive Breakpoints
The carousel supports 8 breakpoint levels for precise responsive control.
Understanding the Breakpoint System
Mobile-First Approach: Settings cascade from mobile to larger screens. You only need to override settings that should change at each breakpoint.
The 8 Breakpoints:
Mobile/Default: 0-374px (Base configuration)
Phone: 375px+ (Small phones)
Large Phone: 480px+ (Standard phones)
Tablet: 680px+ (Small tablets)
Large Tablet: 960px+ (iPad, larger tablets)
Laptop: 1080px+ (Small laptops)
Desktop: 1280px+ (Standard desktops)
Large Desktop: 1440px+ (Large screens)
Configuring Responsive Behavior
Example: Show 1 slide on mobile, 2 on tablet, 3 on desktop
- Select the Mobile/Default tab
- Set Slides to Show: 1
- Select the Tablet tab
- Set Slides to Show: 2
- Select the Desktop tab
- Set Slides to Show: 3
Example: Hide arrows on mobile, show on tablet+
- Mobile/Default tab: Turn OFF arrows
- Tablet tab: Turn ON arrows
- Leave other breakpoints alone (they inherit from tablet)
Responsive Grid Fallback
Destroy the carousel and display as a grid at larger screens:
This is perfect for mobile-first designs where you want a carousel on phones but a static grid on desktops.
How to Set Up:
- Configure your carousel for mobile (Type: loop, slides, etc.)
- Select the breakpoint where you want it to become a grid (e.g., Desktop)
- Set Disable Carousel At dropdown to that breakpoint
Important: Once you set “Disable Carousel At” to a breakpoint, the available settings change for that breakpoint and all larger breakpoints. You’ll no longer see carousel options (Type, Slides to Show, Arrows, etc.). Instead, you’ll see grid options:
- Grid Type: Manual (set column count) or Auto (set minimum column width)
- Columns (Manual mode): Number of columns (e.g., 3)
- Min Column Width (Auto mode): Minimum width per column (e.g., 300px)
- Same Height: Make all grid items the same height
- Configure your grid layout with these new options
- All breakpoints larger than your selection will also be a grid (unless you change “Disable Carousel At” again)
Note on Gap/Gutter:
The gap (spacing between slides/items) is set at the block level, not per breakpoint. Whatever gap you set applies to both carousel mode AND grid mode. You’ll find the gap setting in the block’s spacing controls in the sidebar.
Example Configuration:
Block Settings (applies everywhere):
- Gap: 1.5rem
Mobile/Default:
- Disable Carousel At: Never (Always Carousel)
- Type: Loop
- Slides to Show: 1
- Arrows: Yes
Tablet:
- Disable Carousel At: Inherit (Still a carousel)
- Slides to Show: 2
- (Inherits loop and arrows)
Desktop:
- Disable Carousel At: Desktop
- (Settings change to grid options)
- Grid Type: Manual
- Columns: 3
- Same Height: Yes
Large Desktop:
- Disable Carousel At: Inherit (Still a grid from Desktop)
- Columns: 4
- (Can override grid settings)
Result: Carousel on mobile/tablet with 1.5rem gap, 3-column grid on desktop with 1.5rem gap, 4-column grid on large desktop with 1.5rem gap.
Key Understanding:
- Before the “Disable Carousel At” breakpoint: Configure carousel settings
- At and after the “Disable Carousel At” breakpoint: Configure grid settings
- Gap setting: Shared between carousel and grid modes, set at block level
- The settings panel changes to show only relevant options for carousel or grid mode
Styling with theme.json
You can add default styles for the Groundworx Carousel block in your theme’s theme.json file using the styles.blocks section.
Basic Styling Options
Spacing:
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"spacing": {
"padding": {
"top": "3rem",
"right": "1.5rem",
"bottom": "3rem",
"left": "1.5rem"
},
"margin": {
"top": "2rem",
"bottom": "2rem"
},
"blockGap": "2rem"
}
}
}
}
}
Colors
Block Background and Text Colors:
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
}
}
}
}
}
UI Element Colors:
WordPress doesn’t have built-in controls for arrows, pagination, progress bars, and counters, so we use CSS custom properties to set these colors:
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"css": "--gwx--color--arrows: var(--wp--preset--color--contrast); --gwx--background-color--arrows: var(--wp--preset--color--accent-1); --gwx--border-color--arrows: transparent; --gwx--color--pagination: var(--wp--preset--color--contrast); --gwx--background-color--pagination: var(--wp--preset--color--accent-1); --gwx--border-color--pagination: var(--wp--preset--color--accent-1); --gwx--color--inactive-pagination: var(--wp--preset--color--contrast); --gwx--background-color--inactive-pagination: transparent; --gwx--border-color--inactive-pagination: var(--wp--preset--color--contrast); --gwx--color--progress: var(--wp--preset--color--accent-2); --gwx--background-color--progress: var(--wp--preset--color--base); --gwx--color--counter: var(--wp--preset--color--contrast);"
}
}
}
}
Available Color Variables:
/* Arrows */
--gwx--color--arrows
--gwx--background-color--arrows
--gwx--border-color--arrows
/* Active Pagination */
--gwx--color--pagination
--gwx--background-color--pagination
--gwx--border-color--pagination
/* Inactive Pagination */
--gwx--color--inactive-pagination
--gwx--background-color--inactive-pagination
--gwx--border-color--inactive-pagination
/* Progress Bar */
--gwx--color--progress
--gwx--background-color--progress
/* Counter */
--gwx--color--counter
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"typography": {
"fontSize": "var(--wp--preset--font-size--medium)",
"lineHeight": "1.6",
"fontFamily": "var(--wp--preset--font-family--body)"
}
}
}
}
}
Borders & Shadows:
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"border": {
"radius": "12px",
"width": "1px",
"style": "solid",
"color": "var(--wp--preset--color--contrast)"
},
"shadow": "var(--wp--preset--shadow--natural)"
}
}
}
}
Typography:
Advanced: Template-Specific Styling
You can target specific carousel templates to apply different styling rules based on the layout.
Basic Template Targeting
Target a single template:
json
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"css": "&:where(.template-overlay) { --gwx--color--arrows: white; --gwx--background-color--arrows: rgba(0,0,0,0.5); }"
}
}
}
}
Multiple Templates
Apply the same styling to multiple templates:
json
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"css": "&:where(.template-default, .template-overlay, .template-partial-overlay) { --gwx--color--pagination: var(--wp--preset--color--base); --gwx--background-color--pagination: transparent; }"
}
}
}
}
Complete Example
Here’s a full theme.json configuration combining all styling options:
{
"version": 3,
"styles": {
"blocks": {
"groundworx/carousel": {
"spacing": {
"padding": {
"top": "3rem",
"right": "1.5rem",
"bottom": "3rem",
"left": "1.5rem"
},
"margin": {
"top": "2rem",
"bottom": "2rem"
},
"blockGap": "2rem"
},
"color": {
"background": "var(--wp--preset--color--base)",
"text": "var(--wp--preset--color--contrast)"
},
"typography": {
"fontSize": "var(--wp--preset--font-size--medium)",
"lineHeight": "1.6",
"fontFamily": "var(--wp--preset--font-family--body)"
},
"border": {
"radius": "12px",
"width": "1px",
"style": "solid",
"color": "var(--wp--preset--color--contrast)"
},
"shadow": "var(--wp--preset--shadow--natural)",
"css": "--gwx--color--arrows: var(--wp--preset--color--contrast); --gwx--background-color--arrows: var(--wp--preset--color--accent-1); --gwx--border-color--arrows: transparent; --gwx--color--pagination: var(--wp--preset--color--contrast); --gwx--background-color--pagination: var(--wp--preset--color--accent-1); --gwx--border-color--pagination: var(--wp--preset--color--accent-1); --gwx--color--inactive-pagination: var(--wp--preset--color--contrast); --gwx--background-color--inactive-pagination: transparent; --gwx--border-color--inactive-pagination: var(--wp--preset--color--contrast); --gwx--color--progress: var(--wp--preset--color--accent-2); --gwx--background-color--progress: var(--wp--preset--color--base); --gwx--color--counter: var(--wp--preset--color--contrast);"
}
}
}
}
Styling Individual Slides
You can also style the slide blocks:
{
"version": 3,
"styles": {
"blocks": {
"groundworx/slide": {
"spacing": {
"padding": "2rem"
},
"border": {
"radius": "8px"
}
}
}
}
}
Creating Custom Templates
You can create your own carousel templates using WordPress hooks and custom CSS. The carousel uses a CSS Grid system with named grid areas that you can position however you want.
Understanding the Grid System
The carousel uses CSS Grid with these named areas:
/* Available grid areas: */
track /* The slide track */
arrows /* Arrow container */
arrow-prev /* Previous arrow */
arrow-next /* Next arrow */
pagination /* Pagination dots */
progress /* Progress bar */
counter /* Slide counter */
These areas are automatically assigned to the carousel elements. Your template CSS positions them using grid-template-columns and grid-template-rows.
Step 1: Register Your Template
Add this to your theme’s functions.php:
/**
* Add custom carousel template
*/
function my_theme_add_carousel_template() {
?>
<script>
wp.hooks.addFilter(
'groundworx.carousel.templates',
'my-theme/add-custom-template',
function(templates) {
return [
...templates,
{
label: 'My Custom Template',
value: 'my-custom'
}
];
}
);
</script>
<?php
}
add_action('admin_footer', 'my_theme_add_carousel_template');
Step 2: Create Your Template CSS
The template class follows the pattern .template-{value} where {value} matches your registration.
Basic Structure:
.wp-block-groundworx-carousel.template-my-custom {
> .splide.is-active {
> .splide__wrapper {
/* Define your grid layout here */
display: grid;
grid-template-columns: /* your columns */;
grid-template-rows: /* your rows */;
}
}
}
Step 3: Enqueue Your CSS
/**
* Enqueue custom carousel template CSS
*/
function my_theme_enqueue_carousel_css() {
wp_enqueue_style(
'my-carousel-custom-template',
get_stylesheet_directory_uri() . '/assets/css/carousel-my-custom.css',
array('groundworx-carousel-style'),
'1.0.0'
);
}
add_action('wp_enqueue_scripts', 'my_theme_enqueue_carousel_css');
add_action('enqueue_block_editor_assets', 'my_theme_enqueue_carousel_css'); // Also load in editor
Complete Example: Centered Layout
assets/css/carousel-centered.css:
.wp-block-groundworx-carousel.template-centered {
> .splide.is-active {
> .splide__wrapper {
display: grid;
grid-template-columns: [track-start progress-start pagination-start arrows-start] auto [arrows-end pagination-end progress-end track-end];
grid-template-rows:
[track-start pagination-start] auto
[pagination-end track-end progress-start] auto
[progress-end];
> .splide__track {
z-index: 0;
}
> .splide__arrows {
z-index: 1;
position: relative;
display: grid;
justify-self: center;
align-items: center;
gap: .25rem;
grid-template-columns: [arrow-prev-start] auto [arrow-prev-end counter-start] auto [counter-end arrow-next-start] auto [arrow-next-end];
grid-template-rows: [counter-start arrow-prev-start arrow-next-start] auto [arrow-prev-end arrow-next-end counter-end];
.splide__counter {
align-self: center;
justify-self: center;
z-index: 1;
min-width: 5ch;
text-align: center;
}
}
> .splide__pagination {
align-self: flex-end;
justify-content: center;
z-index: 1;
position: relative;
display: flex;
margin: 0;
padding: var(--wp--preset--spacing--gutter, 1rem);
}
> .splide__progress {
z-index: 1;
position: relative;
}
}
&:where(.splide--has-arrows, .splide--has-counter) {
> .splide__wrapper {
grid-template-rows:
[track-start pagination-start] auto
[pagination-end track-end progress-start] auto
[progress-end] var(--wp--preset--spacing--gutter, 1rem)
[arrows-start] auto [arrows-end];
> .splide__arrows {
z-index: 1;
position: relative;
display: grid;
justify-self: center;
align-items: center;
grid-template-rows: [counter-start arrow-prev-start arrow-next-start] auto [arrow-prev-end arrow-next-end counter-end];
}
}
}
&.splide--has-arrows:not(.splide--has-counter) {
> .splide__wrapper {
> .splide__arrows {
grid-template-columns: [arrow-prev-start] auto [arrow-prev-end arrow-next-start] auto [arrow-next-end];
}
}
}
&.splide--has-counter:not(.splide--has-arrows) {
> .splide__wrapper {
> .splide__arrows {
grid-template-columns: [counter-start] auto [counter-end];
}
}
}
&.splide--has-arrows.splide--has-counter {
> .splide__wrapper {
> .splide__arrows {
grid-template-columns: [arrow-prev-start] auto [arrow-prev-end counter-start] auto [counter-end arrow-next-start] auto [arrow-next-end];
}
}
}
}
}
Conditional Classes
The carousel adds classes based on enabled features:
/* When arrows are enabled */
.splide--has-arrows { }
/* When pagination is enabled */
.splide--has-pagination { }
/* When counter is enabled */
.splide--has-counter { }
/* When progress bar is enabled */
.splide--has-progressbar { }
Use these to adjust your grid:
.wp-block-groundworx-carousel.template-my-custom {
> .splide.is-active {
/* Base layout */
> .splide__wrapper {
grid-template-columns: [track-start] 1fr [track-end];
}
/* Adjust when arrows are enabled */
&.splide--has-arrows {
> .splide__wrapper {
grid-template-columns:
[arrow-prev-start] auto
[arrow-prev-end track-start] 1fr
[track-end arrow-next-start] auto
[arrow-next-end];
}
}
}
}
Multiple Templates
Register multiple templates at once:
function my_theme_add_carousel_templates() {
?>
<script>
wp.hooks.addFilter(
'groundworx.carousel.templates',
'my-theme/custom-templates',
function(templates) {
return [
...templates,
{
label: 'Centered',
value: 'mytheme-centered'
},
{
label: 'Split Layout',
value: 'mytheme-split'
},
{
label: 'Overlay',
value: 'mytheme-overlay'
}
];
}
);
</script>
<?php
}
add_action('admin_footer', 'my_theme_add_carousel_templates');
Then create and enqueue CSS for each template following the same pattern.
Advanced: Block Variations
Create reusable carousel configurations for your team.
Use Case
Instead of manually configuring the same carousel settings repeatedly, create pre-configured variations.
Example 1: Testimonial Carousel
// Add to your theme's JavaScript file
wp.blocks.registerBlockVariation('groundworx/carousel', {
name: 'testimonials',
title: 'Testimonials Carousel',
description: 'Pre-configured carousel for customer testimonials',
icon: 'format-quote',
attributes: {
template: 'simple',
splideOptions: {
type: 'loop',
perPage: 1,
autoplay: true,
interval: 5000,
arrows: true,
pagination: true
},
arrowStyle: 'chevronRounded',
paginationStyle: 'circle'
},
innerBlocks: [
['groundworx/slide', {}, [
['core/paragraph', {
content: 'Add your testimonial text here...',
fontSize: 'large'
}],
['core/paragraph', {
content: '— Customer Name'
}]
]]
],
scope: ['inserter', 'block']
});
Example 2: Product Grid with Mobile Carousel
wp.blocks.registerBlockVariation('groundworx/carousel', {
name: 'product-grid-mobile',
title: 'Product Grid (Mobile Carousel)',
description: 'Shows as carousel on mobile, grid on desktop',
icon: 'products',
attributes: {
template: 'product-showcase', // Your custom template
splideOptions: {
type: 'loop',
perPage: 1,
gap: '1rem',
arrows: false,
pagination: true
},
disableCarouselAt: 'tablet', // Switch to grid at tablet and larger
breakpoints: {
tablet: {
layout: {
type: 'grid',
columnCount: 2
}
},
desktop: {
layout: {
type: 'grid',
columnCount: 4
}
}
}
},
scope: ['inserter', 'block']
});
Example 3: Auto-Width Featured Content
wp.blocks.registerBlockVariation('groundworx/carousel', {
name: 'featured-auto-width',
title: 'Featured Content (Auto Width)',
description: 'Variable width slides with center focus',
icon: 'star-filled',
attributes: {
template: 'default',
splideOptions: {
type: 'loop',
fixedWidth: '350px',
focus: 'center',
gap: '2rem',
arrows: true,
pagination: false,
autoplay: true,
interval: 4000
},
arrowStyle: 'play',
paginationStyle: 'rectangle'
},
scope: ['inserter', 'block']
});
Setting a Default Variation
You can override the default block behavior by setting one variation as the default. Only one variation can be marked as default.
When a variation is set as default:
- It appears first in the block inserter
- It’s what users get when they insert the carousel block
- The original block becomes a variation in the list
Example: Make Product Grid the Default
wp.blocks.registerBlockVariation('groundworx/carousel', {
name: 'product-grid',
title: 'Product Grid',
description: 'Carousel on mobile, grid on desktop',
icon: 'products',
isDefault: true, // This makes it the default
attributes: {
template: 'default',
splideOptions: {
type: 'loop',
perPage: 1,
arrows: false,
pagination: true
},
disableCarouselAt: 'tablet',
breakpoints: {
tablet: {
layout: {
type: 'grid',
columnCount: 2
}
},
desktop: {
layout: {
type: 'grid',
columnCount: 4
}
}
}
},
scope: ['inserter', 'block']
});
Important Rules:
- Only ONE variation can have
isDefault: true– If multiple variations have this, only the last one registered will be default - The original block becomes a variation – Users can still access it from the variations list
- Test thoroughly – Make sure your default variation works for most use cases on your site
Use Cases for Default Variations:
- Agency sites: Set defaults that match your typical project needs
- Client sites: Pre-configure settings so clients don’t need to configure everything
- Theme developers: Provide opinionated defaults that match your theme’s design
Registering Variations in Your Theme
Method 1: Via JavaScript File
Create assets/js/carousel-variations.js:
(function() {
'use strict';
wp.domReady(function() {
// Register your variations here
wp.blocks.registerBlockVariation('groundworx/carousel', {
// ... variation config
});
});
})();
Enqueue in functions.php:
function my_theme_carousel_variations() {
wp_enqueue_script(
'my-carousel-variations',
get_stylesheet_directory_uri() . '/assets/js/carousel-variations.js',
array('wp-blocks', 'wp-dom-ready'),
'1.0.0',
true
);
}
add_action('enqueue_block_editor_assets', 'my_theme_carousel_variations');
Method 2: Inline in functions.php
function my_theme_carousel_variations_inline() {
?>
<script>
wp.domReady(function() {
wp.blocks.registerBlockVariation('groundworx/carousel', {
name: 'my-variation',
title: 'My Custom Variation',
attributes: {
// ... your config
}
});
});
</script>
<?php
}
add_action('admin_footer', 'my_theme_carousel_variations_inline');
Troubleshooting
Carousel Not Sliding
Issue: Carousel displays but doesn’t slide.
Solutions:
- Check that you have more slides than “Slides to Show”
- Verify JavaScript isn’t blocked by another plugin
- Check browser console for errors
- Disable other slider plugins that might conflict
Arrows/Pagination Not Showing
Issue: Navigation controls aren’t visible.
Solutions:
- Verify they’re enabled in block settings
- Check that your theme isn’t hiding them with CSS
- Ensure colors aren’t matching the background
- Try different arrow/pagination styles
Grid Fallback Not Working
Issue: Carousel doesn’t switch to grid at breakpoint.
Solutions:
- Select the breakpoint where you want grid layout
- Set “Disable Carousel At” to that breakpoint (not “Never”)
- Configure grid settings (columns or auto-fit)
- Check browser width actually reaches the breakpoint
- Clear cache (browser and WordPress)
- Inspect element to see if grid styles are applied
Images Different Sizes
Issue: Slides have inconsistent heights.
Solution:
Use the Image block’s built-in aspect ratio feature:
- Select the Image block inside your slide
- In the block toolbar or settings, find Aspect Ratio
- Choose a preset (1:1, 4:3, 16:9, etc.) or set a custom ratio
- Apply the same aspect ratio to all images in your carousel
This ensures all images display at the same proportions without custom CSS.
Autoplay Not Working
Issue: Carousel doesn’t auto-advance.
Solutions:
- Verify Autoplay is enabled
- Check Interval is set (3000+ recommended)
- Ensure Type is “slide” or “loop” (not “fade” + rewind)
- User interaction pauses autoplay – this is expected behavior
Performance Issues
Issue: Page feels slow or carousels are janky.
Likely Cause:
Too many carousels on a single page, or carousels with too many slides and heavy content.
Solutions:
- Limit carousels per page – Each carousel instance adds overhead
- Reduce number of slides – Keep carousels focused with 5-10 slides maximum
- Optimize slide content:
- Use optimized images (WebP format, appropriate dimensions)
- Avoid embedding heavy content (videos, complex blocks) in every slide
- Keep slide markup simple
- Consider pagination – Break large content sets across multiple pages instead of one carousel with 50+ slides
Settings Not Working as Expected
Issue: A setting doesn’t seem to work at a specific breakpoint.
Understanding Breakpoint Inheritance:
The carousel is mobile-first. Settings cascade from Mobile/Default to larger breakpoints:
Mobile/Default > Phone > Large Phone > Tablet > Large Tablet > Laptop > Desktop > Large Desktop
Each breakpoint can either:
- Inherit from the previous breakpoint (default behavior)
- Override with a new value
- Toggle ON/OFF independently for that breakpoint
Common Problems:
Problem 1: Setting is being overridden at a larger breakpoint
Example: You set Arrows ON at Mobile/Default, but they don’t show on Desktop.
Solution: Check the Desktop tab – if Arrows are toggled OFF there, it overrides the Mobile setting. Either:
- Click the three dots (⋮) next to the breakpoint name and select Reset to clear all overrides for that breakpoint
- Or manually set individual settings back to “Inherit”
Problem 2: Trying to inherit but seeing unexpected behavior
Example: You want Desktop to inherit Mobile settings, but it’s not.
Solution: Check every breakpoint between Mobile and Desktop (Phone, Large Phone, Tablet, etc.). If any of them override the setting, Desktop inherits from the closest breakpoint, not from Mobile.
Use the three dots (⋮) menu to reset intermediate breakpoints back to inherit.
Problem 3: Toggle settings (Arrows, Pagination, etc.) staying ON/OFF
Each breakpoint has independent toggle controls. If Arrows are OFF at Tablet, they stay OFF at Desktop unless you explicitly toggle them back ON at Desktop or a breakpoint between.
Quick Fix: Reset a Breakpoint
- Click the three dots (⋮) next to the breakpoint name (e.g., “Tablet”)
- Select Reset all
- All settings for that breakpoint return to “Inherit”
- The breakpoint now uses values from the previous smaller breakpoint
How to Debug:
- Start at Mobile/Default – set your base configuration
- Move to each larger breakpoint in order
- For each setting, check if it shows:
- “Inherit” option → Currently using value from previous breakpoint
- Specific value → Overriding with this value for this breakpoint and larger
- Toggle ON/OFF → Explicitly enabled/disabled for this breakpoint
- Use the three dots menu to reset any breakpoint causing issues
- Add overrides only where you need different behavior
Best Practice:
Configure most settings at Mobile/Default, then only override at specific breakpoints where behavior needs to change. This keeps your configuration simple and predictable.
Colors Not Changing
Issue: UI element colors won’t update in the block editor.
Cause:
The carousel uses :where() selectors for all default styles to keep specificity low. This allows block-level color settings to override the defaults. If a custom template doesn’t use :where(), it will have higher specificity and break the color controls.
Solutions:
If using a custom template: Make sure your template CSS uses :where() for carousel elements:
/* Correct - low specificity */
:where(.wp-block-groundworx-carousel.template-my-custom) {
--gwx--color--arrows: var(--wp--preset--color--contrast);
}
/* Wrong - will break color controls */
.wp-block-groundworx-carousel.template-my-custom {
--gwx--color--arrows: var(--wp--preset--color--contrast);
}
If using default templates: The color controls should work. If they don’t:
- Check your theme’s theme.json isn’t setting high-specificity styles for the carousel block
- Inspect the element in browser dev tools to see what CSS is applying
- Try a different template to isolate if it’s template-specific
Why This Matters:
Without :where(), custom styles have higher specificity than the block’s color controls, making the UI controls non-functional. This breaks the editing experience.
Why Don’t You Support Fade Type?
Question: Splide.js supports fade transitions, why isn’t it available in Groundworx Carousel?
Answer:
Fade type is not currently supported in Groundworx Carousel. While Splide.js does support fade transitions, the configuration options for fade are significantly different from slide/loop types:
- Fade only works with one slide visible at a time (perPage must be 1)
- Many carousel options don’t apply (gap, slides per move, etc.)
- The UI would need different controls for fade mode
This creates a complex user experience where the settings panel would need to change dramatically based on the type selected. We may add fade support in a future version once we can design a clear UX for it.
Next Steps
Congratulations! You now know how to:
- ✅ Set up and configure responsive carousels
- ✅ Choose and customize templates
- ✅ Control behavior across breakpoints
- ✅ Style with theme.json and CSS
- ✅ Create custom templates
- ✅ Build reusable variations
Additional Resources
- Splide.js Options Reference – Full list of carousel configuration options
- WordPress Block Editor Handbook – Learn more about Gutenberg
- Theme.json Documentation – Theme styling guide
- Groundworx Core Framework – Explore other Groundworx blocks
Get Support
- GitHub Issues: Report bugs or request features
- WordPress Forums: Community support
- Website: groundworx.dev
- Support Development: Ko-fi
Found this tutorial helpful? Share it with your WordPress community!
