Word fidelity
Word feature support for editing, rendering, and structural round-trip fidelity, plus security and API stability.
Use this page to check which document features you can edit, display, and preserve when you save. Read each feature's note for limits, including document settings that change layout. Use the guides for setup and editing instructions.
- Fonts and measurement: Supply fonts that control text width and page breaks.
- Right-to-left text: Configure paragraph direction and understand mixed-direction editing.
- Images: Review picture formats, text wrapping, and drawing limits.
- Headers and footers: Configure section variants and edit page content.
- Footnotes and endnotes: Review note placement and continuation limits.
Product behavior
| Area | Behavior |
|---|---|
| Browser editor | Parses, renders, edits, and serializes DOCX data in the browser. |
| Server editing API | Runs where you host it. |
| File format | Reads and writes Office Open XML (OOXML). |
| Unsupported content | Preserves unmodeled markup and package payloads when you edit other content. |
| Support | Contact docx-editor@eigenpal.com. |
Layout checks
Start with the features your documents use. The matrix provides support details and limits for each feature.
| Area | What to check |
|---|---|
| Paragraphs | Check line spacing, paragraph keeps, tab stops, and words split across formatting runs. |
| Sections and page breaks | Check continuous sections, empty section marks, page numbering, and inserted blank sheets. |
| Tables | Check row minimums, merged cells, repeated headers, and floating table placement. |
| Footnotes and endnotes | Check reference placement, note openings, continuation space, and unsupported configurations. |
| Drawings and frames | Check text wrapping, anchor positions, shape groups, and preserved content. |
| PDF export | Check fallback fonts, joined Arabic text, text extraction, and unsupported effects. |
Input-method checks
Test your target browser and input method before deployment. Start composition in an empty paragraph, inside a table cell, and beside an inline picture. Check the composition text, candidate window, committed text, and undo behavior. Review the input-method row in the feature matrix for limits.
Feature matrix
The matrix reports editing, rendering, and round-trip support separately. A feature can display without editing controls, or survive save without displaying.
| Axis | Question |
|---|---|
| Editing | Can a user or API change the feature? |
| Rendering | Does the feature display like Microsoft Word? |
| Round-trip | Does it survive open, edit, save, and reopen? |
| Status | Meaning |
|---|---|
| Full | Supports the feature within the scope described in its note. |
| Partial | Works with the limits in its note. |
| Render only | Displays correctly but is not editable. |
| Preserved | Remains as inert content through editing and save. |
| No | Is not supported. |
Text and formatting
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Bold, italic, underline, strikethrough | Full | Full | Full | Structural XML indentation does not hide run text. Authored spaces inside text elements remain part of the document. |
| Input-method composition | Partial | Partial | Full | Empty paragraphs and lines containing only inline pictures provide a visible font for composition text. Committed text supports undo, redo, collaboration, and save/reopen. Native candidate-window placement depends on the browser and operating system; validate your target input methods. |
| Format painter | Partial | Full | Full | Copies character formatting, and paragraph formatting when the selection covers the paragraph mark. Paragraph borders and character styles stay on the target. Line-fitting spacing adjustments do not become document formatting. |
| Subscript & superscript | Full | Full | Full | Nonzero authored or inherited baseline positions contribute translated run extents to automatic and minimum line spacing, including positioned subscript and superscript text. Exact line spacing retains its authored height. |
| Font family & size | Full | Full | Full | Configure font sources with the fonts prop; customFonts() loads your own files under private editor font names. Search standard, configured, and provider fonts in the picker, including in blank documents. Selecting a font loads it without resetting selection or undo history. The editor validates downloaded files and hashes and resolves theme fonts from the document. Word-compatible wrapping requires font bytes. The fonts package supplies six substitutes: the five default families match covered glyph advance widths, while Century Gothic differs by less than 1% in measured samples. Kerning and glyph differences can still change line breaks. packagedFonts() loads requested families and the default face from packaged assets. googleFonts() adds a pinned remote catalog. Compose sources in priority order with useFonts or useDocxSource; later resolvers can skip faces already loaded. Document font names with commas or semicolons are requested as one family and are not split into candidates. An available whole font-table alternate of up to 31 characters precedes generic substitution. Available script defaults handle unambiguous unresolved names. Names shared across different script defaults retain the existing fallback path. Measurement, painting, and PDF evidence use the selected admitted face. The first collection face paints from the complete admitted bytes, including its signature, under a private browser alias. Other faces use a standalone copy with all selected tables, including DSIG. Collection-header signatures do not block face selection. Registration does not verify signatures. Invalid faces receive no browser alias. Admitted source bytes remain intact. Unmatched families keep fallback measurement. An admitted face that exceeds the shaping byte limit keeps fallback measurement and reports its refusal through onFontError. Eligible non-ASCII text uses its independently declared hAnsi face before measurement and paint. Combining marks retain the base face across source runs. Full-width forms use the East Asian face. Curly and low quotes, en and em dashes, ellipses, and middle dots use hAnsi without an East Asian hint, including beside Han text; existing complex-script overrides still apply. East Asian font hints follow the East Asian language of the run and a Chinese East Asian face for accented and extended Latin letters. Slots no style names use the format default faces, and empty East Asian theme slots use the default face of the theme language. Cached field results use the hAnsi face like other text. Canonical font attributes and model offsets stay unchanged. PDF export reports failed font sources and supports custom fallback sources after embedded fonts. Set fontShaping.maxFontBytes to use admitted faces larger than the default 16 MiB shaping limit, up to 64 MiB. Equal ceiling values preserve the editor instance; changed values reset selection and undo history. Deferred font errors belong to the active document load; replacement and destruction discard older diagnostics. |
| Embedded fonts | Partial | Full | Preserved | The editor de-obfuscates the fonts in word/fonts on load and measures text with them. No configuration and no network request are necessary. The binaries round-trip on save. The editor does not add new embedded fonts. |
| Text color (RGB + theme colors) | Full | Full | Full | Theme color references (accent1...) round-trip as references, not flattened to hex. |
| Highlight & shading | Full | Full | Full | Word highlight palette plus arbitrary w:shd fills. |
| Right-to-left & bidirectional text | Partial | Partial | Full | Paragraphs use inherited bidirectional settings for alignment, script shaping, visual order, and caret placement. Alignment and indents name leading and trailing sides, and kashida alignments justify. Run direction controls numbers and punctuation independently of paragraph alignment. Runs with effective w:rtl or w:cs use complex-script font, size, bold, and italic properties. Formatting commands resolve inherited styles and document defaults, then write both property variants. Direct false values override inherited values. Arabic and other joining scripts preserve letter forms across adjacent formatting runs, including color changes. Joining requires the same bidirectional level and no intervening whitespace. Kerning and cursive offsets across those boundaries remain unsupported. List markers, spacing, indents, and tab stops follow paragraph direction in body text and table cells, and list markers read right to left. Left-to-right and right-to-left paragraph direction controls are in the toolbar, the Format menu, the Paragraph dialog, and the Ctrl+Shift keyboard chords in documents that already contain right-to-left text. The document automation API sets and reads paragraph direction with Paragraph.readingOrder. Review cards show a tracked paragraph direction change. Selection highlights can span separate visual bands; some glyph edges have no distinct caret position. Inline pictures read in the direction of the text around them, in paragraph direction between text of different directions or before the first text, and in the direction of the last text after it. They take the caret and clicks on their leading and trailing sides. Numeric page fields and note marks containing only ASCII decimal digits preserve surrounding text order when they occupy one model character. Positional tabs, other inline objects, paragraphs with floating objects, section direction, and w:dir and w:bdo wrappers have partial support. Typed text does not receive w:rtl automatically. The i18n package includes Hebrew UI translations. |
| Text effects (outline, shadow, emboss, emphasis mark) | No | Partial | Full | Opaque solid w14:textOutline with an explicit RGB color renders. Theme-colored, transparent, gradient, dashed, compound, and inset outlines do not render. Legacy outline, shadow, emboss, imprint, and emphasis marks are preserved but do not render. Text effects have no toolbar controls. |
| Hidden text (vanish) | No | Full | Full | The editor does not draw w:vanish runs or give them space, but preserves their text on save. There is no "show hidden text" option. A paragraph with no visible content collapses when its directly hidden mark precedes another paragraph in the same container, or precedes a table and the paragraph states no space before. Collapsed paragraphs still advance list numbering. Paragraphs with section breaks follow the section layout rules instead. Body paragraphs can share display flow when their resolved marks enable w:vanish. The paragraph must contain ordinary visible text unless its mark also enables w:specVanish. The bounded subset requires matching continuation geometry, paragraph direction, line-breaking settings, and keep constraints. It preserves source paragraphs, member text formatting, first numbering and before-spacing, and last after-spacing and paragraph-mark formatting. Mixed geometry, contextual spacing, tracked content, cross-paragraph fields, non-body stories, and chains above 64 members stay separate. Export reports unsupported-style-separator for preserved visible-content joins outside this subset. |
| Math equations (OMML) | Partial | Partial | Full | Inline (m:oMath) and display (m:oMathPara) equations lay out and paint as math. The document API inserts one inline equation from a Flat OPC package through Range.insertOoxml, untracked or as one tracked insertion that Reject removes whole; other OOXML refuses. Display equations follow m:oMathParaPr justification and center by default when they are the only content of the paragraph. Each equation is one atom in the text: typing beside it creates ordinary runs, and deleting it removes the whole equation. In suggesting mode, a deletion that covers an equation proposes removing the whole equation. The equation popover edits fractions, radicals, scripts, and n-ary operators in a linear format and removes equations; removing the last equation of a display removes the display. Literal and normal text and upper or lower bars also project as math. Structures whose properties carry m:ctrlPr with supported run formatting project as math; their operator glyphs keep the default math formatting, and save keeps the m:ctrlPr source. When every m:ctrlPr in an equation holds the same default formatting (the Cambria Math font, italic, one size, and a language), compact replacement is available and writes the same m:ctrlPr on each structure it creates. The same rule applies to w:rPr on equation runs without m:rPr: when every run holds the same default formatting, compact replacement is available and writes the same w:rPr on each run it creates. An equation whose runs share one w:sz lays out at that size; a display does so only when all of its equations share the size. Compact replacement is disabled for formatted equations, bars, and other control properties because it cannot preserve their source properties. You can remove these equations and edit ordinary text beside them. Constructs outside the supported subset show a text fallback and stay read-only. Unedited equations round-trip verbatim. |
| Symbol characters (w:sym) | Partial | Full | Full | Symbol runs render and survive editing and save. The editor requests fonts for symbol runs, SYMBOL fields, and used numbering markers through the configured font resolver. You can insert a symbol from the Insert menu. A symbol is one character of the paragraph text and reads as an opening parenthesis. The caret steps over it in one move, and Backspace or Delete removes it. Search never matches a symbol. Non-breaking and optional hyphens are characters of the paragraph text, read as U+001E and U+001F, and select, search, and delete like any character. A line can break after an optional hyphen, which then shows as a hyphen at the line end. Existing symbol run properties are not editable. |
Raised and lowered text contributes to automatic and minimum line heights. This includes inherited w:position values combined with subscript or superscript. Exact line spacing retains its authored height.
Equation source formatting
Latin and Greek letters in equations use mathematical italic glyphs from the math font, unless m:sty specifies plain, bold, or bold italic. Run fonts, bold, and italic do not change these letters. Plain-style runs keep the run font, and a font other than Cambria Math also keeps run bold and italic. Normal-text runs keep their original characters and run formatting. Measurement and paint use the same display string; saved OMML retains the original text.
Equations retain their canonical Office Math source when you save the document. Literal text and normal text project within fractions, radicals, scripts, and other supported structures. Upper and lower bars also project as math. Bars, fractions, radicals, scripts, and n-ary operators project when their properties carry control properties (m:ctrlPr). The control properties can hold run fonts, bold, and italic, directly or inside a tracked insertion or deletion. They can also hold default formatting, which this section describes later. Operator glyphs and rules keep the default math formatting, and the control properties remain unchanged on save. Other content in control properties retains the text fallback.
Control properties hold default formatting when their run properties contain only the Cambria Math font, italic, one font size, and a language. If every control property in an equation holds the same default formatting, compact equation replacement is available. The replacement writes the same control properties on each fraction, radical, script, and n-ary operator that it creates. Run properties (w:rPr) on equation runs follow the same rule. If every run in an equation holds the same default formatting and no math run properties (m:rPr), compact equation replacement is available. The replacement writes the same run properties on each run that it creates. If the runs share one font size, the equation lays out at that size. Otherwise, it takes the size of the surrounding text. A display equation takes a run size only when all of its equations share it. Compact equation replacement is disabled when it cannot preserve run formatting, bars, or other control properties, including tracked ones. You can remove the equation and edit ordinary text beside it. This restriction applies to the equation, not the document. Unsupported source properties retain the text fallback and remain unchanged on save.
Paragraphs and styles
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Alignment & justification | Full | Full | Full | Justified lines compare space compression with expansion at an earlier break, including hyphenated fragments and fixed REF results. Justified East Asian lines distribute inter-character spacing. Modern Latin justification measures complete words across formatting runs and terminal note citations before compressing spaces. Citations with reserved page-local widths retain their existing line-break behavior. The final line of a justified paragraph keeps natural spacing at its leading edge. With the w:doNotExpandShiftReturn compatibility setting, a line that ends in a manual line break keeps its natural spacing. In documents that declare compatibility mode 14 or earlier, or no mode, a line that ends in a page or column break stretches to both margins; in mode 15 and later it keeps its natural spacing. Tabs and float passages retain their reserved positions. |
| East Asian typography | Preserved | Partial | Full | Keeps graphemes, punctuation, and full-width number groups together across runs. No-break spaces and word joiners retain their line-break behavior across formatting runs. Theme languages and inherited language hints select Latin, East Asian, and complex-script fonts; unresolved Chinese, Japanese, and Korean faces use named defaults. Font resolvers receive these candidates before shaping. Document settings control line breaking, Korean word wrapping, punctuation overflow, and compression. Adjacent punctuation can share spacing, and narrow plain left-to-right paragraphs can use measured glyph bounds for fitting. Authored spaces, paragraph boundaries, decorated text, tracked changes, right-to-left text, mixed Latin text, fields, and gaps beside floating objects retain conservative spacing or fitting. Kana uses fixed advance reductions. Vertical Japanese composition and typography controls in the UI are unavailable. Only WordprocessingML namespace elements and attributes set run properties, including the run language; foreign extensions remain saved without changing them. Adjacent full-width punctuation compression uses both runs’ kern thresholds, and the document’s noPunctuationKerning setting. It applies only when the East Asian face of the document defaults is an East Asian font. It does not disable Latin font kerning. Kana compression retains natural advances on non-full lines. See Word fidelity for individual compression rules. |
| Thai, Lao, Khmer, and Myanmar line breaking | Preserved | Partial | Full | Lines in Thai, Lao, Khmer, and Myanmar text without spaces wrap at any character cluster that fits, not at dictionary word boundaries. Table AutoFit keeps an unspaced run whole as one segment. Lines can end after a zero-width space (U+200B) in any script, which marks a word boundary, and the zero-width space stays at the end of the line. A space before a zero-width space counts as text while it fits, and hangs only when it does not fit. Line breaks never split a character cluster, a Khmer or Myanmar stacked consonant, or a Myanmar consonant and its vowel sign or visarga. |
| Line & paragraph spacing | Full | Full | Full | Space before, space after, and line spacing (single, multiple, exactly, at least) all reach pagination. If a document does not define its default paragraph properties, paragraphs use 8pt space after and 278/240 automatic line spacing. If it does not define its default run properties, text uses 12pt. An explicitly empty default keeps 10pt text with no spacing. The engine uses line spacing when it calculates page breaks. The paragraph mark size sets the height of an empty paragraph and of the empty line after a trailing line break. A larger mark does not make a line with text, an inline picture, or an equation taller. A line with only inline pictures takes the text height of the runs that hold them, not of the paragraph style or the mark. A line with superscript or subscript text, including a note reference, keeps the full-size height of that text above and below the baseline on every line of the paragraph, and a larger paragraph style size does not make that line taller. Multiple line spacing scales a line with raised or lowered text by its height without the raise, and the raise adds its height unscaled. Spaces and tabs do not set line height, so a line with only spaces or tabs is as tall as an empty paragraph. A character style on the paragraph mark sets the height of an empty paragraph and of the empty line after a trailing line break, and formats the list number. Text typed into an empty paragraph takes that character style. The style does not make a line with text or an inline picture taller. Contextual spacing drops the gap between neighbours of the same style in body text and table cells, including implicit default styles. Line-unit paragraph margins use 12pt units or the section grid pitch. In a section with a document line grid, each body line takes whole grid lines with its text centered. The space below the text in a grid line can extend past the bottom margin, so a line fits when its text fits. Multiple line spacing counts in grid lines: a line takes the larger of the grid lines its text needs and the multiple, so double spacing is two grid lines. At-least spacing up to the grid line takes the grid line, and a taller at-least value keeps its own height with the extra above the text. Paragraphs that turn off grid snapping and paragraphs with exact line spacing keep their own line height. Without a grid, at-least spacing adds its extra height above the text, so the whole line must fit above the bottom margin. With single or multiple spacing, only the space below the text can extend past it, including the lower part of a grid line. Table cells snap only with the adjustLineHeightInTable compatibility option. Footnote and endnote text snaps to the grid of the section that holds it. Headers, footers, and text boxes do not snap. Numbering-level paragraph properties participate in layout. The Paragraph dialog sets contextual spacing. Automatic spacing (w:beforeAutospacing, w:afterAutospacing) uses 14pt in body paragraphs and at list boundaries. Adjacent items in the same list suppress automatic spacing, including nested levels. Lists suppress automatic leading space at section start. Table cells suppress automatic spacing at their outer edges. Adjacent space after and space before collapse to the larger of the two. If the document sets w:doNotUseHTMLParagraphAutoSpacing, they add up instead, in body text, table cells, headers, footers, notes, and text boxes, and automatic spacing is a fixed 5pt before and 10pt after. |
| Keep with next, keep lines, widow/orphan control | Full | Full | Full | w:keepNext, w:keepLines, w:widowControl and w:pageBreakBefore all reach pagination, and the Paragraph dialog sets each of them. Keep-with-next groups account for the following paragraph’s keep-lines and widow-control requirements when the group fits on a page. Groups can contain more than eight consecutive paragraphs, including paragraphs with inherited keep properties. Explicit page breaks and section boundaries end the group. A kept paragraph that does not fit in the space left on a page splits there if its own keep-lines and widow-control settings allow it, and its last lines open the next page with the following paragraph. In documents that use Word 2013 or later layout, the last kept paragraph that fits before a following paragraph that does not also splits, and its last lines move with that paragraph. This applies to any paragraph in a keep-with-next chain. Earlier layout modes move the chain whole. A value a style supplies reads through the cascade, so a checkbox shows what is in force rather than only what the paragraph authors itself. In a body table, keep-with-next on the first paragraph of the first cell keeps the row with the next row, or with the paragraph after the table. The value can come from paragraph or table styles. Kept rows move to the next page as a group when they and the start of what follows do not fit. A kept row does not split. The next row needs only the first lines of each cell, unless it cannot split. In documents that use Word 2013 or later layout, a row after a kept row does not start a new page: it is the next row of the group, which moves only when it does not fit. In earlier layout, a row that starts a new page ends the group. In Word 2013 or later layout, header rows keep with the first body row in the same way. A keep-with-next paragraph before a table keeps with the header rows, and in Word 2013 or later layout also with the first body row. When every body row keeps, that paragraph also keeps with what follows the table. A kept paragraph before an oversized table opening first moves to a fresh page, even when the table cannot fit beside it. Table keep decisions measure up to 256 kept rows and the next row; paragraph lookahead remains separate. A keep chain continues through one table only. Closed vertical merges inside the measured group share their height across their rows. Merges entering or leaving the group, active wrap exclusions, rows whose first cell starts with a nested table, and positioned tables keep their existing placement. |
| Indentation (incl. hanging indents) | Full | Full | Full | Left, right, first-line, and hanging indents control line placement. Increase Indent and Decrease Indent are on the toolbar, on Tab, and on Ctrl+M. Inside a list they change the level, so the marker changes too. Outside a list, Tab over a selection of two or more paragraphs indents them, and Tab over a selection that starts at a paragraph start sets a first-line indent, or steps the left indent when the first line is already indented or hanging. Shift+Tab reverses these steps. Tab over selected table cells indents them. The selected text stays. A caret, or a selection in one paragraph that starts inside the text, types a tab character. |
| Paragraph styles (Heading 1, Quote, custom styles) | Full | Full | Full | The style picker applies document styles, including custom styles with their numbering and indents. Pressing Enter at the end of a paragraph starts the next one in the style that the current style names as its follower (w:next), so a heading is followed by body text. Defining a new style in the UI is not supported yet. |
| Paragraph borders & fills | Partial | Full | Full | Paragraph shading (w:shd) is editable. Borders render the common ST_Border styles: single, double, dashed, and dotted. Thick, 3-D, inset, and outset styles use CSS approximations, and art borders paint as a solid rule. A border box starts where the first line starts, so a hanging indent moves its edge outward. Adjacent paragraphs with identical borders draw one box when their box edges match. Borders round-trip, but you cannot add, change, or remove them in the editor yet. |
| Tab stops & leaders | Partial | Full | Full | Existing tab stops render, with right and decimal tabs and dot, hyphen, and underscore leaders. In left-to-right text without adjacent floating objects, opening words wrap after leading left-aligned tabs without adding a blank line. In table cells without consecutive tabs, an ordinary left tab whose next stop exceeds the line edge moves to the next line before following text. Trailing tabs keep their line. Positional tabs (w:ptab) render too, so a contents line reads as one: entry left, leader dots between, page number right. The document's own w:defaultTabStop is honored, in the body and in headers and footers. The Paragraph dialog sets, clears, and replaces tab stops, including clearing one that a style supplies. Bar tabs are preserved on save but aren't drawn or editable. |
| Drop caps & text frames (framePr) | No | Partial | Full | In single-column sections, bounded body text frames support numeric and relative page, margin, or text positioning; fixed width or the containing text column width when width is omitted; auto, minimum, and exact height; every rectangular wrapping mode; single-line left-to-right dropped caps; and bidirectional margin drop caps. Multiline dropped caps, negative text-relative vertical offsets, and right-to-left dropped caps retain ordinary flow to prevent text overlap. A positive authored height sets a minimum when its height rule is absent. Frame attributes inherit individually from styles. Wrapping defaults alone retain ordinary flow. Adjacent paragraphs with identical resolved frame properties share one frame, including inline pictures. Exact-height content clips to the authored rectangle. Locked anchors remain attached during supported edits. Continuous sections clear preceding frames that intersect the body area. Frames outside that area do not advance text flow. Text remains selectable and editable; frame creation, movement, and resizing have no UI. Centered auto-sized, right-aligned auto-sized over a text line or empty paragraph, and supported fixed-width PAGE footer frames retain their specialized layout. Fixed-width PAGE footer frames over an empty anchor honor numeric page-relative X positions. Exact-height frames also honor numeric text-relative Y positions and clip to their authored rectangle. Unsupported frame attributes retain ordinary flow. Centered PAGE footer frames support auto and around wrapping with direct formatting, unused tab stops, line spacing, and nonnegative first-line indents. The frame and empty anchor share one footer band. A right-aligned frame over an empty paragraph can contain plain text around a simple or complex PAGE field. The empty paragraph sets the flow height. The frame retains its own spacing, except that fixed paragraph spacing suppresses its extra leading space. In a header, an auto-sized frame that opens the header and is empty or holds a PAGE field or plain text shares the first line of the next paragraph at the left, center, right, inside, or outside margin, and adds no height. A text-free frame also preserves the following anchored drawings without adding a line. Whitespace-only frames keep ordinary flow. Inside and outside alternate with the physical page, so a page number restart does not change the side. If a nonempty frame would meet the text of that paragraph, a table, a drawing, or a paragraph border, the header keeps ordinary flow. Headers also support bounded page-anchored plain-text frames with numeric positions and widths. Adjacent paragraphs with identical direct frame properties share one frame, including its paragraph borders and auto or minimum height. These frames do not increase the body inset. Ordinary header paragraphs and inline images keep their flow positions. This subset requires an ordinary paragraph and nonoverlapping content. Headers with fields or revisions, and frames with exact heights, negative positions, or unsupported properties, keep ordinary flow. Frames with unsupported content and groups that block a full fresh page use ordinary flow. All frame properties survive save. |
| Automatic hyphenation | No | No | Preserved | Document hyphenation settings round-trip; the layout engine does not hyphenate automatically. A line can break at an optional hyphen in the text. The line then ends with a visible hyphen, which counts toward the line width. A U+00AD character in run text shows as a hyphen and is not a break opportunity. |
Tabs and paragraph keeps
In left-to-right text, an opening word wraps within the space after leading left-aligned tabs. The tabs retain their advances and do not add a blank line. This applies to ordinary text without floating objects beside it, including table cells.
A paragraph with w:keepNext stays with the opening lines that the following paragraph must keep together. With widow control, a following three-line paragraph stays whole. w:keepLines keeps the entire following paragraph together when the group fits on a page. Consecutive kept paragraphs form one group, including groups with more than eight paragraphs. Inherited keep properties apply to the complete group. Explicit page breaks and section boundaries end the group.
Text frames
Body text frames retain numeric and relative page, margin, or text positions. The engine supports fixed width. Frames with omitted width use the containing text column. It supports auto, atLeast, and exact height rules. A positive authored height sets a minimum when the height rule is absent. Exact-height frames clip content to the authored rectangle. Frame attributes inherit individually from paragraph styles. Wrapping defaults alone do not create a positioned frame. Adjacent paragraphs with identical resolved w:framePr attributes share one frame. Inline pictures remain inside their frame.
All ST_Wrap values use the frame's rectangular contour. auto uses the default around behavior. none, notBeside, and vertical inline alignment move following text below the frame. Single-line left-to-right dropped caps use the requested body-line band. Multiline dropped caps retain ordinary flow. Right-to-left dropped caps retain ordinary flow. Margin caps sit outside the text column on either side.
Frames follow their next ordinary paragraph across page breaks and do not consume normal paragraph height. Bounded negative page-relative and margin-relative offsets remain authored. Negative text-relative vertical offsets retain ordinary flow to prevent overlap with earlier text. Locked anchors remain attached during supported text, property, split, and join edits. A following continuous section clears preceding frames that intersect the body area. Frames outside that area do not advance its text position.
This support applies to single-column sections. Frames containing unsupported drawings, notes, or revision structures retain ordinary layout. Frame groups that block the full text width and leave no vertical room on a fresh page also retain ordinary layout. The editor preserves all frame properties on save. There is no interface for creating, moving, or resizing text frames.
Headers also support bounded page-anchored text frames with numeric positions and widths. Adjacent paragraphs with identical direct frame properties share one frame. These frames retain paragraph borders and auto or minimum heights. They do not increase the header height that positions body text. Ordinary header content, including inline images, keeps its flow position.
This subset requires a separate ordinary paragraph and clear space around the frame. Headers with fields or revisions retain ordinary flow for this subset. Frames with exact heights, negative positions, overlapping content, or unsupported properties also retain ordinary flow. The editor preserves source paragraphs and their text positions.
Lists and numbering
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Bullet lists (multi-level) | Full | Full | Full | The toolbar toggle creates the numbering definition on first use, so a document that never carried a list can start one. Known single-byte Symbol and Wingdings bullets use Unicode fallback when their font is unavailable. Layout still uses the line height and advance widths of the symbol font. Saved numbering stays unchanged. It also applies the List Paragraph style, the way Word does, which is what closes the space between consecutive items. Turning the list off leaves the paragraph in List Paragraph, and indented, as Word does; pressing Enter on an empty item leaves the list and returns to the margin. Enter within a list item continues a single blank-paragraph separator established by preceding items at the same level, including tracked breaks. Tab and the indent buttons change the level, and the marker changes with it. |
| Numbered lists (decimal, roman, letters) | Full | Full | Full | Numbered lists take the List Paragraph style on the same terms as bulleted ones, so consecutive items close up. The tab after a number stops at the first tab stop past the number when that stop comes before the text indent, so the first line can start left of the indent and fit more text. If the document sets w:doNotUseIndentAsNumberingTabStop, the first tab stop past the number applies wherever it is, and the text indent applies only when no such stop exists. Hebrew (hebrew1, hebrew2), Arabic (arabicAlpha, arabicAbjad), and Devanagari digit (hindiNumbers) formats number in their own scripts. Other script-specific formats fall back to decimal. A level with empty number text, such as w:numFmt="none", paints no number but keeps its suffix: a tab moves the first line to the next tab stop, a space moves it one space, and no suffix starts it at the number position. |
| Custom numbering definitions & style-linked numbering | Full | Full | Full | Numbering attached to custom paragraph styles resolves with Word’s precedence rules. |
| List continuation & restart | Full | Full | Full | |
| Picture bullets (numPicBullet) | No | Partial | Preserved | A numPicBullet marker renders as its image, scaled by the marker run font size, in the editor and in PDF export. The level bullet text renders instead when the image is missing or is a media type the editor does not decode. You cannot choose or change a picture bullet in the editor. The numPicBullet definition and its markup are preserved on save. |
Tables
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Table insertion & cell editing | Full | Full | Full | Files without a compatibility mode, and files in compatibility mode 11, 12, or 14, align the content of a top-level percentage-width table with the text column, for every alignment, indent, and layout, and measure the percentage against the text column plus the stated outer cell margins. The same settings apply in body, header, footer, text-box, and note stories. A table percentage width can be larger than 100%, up to 655.34%, and extends the table past the text column for every alignment, AutoFit and fixed layout, and compatibility mode. Fixed tables without a positive table width can use cell preferences to replace their initial grid. Each cell must have a positive absolute width and occupy one column. The largest preference in each column sets its width, even when the initial grid is wider. Hidden revision rows prevent this replacement. Other width conflicts keep their existing reconciliation. A table indent moves a left-aligned table by the full amount, also when the table is wider than the text column or the indent is wider than the space left. A negative indent moves the table into the left margin. Centered and right-aligned tables ignore the indent. A right-to-left table measures the indent from its leading edge. Nested tables ignore a negative indent. A zero indent on a table overrides the indent of its table style. An AutoFit column widens to hold its widest unbroken word, such as a long URL, with indents and cell margins; the other columns give up width in proportion to their spare room. When the minimums are wider than both the text column and the table, the columns shrink in proportion to their minimums to the wider of the two. An AutoFit column whose cells state no width is sized by its content: it takes its widest unwrapped line when the table has room, and room beyond that is shared in proportion to those widths. Columns with a stated width give way to them first; then they wrap. A cell that spans columns widens them to hold its own widest word, and the columns outside the span give up the width. A nested fixed table needs only the content it holds and paints no wider than its cell: its columns give way down to their own content. A nested AutoFit table also keeps its resolved width. Both keep their leading indent; a narrowed nested fixed table keeps the width its cells of vertical text have. Elsewhere, cells with vertical text set no minimum. Cell spacing sits on each side of every cell, so cells sit twice the spacing apart and from the table edge, within the table width. Rows are separated the same way: the cells of each row start twice the spacing below the row above, and the table ends twice the spacing below its last row. A minimum row height sizes the cell below that gap, and an exact row height keeps its authored value. When every row states the same row-level cell spacing and the table states none, that spacing applies to the table. An AutoFit table in which every column states an absolute width starts from those widths, raises each column to its widest word, and then gives up width in proportion to how far each column is wider than that minimum. In older modes, a table with zero cell margins aligns its content with the text column, and a text-box table uses a reference box 0.75 points wider and puts the outer edge of a right-aligned table on the right edge of the box. |
| Visually right-to-left tables | Partial | Full | Full | Authored w:bidiVisual tables display logical cells from right to left, including merged cells and repeated headers. Table styles can supply the property; a direct false value overrides it. Borders, margins, alignment, selection, column insertion, and divider resizing follow the visual grid. HTML copy and paste preserve explicit table direction and physical cell borders and margins. Changing table direction and resizing the outer right edge of an RTL table are not supported. |
| Row/column insert, delete, resize | Full | Full | Full | Hover controls insert a row or column. Drag a divider or the outer right edge to resize. Row drags stop at 8 points, or the initial height when the row starts shorter. Column resizing supports merged cells in left-to-right tables. A divider shows where the row has a cell edge. Legacy horizontal merges, row offsets, and merged right-to-left tables remain unsupported for column resizing. Column insert and delete work on tables with merged cells: a merged cell that spans the edited column widens or narrows. The context menu adds nine structural actions, including Merge cells and Split cells. Both adapters ship the same table chrome. The automation object model adds rows at table edges or before and after an ordinary row. Unrelated merged headers survive row insertion. Automation row insertion refuses merged source rows and boundaries that cross vertical merges. New rows and columns copy the paragraph formatting of the cells they come from, and written values take that formatting too. |
| Table and cell borders & shading | Partial | Partial | Full | Both adapters expose contextual toolbar controls that set borders and fill on the selected cells. Authored table and cell borders, row border exceptions (w:tblPrEx), and table-style shading render and round-trip. Direct cell shading renders. Direct table shading (w:tblPr/w:shd) is preserved but does not render. Apply shading to cells when you need a visible table background. A rule that two cells share paints once, centered on the boundary between them. Rows with omitted leading or trailing grid cells retain their exposed side borders. Explicit cell borders take precedence at those edges. An explicit empty cell border clears its own inherited rule but preserves a border inherited by the neighboring cell. With no compatibility mode, or mode 11, 12, or 14, simple single side rules are centered on the grid line. This applies to top-level, unpositioned, left-to-right tables without cell spacing. If the table has an absolute width, its side cell margins start at the center of the rule, and supported left-aligned fixed tables with automatic widths also use that margin space. Fixed tables with automatic or absolute widths align their leading cell content with the table indent when every row covers the grid and shares that leading margin. Their margins must clear half of each simple side rule. In compatibility mode 15 and later modes, both apply to centered tables with an absolute or automatic width. They also apply to left-aligned or right-aligned tables with an absolute or automatic width and one simple rule width on every cell side. Autofit and right-aligned tables use this geometry only when their outer borders fit within the available width. Tables with complete grid rows and missing side borders share the grid line with cell margins when all visible side borders use one simple rule width. These partial frames keep their existing grid position. Those tables with complete frames put the outer edge of the rule on the aligned edge, so the grid moves inward by half a rule. Leading-aligned fixed-width right-to-left tables with an absolute width and equal simple side borders share the border with cell margins in compatibility mode 15 and later modes. Their grid moves left by one border width. Nested tables, floating tables, and spaced cells keep their existing geometry. Other tables start the side margins at the inner edge of the rule. |
| Merged cells (horizontal & vertical) | Partial | Full | Full | Authored merges render and round-trip. A vertical merge takes its height from the rows it covers, and merges that cover the same rows share that height. If every covered row has a fixed height and the text is taller than the rows, the text flows through all of them and is clipped at the bottom of the last row. A vertical merge that contains other vertical merges in other columns is sized with them. A vertical merge inside repeated header rows is sized the same way on the first page and on every repeat. A merge that continues from the header rows into the body rows sizes its first header row instead. A merge that only partly overlaps another one sizes its first row instead. A row inserted at a boundary inside a vertical merge extends the merge by one row and keeps one cell per column. Deleting the row where a vertical merge starts removes that row’s content and starts the merge in the next row, unless a merged cell above on the same grid columns takes that row over. If no later row continues the merge, the surviving cell becomes unmerged. A continuation cell with no merged cell above it starts its own merge when another row continues it. Merge cells joins a selected rectangle into its top-left cell, which keeps the content of every cell that had content, in reading order. Split cells divides a cell into rows and columns of equal size from a dialog; a cell merged over several rows splits into a number of rows that divides its rows. Both are in the context menu and the table toolbar, and the automation object model offers them as Table.mergeCells and TableCell.split. Both refuse in suggesting mode, because a merge or split has no tracked form, and on legacy horizontal merges. They synchronize in collaboration and undo as one step. Text a participant types into an empty cell while a peer merges it away is discarded. Concurrent merges, splits, and column edits of one table can leave a row that ends before the last grid column; a merge or split that needs its missing part then refuses. |
| Tables split across pages | Full | Full | Full | A row that closes a page reserves room for its bottom border. Fixed-height horizontal cells keep the visible part of a line that starts inside their content box. The authored row height, source text, and line metrics remain unchanged. Empty paragraphs in table cells retain a line and caret space when w:hideMark excludes the end marker from row minimums. Rows split mid-content with correct cut borders. In a body table, pageBreakBefore on the first paragraph of the first cell starts the row on a new page. The value can come from paragraph or table styles. In documents that use Word 2013 or later layout, a row after a row that keeps with the next one does not start a new page. The break skips remaining columns and repeats header rows. A row that starts a vertical merge, or follows one that has ended, can start a new page. A row that continues a vertical merge in any column ignores the property and keeps its placement, because the merge continues through that row. Nested and positioned tables also keep their existing placement. A row that cannot split still clears wrapping header or body pictures. It splits when the fresh space below the picture cannot hold it. A row that cannot break across pages moves to the next page, and a row of that kind taller than a page starts on a new page and then splits. A row with a minimum height starts below other content only when the space left holds that minimum. Otherwise it moves to the next page, also when its content is taller than a page, and a keep-with-next paragraph before the table moves with it. A minimum larger than a fresh page starts on a fresh page. Completed row content fills the available page band. In documents that use Word 2013 or later layout, repeated headers yield when they would displace the row minimum. Authored header rows account for wrapping pictures when keeping with the first body row. Rows of positioned tables keep their existing placement. Positioned tables retain their body text wrap region when drawing obstacles require immediate placement. Vertically merged cells repaint on continuation pages. In documents that use Word 2013 or later layout, a vertical merge over two rows can break right after its first row. If the merged text cannot place a line within that row’s own height, the row keeps its own height and the merged text starts beside the second row on the next page. Supported text-only merges over three or more fixed-height or nonbreaking body rows carry text and cached fields between page fragments. The original head cell remains the address for selection and commands. Each fragment uses its own vertical alignment. A nonbreaking last row grows with the remaining text and moves to the next page as a whole. If every row has a fixed height and the text is taller than the rows, the text continues through the rows on each page and is clipped at the bottom of the last row. Overlapping merges, manual breaks, drawings, notes, nested tables, floating tables, and unsupported formatting keep their existing placement. Merges over more rows, and merged text that splits inside the first row, keep their existing placement. Repeated headers and bounded complete text rows reserve their shared horizontal border before pagination. This boundary adjustment excludes spaced cells, vertical merges, split rows, positioned tables, drawings, nested tables, and vertical text. |
| Nested tables | Partial | Full | Full | The innermost table owns the resize controls, the structural edits, and the cell borders and fill. Outer tables stay unchanged through save and reopen. A nested table continues across pages between its rows, and a nested row taller than the space left splits inside its cells. A nested table with header rows or vertical merges moves whole to the next page, and splits there when a page cannot hold it. |
| Table styles & conditional formatting (header row, banding) | Partial | Full | Full | Table styles resolve through their basedOn chain, and a table that names no style resolves the document default. Borders, cell margins, shading, and conditional paragraph and run formatting come from styles.xml, so a header row comes out bold and centered. Cell text in the default paragraph style keeps the font size of that style when the table style states no size. w:tblLook gates which conditional formats apply, and an explicit w:cnfStyle wins. Conditional cell margins and a table-style picker are not built yet. |
| Floating tables (tblpPr anchored position) | No | Partial | Full | An anchored table uses tblpXSpec or tblpX across the text, margin, or page box, and tblpY or tblpYSpec against its vertical anchor. Body text wraps beside supported floating tables and below full-width tables, including authored text distances. Empty paragraphs follow the table wrapping rules and retain their line height. Full-width table exclusions move empty paragraphs below the table, with or without empty runs or bookmark boundaries. Passages of a quarter inch or less remain empty, so captions and headings clear near-full-width tables. Text-anchored tables with numeric vertical offsets move with their following paragraph and do not add table height to paragraph flow. Negative offsets retain their position when clear of preceding text; intersecting tables move below that text. Page- and margin-anchored tables that span the text column move to the next page with their following paragraph when earlier text on the page cannot clear them and still leave room for that paragraph. Page- and margin-anchored tables that overlap the text column and reach below the bottom margin break across pages in single-column sections. Such a table starts at its authored position, or higher so that the part that fits on the page ends at the bottom edge of the page, and continues at the top of the next page. Text after the table starts below its last row, and rows split even when they are set not to break across pages. A row whose minimum height does not fit moves to the next page, and a nested table row moves whole. In documents that use Word 2013 or later layout, the first part ends at the bottom margin. In earlier layout, only a table that reaches below the bottom edge of the page breaks, and its first part can reach that edge. Tables with an exact-height row, tables with a line or row taller than the page, tables outside the text column, tables that start in the bottom margin, tables that share an anchor paragraph, tables whose anchor paragraph has a page break, column break, or space before it, and documents with doNotBreakWrappedTables keep their placement. Text-anchored tables taller than a page, using vertical alignment, or affected by earlier wrapping pictures or frames retain row pagination. A text-anchored table marked no-overlap still floats. When it would cover an earlier floating table, it moves right of that table, left of it in compatibility mode 15 and later, or below it. Floating tables can overlap one another, and the cell text of a table placed at its anchor never wraps around another. A continuous section on the same page wraps its text beside the floating tables and wrapping pictures of earlier sections. An ordinary table that would cover a floating table starts below it. Before compatibility mode 15, a right-aligned floating table in the body moves right by its table cell margin. A text-anchored table that covers the text column breaks across pages when the rest of the page cannot hold it but can hold its header rows and first body row; otherwise it moves with its following paragraph. This continuation applies to single-column sections with one table per anchor. Anchors with page or column breaks, or space before them, keep whole-table placement. Tables with text distances above or below them also keep whole-table placement. Tables that fit a full page move together when doNotBreakWrappedTables is enabled. Simple terminal empty anchors retain their shared-page layout. In a header or footer, a top-level floating table sits at its anchor position outside the story flow. In documents that use Word 2013 or later layout, the blocks after it wrap beside it or move below it, and the header or footer grows with them. Body text on every page that shows that header or footer wraps around the table in every layout mode. A page- or margin-anchored header or footer table keeps its page position, and it moves up onto the page when it would pass the bottom edge of the page. Footer text moves below such a table when the table ends above the bottom edge of the footer, and above the table when it reaches past that edge or when the text below it would pass the bottom edge of the page. Text that the table pushes down can extend past the bottom edge of the footer, but never past the bottom edge of the page. Footer text that wraps beside a narrow table grows the footer upward when it would pass the bottom edge of the page. Floating-table positioning has no editing UI. |
| Vertical cell text (textDirection) | No | Partial | Full | tbRl and btLr cell text renders through writing-mode and round-trips. btLr text wraps at the row height, does not make the row taller, and is clipped at the cell width. You cannot set it from the UI. |
For fixed tables without a positive table width, explicit cell preferences can replace a wider initial grid. This applies when every cell has a positive absolute width and occupies one column. The largest preference in each column sets its width. Hidden revision rows prevent this replacement. Layout does not rewrite these properties when you save.
Table alignment
Files without a compatibility mode, and files in compatibility mode 11, 12, or 14, align the content of a top-level percentage-width table with the text column. The percentage is a share of the text-column width plus the outer cell margins that the table states. A left-aligned table puts the content of its first cell on the left text edge, moved by its indent. A right-aligned table puts the content of its last cell on the right text edge, and a centered table centers on the text column. A right-to-left table aligns from its leading edge in the same way. This applies to AutoFit and fixed tables, whatever width the authored grid states, in body, header, footer, text-box, and note stories. Floating tables, tables with cell spacing, and tables with uneven or unstated outer margins keep their existing geometry. A top-level table that states no usable width uses the same reference box. An AutoFit table without a width fits the room its leading indent leaves, in every compatibility mode. With neither a table style nor a stated indent, a left-aligned table puts its outer edge, not its content, on the text edge.
Outside that reference box, a percentage excludes the mean width of the table's simple outer side rules, and the table then adds that rule back. This applies to nested tables in every mode and to every table in compatibility mode 15 and later.
In that reference box, a cell margin narrower than half of a single outer side rule counts as half of that rule. A table with zero cell margins, with or without a percentage width, therefore also aligns its content with the text column. A percentage stated with a percent sign above 655.34% uses the same reference box. In a text box, the reference box for a percentage is 0.75 points wider, and a right-aligned table puts its outer edge, not its content, on the right edge of the text box. A nested AutoFit table without a usable width fits the content width of its cell plus its own outer cell margins.
An AutoFit table in which every column states an absolute preferred width starts from those widths. First, each column grows to hold its widest unbroken word. If the table is then wider than its room, or than its percentage share, each column gives up width in proportion to how far it is wider than that minimum. A percentage table that is narrower than its share grows each column in proportion to its width. Nested tables keep proportional scaling.
In compatibility mode 15 and later, a right-to-left table moves toward its visual left by half the mean width of its simple outer side rules.
A table percentage width can be larger than 100%, up to 655.34%. The table then extends past the text column and keeps its cells' line breaks. This applies to every alignment, to AutoFit and fixed tables, and in every compatibility mode. A nested table can extend past its cell in the same way. A supported full-width table in a file without a compatibility mode, or in compatibility mode 11, 12, or 14, measures the percentage against the text-column width plus its outer cell margins. A larger count of fiftieths wraps at 65536, and a count that wraps above 32767 states no width. A larger value stated with a percent sign makes the table as narrow as its content allows.
AutoFit widths account for deleted content across revision views. Each view retains the minimum widths its visible content requires.
An AutoFit column widens to hold its widest unbroken word, such as a long URL, with its indents and cell margins. The other columns give up width in proportion to their spare room. When the minimums are wider than both the text column and the table, the columns shrink in proportion to their minimums to the wider of the two.
An AutoFit column whose cells state no width is sized by its content. Each such column takes its widest unwrapped line when the table has room, and the columns share any extra room in proportion to those widths. A table with no width of its own takes only what its content needs. Columns with a stated width give way first. When the table is still too narrow, the content-sized columns wrap, each by the same fraction of its range.
A cell that spans columns widens them to hold its widest unbroken word. The spanned columns share that width in proportion to their stated width plus their content, and the columns outside the span give up the difference. A nested fixed table needs only the content it holds, whatever its stated width, and paints no wider than its cell: its columns give way down to their own content. A nested AutoFit table also keeps its resolved width. Both keep their leading indent. A narrowed nested fixed table keeps the width its cells of vertical text have; elsewhere, cells with vertical text set no minimum.
Cell spacing applies on each side of every cell. Neighboring cells, and a cell and the table edge, sit twice the spacing apart, and the gaps come out of the table width.
With no compatibility mode, or in compatibility mode 11, 12, or 14, supported fixed tables align the first cell’s content with the table indent. This applies to left-aligned, top-level tables with automatic or absolute widths and no cell spacing. Each row must cover the grid and use the same leading cell margin. Simple side rules share the margin space when the margins clear half the rule. The column widths remain unchanged.
Nested, positioned, and right-to-left tables retain their existing geometry. Tables with row-level geometry exceptions also retain their existing geometry.
Tabs inside cells
In left-to-right table text without adjacent floating objects, an ordinary left tab can continue on the next line. This occurs when its next stop exceeds the cell line edge and visible content follows it. The tab keeps its source position and uses the next line’s tab stops. Paragraphs with consecutive tabs retain their existing placement. Trailing, aligned, and positional tabs also retain their existing placement.
Floating tables
Body text wraps beside supported floating tables and below tables that cover the text column. Text does not wrap into gaps of 0.25 inches or less beside floating tables. Captions and headings move past these gaps. The table's text distances keep the authored gap between its border and surrounding text. Text-anchored tables with numeric vertical offsets follow their next ordinary paragraph onto its page and column.
A page- or margin-anchored table that overlaps the text column and reaches below the bottom margin breaks across pages. It starts at its authored position, or higher so that the part that fits on the page ends at the bottom edge of the page. The rest continues at the top of the next page, and the text after the table starts below its last row. In documents that use Word 2013 or later layout, the first part ends at the bottom margin. In earlier layout, only a table that reaches below the bottom edge of the page breaks, and its first part can reach that edge. Text after a narrow table starts below the table instead of beside its last part.
Negative offsets remain in place when they clear preceding text. A table that intersects preceding text moves below that text.
Text-anchored tables taller than a content page retain row pagination. A text-anchored table that covers the text column can also continue across pages. The remaining space must hold its header rows and first body row. The remaining rows continue at the top of the next page. Following text starts below the last row. This continuation requires a single-column section with one table per anchor.
The table moves with its following paragraph when its first rows do not fit. The following conditions also keep the table whole:
- The anchor has a page break, column break, or space before it.
- The table has text distances above or below it.
- The table fits a full page and the document enables
w:doNotBreakWrappedTables.
Text-anchored tables that use vertical alignment retain their normal flow behavior. Tables whose cells can wrap around earlier floating pictures or frames retain row pagination.
A text-anchored table marked no-overlap floats like other tables, and text wraps around it. If it would cover an earlier floating table, it moves right of that table, so that their text distances touch. In compatibility mode 15 and later, it can also move left of that table. If neither side has room between the margins, it moves below that table. Floating tables without this setting can overlap one another. The cell text of a floating table placed at its anchor never wraps around another floating table.
A continuous section that starts on the same page wraps its text beside the floating tables and wrapping pictures of earlier sections on that page. An ordinary table that would cover a floating table starts below it. A narrower table stays beside it.
Before compatibility mode 15, a right-aligned floating table in the body moves right by the right cell margin of the table, so that its cell text ends at the frame edge. Simple tables can share a terminal empty paragraph without shrinking that paragraph or adding a blank page. The editor preserves floating-table properties when you save. There are no controls for editing those properties.
A floating table at the top level of a header or footer sits outside the story flow. In compatibility mode 15 and later, the header or footer text after it wraps beside it or moves below it, and the header or footer grows with that text. Body text wraps around the table on every page that shows that header or footer, in every compatibility mode. A page- or margin-anchored header or footer table keeps its page position and moves up onto the page when it would pass the bottom edge of the page. Footer text moves below such a table when the table ends above the bottom edge of the footer. When the table reaches past that edge, or when the text below it would pass the bottom edge of the page, the footer text moves above the table instead. Text that the table pushes down can extend past the bottom edge of the footer, but never past the bottom edge of the page. Footer text that wraps beside a narrow table grows the footer upward when it would pass the bottom edge of the page.
When you compare a multipage table, check the space between each repeated header and its first body row. The table pagination note lists the shared-border measurement limits. Keep the original document when you report a spacing issue.
Images and drawings
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Inline images (paste, drag-drop, resize) | Partial | Full | Full | The engine lays out and paints embedded PNG, JPEG, and GIF at the authored size. Embedded PNG, JPEG, GIF, BMP, and WebP images use their detected format. This also applies when the file declares another format from that group. Mismatches involving SVG, TIFF, WMF, or EMF remain refused. The original bytes and package declarations survive save. JPEG validation accepts large metadata segments and accounts for EXIF-oriented intrinsic dimensions without rewriting the photo. The editor refuses picture insertion while another picture is selected. Place the caret in text before inserting another picture. Both adapters ship insert and overlay authoring: the Insert menu, toolbar, properties dialog, and keyboard resize through the shared engine commands. React and Vue hosts can supply a custom image decoder through the imageDecodePort option. An inserted image keeps its natural size when it fits and scales down proportionally to its cell, column, or page content box when it does not. Inline pictures rotated by 90 or 270 degrees reserve their rotated dimensions for text flow and caret positions. Text after an inline image starts at its edge, and a click past the image places the caret after it. An image that does not fit before a floating object continues past it on the same line, like a word. With formatting marks shown, the paragraph mark sits on the text baseline after a trailing image, at the size of the paragraph mark. |
| Floating images & wrap modes (square, topAndBottom...) | Partial | Full | Full | Nine wrap modes, exclusion reflow, z-order, and drag and resize in both adapters. A floating wrap mode on an inline picture keeps the picture in place on the page. Centered, right-aligned, and justified text beside a floating picture aligns separately in each passage on either side of the picture. Square wrapping on the largest side keeps text on the wider side only. In-front and behind-text overlays are not cropped by their anchor cell. The wrap mode controls text flow and behind-text controls only paint order, so a behind-text object with square, tight, through, or top-and-bottom wrap still moves text. A top-and-bottom object that crosses the first line of a paragraph or its space before moves that line below the object, and the line keeps its space before. A top-and-bottom object positioned against the page or a margin keeps that position wherever its anchor paragraph is, and moves only the lines it crosses, before or after its anchor. Authored anchor text distances are preserved. Text clears rectangular gaps narrower than the next glyph. A line break with w:clear restarts the following text below the floating objects on one side: left clears objects that block the start of the line, right clears objects past the break, and all clears every wrapping object. In a table cell, an object with layoutInCell off is placed against the page in compatibility mode 14 or earlier, or when the document declares no mode, and the table rows it touches move below it. In Word 2013 mode and later it stays in the cell, as in Word. A floating object above a table cell paragraph, or beside the lines it holds, does not change how that paragraph breaks or where its lines start. Objects that must not overlap move beside each other before they move down. Before Word 2013 mode, header and footer text outside tables does not wrap around the objects in that header or footer. Header drawings positioned relative to the top margin use the physical sheet top as their origin. Outside table cells, top-and-bottom wrapping clears header text from the same origin. Header and footer objects paint under the body text and body objects, in the editor and in PDF export. In-front and behind-text order them only against the header or footer text. Both share setImageWrapType and toolbarCommandState. |
| BMP and WebP images | No | Full | Full | The browser decodes these and the editor paints them at the authored size, like PNG or JPEG. BMP covers what older documents carry, including top-down bitmaps and the 12-byte BITMAPCOREHEADER. WebP covers the lossy, lossless, and extended containers. Inserting a new one is not supported yet. |
| SVG images | No | Full | Full | Embedded SVG paints at the authored size. The browser renders it in secure static mode, so scripts and external references inside the file stay inert. Inserting a new SVG is not supported yet. |
| WMF / EMF legacy vector images | No | Partial | Full | The browser rasterizes the metafile and the editor paints it at the authored extent. A metafile that will not convert keeps its extent and shows a labelled placeholder. The original bytes round-trip untouched. |
| TIFF images | No | Partial | Full | The browser decodes baseline TIFF and the editor paints it at the authored extent. A multi-page file shows its first page. A flavour that will not decode keeps its extent and shows a labelled placeholder. Inserting a new TIFF is not supported yet. |
| Tracked image changes | Partial | Full | Full | Suggesting mode and review actions require the EigenPal Pro License. Opening and saving existing image revisions require no review module. Suggesting mode records image insertion and deletion. Review actions can accept or reject both changes. Image property edits are unavailable in suggesting mode. |
| Text boxes | Partial | Partial | Preserved | Anchored text boxes render their content clipped inside the authored extent. Empty anchor paragraphs flow around preceding floating objects. An empty paragraph keeps its place beside a floating object that leaves a passage, and moves below one that covers the whole column. This works in the body, in headers, and in footers, including page-relative anchors. PAGE, NUMPAGES, and SECTIONPAGES fields inside a header or footer text box are evaluated per page. Insert → Text Box creates an editable rectangular box from a body paragraph. Unrotated body text boxes support typing, paragraph editing, text formatting, plain-text paste, undo, deletion, dragging, and resizing. These edits synchronize during collaboration, with remote cursors and text selections. Clicking text shows the caret and frame handles. Text boxes with tables and text boxes in headers or footers remain read-only. The automation API reads, searches, and edits floating and inline text box stories in the body, headers, and footers through Shape.body. Saving writes edited text box text into the legacy VML copy too. Inline text boxes take their extent on the line, stand on the baseline, and render their content clipped inside the extent, in the body, in table cells, and in headers and footers. Inline text boxes in the body support the same text editing as anchored ones, and these edits synchronize during collaboration. Inline text boxes move with their line and cannot be dragged or resized. Half of a text box outline width also insets its content. Legacy VML text boxes on rectangles, rounded rectangles, and text box shapes render the same way, floating or inline, with their inset margins and solid fill and outline. Find reaches them, and body boxes take the same text editing, while the VML shape itself stays read-only. A rounded VML text box paints square corners, and vertical VML text flow keeps the shape opaque. A text box inside another text box, linked chains, autofit, and rotation render as a placeholder or clip. |
| Drawing shapes & geometry | No | Partial | Preserved | Solid rectangles, ellipses, diagonal lines, bounded polygon geometry, and grouped shapes render with sRGB or theme colors. An outline keeps its full width past the edge of the drawing. An inset outline (algn=in) draws inside its geometry. Outlines keep authored flat, round, and square line ends and round and bevel joins, in the editor and in PDF export. Vertical and horizontal lines render, standalone or inside a group. A shape group can also hold one embedded picture below its shapes. The picture must be visible, unrotated, unflipped, and rectangular. It must have no fill rectangle offsets, image effects, visible outline, shape effects, or 3D properties. It renders in its own frame, in the editor and in PDF export. Groups and their members must have supported visibility, effects, and 3D settings. A group renders completely or not at all: when any member cannot render, it follows the rule for unsupported groups. Other payloads reserve their extent with a placeholder. In mc:AlternateContent, an unsupported payload shows no placeholder and no part of itself, for example a group that holds a nested group. If it floats with square, tight, through, or top-and-bottom wrapping, text still flows around its wrap area. Text box members of a group render their text in the editor and in PDF export, in the scaled member box with their own insets, vertical anchor, and wrapping. Find reaches that text and selects the group. The text is read-only. A rotated member turns its text with it, a vertical flip turns the text upside down, and a horizontal flip does not mirror it. A rotated or flipped group still follows the rule for unsupported groups. |
| Legacy VML pictures, annotation groups & straight WordArt | No | Partial | Preserved | Standalone w:pict supports bounded unrotated photos and groups of photos, inline photos with one uniform single-line border on all four sides, simple solid geometry including rounded rectangles, arrowed lines, and straight fit-to-box WordArt. Floating lines drawn between from and to points render in the editor and in PDF export. Floating shape paths with two explicit points and one zero extent also render as native lines. Invalid zero coordinate axes remain opaque. Aligned positions (left, center, right, top, bottom, inside, outside) are supported. A shape without absolute positioning is inline. Previews do not replace canonical VML or add media parts. Unknown templates, unsupported members, rotation, and clipped groups remain opaque as a whole. VML-only MC fallbacks are unchanged. |
| Picture cropping (srcRect) | Partial | Full | Full | Crop renders and round-trips. The properties dialog edits the crop in percent in both adapters. |
| Picture adjustments (brightness, contrast, recolor) | No | Partial | Full | Brightness, contrast, grayscale, and bilevel black-and-white adjustments render in the editor. Image alpha and authored adjustment markup are preserved. The PDF exporter applies fixed image opacity but reports unsupported color adjustments. |
| Picture effects (shadow, glow, reflection) | No | No | Preserved | Not painted and not editable. Authored effect markup and effectExtent spacing are preserved. |
| Charts (DrawingML) | No | Partial | Preserved | The extent is reserved with a labelled placeholder. React and Vue DocxEditor.UnsupportedElement declarations replace the fallback with an application component. The original chart payload and layout remain preserved. |
| SmartArt & diagrams | No | Partial | Preserved | Same customizable placeholder policy as charts. Application components can replace the visible fallback without changing the preserved payload or layout. |
| Ink annotations (w:ink) | No | No | Preserved | Not rendered and not editable. Ink markup is preserved generically on save. |
A floating object in a table cell can turn off the Layout in table cell option. Word honors that setting only in compatibility mode 14 or earlier, or when the document declares no mode. The object is then placed against the page, unless it is positioned against its own character or line. If the object wraps text, intersecting table rows move below it. The object keeps its position. In compatibility mode 15 and later, Word ignores the setting and keeps the object in its cell.
Two other placement rules depend on the compatibility mode or the object options. Before compatibility mode 15, ordinary header and footer text ignores wrapping objects in the same header or footer. If an object must not overlap another object, Word moves it beside that object at the same height. The object moves down only when neither side has room.
Page layout, headers, and footers
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| True pagination (Word-metric pages) | Full | Full | Full | The layout engine uses page breaks, paragraph keep rules, and section settings to calculate pages. You can insert a hard page break, which writes `w:br w:type="page"`. With paragraph marks shown, a page break or column break in body text shows a labeled dotted line from the end of the text to the edge of the column. Manual page breaks inside table cells retain their document offsets but do not add lines, line height, or pages. Line wrapping, tab alignment, bidirectional text order, and text wrap around floating pictures ignore them. If the font of the run has Arabic glyphs, layout measures Arabic letters on the two sides of a break as one joined word. If the font has no Arabic glyphs, the browser fallback measures each side separately, so the width can differ from the same text without the break. Manual line breaks still start a new line. When a paragraph starts with a manual page break and has text after the break, the text starts on the next page, even when the current page has no room for another line. A list number or bullet goes to the next page with the text. The top border of the paragraph also goes to the text on the next page, and lines that hold only page breaks draw no border. The space before of the paragraph goes there too, reduced by the space after of the paragraph above. Shading fills each break line where it sits. A break that the current view hides does not count. Paragraphs with only one page break, or with anchored floating tables, text frames, or drawings, keep the ordinary rule, so after a full page their text starts one page later. A paragraph that opens with a page break followed by another page or column break keeps its first break on the current page. |
| Sections (margins, size, orientation, per-section headers) | Partial | Full | Full | Page size, orientation, and margins are editable per section or for the whole document, from the Page Setup dialog or a ruler drag. Each section uses its own page dimensions and margins for pagination. A negative top or bottom margin sets the exact distance from the page edge to the text. A taller header or footer then overlaps the text and does not move it. In that overlap, text, links, note references, pictures, and form fields take the pointer, and a closed header or footer highlights only its part in the page margin. To edit the header or footer, double-click it in the page margin, or on its content where no text is under the pointer. With paragraph marks shown, a section break shows a labeled dotted line in place of its paragraph mark, named by how the next section starts. You can insert a next-page or a continuous section break; a continuous one keeps the new section on the sheet the previous section ended. This also applies when the new section has a taller header or footer, or a different first page. That sheet keeps its header, footer, and text area, and the header and footer of the new section start on the next sheet. A different page size or orientation starts a new sheet. When a section has other content, the empty paragraph that ends it before a continuous section takes no vertical space. A manual page break followed by an empty section-break paragraph advances one page when the next section starts on a new page, so no blank page appears between them. An empty section-break paragraph after other content in its section ignores its own page break before, so it does not add a blank page. An odd-page or even-page section starts on a page whose number has that parity. With different odd and even pages turned on, a numbering restart compares its parity with the continued page number. A restart on a shared continuous page does not reset the sheet sequence used for this comparison. An explicit odd-page or even-page break with a restart selects physical page parity before applying the displayed number. When the next sheet has the wrong parity, layout inserts one empty sheet with no header, footer, or content. `NUMPAGES` counts that sheet, and `SECTIONPAGES` does not. You cannot insert odd-page or even-page section breaks. Per-section columns render from w:cols, but column editing controls are unavailable. A continuous section starts below the lowest in-flow content across all columns on the preceding section’s final page. This does not rebalance sections that span multiple pages. Columns that continue below earlier content retain authored paragraph space before, including later columns. Fresh-page starts retain their existing spacing rules. |
| Headers and footers (edit in place) | Partial | Full | Full | Both adapters have scoped header and footer editing: enter and exit the story, create and remove it, link and unlink to the previous section, and set the title-page and even/odd options. They also insert PAGE, NUMPAGES, and SECTIONPAGES. `editHeaderFooter` takes `variant`, `evenPage`, and `firstPage` on the shared Editor contract. Per-section first, even, and default variants paint like Word. Editing inside a header or footer matches the body: lists, tables, content controls, pictures, fonts, comments, bookmarks, and page setup all act on the story you are in. Tracked changes work in a header or footer: you can suggest an edit there, and the review list shows it with the accept and reject verbs. Selection and comment highlight bands paint in the body only. Watermarks have their own dialog and command. |
| Watermarks (text & image) | Partial | Full | Full | Text watermarks paint as glyph outlines fitted to their shape, diagonal or horizontal, with their color and transparency, in the editor and in PDF export. Picture watermarks paint behind the text with washout. The Insert menu opens a Watermark dialog, and `setWatermark` writes the same watermark into every header the document shows, creating a header where a section has none. One watermark applies to the whole document; a different watermark per section is not available. Curved or styled text art other than plain text stays opaque. |
| Footnotes and endnotes | Partial | Partial | Full | Lines before a held reference can return when widow and orphan rules allow. Final body lines reserve paragraph spacing above notes. The document API exposes Body.footnotes and Body.endnotes in reference order, including scoped table-cell reads. Existing note bodies support edits; API note creation remains unsupported. Both adapters have a typed note model, note layout (pageBottom, beneathText, sectEnd, docEnd), scoped note editing, insert, delete, convert, and chrome slots. A paragraph reference stays when a legal note opening fits below it, even if the whole note fits a fresh page. Note paragraphs respect w:keepLines and w:widowControl; without widow control, one note line can start there. This admission applies to full-width, single-column body paragraphs in every compatibility mode. Note keep-with-next groups and notes containing tables retain whole-note admission. A splittable continuation returns when its required body opening and complete attached notes fit; later references outside that opening add no demand. A reference in a table row keeps its note with that row. The row moves with the note only when the note can place fewer than two lines below the row; otherwise the note continues on the next page. A row that every cell lets split below the reference line continues on the next page below that split; w:cantSplit and exact-height rows do not split there, nor do w:keepLines or widow-controlled cell paragraphs in Word 2013 layout, unless the row is too tall to stay whole. A returning paragraph continuation includes its earlier fragment when checking note space. If the returning reference leaves no note space, the previous split decision stays in place. A reference paragraph that keeps with its successor includes the notes in that successor’s required opening. A successor opening without a reference adds no footnote reserve. Paragraphs ahead of a moved reference return to the earlier page when they fit, unless they keep with the reference paragraph; multi-column sections keep that room, and so does a reference on the second line of a widow-controlled paragraph whose note could not start on the earlier page. A reference on the second line of a widow-controlled paragraph can keep the first two lines on the page while its whole note starts on the next page. The note area can use the space below the text of the last body line with single or multiple line spacing, while a line whose note starts on the same page keeps its full height above the notes in every column. A note taller than the page note column continues across pages. Page-bottom and beneath-text footnotes reserve authored continuation notices, including empty paragraphs, below notes that continue. Notices remain noneditable furniture. Live header changes that resize the body area also update footnote pagination. Oversized notices report note-continuation-notice-height-cap without stopping note text. Section-end and document-end notices remain unsupported. The w:separator rule takes its thickness and its offset above the baseline from the strikeout metrics of the run font. Overflow sheets retain separate page rectangles for painting and hit testing. Editing inside a note matches the body: lists, tables, content controls, pictures, fonts, comments, bookmarks, and page setup. Suggesting mode tracks an inserted reference and requires reference deletion to propose note removal. Notes in headers and footers are out of scope. |
| Multi-column layout | No | Partial | Full | Section w:cols count, gap, separator, and equal or unequal widths paginate into columns. Decimal and unit-suffixed widths and gaps truncate to whole twips. A w:col without a gap has no gap, and one without a width spans the text area. Widths and gaps that do not fit the page are kept, so later columns can extend past the page edge. Equal columns narrow to a minimum of 0.01 inch and keep their gaps. If a w:col width or gap cannot be used, or there are fewer w:col elements than columns, the section uses equal columns. An explicit column break leaves the break paragraph's empty remainder at the top of the next column. Continuous multi-column sections balance their final page, including sections that span several pages. Earlier pages retain their column distribution. Whole-paragraph moves into later columns preserve the continued section’s vertical origin. Column editing chrome is not exposed. |
| Page borders | No | Partial | Full | Page borders draw a frame on every sheet of their section. Offset modes, z-order, and the first-page filter apply. Art borders do not draw. You cannot edit page borders from the UI. |
| Line numbers (lnNumType) | No | No | Full | Parsed and round-tripped; not drawn in the margin. |
| Different even & odd headers | Partial | Full | Full | The first page of a section can use its first variant. Displayed page numbering selects even or default variants, including section numbering restarts. You can edit each variant in an open furniture scope. `editHeaderFooter({ variant: 'even' })` creates or opens the even story and enables `w:evenAndOddHeaders` in one undo unit. Header and footer chrome in both adapters can toggle different even and odd pages. |
| Section vertical alignment (vAlign) | No | No | Full | Round-trips; page content stays top-aligned. |
| Page background color/image (w:background) | No | No | Preserved | Not rendered and not editable. Authored background markup and relationships are preserved. |
| Page number format (pgNumType) | No | Partial | Full | Section numbering start, format, chapter style, and chapter separator parse and serialize. PAGE fields in headers and footers honor the authored start and format, for example lowerRoman. A numeric picture switch or a number-format switch on the field outranks the section format. In PAGE fields, roman page numbers repeat M for each thousand, alphabetic page numbers past 26 repeat one letter (27 is AA, 28 is BB), and page 0 shows a space in both. NUMPAGES and SECTIONPAGES are decimal unless the field states a switch. There is no authoring UI for pgNumType yet. |
Tracked changes, comments, and notes
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Tracked changes (insert, delete, format) | Full | Full | Full | Suggesting mode, review markup, and review actions require the EigenPal Pro License. Opening and saving existing revisions require no review module. The document API tracks text, fonts, paragraph formatting, list membership, and paragraph insertion. Table suggestions support complete insertion, value replacement, row additions, and partial row deletions. Eligible nonempty text can become a proposed text or date control outside collaboration. The document API records a paragraph deletion as deleted text and a deleted paragraph mark, also in collaboration. Tracked replacements across paragraphs and table or cell value replacement refuse in collaboration. Row deletion suggestions must leave a row without a pending deletion. Existing table properties and columns require permanent edits; eligible complete proposed tables support configuration. The editor offers Simple Markup, All Markup, No Markup, Original, author filters, and filtered bulk decisions. Hidden authors and unsupported changes remain pending during filtered bulk decisions. The editor and the document API can change the author, and optionally the date, of pending changes without accepting or rejecting them. Original restores prior run and paragraph formatting; prior table, row, cell, and section formatting remains unsupported. Author filters change the display without changing saved revisions. The Track changes options dialog and viewer markup preferences configure revision marks, named colors, optional text backgrounds, change bars, and cell shading through the API and review dialog. Text backgrounds default to none and remain local viewer preferences. Cell shading supports named colors and revision author colors. The dialog adapts to narrow screens. React and Vue support popup replacement, named dialog parts, and custom draft controls. Track formatting can leave future formatting edits untracked while text edits remain tracked. Suggesting mode requires an author. Editor list, indent-level, tab-stop, and table-property changes remain untracked. Malformed revision wrappers refuse resolution and preserve their content. With `pairReplacements`, the review queue lists a deletion and the insertion that directly follows it from the same author as one replacement item. The review queue lists one item for an addition or deletion that continues across a tracked paragraph mark, and one item for the same paragraph formatting change on consecutive paragraphs by one author. A formatting change that leaves the resolved formatting unchanged has no review item and no change bar; Accept All and Reject All remove it together with the listed changes, unless a tracked change filter narrows the decision or its author is hidden. `getReviewItemsAt` and `getReviewItemRects` return review items and their bands on painted pages, so a host can draw its own tracked change balloons or margin markers. The review pane settings `opening` and `overflow` keep the pane closed until the host opens it, or shrink a fit-width page so the full card column fits. |
| Accept / reject changes (UI + API) | Full | Full | Full | Review actions require the EigenPal Pro License. Accept or reject one change with acceptReviewItem, rejectReviewItem, or the sidebar. The Review menu also resolves changes shown by active filters. Hidden authors and unsupported changes remain pending. The automation API supports individual decisions and strict or partial batches. The browser automation runtime can show a proposed change in the page before the user commits it as one undo step or discards it. Collaboration peers do not receive the proposed change until it is committed. It lists and decides the changes a range overlaps, and getReviewItemRevisions and getReviewItemRange map a review card key to its changes or its range. Deletion and addition revisions keep independent accept and reject decisions, even when their author, ID, and editing time match. Source revision dates survive save. Opening and saving existing revisions require no review module. The revisionsIn review pane setting lists changes in the review pane or opens each change in a tracked change balloon at its text, with replies, a reply field, and accept and reject controls. A tracked change balloon opens on a click in the page, Next Change, or Previous Change, and a caret move alone does not open it. A tracked change balloon that Next Change opens takes the keyboard focus and is announced to screen readers. An adjacent deletion and insertion from one author open as one replacement. A refused accept, reject, or delete shows its cause on the card, such as an external document refresh or a collaboration session that is not ready. |
| Comments (threads, replies, resolve) | Full | Full | Full | Comment authoring and review controls require the EigenPal Pro License. Opening and saving existing comments require no review module. The review rail shows threads, replies, and resolution controls. React hosts use `@docx-editor.dev/pro/react`; Vue hosts use `@docx-editor.dev/pro/vue` with the same engine commands. Saving normalizes recognized empty comment parts when no markers or retained relationship dependencies remain. The commentMarkers review pane setting draws collapsed thread markers as comment icons by default, or as author initials badges with a reply count and a resolved check mark. A refused comment, reply, or resolution names its cause on the card or in the reply field. |
| Programmatic redlining (code-proposed tracked changes) | Full | Full | Full | The automation object model requires the EigenPal Pro License. Manual line breaks use U+000B in text reads and writes, including tracked insertion. Column breaks read as U+000E and refuse text writes. Paragraph separators remain carriage returns. It writes native tracked changes. getTextRanges splits a paragraph or range into word ranges that later edits can target, expandTo joins a run of them, and getReviewedText reads the text as if every pending change were accepted or rejected. It works over DOCX bytes on a server, or over an editor open in a page. |
| Tracked moves (move from/to) | Partial | Full | Full | Imported moves survive save and reopen without a review module. Displaying move markup requires the review module and the EigenPal Pro License. Review actions require the module. Viewer preferences configure moved-from and moved-to marks and colors. Track moves off uses insertion and deletion marks without changing move records. Creating move revisions remains unsupported. |
| Tracked table cell shading | Partial | Partial | Full | Viewer preferences set inserted, deleted, merged, and split cell shading. Imported cellIns, cellDel, and cellMerge records supply the shading. Inserted and deleted rows supply shading for cells without an explicit cell revision. None preserves authored shading without a revision fill. Row-level text indicators keep their existing styling; run revision markup still applies inside cells. A cellMerge change from continuation to non-continuation uses split shading. Creating arbitrary cell merge and split revisions remains unsupported. |
Fields, links, and table of contents
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Hyperlinks (external) | Full | Full | Full | Insert, edit, and remove a link with Ctrl+K, Cmd+K, or the toolbar. Targets are allowlisted: http, https, mailto, tel, and ftp. Any other target renders inert and still round-trips. A HYPERLINK field, complex or w:fldSimple, is a live link too: its target passes the same allowlist, and the link panel shows it read-only. Links in footnote and endnote text work the same way. Links in headers, footers, and anchored text boxes resolve through their own part. You can edit or remove header and footer links with Ctrl+K while editing their story. Secondary-story anchors remain inert and do not open. Opening a document never requests a link target, because activation needs an explicit gesture. A field result with no break opportunity, such as a long URL, wraps at the line edge and stays inside its table cell. |
| Bookmarks & internal links | Partial | Full | Full | Internal links jump to their bookmark and move the caret. This includes a target on a page the editor has not painted yet. The Bookmark dialog (Insert menu or Ctrl+Shift+F5) lists bookmarks by name or location, shows hidden bookmarks on request, adds a bookmark at the selection, deletes one, and goes to one. Names compare without case, so adding an existing name moves that bookmark. Show bookmarks paints gray brackets at each bookmark and an I-beam at a point bookmark, in the main text, headers, footers, and notes. Hosts restyle the marks with CSS tokens and data attributes, choose which bookmarks show, and replace or decorate each mark. Typing at a bookmark start extends the bookmark, typing at its end does not, and deleting all of its text removes it. A deletion across paragraphs removes the bookmarks it encloses. Names are unique in the whole document, so adding a name that another story uses moves that bookmark. When collaborators add one name offline, the first is used and the Bookmark dialog offers to remove the copies. The navigation pane has a Bookmarks tab (Ctrl+G, Cmd+Option+G on macOS, or Insert > Go To Bookmark) that filters bookmarks by name, groups them by place, and jumps to one in any story. The document API adds, lists, reads, and deletes bookmarks. Moving or deleting protected markers refuses the whole change. Markers inside data-bound content controls have the same restriction. Direct marker changes remain supported with TrackMineOnly. |
| PAGE / NUMPAGES / SECTIONPAGES fields | Partial | Partial | Full | PAGE, NUMPAGES, and SECTIONPAGES project as a complex field or w:fldSimple. They evaluate in headers and footers and in the body flow, body tables included. PAGE respects the section pgNumType start and format. Fields inside an anchored header or footer text box also project, as does a page field nested inside another field — simple or complex, such as STYLEREF — up to four levels deep, evaluated per page. React header and footer chrome can insert them, including Page X of Y. A numeric picture switch, for example PAGE \# 0#, renders the computed value. Pictures support digit placeholders, a grouping comma, and literal text. The number-format switches Arabic, roman, alphabetic, and ArabicDash also render the computed value. The case of the first letter of roman or alphabetic selects uppercase or lowercase, and the last number-format switch applies. A number-format switch outranks a picture that comes before it. MERGEFORMAT and CHARFORMAT are accepted. Other switches, such as Ordinal or Upper, a picture after a number-format switch, and extra words keep the result saved in the file. In a header or footer the picture always renders the computed value, so a result cached in the file never reaches the page; in the body a non-empty cached result still wins until the field is updated. A body field with no cached result paints a placeholder that document layout substitutes per page. Without a picture or number-format switch, a multi-digit body value keeps the one-digit measured width, so mid-line following text does not reflow; with one, the switch sets that width, and a wider value overflows it the same way. |
| Table of contents | Partial | Full | Full | The document API inserts inert TOC fields with supported switches; API entry calculation remains unavailable. Insert a body TOC from the shared Insert menu, then refresh it from document headings or TC entry fields. Unsupported source switches preserve the cached table and refuse refresh. A refresh can update the page numbers only. Tab leaders, section-formatted page numbers, and bookmark links all work. The generated rows are read-only navigation links. Ordinary text outside the field boundaries remains editable, including text in the same paragraph. Formatting a selection that includes generated rows changes only the ordinary text. |
| REF and NOTEREF cross-references | Partial | Partial | Full | REF resolves bookmark text and numbered paragraph references in the body, footnotes, and endnotes. The editor supports the \r, \w, \n, \t, \h, and \* MERGEFORMAT switches. REF, PAGEREF, and NOTEREF results with \h navigate to their bookmarks, including cached relative-position results. The \r switch uses the same full-context number as \w, and \t needs a numbering switch. Bookmark text stops at the target paragraph boundary. Line breaks in bookmark text stay line breaks in the result, and save keeps the saved result of such a field. NOTEREF resolves bookmarked note numbers with section formats and eachSect restarts. Unsupported switches, missing targets, bullet targets, eachPage note restarts, and custom note marks keep the saved result. Save refreshes calibrated, writable body and note results as one undo step. Header, footer, and text-box results keep their saved values. |
| AUTONUM field numbers | No | Partial | Full | AUTONUM, AUTONUMLGL, and AUTONUMOUT generate separate document-order sequences. They do not restart by heading context. The \* switch supports Arabic, alphabetic, Roman, ordinal, cardinal text, ordinal text, and hexadecimal formats. The \e switch removes the trailing period. Unsupported switches produce no generated value. Save does not add result runs. |
| Character-style header references | No | Partial | Preserved | Header STYLEREF fields resolve directly applied character styles by display name. The default selects the first page occurrence; \l selects the last. Pages without a match search backward, then forward. Visible revision text supplies results. Header height adjusts per page. Pagination retains each page’s largest admitted live header reserve while painting the current result. Headers from a continued section do not enlarge the shared sheet. Unsupported switches, missing matches, nested result fields, and oversized results keep saved values. Body, footer, paragraph-style, and style-alias references stay cached. Save preserves source fields. |
| Other field codes (DATE, SEQ, MERGEFIELD...) | Partial | Partial | Preserved | The document API inserts REF, PAGEREF, NOTEREF, SEQ, STYLEREF, DATE, and TIME fields, untracked or as one tracked insertion that Reject removes whole. Their instructions are never evaluated, and fields that fetch, embed, link, run, or prompt refuse. The cached result starts empty; Field.result writes plain result text, inside the author's own pending insertion when tracked, and marks the field w:dirty so an application that evaluates fields recomputes it. The saved result displays for a complex field and for w:fldSimple. Complex fields also display embedded pictures from saved results, including nested complex results, without resolving external image links. Text and pictures retain their saved order and existing model ranges. Mixed results use each authored font slot for measurement and painting. All display slices retain the field's original model unit. Line breaks inside a saved result start another line. Page breaks follow the surrounding story rules; page breaks in table cells do not add pages. By default the field moves as one unit with the caret. Caret positions and selections keep both source boundaries, including field-only paragraphs. Computed caches remain read-only. With the fieldResults editor option set to editable, the saved results of DATE, TIME, CREATEDATE, SAVEDATE, PRINTDATE, MERGEFIELD, HYPERLINK, QUOTE, FILENAME, FILLIN, and SEQ fields accept typing, deletion, selection, composed input, undo, and tracked changes inside the result. Backspace after such a field or Delete before it selects the whole field, and a selection that crosses the field edge grows to cover the field. Computed fields and fields that contain another field in their result stay one unit. Collaboration sessions refuse the option. Leading direction marks remain in results without replacing the first visible result run’s formatting. The saved result of a field nested inside another field’s instruction displays nothing, and Find skips it; the outer field keeps its normal display behavior. Field codes round-trip unchanged. Option+F9 on macOS and Alt+F9 on Windows toggle instruction display without changing the document. Some Mac keyboards require Fn. SYMBOL renders its character with the requested font and size. MACROBUTTON and GOTOBUTTON render display text without running the macro or jump. TITLE, AUTHOR, SUBJECT, KEYWORDS, LASTSAVEDBY, COMMENTS, and matching DOCPROPERTY fields render sanitized document metadata. DATE-valued properties stay inert. DATE, TIME, FILENAME, SEQ, LISTNUM, and EQ do not calculate a new value. The editor never runs macros, DDE instructions, or external include instructions. |
| Citations & bibliography | No | No | Preserved | CITATION and BIBLIOGRAPHY fields stay inert, and the b:Sources store is preserved. Citation evaluation and editing are not supported. |
| Legacy form fields (FORMTEXT, FORMCHECKBOX, FORMDROPDOWN) | Partial | Full | Preserved | FORMTEXT supports whole-field selection on click, partial text edits, typing outside the trailing field boundary, whole-field word deletion from field boundaries, select-then-delete at field boundaries and whole-field replacement in unprotected documents, and a shared React/Vue options dialog through double-click or the keyboard-accessible Edit field context action. The dialog supports regular text, number, and date types, maximum length, listed formats, and fill-in enabled. Native selection highlighting and accessible status distinguish a whole field from a caret. In documents protected for forms, plain text results remain fillable and Tab selects the next enabled text field. FORMCHECKBOX renders its checked or default state from w:ffData, and an explicit w:size sets the glyph size. Its line height comes from the run font at that size, not from a fallback font that holds the box glyph. FORMDROPDOWN renders the cached result, or the selected list entry when the file caches none. Field markers, instructions, and w:ffData round-trip, and tracked edits survive. Form-field shading applies unless w:doNotShadeFormData is set. Protected filling enforces maximum length, truncates pasted text to the remaining capacity, and applies supported value formats on exit or save. Save uses the original input locale and rejects invalid pending values without clearing the input. Supported numeric filling and formatted numeric defaults include mixed text, dollar signs, grouping, and accounting parentheses. Unformatted numeric defaults preserve raw text; formatted numeric defaults store their formatted value. The editor locale controls regional Gregorian date input independently of field output formatting, including dotted dates, year-first dates, and locale digits. Locale changes preserve existing dates. Invalid numeric/date fill input opens a shared alert; acknowledgement clears the invalid result with undo support. Full parity across Word locales and input grammars is not established. Computed input types and unlisted format pictures remain preserved without protected filling. FORMCHECKBOX paints as a square box with matching layout advance and caret geometry, a minimum 24px pointer target, and a bounded accessible name when no macro references exist; Tab focuses checkboxes, and a click or Space toggles w:checked in edit mode and under forms protection, and a field with w:enabled off refuses. FORMDROPDOWN uses a native select with keyboard input, undo, and save/reopen; a choice updates w:result and the cached text in edit mode and under forms protection. Disabled fields, viewing mode, and suggesting mode refuse changes. Results with nested fields, revisions, or non-text structure cannot use the default-text dialog or protected filling. |
Character-style STYLEREF headers resolve supported display-name references and adjust each page’s header height. See Fields and cross-references for limits.
Document structure and content controls
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Content controls (SDT): block, inline | Partial | Full | Full | Block, inline, row, and cell controls are addressable across stories, including tables, headers, footers, and notes. Value updates preserve enclosing table structure and formatting after saving and reopening. Typing replaces placeholder prompts inside their controls, including controls inside tracked insertions. The editor rejects updates that would discard tables or nested controls. Find, create, fill, and remove controls by tag, title, or file ID. Inserting at the caret creates an empty control with a placeholder as one undo step. Tag, title, and lock values are editable through the API. All four `w:lock` modes apply, including enclosing locks and nested bound controls. Locks affect the control and its content. Under forms protection, only control content is editable. Hosts can opt in to formatting content-locked controls with `contentLockPolicy.allowFormattingInLockedContent`; text edits stay refused. Repeating-section and custom-XML-bound controls are preserved. Bound content cannot be edited; control removal remains available. With `lockedControlNavigation: 'atomic'`, the caret treats a content-locked inline control as one unit. |
| Repeating section controls | No | Full | Full | Repeating-section markup is preserved and rendered. Item add and remove operations and section configuration edits are unsupported. |
| Dropdown, checkbox, date, picture & gallery controls | Full | Full | Full | The document API can propose text and date controls around existing ordinary text outside collaboration. Accept keeps the control; Reject restores the original text. Empty tracked ranges and existing review markup refuse. Each control accepts only the value its own type allows. A dropdown must name an item it declares, and a combo box also takes free text. A date validates an ISO instant and writes both `w:fullDate` and the formatted text. A checkbox writes its declared glyph and its state together. Editor checkbox toggles use MS Gothic when the state omits its font. The first write replaces a literal prompt whole, so clearing the value later leaves the control empty. A control saved with empty content opens showing the glossary placeholder its properties name, or the type's default prompt, so it can be filled like any other; a control emptied by deletion shows its prompt again. Control buttons appear on hover, at the caret, and under show-all, as Word's tabs do. A `w:temporary` control removes its own wrapper on the first edit and keeps the content. Typing at either edge of a content-locked, data-bound, checkbox, or picture control places the text beside the control, so a chip at the start of a paragraph or next to another chip can have text typed before it. The value button sits past the control's right edge and scales with zoom; menus open under the control's left edge and stay on the page. The date picker follows the editor locale for names, first weekday, and numeric entry. All three renderers offer month/year navigation, Home/End and Page keys, Today, invalid-date feedback, focus return, and Tab wrapping. Dropdowns have typeahead and roving focus; combo inputs connect to their suggestion list. Shared popup placement follows scrolling and size changes, flips above, and clamps to the visible sheet. Host renderers receive dropdown, combo box, date, and gallery presses as sessions, and checkbox or picture presses when they opt in. A picture control's button opens a file dialog; the chosen PNG, JPEG, GIF, BMP, or WebP image replaces the control's picture and keeps the drawing's size. A building block gallery control lists the blocks the document's glossary stores for its gallery and category, and a pick replaces the control's content with the block's body under fresh paragraph identities; a document without matching blocks shows a note. Blocks from Word's Building Blocks template are not available. |
| Custom XML parts & data binding | No | No | Preserved | customXml parts and w:dataBinding round-trip with structural fidelity. The editor does not evaluate a binding. |
| Breaks outside runs (w:br, w:cr) | Partial | Partial | Full | Some files put a break directly in a paragraph or hyperlink, outside a run. The editor keeps that break in place and saves it unchanged. The text around it renders and stays editable. The break itself does not start a new line or page. The caret does not stop at it, and deleting text across it keeps it. |
| VBA macros | No | No | Preserved | The editor never executes a macro, by design. The vbaProject part survives open and save. |
| OLE & embedded objects | No | Partial | Preserved | The editor never runs, loads, or updates OLE objects. An inline embedded object with a standard VML preview picture shows that cached picture read-only, and layout reserves its size. A WMF or EMF preview keeps its size and shows a placeholder when conversion is unavailable. Floating objects, linked objects, and objects with other content show no preview. Picture commands do not apply to a preview. Copy and cut refuse selections containing objects. Rich paste refuses object fragments without changing the target selection. Paragraph frames, including inherited frames, suppress preview geometry but keep object text positions. OLE markup and embedded binaries are preserved through editing and save. |
| Document protection & editing restrictions | Partial | No | Preserved | Protection settings round-trip. Forms protection permits supported legacy text field fills, legacy checkbox toggles and dropdown selections, edits inside unlocked content controls, and edits in unprotected sections. Other content edits are refused with a locked result and a reason; packaged controls disable refused commands. Forms protection disables suggesting mode. Read-only protection opens in viewing mode and refuses content edits and comment writes. Comments-only protection permits adding, replying to, resolving, reopening, and deleting comments in editing mode. Tracked-changes protection requires suggesting mode for edits, with a review module and an author. Explicit view mode refuses all writes, including the protection toggle, and permits text selection and copy. Review > Protect Document for Forms enables forms protection or stops an enforced restriction without a password. Each toggle creates one undo step. Stopping protection retains the restriction with enforcement off. The editor cannot set other protection modes, set or verify passwords, or enable forms protection over a different recorded restriction. Permission exception ranges (w:permStart) do not grant editing access. Remote collaboration updates bypass local protection checks. |
Collaboration, languages, and editing
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Real-time collaboration | Partial | Partial | Preserved | Yjs replicates text, formatting, document structure, review content, tables of contents, notes, headers, footers, drawings, and custom nodes. Presence includes participants, carets, and cross-paragraph selections. Each participant can undo only their edits. A server or headless session can make each operation exactly one undo step with beginUndoGroup, however close together or long the operations are. Concurrent changes to different properties of one paragraph, or to the formatting of the same characters, both apply. Typing survives a peer deleting, reformatting, splitting, or joining away the text it is in, and moves with that text. Text two peers split or join at once shows once, in document order. Accepting or rejecting a tracked change applies to all of that change and to nothing else, also while another participant types or deletes inside it or right after it. Text a participant types inside a deletion while a peer makes it becomes part of that deletion. Formatting applied while a peer moves the same text to another paragraph is not kept. Use WebRTC, Hocuspocus, or another Yjs 13 provider. Editing continues while disconnected and merges buffered changes after reconnection. Applying an edited ProseMirror document is unavailable while a replica is attached. |
| Find & replace | Partial | Full | Full | Searches the body, headers, footers, footnotes, and endnotes, including table cells and saved field results. Find also searches anchored and inline text boxes in the body, headers, and footers. Text boxes in notes are excluded. Selecting a text-box match selects its drawing. Click inside a supported body text box to edit its paragraphs. Cmd+F on macOS, or Ctrl+F elsewhere, opens Find while focus is in the editor. Find highlights every match and the active match. Use setHighlights or useHighlights to highlight your own ranges, such as glossary terms, and createDocumentSearch to drive Find from code. Highlights are not saved or shared. |
| Scroll to and highlight paragraph references | Partial | Partial | Preserved | Use scrollToAnchor with a DocAnchor to reveal a paragraph by its ID. Optional search and occurrence fields locate text within the paragraph. The block, behavior, and offsetPx options control scrolling. Scrolling supports body paragraphs, table cells, block content controls, headers, footers, footnotes, and endnotes. Repeated headers and footers use their first layout occurrence. Text boxes, invalid references, missing references, ambiguous references, and targets without layout positions return false. Use highlightAnchor to highlight body paragraphs, table cells, and block content controls. Highlights use the same styling and timing options as document refresh highlights. Headers, footers, footnotes, endnotes, and text boxes return false. Both methods preserve selection, focus, document content, and undo history. Scrolling also preserves editing scope. Highlights do not affect saved files. React and Vue share these methods. |
| Rich copy/paste (HTML clipboard) | Partial | Full | Full | Copy writes plain text and HTML with an embedded document fragment. Pasting that fragment restores styles, lists, tables, links, images, footnotes, and endnotes. Pasted Microsoft Word HTML restores footnotes, endnotes, and equations. Recovered inline and display equations replace their fallback pictures and retain color, highlight, size, bold, and upright text. Equation editing follows the supported math subset. If equation recovery fails, the fallback picture remains. MathML import supports presentation markup. Unknown MathML elements contribute their children, and annotations are omitted. Copied equations reach Microsoft Word as equations, other applications as MathML, and plain text in their linear form. A display equation pasted beside text becomes an inline equation. Sections, headers, footers, and comments do not travel on the clipboard. Suggesting mode and non-body scopes use plain-text paste. |
| Undo / redo | Full | Full | Full | Typing starts a new undo group after a 1-second pause or 2 seconds of continuous input. A caret move, another edit, a typing format set at the caret, undo, redo, or a collaborator edit to the same paragraph starts a new step. Caret formatting has its own local undo step without changing shared document content. Each Backspace, Delete, and Enter is its own step. Typing over a selection joins following text within the same time limits. Collaborative sessions use the same grouping rules. Undo restores the original text selection across paragraphs; redo restores the final selection. |
| Detached editors, pop-out windows, and iframes | Full | Full | Full | Move one editor between same-origin windows while preserving its document, undo history, selection, and collaboration session. Detached editors still save, run commands, and receive remote edits. React and Vue provide window components. Cross-origin windows are unsupported. Destroy the editor to release its retained document. |
| Editor UI in 12 languages | Full | Full | Full | de, en, es, fr, he, hi, id, ja, pl, pt-BR, tr, and zh-CN via @docx-editor.dev/i18n. |
| Automatic fit / responsive zoom | Full | Full | Full | The default zoom mode is `auto`: it fits the page width between 50% and 100%. A container narrower than a Letter sheet shrinks the document instead of overflowing. Chrome that pads the scroll container, such as the navigation pane or the review rail, recomputes the fit. With the review pane setting `overflow: 'shrinkPage'`, a fit shrinks the page toward its `minZoom` so the full review card column fits beside it. A host can pin a fixed scale with `zoom` or `zoomMode={{ type: 'fixed' }}`, or ask for uncapped fit-width. The toolbar ladder and the Ctrl+= and Cmd+= shortcuts use the same engine-owned mode. With the review pane setting `overflow: 'scroll'`, a capped fit keeps the page at its size beside an open review column or navigation pane, and the viewport scrolls sideways to reach them. |
| Refresh from server updates | Partial | Partial | Full | Accept complete DOCX results in React and Vue without replacing the editor instance. Preserve scroll by default. Deferred replacements finish opening and restore document clicks. Reject local edits, stale results, and collaborative sessions. Present temporary paragraph highlights with configurable color, opacity, padding, corners, borders, CSS decoration, and separate entrance and exit fades. Select changes by ID. Auto-dismiss highlights after a configurable timeout and respect reduced motion. Customize scroll alignment, padding, motion, and focus using validated body locations or a registered review module. Report unavailable anchors with stable diagnostic codes and their requested locations. Match paragraph IDs without case sensitivity. Processor descriptions support review lists for structural changes and deletions without a body location. Reload resets selection and undo history. Arbitrary file comparison and merging are outside this API. |
| Document automation object model | Full | Full | Full | The automation object model requires the EigenPal Pro License. Manual line breaks use U+000B in text reads and writes, including tracked insertion. Column breaks read as U+000E and refuse text writes. Paragraph separators remain carriage returns. Line feeds and carriage returns in inserted text start new paragraphs, including as tracked insertions. It follows a documented subset of the Word JavaScript API. The server entry works over bytes and reports exceeded resource limits with typed errors. The browser entry works over an open editor. Core metadata supports author, title, subject, keywords, comments, and category reads and writes. The last saved author is read-only. Collaborative metadata writes require an existing core-properties part. Standard core, extended, and custom properties can be removed outside collaboration. Removal is the only write in its sync. Other document content remains unchanged. Metadata writes require tracking to be off. Inline picture insertion works on collaborative runtimes, and the picture replicates to every participant. It ships no model integration, tool catalog, or MCP transport. |
Important drawing limits
The matrix defines support status. Check these limits when a document contains drawings.
| Feature | Rendering | Editing | Round-trip |
|---|---|---|---|
| Anchored text boxes | Insert → Text Box creates a rectangular body text box. Supports typing, paragraph editing, text formatting, plain-text paste, undo, deletion, dragging, and resizing. Edits synchronize during collaboration, with remote cursors and text selections. Clicking inside shows the caret and frame handles. Content stays inside the authored extent. Header/footer text boxes and boxes with tables remain read-only. Linked chains, autofit, and rotation can clip or use placeholders. | Body text boxes | Preserved |
| Drawing shapes | Renders solid rectangles, ellipses, lines, bounded polygons, and groups, with outlines drawn at full width. A group can include one unrotated picture below its shapes. Other shapes use a placeholder. Unsupported shapes in alternative content are hidden, and floating ones keep their wrap area. | No | Preserved |
| WMF and EMF | Rasterizes supported files. Other files keep their extent with a placeholder. | No | Full |
Drawing groups require visible members and supported group properties. Groups with unsupported effects or 3D properties retain their unsupported drawing behavior. The editor does not render only the supported members of such a group.
The editor renders opaque solid Word 2010 text outlines with explicit RGB colors. Other text effects remain preserved; the text-effects matrix lists the rendering limits. PDF export does not paint these outlines.
Layout and document settings
The editor calculates document layout without browser flow layout. It uses document fonts, themes, section geometry, margins, and Word units.
The layout result controls line and page breaks. The editor paints selectable DOM text from that result.
Document settings affect pagination as well as appearance. These settings include compatibility mode, paragraph keep rules, section line grids, and table row minimums. The feature notes identify the settings and limits for each behavior.
A valid compatibility mode declared directly under the settings element, outside w:compat, applies when w:compat holds no valid declaration. An invalid value there is ignored.
Manual page breaks
Manual page breaks (w:br w:type="page") inside table cells do not add lines, line height, or pages. This applies to breaks at the start, middle, or end of a cell paragraph. The text on each side of a break stays on the same line. Line wrapping, tab alignment, and text wrap around floating pictures treat the text as if the break were absent. The document retains these breaks for editing and saving. Manual line breaks still start a new line inside a cell.
A manual page break at the start of a paragraph moves its following text or page break to the next page. This also applies when the current page has no room for another line. The position before the break stays at the bottom of the current page. The text on the next page gets the space before of the paragraph, in every compatibility mode. Adjacent paragraph spacing follows the document’s spacing rules.
The preceding space after normally reduces this leading space. The space after of the text overlaps the space before of the next paragraph in the same way. In a numbered or bulleted paragraph, the number or bullet goes to the next page with the text.
This rule also applies to a paragraph with borders or shading. Lines that hold only page breaks draw no border. The text after the breaks starts a separate border box on the next page, including the paragraph’s top border. The preceding paragraph closes its border box with its bottom border. This happens only when the displayed paragraph starts with the break.
A hidden break does not separate the border group. This includes tracked changes hidden by the selected review view. Shading fills each break line where it sits, up to the page edge.
This rule does not apply to some paragraphs. A paragraph with only one page break, or with only hidden content after the break, keeps the ordinary rule. This includes a single break after a table that fills the page. A paragraph that opens with a page break followed by another page or column break keeps its first break on the current page. Each later break starts one more page. A paragraph that anchors a floating table, text frame, or drawing also keeps it. After a full page, its break line moves to a new page. Its text starts one page later.
A manual column break at the start of a paragraph stays at the bottom of a full page or column, even with nothing after it. The content after the break starts in the next column, or on the next page after the last column. That content gets the paragraph's space before and top border, as text after a leading page break does.
A page break directly followed by a line break does not start a new page. The line break still ends the line, so the text after it continues on the next line.
Section boundaries
A continuous section can share the preceding section’s last page when its page size and orientation stay the same. A trailing page break in the preceding section starts the continued text on the next page. A shared page retains its header, footer, and text area, even if the following section uses different variants or heights. The following section’s header and footer start on the next page.
Odd-page and even-page sections can insert an empty sheet to reach the required page number parity. That sheet contains no header, footer, or document content. NUMPAGES includes it; SECTIONPAGES does not. The sections matrix note also explains page numbering restarts.
An empty paragraph that ends a section ignores its own page break before, from direct formatting or its style. It stays after the section's content, so it does not add a blank page. The next section's break type controls where that section starts. This rule does not apply when nothing comes before the paragraph in its section. It also does not apply when the paragraph holds text, a tab, hidden text, or a field. Bookmarks, proofing marks, permission markers, comment range markers, and empty text runs do not prevent this rule.
Table rows and merged cells
Bottom-to-top cell text does not make its row taller. The text wraps at the final row height, or along the full merged cell height. The cell width clips overflowing text.
A table row that closes a page reserves space for its bottom border. A following row that can split can keep the preceding row on the page.
A table row starts below other content only when the remaining space holds its minimum height. If it does not, the row moves to the next page, also when its content is taller than a page. A keep-with-next paragraph before the table moves with the row. If a fresh page cannot hold that minimum below repeated headers, the row splits where it stands. Rows of positioned tables keep their existing placement.
A row with an exact height taller than the page content starts on a fresh page and does not split. It fills the rest of that page, and its border and content stop at the bottom margin. The row does not paint past the margin, with or without w:cantSplit. The next block starts on the next page.
Keep-with-next table groups include closed vertical merges. Their merged content contributes its height once across the covered rows. Table decisions measure at most 256 kept rows and the next row. Longer groups use that measured prefix as a lower bound. Paragraph keep lookahead remains unchanged.
Changes to numbering and document properties update field text and table pagination during editing.
Merges that enter or leave the measured group retain ordinary row placement. Active floating content also uses ordinary row placement when it changes the available width.
Fixed-height horizontal cells display the part of a line that starts inside their content box. A taller line does not enlarge the row. Text below the box stays in the document and does not continue on another page.
Vertical cell merges that cover the same rows share those rows without adding their heights twice. In fixed-height rows, a merged cell whose content fits the complete span displays all of it. If the content does not fit, the text flows through every row of the span and is clipped at the bottom of the last row. A line that starts inside the span shows its visible part. If a text-only span of three or more rows crosses a page, the part above the break shows whole lines, and the text continues in the rows on the next page. Some merges are still clipped at their first row: a merge that contains or partly overlaps another merge, a second, shorter merge that starts in the same row, and a two-row span that crosses a page.
Fields and paragraph spacing
Saved results of fields inside another field's instruction do not add text, line breaks, or links. The outer field keeps its normal display behavior. Fields inside a saved result still display.
Named character styles set the font properties of empty paragraph marks and numbering markers. Direct mark properties override those styles. A mark's character style also sizes the empty line after a trailing line break. It does not enlarge a line that contains text or an inline picture. A direct mark size also leaves lines with text, inline pictures, or equations unchanged.
For lines containing only inline pictures, the picture runs set the text height. A line with superscript or subscript text keeps that text's full-size height above and below the baseline, on every line of the paragraph. A larger paragraph style size does not enlarge that line. When you type in an empty paragraph, the new text takes the character style of the paragraph mark.
Active section line grids set the height of automatically spaced body lines in whole grid steps. The space below the text in a grid line can extend past the bottom margin, so a line fits on a page when its text fits. Multiple line spacing counts in grid steps: a line takes the larger of the steps its text needs and the multiple, with the text centered. Minimum line spacing up to the grid step takes the grid step, and a larger minimum keeps its own height. Exact line spacing keeps its authored rule, and the whole line must fit. A paragraph can turn off snapping through direct formatting or an inherited style. Table cells snap only when the document enables w:adjustLineHeightInTable. Footnote and endnote text snaps to the grid of the section that holds it. Headers, footers, and text boxes do not snap.
Adjacent paragraph spacing normally uses the larger of the preceding space after and following space before. With w:doNotUseHTMLParagraphAutoSpacing, those values add together. That setting also changes automatic spacing to 5pt before and 10pt after. The rule applies in body text, table cells, headers, footers, notes, and text boxes.
Fonts and text direction
Supply usable font bytes for accurate text measurement. For more information, see Fonts and measurement.
Known single-byte Symbol and Wingdings bullets use Unicode fallback when their font is unavailable. Layout still uses the line height and advance widths of the symbol font. The editor preserves the original numbering definition when you save.
No-break spaces (U+00A0, U+2007, and U+202F) retain their line-break behavior across formatting runs. This also applies to word joiners (U+2060 and U+FEFF). Ordinary spaces can still provide break positions. Oversized groups retain the existing overflow rules.
The configured font resolver also receives faces used by SYMBOL fields and numbering markers. Your host must supply usable font bytes for those faces when they are unavailable locally. Unused numbering definitions do not add font requests.
Paragraph w:bidi controls alignment and the order of groups with different run directions. Run w:rtl controls the directional context within each group. Unmarked numeric text such as 1 980 keeps its left-to-right order in right-to-left paragraphs. Arabic, Hebrew, and Arabic-Indic digits retain their Unicode direction within that context. Authored Unicode direction controls use paragraph-wide Unicode ordering. Selection and caret positions follow the displayed text without changing source offsets.
Thai, Lao, Khmer, and Myanmar line breaking
Thai, Lao, Khmer, and Myanmar text puts no spaces between words. Lines in these scripts wrap at any character cluster that fits, not at dictionary word boundaries. Table AutoFit keeps an unspaced run of these scripts whole as one segment.
To mark a word boundary, insert a zero-width space (U+200B). A line can end after a zero-width space in any script, and the zero-width space stays at the end of that line. A space before a zero-width space counts as text while it fits on the line, so a right-aligned line ends one space short of the margin. The space hangs past the margin only when it does not fit. Inside a justified line, a space followed by a zero-width space stretches and compresses like any other space.
Line breaks never split a character cluster. A Khmer coeng or Myanmar virama keeps the consonant stacked under it on the same line. Myanmar vowel signs and the visarga, such as ာ and း, stay with their consonant. A word that starts with a vowel sign after a space, as in Zawgyi-encoded Myanmar, still breaks at the space.
In every script, a dash between letters is a break position even when the text after it starts a new run, so ALPHA followed by a run -PRIME can wrap after the dash.
East Asian typography
East Asian layout keeps punctuation, graphemes, and full-width number groups together across formatting changes. Justified lines distribute inter-character spacing through the same geometry used for paint and caret placement.
Justified lines compare space compression with the expansion needed for an earlier break. Hyphenated fragments and currency or math symbols participate in this fit calculation. Plain REF results can complete a word; changing PAGEREF and NOTEREF results cannot.
Modern Latin justification includes terminal footnote and endnote citations when testing whether a complete word fits. Citations keep their formatting and model positions. Marks with reserved page-local widths retain their existing line-break behavior.
East Asian font hints select the document's East Asian face for supported punctuation, symbols, Greek, and Cyrillic ranges. Combining marks and joined emoji keep their base character's slot across text runs. Explicit symbol fonts retain their selected face.
Document settings control kinsoku, Japanese strict rules, Korean character wrapping, and punctuation overflow. Adjacent full-width punctuation shares a half-cell bearing when both runs enable w:kern at their font size. w:noPunctuationKerning disables this compression. The East Asian face of the document defaults (w:rPrDefault) must be an East Asian font. A known Chinese, Japanese, or Korean font qualifies. A known Latin font, such as Arial, does not. Another face qualifies only when the font table gives it a Shift JIS, Hangul, GB2312, or Big5 w:charset. An East Asian theme font with an empty theme slot qualifies. Korean-language runs retain their advances. Close/open, close/close, open/open, comma/period, and colon/open pairs compress; open/close pairs do not. The run's own font, bold, italic, and authored tracking do not select the rule. Run boundaries do not disable it. Paragraph and manual line-break boundaries retain their advance widths. A pair compresses only when both characters are on the same line, so punctuation at the end of a line keeps its full advance. Punctuation overflow (w:overflowPunct) hangs full-width punctuation past the margin only in justified paragraphs. Latin punctuation with an East Asian run language follows the overflow setting in every alignment.
w:characterSpacingControl does not enable or disable this pair rule. Latin punctuation keeps the font's HarfBuzz kerning, including with w:noPunctuationKerning.
Run language uses w:lang elements and attributes in the WordprocessingML namespace across styles and direct formatting. Foreign language extensions remain saved but do not select the layout language.
Colons can compress before opening brackets, bounded by the following bracket's available bearing. With measured glyph bounds, colons also compress before closing punctuation. This pair rule halves the colon's advance, including authored character spacing. Other centered punctuation, authored spaces, outlined text, decorated text, and tracked changes retain their advances. Colons with highlight or shading retain their advances.
If wrapping separates a compressed colon from its opening bracket, the paragraph uses natural colon advances. Narrow plain left-to-right (LTR) East Asian paragraphs can use measured punctuation bearings to fit the next glyph and protected punctuation. Fitting uses measured glyph bounds and preserves source positions. Mixed Latin text, fields, decorations, revisions, and right-to-left (RTL) text retain conservative fitting. So do gaps beside floating objects and measurers without ink bounds.
Kana uses deterministic advance reductions.
The document's w:themeFontLang selects supplemental theme fonts for its Latin, East Asian, and complex-script theme tokens. The resolver reads val, eastAsia, and bidi independently. It supports CJK languages, common complex-script languages, and explicit script subtags. Complex-script theme tokens also work on Latin font attributes. When no inherited or direct Latin font reference exists, the resolved body Latin theme supplies the default.
When no style supplies an East Asian face, a resolved body East Asian theme face supplies the default. When the East Asian theme language is absent and its face is empty, inherited w:lang/@w:eastAsia selects the supplemental face. Chinese, Japanese, and Korean use named CJK defaults when neither the theme nor the run supplies a face. Word's default language can depend on its installation language and keyboards. Font resolvers receive the selected candidates before shaping.
Supply suitable fonts for matching glyph metrics.
The feature matrix lists the support limits for East Asian typography.
For pipeline details, see Architecture. Test your documents in the live demo.
Round-trip contract
A DOCX file is a ZIP package with XML parts and binary payloads.
| Content | Save behavior |
|---|---|
| Modeled OOXML | Serializes from typed document nodes. |
| Unmodeled XML elements and attributes | Re-emits generic nodes in place. |
| Legacy VML, custom XML, and add-in markup | Preserves structural content. |
| Media, VBA projects, embedded fonts, and OLE binaries | Copies package payloads without modification. |
| Relationship IDs, bookmark names, style IDs, and numbering definitions | Keeps references intact. |
| Tracked changes | Writes Word w:ins and w:del revisions. |
| Theme colors | Keeps theme references instead of flattening them to RGB values. |
The contract protects semantic meaning and structure. It does not promise byte identity for rewritten XML parts.
An xml:space="preserve" attribute on a run does not turn indentation into document text. Spaces inside text elements remain authored text.
The editor preserves w:br and w:cr elements outside runs, directly inside paragraphs or hyperlinks. Save retains their position. The paragraph and its runs still render and stay editable. The misplaced break does not start a new line or page. A w:tab or w:t directly inside a paragraph, outside a run, still makes the whole paragraph unknown content. That paragraph and its text are kept on save, but the paragraph does not render and you cannot edit it.
Continuous integration checks real documents with a canonical tree fingerprint and a save-and-reopen semantic digest. Focused tests cover revisions, fields, hyperlinks, content controls, and browser editing.
If untouched content is lost or reinterpreted, report a round-trip issue with the source document.
Security and data flow
| Concern | Behavior |
|---|---|
| Browser uploads | The editor package does not upload documents or call a conversion service. |
| Macros | The editor preserves VBA payloads but never executes them. |
| OLE | The editor preserves OLE payloads without running them. Supported inline objects display their cached preview picture. |
| Calculated fields | Supported calculated fields update display text only. Macros, DDE, and external includes remain inert. |
| Hyperlinks | Allowlisted targets open only after a user gesture. |
| Server editing | Your host controls where DOCX data runs. |
| Browser automation | Controls an editor already in the page. |
| External artificial intelligence | @docx-editor.dev/editor-api includes no model integration or transport. |
Your application controls any data sent to another service or model.
Bundle and performance
| Area | Behavior |
|---|---|
| Core exports | Subpath exports can tree-shake independently. |
| Engine copies | Adapters use core as a peer dependency to resolve one engine copy. |
| Initial bundle | You can lazy-load the editor with your framework. |
| Layout work | Per-block caches avoid measuring unchanged blocks again. |
| Benchmarks | No published benchmark represents every document. Test your own files. |
License and API stability
| Package or policy | Terms |
|---|---|
@docx-editor.dev/core, @docx-editor.dev/react, @docx-editor.dev/vue, and @docx-editor.dev/i18n | Apache 2.0 |
@docx-editor.dev/fonts | Apache-2.0 AND OFL-1.1 AND LicenseRef-GUST-Font-License |
@docx-editor.dev/fonts-cjk | Apache-2.0 AND OFL-1.1 |
@docx-editor.dev/docx-to-pdf | EigenPal Pro License |
@docx-editor.dev/editor-api | EigenPal Pro License |
@docx-editor.dev/pro | EigenPal Pro License |
| Versions | Semantic Versioning with one fixed version group |
| Public API | CI checks generated API Extractor snapshots |
| Contributions | Require a one-time Contributor License Agreement |
The Pro packages use the EigenPal Pro License. Compare license and support levels on the pricing page.
Next steps
- Quickstart: Load, edit, and save a DOCX file.
- Architecture: Review the engine pipeline.
- Fields and cross-references: Review field evaluation limits.
- Tracked changes: Review revision behavior.