Skip to content
ThemesIonic — home
Elementor

Custom CSS in Elementor

Elementor offers four places to add custom CSS, each with a different scope and a different lifespan. Picking the wrong one is what makes an override impossible to find six months later.

Updated 5 min read intermediate

Where Elementor lets you put custom CSS, in short: four places, each with a different scope and a different lifespan — per-widget, per-page, sitewide through Elementor's own settings, and the child theme stylesheet outside Elementor entirely. Picking the wrong one for the situation is what makes an override impossible to find six months later.

The four places, and their scope

Location Scope Requires Pro Survives removing Elementor
Widget Advanced tab, Custom CSS That one widget instance only Yes No
Page settings, Custom CSS That one page only Yes No
Site Settings, Custom CSS Every page Elementor renders Yes No
Child theme stylesheet Wherever the selector matches No Yes

The first three are Elementor features stored as Elementor data — they render only while Elementor is active, and they are edited from inside the editor rather than a code file. The fourth is ordinary CSS in a child theme's stylesheet, loaded the normal WordPress way regardless of what page builder, if any, is running. Unlike the per-breakpoint responsive controls described in making an Elementor site mobile responsive, none of the four Custom CSS fields are device-aware by default — a rule applies at every width unless the CSS itself includes a media query.

The selector keyword

Widget- and page-level custom CSS in Elementor uses a placeholder, typically written as selector, standing in for the specific, auto-generated class Elementor assigns to that widget or page wrapper. Writing selector { color: red; } compiles to the real class at render time. This is what makes widget-level CSS portable between elements using the same pattern — copy the rule into another widget's Custom CSS field and it targets that widget instead, with no manual editing of the selector needed.

Specificity fights with Elementor's own output

Elementor generates its own CSS for every style control set through the UI — colors, spacing, typography — and that generated CSS is what any custom CSS has to out-rank to take visible effect. Site Settings custom CSS and child theme CSS are both plain stylesheets subject to ordinary cascade and specificity rules, so a rule with too low a specificity, or one loaded before Elementor's own stylesheet, can lose silently rather than throwing any kind of error. Widget-level custom CSS is compiled against the widget's real, auto-generated class, which tends to be specific enough to win against Elementor's generated rules for that same element without extra effort — a large part of why it gets reached for even when it is the wrong tool for a sitewide change. When a rule appears to do nothing, checking computed styles in browser dev tools to see which declaration is actually winning is faster than guessing, the same debugging step covered in when Elementor changes don't show and in troubleshooting CSS that won't load.

Why per-widget CSS is invisible to an audit

Site Settings custom CSS is visible in one place. A child theme stylesheet is visible in one file. Widget- and page-level custom CSS is neither — it is scattered across however many individual widgets and pages someone decided to add a rule to, with no sitewide index of what exists or where. Auditing a site's actual CSS footprint means opening every widget's Advanced tab individually, which nobody does until something breaks — usually the front-end-looks-wrong failure mode described in Elementor not working rather than an editor crash — and the fix turns out to be a three-line rule buried in a widget nobody remembers touching. This is the strongest practical argument for keeping any rule with more than one use in Site Settings or the child theme stylesheet instead — visibility, not code quality, is what is actually at stake.

What happens if Elementor is removed

Widget, page, and Site Settings custom CSS is stored as Elementor data and rendered by Elementor's own output pipeline. Deactivate or remove Elementor and all three stop rendering immediately, along with the layout those rules were adjusting for. Child theme CSS is unaffected either way, since it never depended on Elementor to begin with. This mirrors the same lock-in shape other Elementor-specific features carry, worth weighing alongside the broader trade-offs described in Elementor Free vs Pro.

Practical guidance

  • A one-off, single-element tweak, like nudging one widget's line-height: widget-level Custom CSS is fine, since it is contained and the blast radius of forgetting about it is small.
  • A rule reused across many widgets or pages: Site Settings custom CSS or the child theme stylesheet, not copy-pasted into each widget individually.
  • Anything the site should keep if Elementor is ever replaced: the child theme stylesheet, full stop. This is also where general custom CSS in WordPress belongs when no page builder is involved at all.
  • Typography adjustments a built-in control already covers, such as those handled by changing font size in Elementor, belong in that control rather than a CSS override. A value set through the UI stays visible to anyone else editing that widget later; a CSS override does not.

Common mistakes

  • Scattering the same rule across many widgets. Copy-pasted Custom CSS with no shared source drifts the moment one copy gets edited and the others don't.
  • Reaching for CSS before checking for a built-in control. Most spacing and typography adjustments already have a UI control; a CSS override just hides that the control exists.
  • Forgetting Elementor CSS disappears with Elementor. Anything meant to survive a future platform change belongs in the child theme stylesheet.
  • Fighting specificity with !important. It works until the next override needs to beat that one too, and the stylesheet accumulates increasingly forceful rules nobody wants to touch.
  • Never checking computed styles. A rule that appears to do nothing is a specificity or load-order problem almost every time, not a broken selector.

Verify

Open browser dev tools on a page carrying custom CSS from more than one source, and confirm in the inspector which declaration is actually applied, not just which rules exist. Then temporarily deactivate Elementor on a staging copy and confirm the child theme stylesheet still applies while everything Elementor-specific disappears, so the real dependency is known rather than assumed.

Frequently asked

It is a placeholder Elementor swaps for the real, auto-generated class of the widget or page being edited, so the rule you write targets that specific element without you needing to find its class name yourself.
The per-widget, per-page, and Site Settings custom CSS fields are part of the Pro feature set. A plain child theme stylesheet works regardless of whether Pro is active at all.
Almost always a specificity or load-order conflict with Elementor's own generated CSS for that element. Checking computed styles in browser dev tools shows which declaration is actually winning.

Related guides