DEV Community

Cover image for CSS max-width after transform + scale vs. pseudo elements
Ingo Steinke
Ingo Steinke

Posted on

CSS max-width after transform + scale vs. pseudo elements

Another one of those situations where order of declarations matters (it often does in CSS anyway) and the don't even seem to be handled consistently across browsers.

Ensure max-width after scale transformation

A simple use case: restrict the maximum width of an element after transformation. Maybe this problem only applies to pseudo elements, but we'll see.

The actual case adds another aspect that might cause the problem: a translation on the Z-axis which will result in an additional perceived scale transformation when applied to a 2-dimensional browser window.

First, I apply a z-translation in order to set up a parallax perspective effect, then I apply a 2d scale to compensate for the perceived downsizing.

This worked fine so far (at least in Chrome / Chromium and Firefox, and only in my specific project setup, see below ...)

.container::after {
  content: ""; /* add more visual styles here */
  transform-origin: top left;
  transform: translateZ(-1px) scale(2);
Enter fullscreen mode Exit fullscreen mode

Now I want to add an additional restriction to a maximum width on wide screens, so I add

  width: auto;
  max-width: 100%;
Enter fullscreen mode Exit fullscreen mode

which also worked as intended on Chrome and Firefox. It did not even matter if I put the width before or after the translation, it still got applied to the resulting width - but not in Safari!

Safari consistently used another calculation order, no matter where I put the max-width in my code, it will never apply to the element's width after transformation.

Avoid this combination if you can

This important difference is either documented poorly or just hard to find. It might be another rare edge case that you should avoid if you can, or maybe "max-width", "scale", "transform", "order", and "Safari" are too broad and general terms to yield any helpful result apart from the usual go-to resources covering best practices for beginners.

Don't use transform:translateZ together with scale and max-width if you can avoid it.

But if you do ...

I got so frustrated about wasting my time on cross-browser issues again, that I was tempted to use a CSS browser hack to work around the issue. But this always feels like making it work without knowing why, beyond the perceived browser behavior.

What I actually want to do is state explicitly that the max-width must be applied to the pseudo element after the transition, not before.

Now it seems I finally rephrased my problem in a way where I start getting helpful results after all.

Screenshot of search results

People also asked:

I did not even read the other two, because as I prepared a codepen to reproduce the problem in an isolated way, I found it hard to make it behave as I described.

In short, transformation combined with max-width does not work well, sometimes not at all, on a pseudo element (like .container::after but it does work well on a regular DOM child.

So if you do ...

Avoid using the problematic combination on pseudo elements and make sure to use regular child nodes instead.

Maximum width will then be applied to the calculated width after the transformation has been applied.

Here is the codepen: Transform + max-width on child nodes vs. pseudo elements

Top comments (0)