Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Version 4.0 is out! Version 4.0 is out! Version 4.0 is out!
Version 4.0 is out! Published on: 24/09/2021

This one has been a long time coming. Almost exactly 4 months since the last release, so we are more than excited to present version 4.0 which drastically improves the plugin on all fronts! Let's get into it without any further ado.


Making the complete suite of components faster and more stable was of utmost importance.

Shadow DOM

While development on version 4 started mainly with the goal of integrating the plugin into more page builders and tools, one thing became clear: shielding the components from the environment they are being used in is close to impossible. The only real way out of this was to rewrite all components using Shadow DOM.

An important aspect of web components is encapsulation — being able to keep the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash, and the code can be kept nice and clean. The Shadow DOM API is a key part of this, providing a way to attach a hidden separated DOM to an element. This article covers the basics of using the Shadow DOM.
MDN Web Docs

Now, components are being protected from any styles that are being applied from the outside, while still able to be styled using CSS variables and slots. This also opens the door for easier integrations into page builders without the risk of clashing CSS rules.

For more information on how Shadow DOM makes faster components, check out this article .

No more runtime CSS

Traditionally styles have been applied to elements using Emotion . This meant that on page load, component CSS had to be generated on the client. While this had advantages for the development of the plugin (everything was in one .js file), the performance impact became quite noticeable, especially when creating the element editor .

Now, all CSS is already precompiled and being injected as Constructable Stylesheets or as an inline style tag for browsers that don't support Constructable Stylesheets yet. Wohoooo. 💨


Creating a better and more cohesive experience across all components was another focal point of this release.

Better Shortcodes

Shortcodes are more powerful than ever, as it is now possible to use PHP helpers inside Shortcode attributes.

[spx-masonry images="my_gallery, acf" type="acf"]

The above code would be the equivalent of:

<spx-masonry images="<?php spxGetImages('my_gallery', 'acf'); ?>" type="acf"> </spx-masonry>

Environment independence

Components now automatically know if they are being used in another Shadow DOM enabled web component or the document body and adjust accordingly. This opens the door for anyone wanting to use spx inside their own web components.

New responsive engine

Besides responsively styling components using CSS variables, attributes can now also be changed depending on screen size using the following syntax:

<spx-navigation bp-1024='{"font-size": "18px"}' bp-1280='{"font-size": "24px"}'> </spx-navigation>

Every data attribute that starts with bp- will automatically be added to the responsive options. The number after the dash indicates the screen size (in pixels) when the new settings should be applied. (mobile-first) The example from above is the equivalent to the following CSS:

@media (min-width: 1024px) { body { --spx-navigation-font-size: 18px; } } @media (min-width: 1280px) { body { --spx-navigation-font-size: 24px; } }

Responsive attributes have the big advantage that every component property can be changed depending on the current screen size, even ones that don't have a CSS variable counterpart! This means that you can create fully responsive versions of components without ever leaving the markup of the page.

Tailwind config

Some components like the Accordion or the Edit Button allow you to style the components using Tailwind utility classes. Internally, spx is using Twind to apply those classes to the elements. With version 4.0, it is now possible to add your own Tailwind configuration by adding a variable with the name of spxTailwindConfig to an inline script on the page.

var spxTailwindConfig = { theme: { colors: { gray: colors.coolGray, blue: colors.lightBlue, red: colors.rose, pink: colors.fuchsia, } } }

The configuration will be available to all components that use headless styling and the new Tailwind element.

New components

Is it really a new major release without some new components? We don't think so.


The utility driven framework has taken the frontend world by storm for a good reason: It keeps styling and markup together, makes naming CSS classes redundant and speeds up web development. Now, Tailwind can be used without including any CSS files, simply by wrapping your code inside this new component.

<spx-tailwind> <div class="flex items-center justify-center"> <div class="max-w-md bg-white rounded-xl overflow-hidden shadow-lg"> <div class="p-4"> <img class="rounded-xl" src="{{ url.examples }}/7.svg" alt="" /> </div> <div class="flex justify-between p-6"> <div class="flex items-center space-x-4"> <img class="h-10 w-10 object-cover rounded-full" src="{{ url.examples }}/2.svg" alt="" /> <p class="text-lg text-gray-900 font-bold">John Doe</p> </div> <div class="flex space-x-6 items-center"> <div class="flex space-x-2 items-center"> <span> <svg xmlns="" class="h-6 w-6 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z" /> </svg> </span> <span class="text-gray-700 font-semibold">20</span> </div> <div class="flex space-x-2 items-center pr-4"> <span> <svg xmlns="" class="h-6 w-6 text-red-600 hover:text-red-500" viewBox="0 0 20 20" fill="currentColor"> <path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd" /> </svg> </span> <span class="text-gray-700 font-semibold">22</span> </div> </div> </div> </div> </div> </spx-tailwind>

John Doe


All classes recognised inside the element will be generated dynamically and added to the to page.

Text Path

Wrapping text around paths is possible with SVGs, but not quite as straightforward as other techniques. The new Text Path component is here to change that and give you an easy way to accomplish this neat visual trick.

<spx-text-path text="This text is wrapping around a circle path" text-font-weight="600" text-transform="uppercase" start-offset="20%" src="{{ url.examples }}/3.svg"> </spx-text-path>

In the future, other (and custom) paths will be supported, but for now the component is limited to a circle shape.

Element editor

If you've been following spx for the beginning, you might remember a time when there was a Playground page that enabled playing around with all available components and it's attributes. Due to a wrong design approach, the page was eventually shut down, as it's poor design choices meant that maintaining it became too much of a bottleneck down the road.

However, over the last months we have worked hard to bring an update version of the editor back and it is more powerful and stable than ever!

Check it out here!

Breaking changes

To really give our users the best product possible (now and in the future), a couple of changes were inevitable. Ultimately, this means that we are tightening up the whole experience of using spx and setting a more solid base for years to come.

Bye Snackbar

When spx was released 1.5 years ago, it's exact future wasn't clear. Today, the vision is pretty simple: create a universal element library that can be used with page builders and by itself.

Since Snackbars (or Alerts) are usually more UI related, it didn't make sense to continue keeping it in the plugin. On top of that, it wasn't really following the principles of how the other components work, as it was rendering an element outside of the component and then destroying itself.

If you were relying on the Snackbar component in any of your sites, we suggest you to take a look at the Shoelace component library instead.

Mockup responsiveness

Since the devices of the Mockup element are built using absolute px units (to ensure the correct size ratios), we had to create a customised solution using CSS transform to adjust its size depending on the screen width.

The problem with that approach was the lack of specific size controls on top of being dependant on the outer element. Since all spx components are now encapsulated by the Shadow DOM, this solution wasn't working anymore.

Now, the element size is being controlled by a minimum and maximum value which will scale the component accordingly depending on the screen size.

<spx-mockup type="iphone-x" size-min="0.2" size-max="0.5" src="{{ url.examples }}/4.svg"> </spx-mockup>

Of course, these values can be altered for different media queries with CSS variables or responsive attributes.

Other changes

To ensure a cohesive API and unified experience across all components, the following attributes have been renamed:

  • Accordion: disable-animation → animation (boolean)
  • Accordion: font-size-max → font-size-header-min, font-size-header-max
  • Accordion: font-size-min → font-size-content-min, font-size-content-max
  • Accordion: indicator-icon → icon
  • Accordion: indicator-icon-transform → icon-transform
  • Accordion: indicator-icon-type → icon-type
  • Code: scrollbar → hide-scrollbar (boolean)
  • Edit Button: position → left, right, top, bottom
  • Edit Button: position-css → position
  • Iframe: padding → loader-padding
  • Image Comparison: loading → lazy (boolean)
  • Masonry: images-src → image-src
  • Slider: images-src → image-src
  • Slider: pagination-bullets-space-between → pagination-bullets-gap
  • Slider: space-between → gap
  • Slideshow: images-src → image-src

Animate: doesn't animate it's opacity value by default anymore, so it can be used with auto-alpha instead of opacity.

Typewriter: to animate multiple texts one after the other, the delimiter attribute has to be used now to specify the start of the new sentence. This change was made since the original approach of wrapping all sentences in an array (['text one', 'text-two']) broke Shortcodes.


This new version is setting the groundwork for a lot of exciting features to come. The redesign of the editor meant that we were able to create a variety of control elements that are going to be playing an important role in extending the Edit Button and related it's related component family.

Furthermore, the introduction of Shadow DOM to all components really solidified future integrations into other page builders. Bringing the whole element suite to Gutenberg is already underway and can be expected for Version 4.1. Of course, that doesn't mean that spx can't be used with everything already as Shortcodes!

For a full list of new changes, please visit the changelog .