The precise meaning of default ignorable
The Unicode Default_Ignorable_Code_Point property (often abbreviated DI) identifies code points that should ordinarily be ignored for display in fallback rendering if their intended behavior is not supported. It is a derived Boolean property recorded in the Unicode Character Database. The name can be dangerously misleading: default ignorable does not mean semantically disposable, universally invisible, or safe to strip from storage.
Unicode's rendering guidance distinguishes between the intended effect of a formatting or variation character and how an implementation should behave when it cannot support that effect. A font without support for a variation sequence should not normally show a standalone square box for its variation selector. Likewise, a zero-width joiner may be invisible as an isolated glyph but can alter the shape or composition of neighboring characters when the font and shaping system understand the sequence.
The authoritative DI set is derived for each Unicode release in DerivedCoreProperties.txt and described in the core standard and UAX #44. An implementation should not hardcode an informal list of “invisible Unicode characters” from a blog post or assume that every Cf format character is covered and all other categories are excluded.
Important character families and their behaviors
| Example | Typical function | Why removal can be destructive |
|---|---|---|
U+200D ZERO WIDTH JOINER (ZWJ) | Influences joining, ligatures or standardized emoji ZWJ sequences | Can split an intended joined pictograph or alter script shaping |
U+200C ZERO WIDTH NON-JOINER (ZWNJ) | Suppresses joining behavior in supported scripts | Can change word spelling/appearance, especially in joining scripts |
U+FE0E VARIATION SELECTOR-15 | Requests text-style presentation in eligible standardized sequences | Can alter text versus emoji presentation |
U+FE0F VARIATION SELECTOR-16 | Requests emoji-style presentation in eligible standardized sequences | Can change emoji display behavior |
U+2060 WORD JOINER | Prevents a line-break opportunity between adjacent characters in relevant contexts | Stripping can change wrapping |
U+00AD SOFT HYPHEN | Marks a possible line-break location with a displayed hyphen under appropriate line-break behavior | Can change hyphenation opportunities |
U+034F COMBINING GRAPHEME JOINER | Can affect normalization ordering and certain cluster-related behavior | May alter equivalence or ordering semantics |
U+FEFF ZERO WIDTH NO-BREAK SPACE / BOM | Legacy no-break usage; also byte-order signature in encoded streams | Meaning depends on input format and position |
U+E0100..U+E01EF | Supplementary variation selectors | Can select registered ideographic or other variants where supported |
The DI property also covers certain reserved/unassigned ranges specifically intended for future formatting-style uses. Unicode 18.0's Chapter 5 identifies reserved areas including U+2060..U+206F, U+FFF0..U+FFF8 and U+E0000..U+E0FFF for such forward-compatible fallback behavior. Being reserved does not mean that assigning an arbitrary private meaning to one of these positions is safe for interchange.
Not every property member is best understood as “zero width” in all implementations. Soft hyphen, for example, can produce a visible glyph at a permitted line break. The DI recommendation concerns fallback handling; it is not a promise that rendering output is always empty.
Default_Ignorable versus General_Category and White_Space
Unicode properties answer different questions. General_Category=Cf classifies format characters. Default_Ignorable_Code_Point specifies fallback-rendering behavior. White_Space identifies whitespace-related characters for higher-level processing. Variation_Selector, Grapheme_Cluster_Break, and Line_Break describe additional behavior. These sets overlap but are not interchangeable.
- Not all DI code points are in
Cf: variation selectors belong to mark categories, and other special values can be unassigned/reserved positions. - Control characters and surrogate code points are not collectively DI; they need their own decoding and control-handling policies.
- Some characters that appear blank or occupy whitespace are not DI. A visible space (
U+0020) is not “default ignorable” merely because it has no ink. Default_Ignorable_Code_Pointis a derived property rather than a font's internal “zero advance” flag. Font metrics cannot reliably determine it.
For strict Unicode database analysis, read the properties from the same UCD release. Combining property tables from two different releases can misclassify recently added code points and produce inconsistent security or validation rules.
Rendering fallback and variation behavior
Text shaping typically interprets DI characters in the context of adjacent code points. A supported ZWJ sequence can select a composite emoji glyph or different joining form, but if that glyph is unavailable the renderer may fall back to showing components. A variation selector can request a standardized text or emoji variation, but a font may ignore the request and display its default glyph. In those fallback scenarios, the selector or joiner should not itself become a conspicuous missing-glyph box.
This behavior is not equivalent to saying that the DI code point has “zero width” as a general metric. A code point sequence may influence glyph advances and cluster shaping without introducing a standalone glyph. Font selection, ligature substitution, mark attachment and fallback policy all matter.
Grapheme segmentation is separate. A variation selector generally participates in the same extended grapheme cluster as the preceding eligible base. ZWJ sequences may join extended pictographs under UAX #29's GB11 context rule. Deleting a DI code point can therefore alter both the stored sequence and the boundaries of later editing operations.
Invisible sequences that materially change text
Emoji ZWJ changes a sequence
U+1F469 U+200D U+1F4BB (woman + ZWJ + laptop) is an emoji sequence commonly displayed as one woman technologist pictograph. Removing U+200D leaves the woman and laptop separately encoded; a text system can display them as independent emoji. No letter changed, but meaning and grapheme structure may have changed.
Variation selector distinguishes presentation requests
Many emoji-capable characters accept explicit text-style or emoji-style variation selectors. Whether the request is honored depends on a defined standardized variation sequence and a supporting font. Appending arbitrary U+FE0F after any character does not automatically create a legitimate emoji variation.
Word joiner and discretionary hyphenation
U+2060 WORD JOINER can inhibit line breaking at a surrounding position. U+00AD SOFT HYPHEN can allow a discretionary break and produce a hyphen when broken. Rendering behavior depends on layout. Stripping both because they are normally invisible changes text-flow instructions in opposite ways.
Copyable decorative text
A string copied from a Fancy Text generator can contain visibly styled Unicode characters, combining marks or emoji-related sequences. A responsible text inspection feature can expose code points and DI positions without automatically deleting them; doing so preserves both the chosen appearance and the ability to diagnose compatibility problems across apps.
JavaScript detection, auditing and safe handling
Modern JavaScript engines support the binary Unicode property escape \p{Default_Ignorable_Code_Point} in Unicode-mode regular expressions. The returned property data are runtime-dependent. An audit should report code points rather than silently modifying user content.
const ignorable = /\p{Default_Ignorable_Code_Point}/u;
const value = "woman:\u{1F469}\u200D\u{1F4BB}";
const findings = [];
let offset = 0;
for (const ch of value) {
if (ignorable.test(ch)) {
findings.push({
codePoint: "U+" + ch.codePointAt(0).toString(16)
.toUpperCase().padStart(4, "0"),
utf16Offset: offset
});
}
offset += ch.length; // advance by 1 or 2 UTF-16 code units
}
console.log(findings);
// [{ codePoint: "U+200D", utf16Offset: 8 }]
The example's offset is relative to JavaScript's UTF-16 indexing. The words "woman:" occupy 6 units, WOMAN occupies 2 more, and ZWJ begins at offset 8. To display offsets in a user interface, convert them to grapheme boundaries if appropriate; do not confuse code-unit indices with cursor positions.
Use Array.from(text) or for…of for code-point iteration in JavaScript. For a precise warning system, maintain a whitelist or risk classification tuned to your field rather than treating every DI member as malicious. For example, an emoji caption field may safely permit joiners and variation selectors, while a machine-generated identifier might apply a stricter profile and a security-sensitive account label might warn about unexpected invisible controls.
Property escapes do not replace a protocol's formal character profile. When a supported Unicode release changes, diff the detected set as part of regression testing and update your documentation. A regular expression that detects DI characters should never be presented as a complete “remove zero-width attacks” sanitizer.
Security, accessibility and text integrity
Invisible characters can support deceptive text, but they are also essential in legitimate writing systems, emoji sequences and typography. An attacker might insert format characters into a username, change the apparent grouping of a document, or create text that compares differently while looking similar. Mitigation should be context-sensitive:
- Identifiers: Apply a specified identifier profile (UTS #39, language-specific syntax, or domain-name IDNA rules as appropriate). Keep track of normalization and case mapping in comparison pipelines.
- User-facing display: Consider showing a visible warning, revealing code-point names on demand or displaying suspicious control positions in editing tools—without corrupting original data.
- Rich-text import: Distinguish user data from markup. Escaping HTML and handling text direction safely are separate obligations; they are not guaranteed by removing DI characters.
- Accessibility: Invisible format controls may affect speech, selection and direction. Replacing them with printable placeholders in normal reading can itself misrepresent the text; offer a diagnostic view separately.
- Audit logs: Keep a lossless representation (for example, escaped code points) alongside a human-readable display. Truncation should not split surrogate pairs or leave incomplete sequences silently.
Never assume that removing every default-ignorable code point is an acceptable universal security solution. Unicode's explicit fallback guidance is not a directive to strip code points from stored strings.
Versioned tests and operational checklists
| Input | Expected diagnostic | What to verify |
|---|---|---|
A | No DI code points | Basic Latin unaffected |
U+200D | DI | Joiner in emoji and script context |
U+FE0F | DI | Variation selector detected |
U+2060 | DI | Line-break behavior not confused with whitespace |
U+00AD | DI | Soft-hyphen behavior preserved at layout |
U+0020 | Not DI | Whitespace is not synonymous with DI |
U+D800 | Not a scalar value | Reject malformed interchange independently |
As part of a release pipeline, test both the DI property table and observable rendering/clipboard behavior on representative systems. A unit test that recognizes U+200D cannot establish that the platform supports all ZWJ ligatures. Likewise, two strings with different DI code points can remain distinguishable at the data layer while displaying identically.
Primary specifications and property files
- Unicode Standard, Chapter 5 — Implementation Guidelines, default ignorable rendering and data handling.
- UAX #44 — Unicode Character Database, definition and derivation of properties.
- DerivedCoreProperties.txt, Unicode's versioned DI data.
- UTS #51 — Unicode Emoji, sequences and presentation selectors.
- UTS #39 — Unicode Security Mechanisms, identifier restriction and confusable mechanisms.
- UAX #29 — Unicode Text Segmentation, sequence-aware grapheme boundaries.
Independent Unicode research. Default-ignorable behavior and application-level security policies must not be conflated; verify the runtime's UCD version.