Skip to content

Working with HTML specific helpers

Greg Bowler edited this page Apr 18, 2026 · 1 revision

Beyond the generic DOM interfaces, this library implements a large amount of browser-style HTML behaviour on HTMLElement.

This page is not a catalogue of every element property. Instead, it highlights the pieces that are especially useful in server-side code.

classList

classList behaves as a DOMTokenList, so we can add, remove, replace, and toggle class names in a clean way:

$button = $document->querySelector("button");
$button->classList->add("is-ready");
$button->classList->remove("is-loading");

This is usually clearer than manual string concatenation on the class attribute.

dataset

dataset is supported through DOMStringMap:

$card = $document->querySelector(".card");
$card->dataset->productId = "42";

That becomes data-product-id="42" in the markup.

CamelCase property names are converted to kebab-case data attributes, which makes it pleasant to work with from PHP.

To help with static analysis, a non-standard get and set method is added to DOMStringMap, allowing for the following:

$card = $document->querySelector(".card");
$card->dataset->set("productId", "42");

innerHTML, outerHTML, and innerText

These properties are often the quickest way to make targeted changes:

$panel = $document->querySelector("#panel");
$panel->innerHTML = "<p>Updated content</p>";

For server-side use, the important distinction is this:

  • use innerText when the value is text and should be escaped safely
  • use innerHTML when the value is markup we intend to parse

This matters just as much in PHP as it does in the browser.

innerText also respects [hidden] ancestors when reading text, which makes it closer to the browser's rendered-text behaviour than plain textContent.

Forms, tables, and document conveniences

This repository includes a substantial amount of HTML-specific IDL behaviour, including support around:

  • forms and form controls
  • select boxes and selectedOptions
  • table sections, rows, and cells
  • document shortcuts such as forms, images, links, and scripts

MDN is the right reference for the precise browser semantics:

The practical point for this library is that we can usually write the same kind of code we would expect in browser JavaScript:

$table = $document->querySelector("table");
$row = $table->insertRow();
$row->insertCell()->innerText = "Ada";
$row->insertCell()->innerText = "Admin";

Browser-only properties

Some parts of the DOM specification simply do not make sense on the server. Anything that depends on user interaction, layout, media playback state, browsing context, or browser UI cannot be implemented in PHP.

In those cases, this library throws ClientSideOnlyFunctionalityException.

Examples include behaviour around:

  • file inputs and selected files
  • media playback state
  • iframe browsing contexts
  • style/layout information that depends on a rendering engine

That is intentional. It is better to fail explicitly than to pretend the browser state exists on the server when it does not.

Practical advice

  • Use the browser-shaped helpers when they make code clearer.
  • Prefer innerText or node construction over innerHTML for plain text, to avoid cross-site-scripting attacks.
  • Treat ClientSideOnlyFunctionalityException as a sign that the job belongs in browser JavaScript rather than server PHP.

Next, we will place this library in its most common real-world context: WebEngine and DomTemplate.

Clone this wiki locally