Skip to content

Instability of output during repeated formatting when parent element needs vendor prefixes #478

@thecrypticace

Description

@thecrypticace

Hi! 👋

While working in the Tailwind CSS tests a change in Lightning CSS 1.19+ caused instability in the input/output when formatting multiple times. What I've done here is taken the input and formatted it, taken that output and formatted it again, and done the same thing again.

Basically this:

  • format(input)
  • format(format(input))
  • format(format(format(input)))

The reason we do this is that we format both the received input as well as the expected output files with Lightning CSS — this us perform a meaningful diff even when the input might actually produce rules that are not merged due to slight formatting differences. If we try to update the expected file with the output Lightning CSS gives us it's still not 100% correct because when it formats it again it'll change.

For example, this CSS is produces different output when passed back into lightning CSS multiple times:

/* Original Input */
.foo:placeholder-shown .bar { color: red; }
.foo:autofill .baz { color: red; }

/* Processed 1 time with Lightning CSS */
.foo:placeholder-shown .bar,.foo:autofill .baz{color:red}

/* Processed 2 times with Lightning CSS */
.foo:-webkit-placeholder-shown .bar,.foo:-webkit-autofill .baz{color:red}.foo:placeholder-shown .bar,.foo:autofill .baz{color:red}

/* Processed 3 times with Lightning CSS */
.foo:-webkit-placeholder-shown .bar,.foo:-webkit-autofill .baz,.foo:-webkit-placeholder-shown .bar,.foo:-webkit-autofill .baz{color:red}

However, this CSS produces the same output when passed back into lightning CSS multiple times — the difference here is that the thing with the vendor-prefixable pseudo-class is not the last item in the selector:

/* Original Input */
.bar:placeholder-shown { color: red; }
.baz:autofill { color: red; }

/* Processed 1 time with Lightning CSS */
.bar:placeholder-shown{color:red}.baz:-webkit-autofill{color:red}.baz:autofill{color:red}

/* Processed 2 times with Lightning CSS */
.bar:placeholder-shown{color:red}.baz:-webkit-autofill{color:red}.baz:autofill{color:red}

/* Processed 3 times with Lightning CSS */
.bar:placeholder-shown{color:red}.baz:-webkit-autofill{color:red}.baz:autofill{color:red}

So it appears that when a parent element needs vendor prefixes on a selector the prefixes are not added immediately but only in subsequent formatting passes. However, if the last item in a selector is the one needing a vendor prefix it seems to be added as expected.

This is reproducible in the Lightning CSS playground as well:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions