A dead key changes the meaning of subsequent key input without immediately inserting a visible independent letter. That mechanism is part of a keyboard-layout or input-method system, not a Unicode scalar category. To debug an accent that looks wrong, separate the keys pressed, the text committed by the operating system, the normalization form of that text, and the glyphs produced by the font.
A dead key is an input state, not an encoded character
In many keyboard layouts, pressing an acute-accent dead key followed by e commits é. The initial keystroke might produce no text input event until the next key, and an application must not assume that every keydown produces a Unicode character. Keyboards can also support key sequences yielding characters for which no precomposed Unicode scalar exists.
The resulting value can be U+00E9, or in some configurations U+0065 followed by U+0301, or a different mapped output. Neither representation is guaranteed solely by the physical layout. Inspect the application-level string after input rather than reverse-engineering characters from hardware key names.
Combining marks are real Unicode scalars
U+0301 COMBINING ACUTE ACCENT is an encoded mark that typically modifies a preceding base character. The sequence U+0065 U+0301 is canonically equivalent to U+00E9 LATIN SMALL LETTER E WITH ACUTE. Both may display as the same letter in an appropriate font, but they use different numbers of scalars and UTF-16 code units.
A combining mark can appear with a dotted circle when isolated, depending on font and rendering. The dotted circle is a rendering aid, not necessarily a U+25CC character inserted into the source. A data inspector should show both the mark's actual code point and whether a base is present.
Normalization is a separate and explicit operation
NFC performs canonical composition where defined; NFD produces canonical decomposition. For é, NFC of the decomposed pair yields U+00E9, while NFD of U+00E9 yields the base-plus-mark sequence. Unicode canonical equivalence does not require every application to store both forms identically.
An editor may choose NFC for saved documents, but silently normalizing while the input method is still composing can interfere with selections or candidate boundaries. Capture committed text first, then apply an application-wide policy if needed; never use NFKC merely to 'repair' a visual accent.
Canonical ordering matters with multiple marks
A text run may contain more than one combining mark. UAX #15 describes canonical ordering using the Canonical_Combining_Class property. For example, U+0323 COMBINING DOT BELOW has combining class 220, and U+0301 COMBINING ACUTE ACCENT has class 230, so normalization can reorder a sequence to a stable canonical order where permitted.
Not every mark with a similar visual position has the same class; class zero and blocked compositions require care. A font's mark attachment is an additional concern. Correctly ordered Unicode text can still display with overlapping accents if the font lacks appropriate GPOS anchors.
Browser keyboard events cannot reconstruct the final text
The KeyboardEvent.key property and keydown/keyup describe keyboard interaction, not necessarily the exact Unicode payload delivered by dead-key composition. beforeinput and input events better reflect editing operations, while composition events may be involved on some platforms.
A shortcut handler that cancels or rewrites keystrokes at the wrong moment can prevent a dead-key sequence from completing. On desktop browsers, test actual international layouts, not just synthetic keyboard events, which generally do not reproduce the operating system's input pipeline.
Physical layouts and Unicode repertoire are independent
A language may use many written accents but only one layout's preferred keystrokes; alternatively, the same Unicode character may be entered using a dead key, a compose key, an IME, an on-screen palette or paste. A record of pressed keys cannot serve as a canonical identifier for a text string.
Users who switch keyboard layouts mid-session can commit different scalars using nominally similar physical keys. Record layout, OS, locale, active app and actual output scalars for reproducibility. Do not declare text invalid just because it came from an unfamiliar input method.
Caret movement should respect the composed grapheme
Whether committed as U+00E9 or as U+0065 U+0301, the accented letter is normally one extended grapheme cluster under UAX #29. A text editor that deletes only the base character and leaves the mark may surprise the user; deleting a lone UTF-16 code unit is still worse for supplementary characters.
Use a grapheme segmentation API for default editing boundaries and preserve a translation to DOM UTF-16 offsets. A dedicated code-point inspector may permit fine-grained navigation, but this mode should be visibly distinct from ordinary Backspace behavior.
Font support and data fidelity are separate failure modes
An accent that floats away from a base may indicate missing GPOS mark positioning, font fallback across a cluster, or inconsistent scaling. It does not necessarily mean the keyboard generated an invalid sequence. A replacement character U+FFFD is a different issue, usually associated with decoding or actual stored data.
Compare NFC and NFD specimens using the same font file, then inspect glyph IDs, offsets and source scalars. If the source is canonically correct and only one font displays it badly, fixing Unicode normalization may mask rather than solve the font defect.
Design a keyboard-composition regression corpus
Include precomposed é, decomposed é, a character with two marks, an unsupported base-plus-mark sequence, an emoji and a non-Latin IME composition. Capture input/composition event logs and the final code-point sequence.
Verify that repeated editing, selection, undo, copy/paste and storage all respect the chosen integrity policy. The test should declare whether exact scalars or canonical equivalence are required; a mere screenshot of a correctly accented letter cannot establish a lossless round trip.
Reproducible specimen and observable boundaries
The following controlled example tests one narrowly defined distinction. It cannot alone establish correctness of a complete multilingual application. Preserve the original Unicode scalar values, identify any normalization or transliteration performed, and separately inspect font rendering, selection, data serialization and user-interface behavior.
const samples = ['é', 'e\u0301', 'e\u0323\u0301'];
const hex = s => [...s].map(c => 'U+' + c.codePointAt(0).toString(16).toUpperCase());
for (const s of samples) console.log(hex(s), hex(s.normalize('NFC')));
console.log('é'.normalize('NFD') === 'e\u0301'); // true
// Record the actual value on input; keydown events do not guarantee insertion.For interop reports, record the input stream, chosen language or locale (if meaningful), browser or runtime version, relevant font files and output. When the outcome is only visually different, avoid changing source characters until the rendering or layout stage responsible for the mismatch has been isolated.
Technical comparison: data, algorithms and presentation
| Component or case | Concrete input | Correct interpretation |
|---|---|---|
| Dead-key sequence | acute dead key + e | input state; final scalar depends on layout |
| NFC form | U+00E9 | one precomposed code point |
| NFD form | U+0065 U+0301 | two scalars, one grapheme cluster |
| Two marks | U+0323 + U+0301 | canonical order and font attachment differ |
| Render error | detached accent | inspect selected font/GPOS before rewriting data |
Examples in this table represent distinct test contracts. Exact Unicode scalar equivalence is stronger than visual similarity, and an application may legitimately tailor text processing to language or product needs. Do not generalize one font's glyph appearance as a universal Unicode requirement.
Conformance and regression testing
- Dead-key sequence. Preserve a fixture containing
acute dead key + e. Specify the Unicode version, application environment and expected observations. Verify that input state; final scalar depends on layout; compare the actual code-point stream separately from appearance. - NFC form. Preserve a fixture containing
U+00E9. Specify the Unicode version, application environment and expected observations. Verify that one precomposed code point; compare the actual code-point stream separately from appearance. - NFD form. Preserve a fixture containing
U+0065 U+0301. Specify the Unicode version, application environment and expected observations. Verify that two scalars, one grapheme cluster; compare the actual code-point stream separately from appearance. - Two marks. Preserve a fixture containing
U+0323 + U+0301. Specify the Unicode version, application environment and expected observations. Verify that canonical order and font attachment differ; compare the actual code-point stream separately from appearance. - Render error. Preserve a fixture containing
detached accent. Specify the Unicode version, application environment and expected observations. Verify that inspect selected font/GPOS before rewriting data; compare the actual code-point stream separately from appearance.
For broader coverage, exercise known difficult cases rather than only ASCII text: decomposed accents, supplementary characters, mixed direction, language-specific scripts and emoji sequences where relevant. Include expected negative results and document any product-specific tailoring. Keep fixtures stable and versioned so future Unicode or browser updates remain diagnosable.
Interpreting false positives
A difference is not automatically a failure. Some font and platform variation is permitted; conversely, two identical screenshots may hide distinct scalar streams. A reliable defect report cites the applicable rule, names the observed implementation layer, and demonstrates how its contract is violated without silently discarding the original text.
Primary standards and authoritative implementation documentation
These references define the relevant Unicode properties, web layout semantics or platform APIs. Unicode data files and browser conformance can evolve independently; record the tested version rather than presuming that every installed system has identical support.
- Unicode Normalization UAX #15 — consult the primary specification or implementation reference for precise conformance wording, versions, property definitions and edge conditions.
- Unicode Text Segmentation UAX #29 — consult the primary specification or implementation reference for precise conformance wording, versions, property definitions and edge conditions.
- Unicode Character Database UAX #44 — consult the primary specification or implementation reference for precise conformance wording, versions, property definitions and edge conditions.
- W3C UI Events Keyboard — consult the primary specification or implementation reference for precise conformance wording, versions, property definitions and edge conditions.
- W3C Input Events Level 2 — consult the primary specification or implementation reference for precise conformance wording, versions, property definitions and edge conditions.
- OpenType GPOS — consult the primary specification or implementation reference for precise conformance wording, versions, property definitions and edge conditions.
Related technical references
Within the Multilingual Text & Input Systems virtual silo, these already published studies provide additional context for source text, rendering, editing and interchange: