@charset

Juan Diego Rodríguez on

Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.

The @charset declaration (it’s not technically an at-rule) sets the stylesheet character encoding. It isn’t a proper at-rule, but a byte sequence that says how to decode the stylesheet. As a result, it has to be the first thing the browser reads, so it has to be written before anything else in CSS, even comments.

@charset "UTF-8";

The @charset at-rule is defined in the CSS Syntax Module Level 3 specification.

Syntax

@charset <character-set>;

Arguments

@charset "UTF-8";
@charset "ISO-8859-7";
  • <character-set>: The character set enclosed in a string. 99.9% percent of the time, it will be "UTF-8", but it could be another valid character set.

Not an at-rule!

While formatted as one, @charset isn’t an at-rule! In CSS 2.1 @charset was a valid rule, but it shouldn’t be regarded as one nowadays. To understand why, we need to know that before parsing, a stylesheet might initially be just a stream of bytes which has to be decoded by the browser. And to decode the stylesheet, it will read its first byte sequence to determine the encoding used. This first byte sequence is what @charset really is, communicating to browsers the stylesheet’s encoding.

Since @charset defines the encoding for a CSS file, it’s just ignored if we use it inside a <style> tag or style attribute in HTML.

Basic usage

For our stylesheet to be parsed correctly, we have to write the @charset declaration as the first thing in our CSS, before any other @import@namespace and even comments. We can then set the character set used for the encoding as a string, which is usually "UTF-8" ("utf-8" also works fine).

@charset "UTF-8";
/* Unicode */

We can change it to some other encoding. However, just declaring the encoding inside our stylesheet won’t actually change the bytes — it’s just a hint for browsers on how it was encoded, but it doesn’t change the encoding process. To do so, you have to save your stylesheet in that encoding. Once that’s done, you can write the corresponding @charset declaration.

@charset "ISO-8859-7";
/*  Latin/Greek alphabet */

Is it deprecated?

You and I have probably never written a @charset declaration, and yet somehow our CSS doesn’t spontaneously combust. Different encodings for the web also seem like a thing from the past, especially if most things on the web use UTF-8 by default. This prompts the question, is @charset deprecated? My answer is “No, but it’s still extremely, uncommonly, rarely, hardly ever needed”.

Even if UTF-8 is considered the standard encoding, a CSS stylesheet doesn’t have any default encoding. As the spec says, “CSS was created before it was clear which encoding would win, and thus can’t automatically assume the stylesheet is UTF-8.”

However, not setting @charset doesn’t seem to break anything, even if the spec does recommend using it. Luckily, browsers have fallback ways to choose a stylesheet’s encoding: it first looks at the HTTP encoding label and then if the HTML has a <meta charset="UTF-8"> tag, which almost everyone uses.

The confusion over whether @charset is deprecated or not comes from the switch from CSS 2.1 to CSS 3, in which @charset stopped being considered an at-rule. And while deprecated as an at-rule, it is still a valid piece of CSS supported on every browser.

Specification

The @charset at-rule is defined in the CSS Syntax Module Level 3 specification, which is currently in Editor’s Draft. You can also find a full list of all valid Character Sets in the Internet Assigned Numbers Authority site.

Browser support

More information