The quotes property sets which quotation mark strings the browser inserts for the HTML <q> element and for the open-quote / close-quote values of the content property.
Modern CSS uses auto for language-appropriate marks (via inherited lang). You can also set explicit string pairs for outer and nested levels, or use none to suppress marks. The property is inherited.
Baseline · Widely available.
Not deprecated. Standard-track CSS. Pair it with semantic <q>, or with ::before / ::after and content: open-quote / close-quote. Not a runtime API.
Set the pair on the element.quotes: "«" "» defines open and close strings.
Request open-quote.::before { content: open-quote; } inserts the first string.
Request close-quote.::after { content: close-quote; } inserts the second string.
Prefer <q> when possible. Generated content is useful when you cannot use <q>.
Edge Cases & Pitfalls
If the wrong marks appear, one of these is usually why.
pairs
Values come in open/close pairs
Always provide strings in pairs. A single string alone is invalid. Deeper nesting repeats the last pair when you run out of pairs.
lang
auto follows surrounding language
Put lang on an ancestor of the quote for the language of the surrounding text. Customary typography quotes the text with marks of the surrounding language, not necessarily the quote’s own language.
inherit
quotes is inherited
Setting it on a parent affects nested <q> elements. Override on a child only when that subtree needs different marks.
content
no-open-quote still changes depth
content: no-open-quote / no-close-quote change nesting depth without inserting marks. Useful for multi-paragraph quotations.
typing
Do not hard-code marks in HTML text
If you type “...” inside <q>, you get double marks. Let quotes (or generated content) insert them.
Compatibility
Browser Support
quotes is a browser CSS property for quotation mark strings. Node.js, Deno, and Bun do not apply it.
✓ Baseline · Widely available
quotes
Widely supported across modern browsers. String pairs work in long-standing engines including Internet Explorer. auto is the modern language-aware keyword.
97%Core support
Google ChromeAll modern
Full support
Mozilla FirefoxAll modern
Full support
Apple SafariAll modern
Full support
Microsoft EdgeAll modern
Full support
OperaModern
Full support
Samsung InternetAll modern
Full support
Internet Explorer8+ (pairs)
Partial
quotesWidely supported
Bottom line: Safe to teach and ship for string pairs and none. Prefer auto for language-aware defaults in modern browsers. It is not a runtime API.
Remember
Key Takeaways
Role: choose which strings become automatic quotation marks.
auto vs pairs: auto follows language; string pairs override with exact marks.
Nesting: first pair is outer; next pairs are deeper levels.
Hooks: works with <q> and with content: open-quote / close-quote.
One line: set quote string pairs (or auto), then let <q> or open/close-quote insert the marks — do not type them twice in HTML.
Frequently Asked Questions
It sets which quotation mark strings the browser uses for the HTML q element and for the open-quote and close-quote values of the content property, including nested quote levels.
Modern CSS treats auto as the language-appropriate default: the browser picks marks based on the inherited language (for example via the lang attribute). The formal initial value can depend on the user agent.
List open-close string pairs in order. The first pair is the outer level, the second is the first nested level, and so on. If nesting goes deeper than the list, the last pair repeats.
none makes open-quote and close-quote insert no marks (as if no-open-quote and no-close-quote). Automatic marks on q are also suppressed.
The q element inserts marks by itself using quotes. For other elements, set quotes and use ::before / ::after with content: open-quote and content: close-quote.
quotes is Baseline Widely available across modern browsers and has long support in Internet Explorer for string pairs. It is a browser CSS property, not a Node.js feature.