The CSS quotes property chooses which quotation marks a browser draws for the q element and for content: open-quote and close-quote. quotes: auto picks marks that suit the lang attribute, a list of string pairs sets your own marks per nesting level, and quotes: none removes them. A blockquote gets no marks unless you add them.
| Value | Effect |
|---|---|
| auto | Marks suited to the element's language (set with lang) |
| none | open-quote and close-quote draw nothing |
| "“" "”" | One pair, used at every nesting level |
| "“" "”" "‘" "’" | Outer pair, then inner pair for nested quotes |
Updated
Quotation marks are a typography detail most sites get wrong: straight quotes typed into templates, the wrong marks for French or German, or a decorative blockquote mark that screen readers read aloud. Here the quotes property is shown live in several languages, along with clean patterns for pull quotes and testimonials.
q {
quotes: auto;
}| Mark | Name | CSS escape |
|---|---|---|
| “ ” | Left and right double quotation mark | \201C \201D |
| ‘ ’ | Left and right single quotation mark | \2018 \2019 |
| « » | Double angle quotation marks (guillemets) | \AB \BB |
| ‹ › | Single angle quotation marks | \2039 \203A |
| „ | Double low-9 quotation mark | \201E |
| 「 」 | Corner brackets | \300C \300D |
The outer q uses double marks, the q inside it uses single marks. The escapes produce curly quotes.
<style>
q { quotes: "\201C" "\201D" "\2018" "\2019"; }
</style>
<p>She said, <q>The sign read <q>closed for lunch</q>, so we waited.</q></p>The big mark uses alternative text set to empty, so it is not read aloud. figure and figcaption tie the quote to its source. Browsers without the alternative text syntax skip that rule and draw no mark.
<style>
figure { margin: 0; padding: 20px 24px; border-left: 4px solid #4F98FB; background: #f1f5f9; border-radius: 0 12px 12px 0 }
blockquote { margin: 0; font: 500 19px/1.5 Georgia, serif; position: relative }
blockquote::before { content: "\201C" / ""; position: absolute; left: -6px; top: -26px;
font-size: 64px; color: #4F98FB; opacity: .35 }
figcaption { margin-top: 10px; font: 14px system-ui; color: #475569 }
</style>
<figure>
<blockquote><p>A pull quote should be short enough to read at a glance.</p></blockquote>
<figcaption>Name of the person quoted, their role</figcaption>
</figure>open-quote and close-quote take part in nesting, so a q inside this blockquote gets the inner marks.
<style>
blockquote { quotes: auto; font-style: italic; margin: 8px 16px }
blockquote::before { content: open-quote; }
blockquote::after { content: close-quote; }
</style>
<blockquote lang="en">Plans change, but <q>good enough</q> rarely is.</blockquote>
Every open-quote raises the nesting depth by one and every close-quote lowers it. Depth zero uses the first pair in quotes, depth one the second, and so on. That is why a q inside a q switches from double to single marks in English automatically.
Because depth is tracked across the whole document, an unbalanced open-quote leaves every later quotation one level too deep. Pair them carefully in pseudo-elements, or use the no- variants to adjust depth silently.
The keyboard's " and ' are typewriter marks. Printed text uses curly marks that point towards the quotation: “ and ” for double, ‘ and ’ for single. Generating marks with CSS keeps them consistent even when content editors type straight ones.
Other languages use different shapes and positions: guillemets « » in French, low-high „ “ in German, corner brackets 「 」 in Japanese. quotes: auto with the right lang handles this for q without per-language CSS.
Set q { quotes: none; }. The marks come from the browser's default ::before and ::after content of open-quote and close-quote, and none makes those draw nothing while keeping the element's meaning.
Browsers add marks automatically only for q. A blockquote is indented by default but unmarked. Add blockquote::before { content: open-quote; } and a matching ::after, or a decorative mark, if your design wants one.
Write the characters directly in a UTF-8 stylesheet, quotes: "“" "”" "‘" "’";, or as escapes such as "\201C" and "\201D". Escapes are handy when an editor or build step mangles non-ASCII characters.
Generated content can be announced by assistive technology, so treat marks as text. A huge decorative mark is better drawn with a background image, an SVG with aria-hidden, or content with empty alternative text: content: "“" / "";.
Related: CSS text styling, HTML comments, line breaks and spaces, CSS selectors cheat sheet, HTML and CSS cheat sheet, How to link CSS to HTML.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.