Hidden Mechanics: U+00AD and U+2060 vs. Common Space Controls
The soft hyphen and the word joiner are format characters (Unicode category Cf). They have no width, no glyph and no meaning in the text itself. What they carry is a single instruction to the line breaker, the part of a rendering engine that decides where a line of text may wrap.
Unicode’s line-breaking algorithm, UAX #14, gives each character a class. The soft hyphen is class BA, “break after”: the browser may end a line right after it, and if it does, it draws a visible hyphen. The word joiner is class WJ, which forbids a break both before and after it. The zero width space (ZW) does the reverse of the joiner and allows a break with no hyphen, while the ordinary hyphen-minus (HY) allows a break after itself in most contexts.
U+00AD dates back to the Latin-1 character set and takes 2 bytes in UTF-8 (C2 AD). U+2060 arrived in Unicode 3.2 to take over the “don’t break here” job that the byte-order mark U+FEFF used to do, and takes 3 bytes (E2 81 A0). If you still see U+FEFF used as a joiner in old code, replace it: modern software treats a leading U+FEFF as a byte-order mark and often strips it.
| Character | Unicode hex code | CSS word-break behaviour | Text wrap prevention capacity | Hidden validation traversal |
|---|---|---|---|---|
| Soft Hyphen | U+00AD · 2 bytes |
Break point used with hyphens: manual or auto; ignored with hyphens: none. Shows “-” only when the line breaks there |
None. It adds a break point | Invisible, survives JS trim(), not matched by s; breaks exact matching |
| Word Joiner | U+2060 · 3 bytes |
No break before or after; overflow-wrap: anywhere can still force one when a run cannot fit |
Strong, at zero width | Invisible, survives trim(), not matched by s; often stripped as a “default ignorable” character |
| Zero Width Space | U+200B · 3 bytes |
Always a break point, never shows a hyphen | None. It is a pure break point | Invisible, survives trim(); the hidden character apps strip most often |
| Hyphen-Minus | U+002D · 1 byte |
Break allowed after it before letters; never hidden | None | Visible ASCII; every validator sees it |
The column that bites developers is the last one. All three invisible characters survive JavaScript’s trim() and slip past s, so a naive “is this field empty?” check will not catch them. The invisible character detector marks every one in place, and remove invisible characters strips them from a whole document. For the U+200B side of the table, the zero width space page has its own wrap demo.
Code Integration: Overriding Browser Wrapping Engines Natively
How Blink, WebKit and Gecko treat these anchors
Chrome and Edge (Blink), Safari (WebKit) and Firefox (Gecko) all follow UAX #14, so a soft hyphen or word joiner you place by hand behaves the same in each. The differences live in the CSS around them:
hyphens: manualis the default everywhere, so soft hyphens work without any CSS.hyphens: noneswitches soft hyphens off completely; check for it in a reset stylesheet if yours seem dead.hyphens: autoadds dictionary hyphenation on top, but only when the element has alangattribute, and Safari still wants the-webkit-hyphensprefix.word-break: break-allandoverflow-wrap: anywhereare emergency rules. They split long strings with no hyphen, which is usually uglier than a soft hyphen in the right place.
Clean wraps on responsive viewports
Long single words are the classic overflow on a 320-pixel phone. German compounds, chemical names and product codes like “Internationalization” have no break points at all, so they push past the column edge. You have three ways to fix that:
- Soft hyphens at syllable boundaries, which you control exactly and which work in every browser.
hyphens: autowith a correctlangattribute, which is automatic but depends on the browser having a dictionary for that language.<wbr>or U+200B, for URLs and file paths, where a hyphen would change the meaning.
Use word joiners in the opposite situation, when a break point exists but splitting there misleads the reader: “COVID-19”, “−5 °C”, “Wi-Fi”, or an em dash that should stay attached to the word before it. The auto-inserter above does both jobs in one pass.
Preventing orphan words on mobile breakpoints
An orphan is a single short word left alone on the last line of a heading or button. Two native fixes exist. text-wrap: balance evens out line lengths in headings, and text-wrap: pretty (Chromium 117 and later) avoids single-word last lines in paragraphs. Where those are not supported, glue the last two words: a no-break space between them is the usual tool, and a word joiner works where the words are joined by a dash rather than a space.
Input fields and form handling
Inside a single-line <input> there is no wrapping, so soft hyphens and word joiners do nothing visible at all. That makes them dangerous in copied credentials and codes. Normalise on the server: remove /[]/g from usernames, emails, coupon codes and search queries before comparing them. Do not strip them from body text you will render later; there they are doing a job.
Frequently Asked Questions (FAQ): Mastering Hidden Word Boundaries
Why don’t my soft hyphens do anything?
Usually because hyphens: none is set somewhere, often by a CSS reset or a framework. Remove it, or set hyphens: manual on the text. The other common cause is a column wide enough that the word never needs to break; drag the slider in the width lab to see the exact point where it kicks in.
Is ⁠ the same as ?
No. is U+00A0, a visible space that cannot break. ⁠ is U+2060, which has no width at all. Use the first between words and the second between characters that already touch, such as the parts of “COVID-19”. The html space characters table lists both with their real widths.
Can a soft hyphen or word joiner make a blank username?
Not reliably. Both are format characters, not letters, so “has at least one letter” checks fail and many apps strip them as default ignorables. For a blank that sticks, the blank text generator uses the Hangul Filler, which counts as a letter, and the space copy and paste page lists 11 other blanks.
Do soft hyphens hurt SEO or on-page search?
Search engines handle them in visible text, but your own code may not: "inter­national".includes("international") returns false. If your site search runs in JavaScript, strip U+00AD and U+2060 from both the content and the query before matching.
The single most useful takeaway for U+00AD and U+2060
Use a soft hyphen to let a long word break and a word joiner to stop a short term from breaking, and keep both out of anything a person or a program has to match exactly.
Need one now? Both copy buttons are at the top, and the width lab shows the result before you ship it.