A client site I look after has the same decoration on every page: a thin SVG grid sitting behind the top of each section, full width, rendered at exactly 1440×192, stretched. Sixteen pages, one decoration. It sounds like a five minute job. Instead I failed three times in three different ways, each failure with its own distinct root cause, before landing on the one combination that actually works.
Some context on why I insisted on native elements. The decoration used to live as page-scoped ::before custom CSS, around 28 thousand characters of it, with every selector pinned to Elementor element IDs. Every time a template got re-applied, Elementor regenerated those IDs and the whole thing broke at once. So the goal was clear: the decoration had to become a real Elementor element, with no fragile selectors that could die at any moment.
Failure one: background image on the container
The lazy route first: make the SVG the container's background_image and set background_bg_width to 1440. Result: the SVG rendered at its natural size, 1459×520, not the 1440×192 I asked for.
Root cause: background_bg_width only controls width. It emits background-size: 1440px, a single value, which leaves the height on auto. Once height is auto, the SVG's intrinsic ratio wins, and that is exactly where 1459×520 comes from. There is no native control that forces both dimensions on a container background.
Failure two: offset orientation "center"
New strategy: give the decoration its own container with position: absolute and just center it horizontally. Elementor's settings have _offset_orientation_h, so I set it to center and expected to be done.
The emitted CSS: left: 0px. No error, no warning, just silently wrong. It turns out the schema for _offset_orientation_h only accepts two values, start and end. center is not in the enum, so Elementor falls back to start without saying a word. This is the most annoying class of failure: the setting looks saved, the output is lying.
Failure three: left 50% plus translate
Fine, the classic CSS trick then: left: 50% plus translateX(-50%). Elementor has _transform_translate_popover for exactly this. I filled the popover in, checked the output, and the CSS variable did show up: --e-con-transform-translateX: -50%. But only the variable. No transform rule ever appeared to consume it.
Root cause: toggling the popover alone does not activate Elementor's transform rule output. The variable gets set, the rule never renders, and visually nothing happens.
The one that worked
All three failures share one pattern: I kept trying to center the element. The approach that works stops centering the container entirely, spans it across the full ancestor instead, and lets flex do the centering inside.
Concretely: one decoration container as the first child of the section, position: absolute, and here is the key, set BOTH _offset_x: 0 AND _offset_x_end: 0. With both filled in, the emitted CSS becomes left: 0; right: 0, which stretches the container across the entire positioned ancestor. Then flex_justify_content: center centers the content, and z_index: 0 keeps the decoration behind everything.
{
"container_type": "flex",
"content_width": "full",
"min_height": { "unit": "px", "size": 192 },
"flex_direction": "row",
"flex_justify_content": "center",
"flex_align_items": "flex-start",
"position": "absolute",
"_offset_orientation_h": "start",
"_offset_x": { "unit": "px", "size": 0 },
"_offset_x_end": { "unit": "px", "size": 0 },
"_offset_orientation_v": "start",
"_offset_y": { "unit": "px", "size": 0 },
"z_index": 0
}Note that _offset_orientation_h stays on start. That is the lesson from failure two: start and end are the only values that exist, so stop fighting the enum.
Inside that container, a single image widget locked to exactly 1440×192:
{
"image_size": "full",
"width": { "unit": "px", "size": 1440 },
"height": { "unit": "px", "size": 192 }
}The last piece lives in the SVG file itself: it has to keep preserveAspectRatio="none". Without it, the width and height attributes on the img tag cannot force the stretch, and the 1459×520 ratio wins again. With it, the browser obeys the 1440×192 I asked for.
Finally, every content sibling in the section got bumped to z_index: 1 so nothing ends up hidden behind the decoration. I applied the pattern identically across all sixteen pages, then deleted the 28 thousand characters of per-page custom CSS for good. Templates can now be re-applied as often as anyone likes and the decoration never breaks.
The takeaways
- Elementor's background controls cannot force both dimensions.
background_bg_widthemits a single-valuebackground-size; height always follows the intrinsic ratio. - Settings values outside the enum fail silently.
centeron_offset_orientation_hbecameleft: 0pxwith no error. Always verify the CSS that actually ships, not the setting that got saved. - The transform popover needs more than being filled in. If all you get is a CSS variable with no rule consuming it, stop wasting time fighting it.
left: 0plusright: 0plus flex centering beatsleft: 50%plus translate for full-width absolute elements.- An SVG you want stretched must carry
preserveAspectRatio="none". Without it, the dimensions you lock on the widget mean nothing.
