Curly quotes (also called smart quotes, typographic quotes, or book quotes) are the typographically correct forms of quotation marks that curve or point toward the quoted text, as opposed to the straight vertical marks used in programming and early typewriters. Proper quotation marks are among the most visible markers that distinguish professional typesetting from typewriter-era text.
The Four Curly Quote Characters
U+201C LEFT DOUBLE QUOTATION MARK (open double quote)
U+201D RIGHT DOUBLE QUOTATION MARK (close double quote)
U+2018 LEFT SINGLE QUOTATION MARK (open single quote)
U+2019 RIGHT SINGLE QUOTATION MARK (close single quote, apostrophe)
Note that U+2019 (right single quotation mark) doubles as the typographic apostrophe -- the correct character for contractions (don't, it's) and possessives (Alice's).
HTML Entities
<!-- Double quotes -->
“ text ”
“ text ”
<!-- Single quotes / apostrophe -->
‘ text ’
‘ text ’
<!-- Guillemets (French / European quotation marks) -->
« text » <!-- angle quotes -->
‹ text › <!-- single angle quotes -->
Curly Quotes vs Straight Quotes in HTML
Straight double quotes are overloaded with meaning in HTML (attribute delimiters) and programming languages (string delimiters). While they work fine in HTML text content, curly quotes are semantically unambiguous and typographically superior:
<!-- Straight quotes -- valid but typographically poor -->
<p>She said "hello" to him.</p>
<!-- Curly quotes -- typographically correct -->
<p>She said “hello” to him.</p>
<p>She said “hello” to him.</p>
CSS and JavaScript Smart Quote Conversion
// Basic smart quote conversion (not perfect -- context matters)
function smartQuotes(str) {
return str
// Double quotes: opening vs closing by context
.replace(/(^|[-\u2014\s(\[{])"/g, '$1\u201C') // opening
.replace(/"/g, '\u201D') // closing
// Single quotes / apostrophes
.replace(/(^|[-\u2014\s(\[{])'/g, '$1\u2018') // opening
.replace(/'/g, '\u2019'); // closing/apostrophe
}
// More robust: use a library like 'smartquotes' on npm
// import smartquotes from 'smartquotes';
// document.querySelectorAll('p').forEach(p => smartquotes.element(p));
Locale Variations
Different languages use different quotation conventions:
English (US): U+201C...U+201D outer, U+2018...U+2019 inner
English (UK): U+2018...U+2019 outer, U+201C...U+201D inner
French: guillemets with non-breaking spaces inside
German: U+201E (low-9 open), U+201C (high close)
Swiss German: guillemets like French
Japanese: corner brackets
/* CSS quotes property controls generated quotes */
:lang(en) { quotes: '\201C' '\201D' '\2018' '\2019'; }
:lang(fr) { quotes: '\00AB' '\00BB' '\2039' '\203A'; }
:lang(de) { quotes: '\201E' '\201C' '\201A' '\2018'; }
/* Used with <q> element */
q { quotes: '\201C' '\201D'; }
q::before { content: open-quote; }
q::after { content: close-quote; }
The q Element
<!-- The semantic HTML approach: browser applies locale-appropriate quotes -->
<p>She said <q>the project is complete</q>.</p>
<p lang="fr">Il a dit <q>bonjour</q>.</p>
The <q> element with correct lang attributes lets browsers and CSS apply the right quotation marks automatically, which is the most maintainable approach for multilingual sites.