
How to Control Hyphenation with CSS?
- Sajjad
- Typography
- 01 Oct, 2026
A German client sends over product copy containing "Kundenzufriedenheitsumfrage," and on a 360-pixel phone screen that single word pushes past the edge of its card and triggers horizontal scrolling. On the English version of the same site, a narrow sidebar column shows ragged lines with huge gaps because words like "internationalization" cannot fit anywhere. Neither problem is about the font or the font size. They are line-breaking problems, and hyphenation is the tool designed to solve them.
This article explains how CSS hyphenation works, why it depends on the lang attribute, how to use soft hyphens for manual control, how to fine-tune the hyphen character and word-length limits, and when you should reach for overflow-wrap instead.
What Is Hyphenation?
Hyphenation is the practice of breaking a word across two lines at a syllable boundary and marking the break with a hyphen. Print typesetters have done it for centuries to keep line lengths even and avoid big gaps. On the web, browsers do not hyphenate by default; a word that does not fit simply moves to the next line, or overflows its container if it is longer than the line itself.
CSS gives you three levels of control:
- Whether hyphenation happens at all, with the
hyphensproperty. - Where it is allowed, with soft hyphens in the markup and the browser's language dictionary.
- How it looks and how aggressive it is, with
hyphenate-characterandhyphenate-limit-chars.
The hyphens Property
The hyphens property takes three values:
| Value | Behaviour |
|---|---|
none | Never hyphenate, even at soft hyphens |
manual | The default. Break only at explicit soft hyphens (­ or U+00AD) |
auto | Let the browser hyphenate using its dictionary for the element's language |
article p {
hyphens: auto;
-webkit-hyphens: auto; /* older Safari versions */
}
h1,
h2,
h3,
code,
.brand-name {
hyphens: manual;
}
hyphens is inherited, so setting it on a container affects everything inside. That is why it is good practice to explicitly opt headings, code, and brand names back out.
Why lang Is Required
hyphens: auto does nothing unless the browser knows what language the text is in. Hyphenation rules are language-specific: the correct break in "present" (the noun, pres-ent) differs from "present" (the verb, pre-sent), and German, French, and Dutch all have completely different rules. Browsers ship or download hyphenation dictionaries per language, and they choose a dictionary from the element's lang attribute.
<html lang="en">
<body>
<article>
<p>English paragraph that will be hyphenated with English rules.</p>
<blockquote lang="de">
<p>Ein deutsches Zitat mit deutschen Trennregeln.</p>
</blockquote>
</article>
</body>
</html>
If your root element has no lang, or the wrong one, hyphens: auto quietly fails or hyphenates incorrectly. In Next.js App Router projects, set it in the root layout:
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
For multilingual sites, set lang per locale in the layout and per element for embedded passages in another language. The post on fonts for multilingual websites covers the font side of the same problem.
Language Coverage Varies
Browser support for hyphens: auto is universal for the property itself, but the set of supported languages differs by engine and platform. Firefox and Safari cover a broad range of languages; Chromium-based browsers support many common languages on desktop and Android. If a language has no dictionary, the browser behaves as if you set manual. Always test hyphenation in each browser for each language you publish in.
Manual Hyphenation with Soft Hyphens
A soft hyphen is an invisible character (U+00AD) that marks a permitted break point. It renders nothing unless the browser actually breaks the line there, in which case a hyphen appears. In HTML you write it as the entity ­.
<h2>Kunden­zufriedenheits­umfrage</h2>
<p>Configure the super­cali­fragilistic module first.</p>
Soft hyphens are respected under both manual and auto. Under auto, they also take priority: if a word contains any soft hyphen, the browser uses only those break points for that word and skips its dictionary. That makes them useful for correcting bad dictionary breaks in product names or technical terms.
Two things to watch:
- Search and copy. Soft hyphens are real characters in the DOM. Most browsers strip them on copy and ignore them in find-in-page, but some downstream systems (CSV exports, some search indexes) may not. Keep them out of data that gets reused elsewhere, such as SKUs.
- CMS escaping. Many editors encode
­as&shy;, which displays the literal text. Insert the actual U+00AD character, or confirm your CMS preserves the entity.
The Word Break Opportunity Element
The <wbr> element is the non-hyphen cousin of the soft hyphen. It marks a place where a line may break without inserting any hyphen. That is the right choice for URLs, file paths, and long identifiers, where adding a hyphen would change the meaning.
<p>Download from https://example.com/<wbr>downloads/<wbr>2026/<wbr>release-notes.pdf</p>
Customizing the Hyphen with hyphenate-character
By default the browser inserts the hyphen appropriate to the language, typically U+2010 or a regular hyphen-minus. hyphenate-character lets you change it:
.prose {
hyphens: auto;
hyphenate-character: "-";
}
/* Some designs use an en dash or a special glyph */
.editorial {
hyphens: auto;
hyphenate-character: "\2010";
}
/* Reset to the language default */
.reset {
hyphenate-character: auto;
}
Older Safari releases require the -webkit-hyphenate-character prefix. Most sites never need to change this, but it matters if your font lacks the default hyphen glyph and falls back to a mismatched one.
Limiting Aggressive Hyphenation with hyphenate-limit-chars
Unrestricted hyphenation can be ugly: breaking "every" into "ev-ery" or leaving two letters dangling at the start of a line. hyphenate-limit-chars sets three minimums:
- The minimum word length that may be hyphenated.
- The minimum number of characters before the hyphen.
- The minimum number of characters after the hyphen.
article p {
hyphens: auto;
/* Only hyphenate words of 7+ characters, keep 3 before and 3 after */
hyphenate-limit-chars: 7 3 3;
}
/* Use 'auto' for any value you want the browser to decide */
.sidebar p {
hyphens: auto;
hyphenate-limit-chars: 10 4 auto;
}
A setting like 6 3 2 is a reasonable starting point for English body text. Raising the first value to 8–10 makes hyphenation much rarer and is a good fit for wider columns where you only want it to rescue the very long words.
Support for hyphenate-limit-chars arrived in Chromium first and is still not universal. Unsupported browsers ignore it and apply their own defaults, so it is safe to include as a refinement.
When to Use Hyphenation, and When Not To
Hyphenation is a trade-off. Each hyphen interrupts the reader slightly, but avoiding hyphens in narrow columns creates uneven lines and rivers of white space.
| Situation | Recommendation |
|---|---|
| Justified text | Required. Justified text without hyphenation looks bad |
| Narrow columns (under about 40 characters) | Strongly recommended |
| Mobile body text | Often helpful, especially in German, Finnish, Dutch |
| Standard-width articles (60–75 characters) | Optional. Use limits to keep it rare |
| Headings and display text | Avoid. Break manually with soft hyphens if needed |
| Buttons, labels, navigation | Avoid. Rewrite the label instead |
| Code, URLs, product names, emails | Never. Use wbr or overflow-wrap instead |
If you are considering justified text, read why justified text is usually a bad idea on the web first. Hyphenation reduces its problems but does not eliminate them.
Accessibility Considerations
Frequent hyphens slow some readers down, especially people with dyslexia or cognitive disabilities, because they have to reassemble the word across lines. For accessibility-sensitive content, keep hyphenation off on wide layouts, or restrict it heavily with hyphenate-limit-chars. Hyphenation does not affect screen readers, which read the original word.
Hyphenation vs. overflow-wrap and word-break
These properties are often confused. They solve different problems.
| Property | What it does | Adds a hyphen? |
|---|---|---|
hyphens: auto | Breaks at linguistically correct syllable boundaries | Yes |
overflow-wrap: break-word | Breaks an unbreakable string anywhere, only if it would overflow | No |
overflow-wrap: anywhere | Same, but also allows the break to shrink min-content width | No |
word-break: break-all | Breaks any word at any character, even if it would fit | No |
word-break: keep-all | Prevents breaks within words in CJK text | No |
A robust setup for user-generated content combines them: hyphenate real words, and let overflow-wrap catch the long URL or hash that has no syllables.
.comment-body {
hyphens: auto;
overflow-wrap: anywhere;
}
The difference between break-word and anywhere matters inside flex and grid items and tables. With break-word, a long URL still forces the item to be as wide as the URL when calculating its minimum size. With anywhere, the item can shrink and the URL wraps. If a card in a grid stretches because of a long link, overflow-wrap: anywhere is usually the fix.
Avoid word-break: break-all on prose. It splits ordinary words at arbitrary letters, which is much harder to read than hyphenation.
A Production-Ready Hyphenation Setup
/* The element that wraps .prose becomes the query container */
.prose-container {
container-type: inline-size;
}
:root {
--hyphen-limits: 7 3 3;
}
.prose {
hyphens: auto;
-webkit-hyphens: auto;
hyphenate-limit-chars: var(--hyphen-limits);
overflow-wrap: break-word;
}
/* Narrow layouts benefit most */
@container (max-width: 30rem) {
.prose {
--hyphen-limits: 6 3 2;
}
}
/* Wide layouts: only rescue very long words */
@container (min-width: 48rem) {
.prose {
--hyphen-limits: 10 4 4;
}
}
.prose :is(h1, h2, h3, h4, code, pre, kbd, a[href^="http"]) {
hyphens: manual;
-webkit-hyphens: manual;
}
This uses container queries so the rules follow the column width rather than the viewport. The container-type declaration must sit on an ancestor of .prose, because an element cannot query its own size. A sidebar on a desktop gets the narrow-column treatment automatically. For more on that pattern, see container queries for responsive typography.
In Tailwind CSS v4
Tailwind provides hyphens-none, hyphens-manual, and hyphens-auto utilities. For limits, add a custom utility:
@import "tailwindcss";
@utility hyphen-limits-strict {
hyphenate-limit-chars: 8 3 3;
}
<article lang="en" class="hyphens-auto hyphen-limits-strict">
...
</article>
Hyphenation and text-wrap: pretty
Hyphenation gives the line-breaking algorithm more break points to choose from. Combined with text-wrap: pretty, especially in Safari, the browser can weigh hyphens against line evenness and avoid consecutive hyphenated lines. The details are in the article on text-wrap: balance and pretty.
.prose p {
hyphens: auto;
text-wrap: pretty;
}
How to Test Hyphenation
- Force a narrow column. Set
max-width: 20chtemporarily on a paragraph so hyphenation kicks in often. - Switch languages. Change
langfromentodein DevTools and confirm breaks change. If nothing changes, the browser has no dictionary for that language. - Check every engine. Chrome, Safari, and Firefox use different dictionaries and break different words.
- Look for bad breaks in brand terms. Search for product names and add soft hyphens or
hyphens: manualwhere the dictionary gets them wrong. - Zoom to 200%. WCAG 1.4.4 requires text to resize to 200% without loss of content. Hyphenation and
overflow-wraphelp keep long words inside their containers at high zoom levels.
Hyphenation FAQ
The most common cause is a missing or wrong lang attribute on the element or one of its ancestors. The browser needs the language to pick a hyphenation dictionary. Other causes include the browser lacking a dictionary for that language, the word containing a soft hyphen, or the line being wide enough that no break is needed.
A regular hyphen is always visible and is a permanent part of the word, as in well-known. A soft hyphen is invisible and only appears when the browser breaks the word at that point. It marks an optional break, not a required character.
Often yes, especially for languages with long compound words such as German or Finnish, or for any narrow column. On mobile, hyphenation reduces large gaps and prevents long words from overflowing. Use hyphenate-limit-chars to keep it from breaking short words.
Automatic hyphenation is purely visual and does not change the text in the HTML, so it has no effect on search engines. Soft hyphens are real characters in the markup, but major search engines handle them correctly. Avoid them in titles and metadata to be safe.
Use overflow-wrap set to anywhere on the container, or insert word break opportunities after slashes. Hyphenation will not help with URLs because they are not dictionary words, and adding hyphens would change the address a reader might copy.
You can, but automatic hyphenation in headings usually looks careless. Keep headings on manual, use text-wrap balance for even lines, and add a soft hyphen to any very long word that needs to break on small screens.
Conclusion
Hyphenation is one of the few typographic controls where the browser does most of the work for you, but only if you give it the right input. Set an accurate lang attribute, turn on hyphens: auto for body text in narrow or justified layouts, and opt headings, code, and names out. Use soft hyphens to fix the words the dictionary gets wrong and wbr or overflow-wrap for strings that are not words at all.
Then restrain it. hyphenate-limit-chars keeps short words intact and makes hyphens rare on wide layouts, while container queries let you loosen the rules only where columns are tight. Test in every browser and every language you publish, because each engine brings its own dictionary.
Here are some useful references for going deeper on CSS hyphenation:
- MDN Web Docs: hyphens — values, language requirements, and browser support.
- MDN Web Docs: hyphenate-limit-chars — syntax and examples for controlling word-length limits.
- MDN Web Docs: overflow-wrap — how break-word and anywhere differ.
- W3C: CSS Text Module Level 4 — the specification for hyphens, hyphenate-character, and hyphenate-limit-chars.
- Butterick's Practical Typography: Hyphenation — when hyphenation helps and when it hurts.


