Skip to main content

Style Mappings & Default Styles

Adapters convert the intermediate DocumentElement[] into a specific output format (e.g., DOCX, PDF). One of the most powerful features of html-to-document is that you can fully control how CSS styles are interpreted by those adapters — or provide defaults when HTML styles are missing.


What Are Style Mappings?

A style mapping defines how HTML/CSS styles like font-weight, text-align, or padding should be transformed into document-native properties (e.g., for DOCX: { bold: true } or { spacing: { line: 240 } }).

The built-in DOCX adapter owns these mappings through its adapter-specific config.


Example: Custom Style Mapping for DOCX

For DOCX-specific mapping types, import them from html-to-document-adapter-docx.

import { init } from 'html-to-document';
import { DocxAdapter, DocxStyleMapping } from 'html-to-document-adapter-docx';

const mapping: DocxStyleMapping = {
fontWeight: (value) => ({ bold: value === 'bold' }),
fontStyle: (value) => ({ italics: value === 'italic' }),
color: (value) => ({ color: value }), // use hex or theme color string
};

const converter = init({
adapters: {
register: [
{
format: 'docx',
adapter: DocxAdapter,
config: {
styleMappings: mapping,
},
},
],
},
});

Now, any HTML content like <p style="font-weight: bold">Bold text</p> will be interpreted and rendered as bold in the DOCX output.


When Would You Use This?

  • To override default interpretation of CSS
  • To convert inline styles into well-formed document formatting
  • To add support for new styles like background-color, margin, border, etc.
  • To handle platform-specific styles (e.g., Google Docs HTML quirks)

Default Styles for Adapters

You can define fallback styles for specific element types using adapters.defaultStyles. These are applied when the HTML element does not explicitly define any style.

const converter = init({
adapters: {
defaultStyles: [
{
format: 'docx',
styles: {
heading: { color: 'darkblue', fontSize: 24 },
paragraph: { lineHeight: 1.8 },
'table-cell': { padding: '6px' },
},
},
],
},
});

Each styles object uses the internal ElementType keys, such as:

  • paragraph
  • heading
  • text
  • table-cell
  • list-item
  • etc.

About the Built-in DocxStyleMapper

Internally, the DOCX adapter uses a DocxStyleMapper instance to apply mappings. It includes comprehensive mappings for:

CSS PropertyMapped To (docx)
font-weight{ bold: true }
font-style{ italics: true }
text-align{ alignment: 'center' }
color{ color: '#RRGGBB' }
background-color{ shading: { fill: ... } }
font-size{ size: px × 1.5 }
line-height{ spacing: { line: value×240 }}
margin/padding{ spacing, indent, margins }
border{ borders or outline }

You can override or extend this behavior by adding your own DocxStyleMapping.

Each style mapping function receives two arguments:

(key: keyof CSS.Properties, value: string | number, el: DocumentElement) =>
object;

This allows for context-aware styling, meaning you can vary the output depending on the element type.

For example, here’s how the built-in margin mapper behaves differently depending on the element:

margin: (v: string, el: DocumentElement) => {
const raw = String(v).trim();
const px = parseFloat(raw);
if (isNaN(px)) return {};

const floatDir = (el.styles as { float: string })?.float;
if (el.type === 'image' && (floatDir === 'left' || floatDir === 'right')) {
const dist = pixelsToTwips(px);
return {
floating: {
wrap: {
margins: { distL: dist, distR: dist, distT: dist, distB: dist },
},
},
};
}

if (el.type === 'table') return {};

if (el.type === 'table-cell') {
const space = pixelsToTwips(px);
return {
margins: { top: space, bottom: space, left: space, right: space },
};
}

const before = px * 20;
const after = px * 20;
const horiz = pixelsToTwips(px);
return {
spacing: { before, after },
indent: { left: horiz, right: horiz },
};
};

This flexibility makes DocxStyleMapper a powerful mechanism for fine-tuning how layout and design decisions translate into DOCX output.


Advanced: Replace or Extend DocxStyleMapper

You can also instantiate a DocxStyleMapper manually and pass it into the DOCX adapter config:

import { init } from 'html-to-document';
import { DocxAdapter, DocxStyleMapper } from 'html-to-document-adapter-docx';

const customMapper = new DocxStyleMapper();
customMapper.addMapping({
letterSpacing: (v) => ({ characterSpacing: parseFloat(v) * 10 }),
});

const converter = init({
adapters: {
register: [
{
format: 'docx',
adapter: DocxAdapter,
config: { styleMapper: customMapper },
},
],
},
});

Summary

FeaturePurpose
config.styleMappingsMaps CSS styles → DOCX properties
defaultStylesApplies fallback styles for missing styles
DocxStyleMapperBuilt-in logic engine for DOCX style mapping
.addMapping()Extend or override the behavior dynamically

Want more detail? Explore the DocxStyleMapper source in the DOCX adapter package for complete coverage.