CSS @charset Property
The @charset rule specifies the character encoding used in the style sheet. The @charset rule must be the first element in the style sheet. See Examples.
The @charset at-rule declares the character encoding used in an external stylesheet. Character encoding maps the raw bytes in a file to readable characters, so the browser needs to know which encoding a stylesheet uses before it can correctly interpret non-ASCII text — accented letters, currency symbols, emoji, or content inside content: "…" declarations.
This page covers when @charset actually applies, the strict syntax rules that make it easy to get wrong, how the browser decides which encoding wins, and the common pitfalls to avoid.
When does @charset apply?
@charset is strictly intended for external stylesheets (a separate .css file linked with <link> or pulled in with @import). It is ignored when:
- It appears inside an HTML
<style>block. - It appears inside an inline
styleattribute. - It is not the very first thing in the file.
In an HTML document itself, you set the encoding with the <meta charset> tag, not with @charset.
In practice you rarely need @charset at all: if you save your stylesheet as UTF-8 (the default for almost every editor and the recommended encoding for the web), the browser will usually detect it correctly. @charset matters most for legacy stylesheets stored in non-UTF-8 encodings, or as an explicit safeguard.
Syntax
@charset "encoding";The rule takes a single string naming an encoding from the IANA registry, such as "UTF-8" or "iso-8859-15".
The syntax is unusually strict — @charset is not a normal at-rule and does not honor CSS's usual flexibility about whitespace and comments:
- It must be the first byte of the stylesheet. No characters, comments, or even whitespace may come before it.
- The encoding must be wrapped in double quotes.
- There must be exactly one space between
@charsetand the opening quote. - The line must end with a semicolon.
@charset "UTF-8"; /* Set the stylesheet encoding to Unicode UTF-8 */Valid vs. invalid usage
Because of the strict rules above, small formatting differences flip the rule between valid and ignored:
@charset "UTF-8"; /* Valid: standard form */
@charset "ISO-8859-15"; /* Valid: any registered encoding name */
@charset "UTF-8"; /* Invalid: a space precedes the at-rule */
@charset 'UTF-8'; /* Invalid: single quotes are not allowed */
@charset "UTF-8"; /* Invalid: more than one space after @charset */
@charset "UTF-8" /* Invalid: missing the closing semicolon */
@charset UTF-8; /* Invalid: the value must be quoted */When @charset is invalid or ignored, the browser doesn't throw an error — it simply falls back to the next encoding source it can find.
How the browser chooses an encoding
@charset is only one of several signals, and it has a fixed priority. The browser uses the first source it finds, in this order:
- A byte order mark (BOM) at the start of the file.
- The
charsetparameter of the HTTPContent-Typeresponse header (e.g.text/css; charset=utf-8). - The
@charsetat-rule. - The
charsetattribute on the<link>element that loaded the stylesheet (deprecated). - The encoding of the referring document.
- A fallback of UTF-8.
Because a server-sent Content-Type header outranks @charset, a misconfigured server can override your declared encoding. This is one reason setting the encoding at the HTTP level (or simply using UTF-8 everywhere) is the most reliable approach.
Values
@charset accepts a single quoted string naming the character encoding, for example "UTF-8" or "iso-8859-1". It does not accept the initial or inherit keywords — those apply to CSS properties, and @charset is an at-rule, not a property.
Related at-rules
@import— pull one stylesheet into another. If used,@importrules must come right after any@charset.@media— apply styles conditionally based on media features.@font-face— load and name custom web fonts.