Skip to content

data-dw-* Attributes

This page is the authoritative specification of the data-dw-* attribute system used by docwow's HTML output.

Every element in a docwow HTML document carries two things:

  1. CSS classes — control visual appearance in the browser
  2. data-dw-* attributes — carry Word metadata needed for lossless round-trip back to DOCX

If you are building a browser-based editor on top of docwow, you must preserve all data-dw-* attributes on every element. Stripping them will cause information loss when converting back to DOCX.


Document container

<div class="dw-document"
     data-dw-page-width="595.28"
     data-dw-page-height="841.89"
     data-dw-margin-top="72.0"
     data-dw-margin-right="72.0"
     data-dw-margin-bottom="72.0"
     data-dw-margin-left="72.0">

All dimension values are in points (pt).

Attribute Type Description
data-dw-page-width float (pt) Page width
data-dw-page-height float (pt) Page height
data-dw-margin-top float (pt) Top margin
data-dw-margin-right float (pt) Right margin
data-dw-margin-bottom float (pt) Bottom margin
data-dw-margin-left float (pt) Left margin

Paragraphs (<p class="dw-p">)

<p class="dw-p dw-style-Normal"
   data-dw-style="Normal"
   data-dw-align="justify"
   data-dw-indent-left="36.0"
   data-dw-indent-right="0.0"
   data-dw-indent-first-line="18.0"
   data-dw-space-before="12.0"
   data-dw-space-after="6.0"
   data-dw-line-spacing="14.0"
   data-dw-page-break-before="true"
   data-dw-keep-together="true"
   data-dw-keep-with-next="true">

Paragraph attributes

Attribute Type Description
data-dw-style string Named Word style ID (e.g. Normal, Heading1)
data-dw-align string left | center | right | justify
data-dw-indent-left float (pt) Left indent
data-dw-indent-right float (pt) Right indent
data-dw-indent-first-line float (pt) First-line indent. Negative value = hanging indent
data-dw-space-before float (pt) Space before paragraph
data-dw-space-after float (pt) Space after paragraph
data-dw-line-spacing float (pt) Exact line spacing. Absent = auto
data-dw-page-break-before "true" Forces a page break before this paragraph
data-dw-keep-together "true" Keep all lines of paragraph on same page
data-dw-keep-with-next "true" Keep this paragraph on same page as the next
data-dw-shading hex RGB string Paragraph background shading color (e.g. 4472C4). Absent = no shading
data-dw-tab-stops string Comma-separated tab stops: pos:align or pos:align:leader (e.g. 36pt:left,144pt:right:dot). Absent = no custom stops
data-dw-borders string Pipe-separated paragraph borders: side:style:width_pt:color (e.g. top:single:0.5:FF0000\|bottom:single:0.5:). Absent = no borders

List paragraph attributes

When a paragraph belongs to a list, it gains two additional attributes:

Attribute Type Description
data-dw-num-id string Numbering definition ID (matches data-dw-num-id on the <ul>/<ol>)
data-dw-level integer List nesting level, 0-based

Section break attributes

Section breaks render as <div class="dw-section-break"> elements (always display:none):

Attribute Type Description
data-dw-break-type string nextPage | evenPage | oddPage | continuous
data-dw-page-width float (pt) Page width of the section
data-dw-page-height float (pt) Page height of the section
data-dw-margin-top float (pt) Top margin
data-dw-margin-bottom float (pt) Bottom margin
data-dw-margin-left float (pt) Left margin
data-dw-margin-right float (pt) Right margin

Cross-reference attributes

Cross-references render as <a class="dw-xref"> elements:

Attribute Type Description
data-dw-xref string Target bookmark name (matches a data-dw-bookmark anchor elsewhere in the document)

Runs (<span class="dw-r">)

<span class="dw-r dw-cstyle-Strong"
      data-dw-bold="true"
      data-dw-italic="true"
      data-dw-underline="true"
      data-dw-strike="true"
      data-dw-font="Arial"
      data-dw-size="14.0"
      data-dw-color="FF0000"
      data-dw-highlight="yellow"
      data-dw-valign="superscript"
      data-dw-char-style="Strong">
  text content
</span>
Attribute Type Description
data-dw-bold "true" Bold
data-dw-italic "true" Italic
data-dw-underline "true" Underline
data-dw-strike "true" Strikethrough
data-dw-small-caps "true" Small caps (lowercase letters rendered as smaller uppercase)
data-dw-all-caps "true" All caps (all letters rendered as uppercase)
data-dw-vanish "true" Hidden text (w:vanish); rendered as display:none in HTML
data-dw-font string Font family name
data-dw-size float (pt) Font size
data-dw-color string Font color as 6-digit hex, no # (e.g. FF0000)
data-dw-highlight string Highlight color name (e.g. yellow, cyan, red)
data-dw-valign string superscript | subscript
data-dw-char-style string Named Word character style ID (e.g. Strong, Emphasis). Absent = no character style

When a character style is applied, the span also gains a CSS class dw-cstyle-{id} (e.g. dw-cstyle-Strong) for CSS-based styling.

Boolean attributes (data-dw-bold, etc.) are only present when true; their absence means false.

Newlines within a run are represented as literal \n characters in the text content (preserved by white-space: pre-wrap in CSS).


Tables (<table class="dw-table">)

<table class="dw-table"
       data-dw-style="TableGrid"
       data-dw-width="360.0"
       data-dw-col-widths="120.0,120.0,120.0">
Attribute Type Description
data-dw-style string Word table style ID
data-dw-width float (pt) Total table width
data-dw-col-widths comma-separated floats (pt) Width of each column, in order

Table cells (<td class="dw-td">)

<td class="dw-td"
    colspan="2"
    data-dw-width="240.0"
    data-dw-v-merge-start="true">
Attribute Type Description
colspan integer HTML standard colspan (column span)
data-dw-width float (pt) Cell width
data-dw-v-merge-start "true" This cell starts a vertical merge group
data-dw-v-merge-continue "true" This cell continues a vertical merge (is a continuation row)
data-dw-shading hex RGB string Cell background shading color (e.g. ED7D31). Absent = no shading

Note

Vertically merged cells use the standard HTML rowspan attribute for visual rendering, but data-dw-v-merge-start / data-dw-v-merge-continue are also written so the round-trip reconstructs Word's <w:vMerge> elements exactly.


Lists (<ul> / <ol>)

<ul class="dw-list"
    data-dw-num-id="1"
    data-dw-num-fmt="bullet">

<ol class="dw-list"
    data-dw-num-id="2"
    data-dw-num-fmt="decimal">
Attribute Type Description
data-dw-num-id string Numbering definition ID — links list paragraphs to this list
data-dw-num-fmt string bullet | decimal | lowerLetter | upperLetter | lowerRoman | upperRoman

Nested lists are represented as nested <ul>/<ol> elements inside <li> elements, matching the HTML spec. Each nesting level inherits the data-dw-num-id of its parent list.


Inline images (<img class="dw-img">)

<img class="dw-img"
     src="data:image/png;base64,iVBOR..."
     data-dw-width="72.0"
     data-dw-height="36.0"
     data-dw-content-type="image/png"
     alt="Chart 1">
Attribute Type Description
src data URI Image bytes encoded as base64 (data:<content-type>;base64,<data>)
data-dw-width float (pt) Rendered width in points
data-dw-height float (pt) Rendered height in points
data-dw-content-type string MIME type (e.g. image/png, image/jpeg)
alt string Alt text from Word's image description

<header class="dw-header dw-header-default" data-dw-header-type="default">
  <p class="dw-p">...</p>
</header>

<footer class="dw-footer dw-footer-default" data-dw-footer-type="default">
  <p class="dw-p dw-page-only">...</p>
</footer>
Attribute Type Description
data-dw-header-type string default | first | even — which slot this header occupies
data-dw-footer-type string default | first | even — which slot this footer occupies

The data-dw-title-pg attribute on the document div signals that a different first-page header/footer is active:

<div class="dw-document" data-dw-title-pg="true" ...>
Attribute Type Description
data-dw-title-pg "true" Document uses a distinct first-page header/footer

Floating images (<figure class="dw-float-img">)

Floating images are rendered as <figure> elements (or <span> for wrap="none" to stay inside the paragraph's stacking context). The inner <img> carries the base64 data URI; all positioning metadata is on the outer element.

<figure class="dw-float-img"
        style="float:left;margin:0 8pt 4pt 0;z-index:1;"
        data-dw-float-wrap="square"
        data-dw-float-h-anchor="column"
        data-dw-float-v-anchor="paragraph"
        data-dw-float-pos-h="72pt"
        data-dw-float-pos-v="36pt"
        data-dw-float-behind="false"
        data-dw-rid="rId5"
        data-dw-width="144pt"
        data-dw-height="72pt">
  <img src="data:image/png;base64,iVBOR..."
       alt="Company logo"
       style="width:144pt;height:72pt;display:block">
</figure>
Attribute Type Description
data-dw-float-wrap string Text wrapping type: square | tight | topAndBottom | through | none
data-dw-float-h-anchor string Horizontal reference frame: margin | page | column | character
data-dw-float-v-anchor string Vertical reference frame: margin | page | paragraph | line
data-dw-float-pos-h CSS string (e.g. 72pt) Horizontal offset from the h-anchor origin
data-dw-float-pos-v CSS string (e.g. 36pt) Vertical offset from the v-anchor origin
data-dw-float-behind "true" / "false" Whether the image floats behind body text
data-dw-rid string Original OOXML relationship ID — used on round-trip to preserve the relationship
data-dw-width CSS string (e.g. 144pt) Rendered width
data-dw-height CSS string (e.g. 72pt) Rendered height

The image content type is derived from the base64 data URI (data:<content-type>;base64,...). The HTML parser reads this to reconstruct the binary image data.


Page number fields (<span class="dw-field">)

<span class="dw-field" data-dw-field="PAGE">1</span>
<span class="dw-field" data-dw-field="NUMPAGES">1</span>
<span class="dw-field" data-dw-field="DATE">2025-01-01</span>
Attribute Value Description
data-dw-field PAGE Current page number (static placeholder 1 in HTML)
data-dw-field NUMPAGES Total page count (static placeholder 1 in HTML)
data-dw-field SECTIONPAGES Pages in the current section (static placeholder 1 in HTML)
data-dw-field DATE Document date (rendered as a static string in HTML)
data-dw-field TIME Document time (rendered as a static string in HTML)
data-dw-field AUTHOR Document author (rendered as a static string in HTML)
data-dw-field TITLE Document title (rendered as a static string in HTML)
data-dw-field FILENAME File name (rendered as a static string in HTML)

The HTML parser reads data-dw-field to reconstruct the PageNumberField model on round-trip — the displayed text content is ignored.


Page breaks (<div class="dw-page-break">)

<div class="dw-page-break" data-dw-page="2"></div>
Attribute Type Description
data-dw-page integer The page number that begins after this break

Always display:none. Preserved for round-trip only.


Footnote and endnote references (<a class="dw-footnote-ref">)

<a class="dw-footnote-ref"
   href="#fn-1"
   data-dw-note-type="footnote"
   data-dw-note-id="1">[1]</a>
Attribute Type Description
class string dw-footnote-ref for footnotes, dw-endnote-ref for endnotes
href string Anchor link to the note body (#fn-N for footnotes, #en-N for endnotes)
data-dw-note-type string footnote | endnote
data-dw-note-id integer (as string) The note ID (matches the body section entry)

Footnote and endnote sections (<section>)

<section class="dw-footnotes" data-dw-note-section="footnotes">
  <div class="dw-fn" id="fn-1" data-dw-note-id="1" data-dw-note-type="footnote">
    <span class="dw-fn-marker">[1]</span>
    <div class="dw-fn-body">
      <p class="dw-p">Footnote content.</p>
    </div>
  </div>
</section>

<section class="dw-endnotes" data-dw-note-section="endnotes">
  <div class="dw-en" id="en-1" data-dw-note-id="1" data-dw-note-type="endnote">
    <span class="dw-en-marker">[1]</span>
    <div class="dw-fn-body">
      <p class="dw-p">Endnote content.</p>
    </div>
  </div>
</section>
Element / Attribute Description
<section class="dw-footnotes"> Container for all footnote bodies
<section class="dw-endnotes"> Container for all endnote bodies
data-dw-note-section footnotes | endnotes
<div class="dw-fn"> / <div class="dw-en"> Individual note body container
id fn-N (footnotes) or en-N (endnotes) — anchored from body references
data-dw-note-id Integer note ID as string
data-dw-note-type footnote | endnote
<span class="dw-fn-marker"> / <span class="dw-en-marker"> Visual marker (e.g. [1])
<div class="dw-fn-body"> Container for note paragraph content

Bookmark anchors (<a class="dw-bookmark">)

<a id="section1"
   class="dw-bookmark"
   data-dw-bookmark="section1"></a>

A zero-width anchor that marks the position of a Word w:bookmarkStart element.

Attribute Type Description
id string The bookmark name — used as the fragment target for #name links
class string Always dw-bookmark
data-dw-bookmark string The bookmark name (same as id; used by the HTML parser to reconstruct the model)

The element is always empty (no text content). Anchor hyperlinks pointing to #name resolve to the bookmark with the matching id.


Table of Contents (<nav class="dw-toc">)

<nav class="dw-toc"
     data-dw-toc="true"
     data-dw-toc-title="Contents">
  <p class="dw-toc-title">Contents</p>
  <ul class="dw-toc-list">
    <li class="dw-toc-entry dw-toc-level-1" data-dw-toc-level="1">
      <a class="dw-toc-link" href="#_Toc123456789">Introduction</a>
    </li>
    <li class="dw-toc-entry dw-toc-level-2" data-dw-toc-level="2">
      <span class="dw-toc-text">Background</span>
    </li>
  </ul>
</nav>

Represents a Word w:sdt structured document tag that contains a table of contents.

Element / Attribute Description
<nav class="dw-toc"> Container for the whole TOC block
data-dw-toc Always "true" — marks the element as a TOC for the HTML parser
data-dw-toc-title The TOC heading text — used to reconstruct the model on round-trip
<p class="dw-toc-title"> Visible heading paragraph — omitted when the title is empty
<ul class="dw-toc-list"> Ordered list of TOC entries
<li class="dw-toc-entry dw-toc-level-N"> One TOC entry; N is 1–9
data-dw-toc-level Integer level of this entry (1–9)
<a class="dw-toc-link" href="…"> Clickable link to the heading anchor (when a URL is available)
<span class="dw-toc-text"> Non-linked entry text (when no anchor URL is available)

Track changes (<ins class="dw-ins"> / <del class="dw-del">)

Insertions use <ins> and deletions use <del>. Both carry the same set of data-dw-* attributes. A hover popup with Accept/Reject buttons is injected by the renderer as a child <span class="dw-tc-popup"> — this span is ignored by the HTML parser on round-trip.

<ins class="dw-ins"
     data-dw-author="Alice"
     data-dw-date="2025-07-10T09:00:00Z"
     data-dw-change-id="1">
  <span class="dw-tc-popup">...</span>
  <span class="dw-r">inserted text</span>
</ins>

<del class="dw-del"
     data-dw-author="Alice"
     data-dw-date="2025-07-10T09:00:00Z"
     data-dw-change-id="2">
  <span class="dw-tc-popup">...</span>
  <span class="dw-r">deleted text</span>
</del>
Attribute Type Description
data-dw-author string Reviewer display name
data-dw-date string ISO-8601 datetime of the change
data-dw-change-id integer (as string) OOXML w:id for the change

The inner <span class="dw-tc-popup"> is a purely visual element (contains author, date, and Accept/Reject buttons). It is ignored by the HTML parser. The <span class="dw-r"> children are the only children the parser reads to reconstruct run content.

Accepting or rejecting in the browser removes the <ins>/<del> wrapper. A subsequent HTML→DOCX round-trip will see the remaining <span class="dw-r"> elements as plain text runs — the accepted/rejected state is preserved.


Comment references (<a class="dw-comment-ref">)

Each inline comment reference renders as a superscript [N] anchor. When the document has comment bodies available, the renderer embeds a CSS-only hover popup directly inside the <a> element — no JavaScript required.

<a href="#comment-1"
   class="dw-comment-ref"
   data-dw-comment-id="1">
  [1]
  <span class="dw-comment-popup">
    <span class="dw-comment-popup-author">
      Alice
      <span class="dw-comment-popup-date">· 2024-01-15T10:00:00Z</span>
    </span>
    <span class="dw-comment-popup-text">This is a great example!</span>
  </span>
</a>

The popup spans are purely visual and are ignored by the HTML parser on round-trip — they carry no data-dw-* attributes. The data-dw-comment-id on the <a> is the only attribute the parser reads.

Attribute / Element Type Notes
class="dw-comment-ref" string Marks the inline reference; used by the HTML parser
data-dw-comment-id integer Comment ID; used to reconstruct CommentRef on round-trip
href string Anchor pointing to #comment-{id} in the hidden comments section
dw-comment-popup CSS hover popup container; hidden by default, shown on :hover
dw-comment-popup-author Author name and optional date
dw-comment-popup-date Omitted when date is empty
dw-comment-popup-text Plain text of the comment body

Comment sections (<section class="dw-comments">)

The comment section is present in every HTML document that has comments, but it is visually hidden (display: none). It exists solely to preserve the full comment metadata for the HTML → DOCX round-trip; the HTML parser reads it to reconstruct Comment objects.

<section class="dw-comments" data-dw-note-section="comments">
  <div class="dw-comment"
       id="comment-1"
       data-dw-comment-id="1"
       data-dw-comment-author="Alice"
       data-dw-comment-date="2024-01-15T10:00:00Z"
       data-dw-comment-initials="A">
    <span class="dw-comment-marker">[1]</span>
    <div class="dw-comment-body">
      <p class="dw-p"></p>
    </div>
  </div>
</section>
Element / Attribute Description
<section class="dw-comments"> Hidden container for all comment bodies (display:none)
data-dw-note-section Always "comments" — marks the section for the HTML parser
<div class="dw-comment"> One comment body
id comment-{id} — anchor target for the in-text reference
data-dw-comment-id Integer comment ID — used to reconstruct the model on round-trip
data-dw-comment-author Author display name
data-dw-comment-date ISO-8601 datetime string, or empty string
data-dw-comment-initials Author initials, or empty string
<span class="dw-comment-marker"> [N] marker at the start of the comment
<div class="dw-comment-body"> Contains one or more <p class="dw-p"> paragraphs

Attribute presence rules

  • Omitted = default. Attributes are only written when their value differs from the Word default (e.g. data-dw-align is omitted for left-aligned paragraphs).
  • Boolean flags (data-dw-bold, data-dw-page-break-before, etc.) are present only when true.
  • Numeric values use the Python repr of a float (e.g. "36.0", "595.28").