D
P
0
← All articles Baca dalam Bahasa Indonesia

Elementor: Under the Page Builder's Hood

Scaled Down with `transform: scale()` but the Layout Still Reserves the Full Width? The Layout Box Never Shrinks

· · 5 min read
Scaled Down with `transform: scale()` but the Layout Still Reserves the Full Width? The Layout Box Never Shrinks

The rule that produced this bug came from the client. On 18 May 2026 they flagged that responsive work has to be designed around the function and purpose of each component, and the example they reached for was the avatar: on one page it had stretched wide when an avatar should have stayed a circle. That complaint had history behind it. Several earlier rounds of bulk responsive operations, three batches of 18, 12, and 11 operations, had failed visually because they treated every flex child in exactly the same way, and the client called the result "jelek".

Out of that came a rule binding on the rest of the project: no hide_*, no rotation, every component visible at every breakpoint, and if a component is wider than the viewport, scale it down until it fits. The rule makes sense from the product side. The consequence only showed up in one section.

That section measured 1008×395, a radial diagram holding 12 tool icons and 6 connecting lines, its children absolutely positioned at hard pixel coordinates. The project's responsive recipe wrote the 1008 into 375 reduction as scale(0.37) displaying at 375×147. What actually shipped was 0.36. The arithmetic is easy to repeat: 1008 × 0.36 = 362.88, so roughly 363px of visual width in a 375 viewport. Visually that was correct. The diagram fit, its landscape orientation survived, nothing had to be enlarged to be readable.

What was not correct was everything standing next to it.

The visual shrank, the layout did not

The diagram lived inside a flex parent alongside two siblings: a title group and a CTA. At a 375 viewport the diagram read as 363px, but its flex parent stayed pegged at 1008px wide, and both siblings were pushed right until they left the screen. Two different truths on the same page: the eye saw 363, the layout counted 1008.

The stack was CSS on Elementor on WordPress, and none of those three was wrong here. What was wrong was my assumption that scale() changes an element's size.

scale() paints, it does not carve

transform: scale() is purely visual. The element's layout box keeps its original 1008px dimensions, so flexbox still lays out the siblings against the unscaled width. The transform happens later, after layout has already been computed, and it never goes back to tell flexbox that the contents are now a third of the width they were.

That is why forcing a smaller width_mobile on the diagram is not the escape hatch. The transform needs that original box in order to scale something correct. Shrink the box and the diagram inside falls apart, because its children sit at absolute coordinates measured against a width of 1008.

Keep the box, then move the box

The decision I made was to leave width_mobile at 1008 and compensate for the overhang with explicit negative left margins on all three of the section's children, so they re-center inside the 375 viewport.

You can derive the number yourself. If that 1008-wide box starts at the left edge of a 375 viewport, the overhang is 1008 - 375 = 633px, and half of that is 316.5px per side. What I set was -320, so about 3.5px further left than the theoretical center. There is room for that, because a 363px visual inside a 375 viewport still leaves 375 - 363 = 12px, six pixels on each side.

One Elementor detail makes changes like this feel like they are not sticking: containers use the margin key while widgets use the _margin key. The diagram and the title group are containers, the CTA is a widget, so the keys differ even though the intent is identical.

radialDiagram.width_mobile          = 1008   // original box kept for the transform
radialDiagram.margin_mobile.left    = -320
radialTitleGroup.margin_mobile.left = -320
radialCta._margin_mobile.left       = -320   // widget uses _margin
radialCta._margin_mobile.top        = 60     // spacing from the scaled diagram

The trick lives on the mobile breakpoint only. Tablet at 1024 and desktop were already correct without any negative margin, and adding it there would only break what already worked.

Verification

The final result was checked across four viewports, 375, 768, 1024, and 1440, with zero overflow. This negative-margin fix is recorded in the project memory as verified rather than merely proposed, and for a trick that looks as fragile as the number -320, that distinction carries weight.

The procedure I held to for all responsive work on that project was never just an overflow check. After every change, take a screenshot at the target viewport and inspect the shape integrity of each element type one by one. Zero overflow does not mean the avatar is still a circle.

The takeaway

This case entered the project's recipe notes as pitfall number 20 out of a final count of 21. Three things came out of it.

First, transform and layout live on two different layers, and flexbox only ever sees the lower one. When an element is scaled but its neighbours behave as though it were still full size, you are not looking at a flexbox bug, you are looking at the definition of transform doing exactly what it says.

Second, the project's general container recipe was fixed px on desktop and 100% of the viewport width on mobile and tablet, paired with _flex_size: none so it cannot shrink. But a general recipe stays general. A blanket rule like "all containers get width 100% on mobile" cannot be trusted, because it applies to layout containers, not to avatar, icon, or decoration containers that need to hold their aspect.

Third, and this is the one I keep forgetting during large batches: stacking and scaling alone is never enough. Avatars stay circles, icons keep their aspect, pills stay pills, buttons stay tappable. Responsive work is a redesign per component semantics, and a 1008px radial diagram is a component whose semantics refuse to be clipped, hidden, or rotated. The only thing you are allowed to do to it is make it smaller, then tell it where to stand.