Skip to content

[css-syntax] Allow empty values for every production produced by # #13851

@LeaVerou

Description

@LeaVerou

Trailing commas were proposed in #4968 for gradients, and were rejected on the basis that it should be a language-wide thing (see #4968 (comment) by @tabatkins )
However, then no issue seems to have been filed to make it so 😅 Oh well, better late than never!

This would affect:

  • Comma-separated arguments in functions
  • List-valued properties
  • Where else do we use #?

Framing it around empty values on # rather than trailing commas covers more use cases:

  • Trailing commas (foo(bar, baz, ))
  • Leading commas (foo(, bar, baz))
  • Intermediate repeated commas (foo(bar,, baz))

Challenges:

  • Is it web compatible? Given that these are currently syntax errors, I think it has good chances to be, but you never know.
  • Does it change the meaning of existing grammars? Are there cases where we accept empty comma-separated values today and this would change the meaning of existing syntax? The only case I could think of is var() and other fallback-able functions. Thankfully, these are generally not defined via #! E.g. https://drafts.csswg.org/css-variables/#using-variables

Use cases

This will simplify many things:

1. Fallbacks

I find it quite readable to define variables with potentially-not-supported tokens instead of having @supports all over the place:

:root {
	--in-oklab: ;

	@supports (background-image: linear-gradient(in oklab, red, tan)) {
		--in-oklab: in oklab;
	}
}

.div {
	background: linear-gradient(var(--in-oklab), var(--color1), var(--color2));
}

But whoops, this is actually invalid in unsupporting browsers. You have to always remember to use some other token there as well (e.g. to bottom).

2. Commenting out layers in list-valued properties

Today, this is a syntax error:

background: 
	url(foo.png),
	url(bar.png),
	/* url(baz.png) */;

3. Literally any other time we want to combine variables into a list

E.g. If I have a color-interpolate(in oklab, var(--progress), var(--some-colors), var(--another-color), var(--another-color-dark)) there is no value I can set var(--some-colors) to to just remove it from the list.

4. Formatting & leaner diffs

In JS, it's common practice to use trailing commas in multiline structures to keep diffs smaller. This would allow doing this in CSS too.

5. Makes additive CSS easier

Regardless of whether we go with revert-rule() (#11773) or any of the ideas in #1594, it seems likely that we'd need to append or prepend values to a list. Not having to worry about what to do if they're empty seems like a big DX win.

Even doing this with JS is quite tricky today, see https://github.com/LeaVerou/style-observer/blob/main/src/element-style-observer.js where we have to insert a no-op fake CSS property (--style-observer-noop) to ensure the list-valued transition value is valid at all times.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions