Firefox 72: Individual CSS Transform Properties

New in Firefox 72 is the ability to individually define CSS Transform Properties. You can now separately define scale, rotate, and translate CSS properties, instead of having to chuff them all into one single transform property.

The translate, rotate, and scale properties allow authors to specify simple transforms independently, in a way that maps to typical user interface usage, rather than having to remember the order in transform that keeps the actions of transform(), rotate() and scale() independent and acting in screen coordinates.

element {
  scale: 2;
  rotate: 30deg;
  translate: -50% -50%;
}

The order that they are applied is, as per CSS Transforms Level 2 spec, first translate, then rotate, and then scale — not the order which you define them in.

By having individual transform props, this also means that we can animate and transition them separately.

@keyframes individual {
  50% {
    translate: 0 50%;
  }
  75% {
    scale: 1;
  }
}
element {
  transition:
    rotate 200ms ease-in-out,
    scale 500ms linear;
}

element:hover {
  scale: 2;
  rotate: -3deg;
}

Here’s a pen demonstrating its usage:

See the Pen
Individual CSS Transform Properties Demo
by Bramus (@bramus)
on CodePen.

In Chrome these new props are still behind the #enable-experimental-web-platform-features feature flag.

~

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

How the CSS :is() selector will simplify things

One of the selectors in CSS Level 4 is :is(). It is the successor to :any() and :matches() (which are supplanted by :is()):

The :is() CSS pseudo-class function takes a selector list as its argument, and selects any element that can be selected by one of the selectors in that list. This is useful for writing large selectors in a more compact form.

/* Without :is */
article > h1,
article > h2,
article > h3,
article > h4,
article > h5 {
  /* … */
}

/* With :is() */
article > :is(h1, h2, h3, h4, h5) {
  /* … */
}

Browser Support isn’t quite there yet though, as they’re either all behind feature flags or use the outdated :matches() or (prefixed) :any()

MDN Web Docs; :is() (:matches(), :any())

Video via @argyleink

The future of CSS: Nesting Selectors

Early March the first draft for the CSS Nesting Module was published. The draft outlines a future mechanism by which we’ll be able to nest CSS selectors natively (e.g. in pure CSS, without the use of any preprocessors)

This module describes support for nesting a style rule within another style rule, allowing the inner rule’s selector to reference the elements matched by the outer rule. This feature allows related styles to be aggregated into a single structure within the CSS document, improving readability and maintainability.

Using the & selector (read this as “the nesting selector”), you can refer to the elements matched by the parent rule:

table.colortable {
  & td {
    text-align: center;
    &.c { text-transform: uppercase }
    &:first-child, &:first-child + td { border: 1px solid black }
  }
  & th {
    text-align: center;
    background: black;
    color: white;
  }
}

As it’s an actual selector, you always need to use the & selector, so you won’t be able to do this:

/* INVALID */
.foo {
  .bar {
    color: hotpink;
  }
}

(The fix would be to write & .bar instead of .bar)

The & selector can also only be used when it’s first compound selector (e.g. it appears at the first position) of an inner selector.

/* INVALID */
.foo {
  .bar & {
    color: hotpink;
  }
}

To cater to these scenarios you’ll need to use the @nest rule, which is more lax:

/* VALID */
.foo {
  @nest .bar & {
    color: hotpink;
  }
}

To me it feels like this @nest rule should go. The interpreter should be smart enough to figure things out all by itself.

CSS Nesting Module (Draft) →