An FAQ section on a client site needed a decorative circle sitting behind it, centered at every viewport width. The section is reused across 16 pages, so I needed one pattern that survives duplication, not a position hack retuned on every page.
First attempt: an absolutely positioned decoration container. That dead end exposed itself fast. Elementor's offset controls only anchor an element to start or end; there is no center anchor. A px offset can land the circle dead center, but only at ONE viewport width per breakpoint. Nudge the browser width and the circle drifts. For an element whose entire job is "always centered", the approach loses before it starts.
So I changed strategy: drop the container and make the circle the section's background_image. A background gets background_position: center center for free, and that centers at every viewport width with zero offset math. That left exactly one thing to control: size. The SVG is drawn on a 600x600 canvas, and the design wanted a different width per breakpoint. Elementor ships background_bg_width for exactly this.
Since the pattern lives on 16 pages, I set the section settings in code instead of clicking through the editor. I filled background_bg_width with 720px for desktop, 528px for tablet, 336px for mobile, then checked the CSS Elementor generated. There was no background-size rule at all. Not a wrong value. The rule simply never got written.
Dead ends: the data is there, the CSS is not
The obvious first suspect is a failed save. I checked the stored section data: background_bg_width was saved cleanly, unit px, size 720. Not it. I regenerated Elementor's CSS and hard refreshed; still nothing. The control name was correct too, no typo. Every standard suspect fell away while the symptom stayed consistent: my custom width values were dead data sitting in the database.
The root cause: 'Custom' in the UI is initial in the data
The answer only surfaced when I read the background control definition in Elementor's source. The Display Size dropdown is an enum with four values: auto, cover, contain, and initial. The misleading part: the value initial is labeled "Custom" in the UI. Those two words never met in my head, because nothing in the editor hints that the "Custom" you see on screen is stored as initial.
And that explains the symptom exactly: background_bg_width is only emitted to CSS when background_size is precisely initial, and it comes out as background-size: Npx auto. An empty string emits no rule at all. auto renders the SVG at its natural size. I was writing settings in code and never touched initial, so Elementor dutifully ignored every width value I supplied.
The fix
Once you know the magic value, the fix is short. I deleted the old absolutely positioned container for good and gave the section this one block of settings:
'background_background' => 'classic',
'background_image' => [ 'url' => $svg_url, 'id' => $svg_attachment_id, 'source' => 'library' ],
'background_position' => 'center center',
'background_repeat' => 'no-repeat',
'background_size' => 'initial', // 'initial' = "Custom" in the UI
'background_bg_width' => [ 'unit' => 'px', 'size' => 720 ],
'background_bg_width_tablet' => [ 'unit' => 'px', 'size' => 528 ],
'background_bg_width_mobile' => [ 'unit' => 'px', 'size' => 336 ],The background asset itself is an SVG of roughly 150 bytes:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600"><circle cx="300" cy="300" r="300" fill="#F6F1F6"/></svg>With background_size set to initial, the CSS I had been waiting for finally showed up:
/* desktop */
background-size: 720px auto;
/* @media (max-width: 1024px) */
background-size: 528px auto;
/* @media (max-width: 767px) */
background-size: 336px auto;The circle now auto-centers at every viewport, with zero offset math, and the pattern propagates across all 16 pages without per-page tuning.
The takeaway
- Elementor UI labels are not data values. "Custom" in the Display Size dropdown is stored as
initial. When you set settings in code, read the control definition instead of guessing from the label. background_bg_widthonly emits whenbackground_sizeis exactlyinitial. An empty string means no rule at all, andautomeans the image's natural size.- For decoration that must always stay centered, a section background image with
center centerbeats absolute positioning: no offsets that are only accurate at one viewport width, and it survives every breakpoint.
