The Complete Guide to Groundworx Carousel Block

Home / Resources / The Complete Guide to Groundworx Carousel Block
Groundworx Carousel Block

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:

  1. Navigate to Plugins → Add New
  2. Search for “Groundworx Carousel”
  3. Click Install Now, then Activate

Manual Installation:

  1. Download the plugin from WordPress.org
  2. Upload via Plugins → Add New → Upload Plugin
  3. Activate the plugin

Creating Your First Carousel

Step 1: Add the Carousel Block

  1. Create or edit a post/page
  2. Click the + icon to insert a block
  3. Search for “Carousel” or browse to Design → Carousel
  4. Insert the block

Step 2: Add Slides

The carousel automatically creates one slide. To add more:

  1. Click Add Slide in the block toolbar
  2. Or click the + icon inside the carousel
  3. 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:

  1. Less is more – Avoid setting too many default values
  2. Don’t override user controls – If the block has color settings, don’t force colors in CSS
  3. Keep specificity low – Use :where() so users can override your styles
  4. Test thoroughly – Always verify that block settings still work after adding custom styles
  5. 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

  1. Select the Mobile/Default tab
  2. Set Slides to Show: 1
  3. Select the Tablet tab
  4. Set Slides to Show: 2
  5. Select the Desktop tab
  6. Set Slides to Show: 3

Example: Hide arrows on mobile, show on tablet+

  1. Mobile/Default tab: Turn OFF arrows
  2. Tablet tab: Turn ON arrows
  3. 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:

  1. Configure your carousel for mobile (Type: loop, slides, etc.)
  2. Select the breakpoint where you want it to become a grid (e.g., Desktop)
  3. 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
  1. Configure your grid layout with these new options
  2. 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:

  1. Only ONE variation can have isDefault: true – If multiple variations have this, only the last one registered will be default
  2. The original block becomes a variation – Users can still access it from the variations list
  3. 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:

  1. Check that you have more slides than “Slides to Show”
  2. Verify JavaScript isn’t blocked by another plugin
  3. Check browser console for errors
  4. Disable other slider plugins that might conflict

Arrows/Pagination Not Showing

Issue: Navigation controls aren’t visible.

Solutions:

  1. Verify they’re enabled in block settings
  2. Check that your theme isn’t hiding them with CSS
  3. Ensure colors aren’t matching the background
  4. Try different arrow/pagination styles

Grid Fallback Not Working

Issue: Carousel doesn’t switch to grid at breakpoint.

Solutions:

  1. Select the breakpoint where you want grid layout
  2. Set “Disable Carousel At” to that breakpoint (not “Never”)
  3. Configure grid settings (columns or auto-fit)
  4. Check browser width actually reaches the breakpoint
  5. Clear cache (browser and WordPress)
  6. 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:

  1. Select the Image block inside your slide
  2. In the block toolbar or settings, find Aspect Ratio
  3. Choose a preset (1:1, 4:3, 16:9, etc.) or set a custom ratio
  4. 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:

  1. Verify Autoplay is enabled
  2. Check Interval is set (3000+ recommended)
  3. Ensure Type is “slide” or “loop” (not “fade” + rewind)
  4. 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:

  1. Limit carousels per page – Each carousel instance adds overhead
  2. Reduce number of slides – Keep carousels focused with 5-10 slides maximum
  3. Optimize slide content:
    • Use optimized images (WebP format, appropriate dimensions)
    • Avoid embedding heavy content (videos, complex blocks) in every slide
    • Keep slide markup simple
  4. 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

  1. Click the three dots (⋮) next to the breakpoint name (e.g., “Tablet”)
  2. Select Reset all
  3. All settings for that breakpoint return to “Inherit”
  4. The breakpoint now uses values from the previous smaller breakpoint

How to Debug:

  1. Start at Mobile/Default – set your base configuration
  2. Move to each larger breakpoint in order
  3. 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
  4. Use the three dots menu to reset any breakpoint causing issues
  5. 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

Get Support


Found this tutorial helpful? Share it with your WordPress community!

Let’s solve what’s holding you back.

Ready to Build Better WordPress Sites?

Join agencies and freelancers who’ve stopped fighting with page builders