stylelint: Add `at-charset-rule-no-invalid`

What is the problem you’re trying to solve?

I went to fix this bug. And found out that @charset is not even an at-rule, but a special construct with much stricter syntax requirements than at-rules. And it doesn’t seem to be about choosing a formatting style at all. After all, if the quotes are single, the parser will just pass it by without recognizing it as an encoding declaration. It is good if the encoding is utf-8, which is the default encoding. But if another encoding is used, it will probably cause an error.

So it’s so much a matter of syntax (rather than formatting style) that the rule controlling @charset:

  1. should be in Stylelint itself, not in the plugin;
  2. should have one single option — the value true;
  3. should be added not even to the standard, but to the recommended config.

What solution would you like to see?

Add a separate rule to control the @charset syntax, which would take into account the character set of this declaration, its location in the style file, and maybe something else I may not know about yet.

About this issue

  • Original URL
  • State: open
  • Created 5 months ago
  • Comments: 17 (17 by maintainers)

Most upvoted comments

Correct, the default is utf-8 anyway and I haven’t used @charset in ages.

The primary use case is:

  • you do not have control over the http response headers for the stylesheet (this is not uncommon)
  • there is an environment encoding (this is extremely rare)
  • the stylesheet encoding differs from the environment encoding (this is extremely rare)

In that very specific case you can use @charset "utf-8" (or your encoding instead of utf-8) to make sure your stylesheet is correctly read.

Today it would be exceedingly rare to need this given that everything has become utf-8 by default.


I think there can be general guidance that @charset is not something you need. While I also agree with @firefoxic that if people do include it that it must be correct.

I have already started to think about how much, what and how I will have to change in the plugin in view of everything discussed here.

But I decided to take a look at the Stylelint code — it turns out that it also needs a lot of changes. For example:

image

And if in the readme files in the code examples @charset can easily be replaced by any @layer without losing much of its meaning, then the code where the logic relies on the fact that @charset can be written in different ways will also need to be corrected somehow.

Also, considering that @charset is not an at-rule at all, it might be better to ignore @charset in the linter rules that regulate the at-rules.


Looks like I’ve opened a closet whose junk has us all in over our heads 🤪

I’ve opened an issue to ask the spec editors directly : https://github.com/w3c/csswg-drafts/issues/9838

As far as I understand it, if the developer even crookedly wrote something like charset somewhere, he wanted to rely on what he specifies. And the linter needs to see to it that it’s spelled correctly (including the location of that declaration, yes).

There is no necessity for @charset of course.

And preceding content :

/* a comment */
@charset ... /* invalid because it is not at the very start */

Given the answer, it seems that the rule would still make sure that @charset "..."; is spelled correctly in the presence of something like it (disallow single quotes, upper case, spaces greater than one, no semicolons, etc.). Am I understanding this correctly?

I think this is an error/ambiguity in the mdn docs.

In CSS 2.1 @charset ... would be parsed as an atrule contruct. Later specifications require it to be dropped instead.

https://www.w3.org/TR/css-syntax-3/#charset-rule

So the deprecation is limited to how @charset ... is exposed or not to further parser internals and thereby to things like CSSOM.

If I am reading everything correctly