D
P
0

WordPress & Elementor

Elementor POPOVER_TOGGLE: Saving 'yes' Gives Class e-yes, and Your Transform Never Fires

June 10, 2026·3 min read
Elementor POPOVER_TOGGLE: Saving 'yes' Gives Class e-yes, and Your Transform Never Fires

While building a custom Elementor widget on a WordPress site I maintain, I needed a transform (rotate) feature that could be switched on through a popover toggle control. The logic looked straightforward: save "yes" when the toggle is on, and my CSS targeting the transform class would fire. Except the transform never fired. The element simply didn't rotate.

The symptom: the class that appeared wasn't the one I expected

I was saving the toggle value like this, assuming "yes" was the correct "on" value:

// value saved when the toggle is on
'_transform_rotate_popover' => 'yes',

My CSS targeted the transform class I assumed Elementor would attach:

.e-transform {
    transform: rotate( var( --e-transform-rotateZ ) );
}

But when I inspected the element in the browser, the class that appeared was not .e-transform. What showed up instead was:

<div class="elementor-element e-yes">

e-yes. Not e-transform. And because my CSS targeted .e-transform, the selector never matched anything → the transform never applied. The element sat still, with no error at all.

The cause: POPOVER_TOGGLE concatenates prefix_class + return_value

Here's the part that caught me out. Elementor's POPOVER_TOGGLE control builds its CSS class by concatenating two things: a prefix_class (here 'e-') with the control's return_value — not with the literal string "yes".

So the final class is prefix_class + return_value. If I save "yes", Elementor assembles 'e-' + 'yes' = e-yes. The one I wanted — e-transform — only appears if the saved value is 'transform', not 'yes'.

In other words, return_value is not a boolean on/off flag. It's a class-name fragment appended to the prefix. I was treating this toggle like a plain checkbox that stores "yes", when Elementor expected a class-name token.

The fix: save the return_value, not "yes"

The fix is to save the actual return_value token — 'transform', 'translate', 'scale', or 'skew' — so the generated class matches my CSS:

// save the return_value token, not "yes"
'_transform_rotate_popover' => 'transform',

Now Elementor assembles 'e-' + 'transform' = e-transform, my .e-transform selector matches, and the rotate applies:

.e-transform {
    transform: rotate( var( --e-transform-rotateZ ) );
}

Valid tokens follow Elementor's transform group: transform, translate, scale, skew. Use the token that matches the class your CSS targets.

Don't forget the responsive variants and CSS regeneration

Two follow-on steps that are easy to miss:

Add the desktop base plus per-breakpoint variants. If the transform needs to differ on tablet/mobile, set the desktop base plus the _tablet and _mobile keys:

'_transform_rotate_popover'         => 'transform', // desktop base
'_transform_rotate_popover_tablet'  => 'transform',
'_transform_rotate_popover_mobile'  => 'transform',

Regenerate Elementor's CSS after writing meta directly. If you set these values via code (rather than through the editor), the cached CSS won't update on its own. Force a rebuild:

\Elementor\Core\Files\CSS\Post::create( $pid )->update();

Without this step, the class may already be correct in the markup while the rendered CSS is still the old version — and you'll be chasing a bug that's actually already fixed.

The lesson

Elementor's POPOVER_TOGGLE looks like a boolean toggle, but its return_value isn't "on" — it's a class-name fragment appended to the prefix_class. Saving "yes" produces e-yes, not e-transform, so any CSS targeting the transform class never matches. Save the actual return_value token (transform, translate, scale, skew), include the responsive _tablet/_mobile variants, then regenerate the CSS via Post::create($pid)->update(). When an element refuses to react even though your CSS is "correct," inspect its class first: what's on it might not be what you think.