paged.IDML Reference
Styles

The cascade

How BasedOn links a style to its parent, how InDesign writes it as a typed Properties child, and how a chain of styles folds into one set of values.

Tier: IntermediateIntermediateIIexplanation

BasedOn names a style's parent; a style's effective values are its own attributes, then whatever its parents supply for the rest.

In short A style rarely sets everything. "Body Indented" might set only a first-line indent and take its font, size and colour from "Body", which takes its font from the root. Each style names its parent in BasedOn, and InDesign writes that as a typed child of the style's <Properties> block, not as an attribute. To find a style's value for any attribute, walk up the chain from the applied style and take the first value set. A value set directly on the text or frame that applies the style sits above the whole chain.

[No paragraphstyle] (root)BasedOn"Body"appliedthe runPointSize="18" (local override wins)
A run resolves through the BasedOn chain; a local override on the range wins over both.

How InDesign writes BasedOn

InDesign writes a style's parent as the first child of its <Properties> block:

  • <BasedOn type="object">ParagraphStyle/Body</BasedOn> names a parent by its Self id.
  • <BasedOn type="string">$ID/[No paragraph style]</BasedOn> is how InDesign names one of its reserved roots: the $ID/ name, without the kind prefix.

Paragraph, character, object, table and cell styles all use this form. A BasedOn="…" attribute on the style's start tag is not InDesign's spelling, and InDesign ignores it when it opens the file: the style opens based on the root, as if no parent were named. In the census of real documents, paragraph styles use the attribute form in one document and the child in 271.

The chain of every paragraph style ends at [No paragraph style], and of every character style at [No character style]; a style that names no parent is based on that root.

A three-link chain: "Body Indented" is based on "Body", which is based on the [No paragraph style] root. Each parent is a typed BasedOn child.

Resources/Styles.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<idPkg:Styles xmlns:idPkg="http://ns.adobe.com/AdobeInDesign/idml/1.0/packaging" DOMVersion="20.0">
  <RootCharacterStyleGroup>
    <CharacterStyle Self="CharacterStyle/$ID/[No character style]" Name="$ID/[No character style]"/>
  </RootCharacterStyleGroup>
  <RootParagraphStyleGroup>
    <ParagraphStyle Self="ParagraphStyle/$ID/[No paragraph style]" Name="$ID/[No paragraph style]" PointSize="12" FillColor="Color/Black">
      <Properties>
        <AppliedFont type="string">Open Sans</AppliedFont>
      </Properties>
    </ParagraphStyle>
    <ParagraphStyle Self="ParagraphStyle/Body" Name="Body" PointSize="14" SpaceAfter="6">
      <Properties>
        <BasedOn type="object">ParagraphStyle/$ID/[No paragraph style]</BasedOn>
      </Properties>
    </ParagraphStyle>
    <ParagraphStyle Self="ParagraphStyle/Body Indented" Name="Body Indented" FirstLineIndent="18">
      <Properties>
        <BasedOn type="object">ParagraphStyle/Body</BasedOn>
      </Properties>
    </ParagraphStyle>
  </RootParagraphStyleGroup>
  <RootObjectStyleGroup>
    <ObjectStyle Self="ObjectStyle/$ID/[None]" Name="$ID/[None]" FillColor="Swatch/None" StrokeColor="Swatch/None" StrokeWeight="0" AppliedParagraphStyle="ParagraphStyle/$ID/[No paragraph style]" CornerOption="None" CornerRadius="0" EndCap="ButtEndCap" EndJoin="MiterEndJoin" MiterLimit="4" StrokeAlignment="CenterAlignment" StrokeType="StrokeStyle/$ID/Solid" Nonprinting="false"/>
  </RootObjectStyleGroup>
</idPkg:Styles>

In Paged: the importer reads both the typed child and the attribute; when a style has both, the attribute wins. The exporter always writes the child, as type="object" with the parent's Self. A reserved root written in the type="string" form ($ID/[No paragraph style]) is not matched to the root style, so the chain stops one step early. Swatch/None on a text style's stroke, or on an object, table or cell style's fill or stroke, is read as unset rather than as "no paint", so a parent's colour shows through (see conflict resolution).

Supported · verified

How a chain resolves

For each attribute, the first style in the chain that sets it wins. Resolving "Body Indented" in the example above gives:

AttributeValueSet by
FirstLineIndent18Body Indented, the applied style
PointSize14Body
SpaceAfter6Body
AppliedFontOpen Sansthe root
FillColorColor/Blackthe root

A child shadows its parent: if "Body Indented" set its own PointSize, Body's 14 would never be reached. There is no later-rule-wins step as in CSS. The chain order is the precedence.

What counts as "set" depends on the attribute. A colour attribute set to Swatch/None is a real value meaning "no paint", and it shadows a parent's colour like any other value. An attribute that is absent is not set, and the walk continues.

Cycles and missing parents

Nothing in the format forbids a cycle, A based on B based on A, and a hand-edited file can contain one. A parent id that names no style can appear the same way. A reader should stop the walk in both cases and keep what it has gathered.

In Paged: the walk stops after 16 steps, which is far above any real chain (one to three links is typical), and stops at a parent it cannot find.

Local overrides sit above the chain

The cascade turns one applied style into a set of values. The element that applies the style can also set an attribute on itself: PointSize="24" on a <CharacterStyleRange>. That value belongs to the element, not to the style, and wins over the whole chain. For text there is one more layer, because a run sits inside a paragraph: conflict resolution gives the full order.

Frequently asked questions

How does InDesign write BasedOn in IDML? As a typed child of the style's <Properties> block: <BasedOn type="object"> with the parent's Self id, or <BasedOn type="string"> with the $ID/ name of a built-in root such as $ID/[No paragraph style].

Does InDesign read a BasedOn attribute? No. A BasedOn="…" attribute on the style's start tag is ignored, and the style opens with no parent. Write the <Properties> child.

How is a chain of styles resolved? Start at the applied style and walk up through BasedOn. For each attribute, take the first value you meet. The applied style's own values therefore win over its parent's, and its parent's over the grandparent's.

What happens with a cycle or a missing parent? The format does not prevent either. Stop the walk when it repeats or when a parent id names no style, and use the values gathered so far.

On this page