# How to Handle Nested HTML Elements in html-to-pdfmake: A Complete Guide

> Learn how to handle nested HTML elements in html-to-pdfmake. This guide explains the library's recursive DOM traversal for converting nodes into text or stacks. Optimize your PDF generation.

- Repository: [Aymeric/html-to-pdfmake](https://github.com/aymkdn/html-to-pdfmake)
- Tags: how-to-guide
- Published: 2026-02-26

---

**The `html-to-pdfmake` library handles nested HTML elements by recursively traversing the DOM tree in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js), converting each node into either a `text` object or a `stack` array depending on whether mixed content is detected.**

The `aymkdn/html-to-pdfmake` library transforms HTML strings into pdfmake document definitions. When working with complex documents containing nested lists, tables within tables, or mixed inline and block elements, understanding how the library processes hierarchy is essential for generating correct PDF output.

## Understanding the Recursive Parsing Engine

The core mechanism for handling nested HTML resides in the `parseElement` method located at [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) (line 41). This function implements a depth-first traversal of the DOM tree created by `DOMParser`.

When you call `htmlToPdfMake(htmlString)`, the library first instantiates a `DOMParser` at line 21 to parse the string into a document object. The root element is then passed to `parseElement(element, [])`, which initiates the recursive walk.

Each invocation of `parseElement` processes the current node and then iterates over `element.childNodes` using `[].forEach.call` at line 89. Child nodes trigger recursive calls to `parseElement`, building a tree of pdfmake objects that mirrors the original HTML structure.

## How Nested Elements Become pdfmake Stacks

The library distinguishes between simple text nodes and complex nested structures using the `searchForStack` method at [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) (line 237). This determination controls whether a node renders as a `text` entry or a `stack` (array of mixed objects).

**Plain text nodes** become `{text: "content"}` objects. **Mixed content**—such as a `<p>` tag containing both text and an `<img>`—becomes a **stack**: `{stack: [{text: "..."}, {image: "..."}]}`.

The `searchForStack` function analyzes the processed children to detect heterogeneous content types. When it identifies mixed inline and block elements, it signals the parent to wrap children in a stack array, preserving the document order and structure required by pdfmake.

## Practical Examples of Handling Nested HTML

### Nested Lists

When converting nested `<ul>` or `<ol>` structures, `parseElement` processes each `<li>` and recursively handles any child lists found within.

```javascript
const htmlToPdfMake = require('html-to-pdfmake');

const html = `
  <ul>
    <li>Item 1
      <ul>
        <li>Sub-item A</li>
        <li>Sub-item B</li>
      </ul>
    </li>
    <li>Item 2</li>
  </ul>
`;

const pdfDef = htmlToPdfMake(html);
console.log(JSON.stringify(pdfDef, null, 2));

```

The output produces a nested structure where the inner `<ul>` is automatically wrapped in a `stack` because it appears after regular text within the same `<li>`:

```json
{
  "ul": [
    {
      "stack": [
        {"text":"Item 1"},
        {
          "ul": [
            {"text":"Sub-item A"},
            {"text":"Sub-item B"}
          ]
        }
      ]
    },
    {"text":"Item 2"}
  ]
}

```

### Mixed Inline and Block Elements

When a paragraph contains both formatted text and block-level elements like images, `searchForStack` ensures proper array wrapping.

```javascript
const html = `
  <p>
    This is <strong>bold</strong> and an image:
    <img src="logo.png" width="50" />
  </p>
`;

const pdfDef = htmlToPdfMake(html);

```

The library detects the mixture of text nodes and the image element, returning a stack that preserves the content order:

```json
{
  "stack": [
    {"text":"This is "},
    {"text":{"bold":true,"text":"bold"}},
    {"text":" and an image:"},
    {"image":"logo.png"}
  ]
}

```

### Deeply Nested Tables

Tables containing other tables are handled through recursive calls where each cell's content is processed independently.

```javascript
const html = `
  <table>
    <tr><td>
      <table><tr><td>Inner</td></tr></table>
    </td></tr>
  </table>
`;

const pdfDef = htmlToPdfMake(html);

```

The outer table's cell receives a nested table object (`{table: {body: …}}`) because the recursive `parseElement` call returns a complete pdfmake table element, which the parent cell inserts into its body array.

## Style Inheritance in Nested Structures

The `applyStyle` method at [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) (line 555) handles CSS inheritance by merging styles from all ancestor elements. As `parseElement` traverses upward through the DOM tree, it accumulates parent styles and classes, applying them to child nodes before returning the final object.

This ensures that a `<span>` inside a `<div class="highlight">` receives the highlight styling, and nested `<strong>` tags within lists maintain their bold formatting while inheriting list-specific margins or colors from parent `<ul>` elements.

## Summary

- **Recursive parsing** via `parseElement` in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) is the core mechanism for handling nested HTML elements.
- The library automatically chooses between **`text`** and **`stack`** representations using `searchForStack` to accommodate mixed content.
- **Style inheritance** is managed by `applyStyle`, which merges ancestor CSS classes and inline styles into child nodes.
- Complex structures like nested lists, tables within tables, and mixed inline/block content are preserved accurately through depth-first DOM traversal.

## Frequently Asked Questions

### How does html-to-pdfmake handle deeply nested lists?

The library processes each `<li>` element recursively, detecting when a list item contains both text and child lists through the `searchForStack` method. When mixed content is found, it wraps the elements in a `stack` array, ensuring the nested structure renders correctly in the final PDF while maintaining proper indentation and hierarchy.

### What happens when inline and block elements are mixed in html-to-pdfmake?

When `parseElement` encounters a parent node containing both text nodes and block-level elements like images, the `searchForStack` function identifies this heterogeneous content and signals the parent to return a `stack` array rather than a simple text object. This preserves the sequential order of inline text and block elements in the generated pdfmake definition.

### Does html-to-pdfmake support nested tables?

Yes, nested tables are fully supported through recursive processing. When `parseElement` encounters a `<table>` inside a `<td>`, it processes the inner table completely and returns a table object, which the parent cell then inserts into its body array. This allows for complex table layouts with sub-tables inside individual cells.

### How are CSS styles inherited in nested HTML elements?

Style inheritance is handled by the `applyStyle` method at line 555 of [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js), which merges styles and classes from all ancestor elements before returning the final node object. As the recursive parser traverses the DOM tree, it accumulates parent styling information, ensuring that child elements inherit font families, colors, and other CSS properties from their containing elements while allowing specific overrides.