HTML: New Beginnings

What if HTML didn’t start with documents, but with pixels?

HTML started with documents and how they were connected. Its fundamental objects were text, headings, lists and links.

Tag Description
<title> document title
<h1>, <h2>, .. heading level 1, 2, ..
<p> paragraph
<ul>, <dl> unordered, definition list
<a> anchor, the start or destination of a link

Combined with the internet, this started a revolution.

This article isn’t about the network, though. It’s about HTML itself — and what it might have looked like if it had started somewhere else.

HTML would evolve and add many things. Documents gained images, forms, buttons, canvas, video, and all the other things we now expect from a web page. HTML was no longer just describing documents; it had become a way to describe applications and interfaces.

The original idea remained: HTML describes what things are and how they relate to each other. But what if HTML had started somewhere else? What if it hadn’t started with documents, but with pixels?

What?

Today, pixels are produced by specialized processors: GPUs.

But a GPU has no concept of what those pixels mean. It doesn’t know whether they came from a paragraph, a heading, a button or a video. It works with more fundamental building blocks: geometry, textures, colors, transformations, and operations performed on them.

So what would our HTML look like if, instead of starting with documents, we started with what needs to be drawn?

We would need a small set of elements that covers everything that appears on screen. The most general of these is a path: a sequence of points and curves that can describe essentially any shape. But we use some shapes so often that writing them out as paths every time would be unnecessarily verbose. Lines, rectangles, and ovals give us convenient elements for those common cases.

Text can ultimately be reduced to paths too: each glyph is a shape. But describing text as a collection of paths is hardly convenient. So text gets its own element.

Text is usually grouped into paragraphs. But within a paragraph, different parts of the text may need different properties: a word can be bold or italic, use a different font or color, or even be clickable. So we need a way to express that without affecting the surrounding text. We’ll call such a run of text a span.

And then there is pixel data itself. Images, video frames, and other generated pixel data don’t need to be broken down into shapes. We can put the pixels directly on screen. A texture gives us that capability. It represents a block of pixel data that can be placed, transformed, and composited like any other visual element.

Together, these form our drawing primitives:

Element Description
<path> arbitrary shapes
<line> straight lines
<rect> areas
<oval> ellipses and circles
<text> text
<span> styled text run
<texture> direct access to pixels

With these elements, we can draw anything.

Now we know what to draw, we also need to know how.

How?

A rectangle is an area that can be filled with color, or outlined with a stroke. The color could be a gradient, or blend in a certain way with what’s drawn behind it. This isn’t exclusive to rectangles — these properties apply to almost every drawing primitive.

We call this paint.

A paint describes how an element is rendered: fill or stroke, colors and gradients, stroke properties, blending. It is a separate concept from the shape — the same paint applies to a rectangle, a path or a run of text.

Paint property Description
color a color or a gradient
drawStyle fill, stroke or both
stroke* stroke properties
blendMode how the result combines with what is behind it

We now know what to draw and how to paint it. But where do we put it?

Where?

In modern HTML, this has been solved by CSS: flex and grid layout. We don’t need to reinvent this. Flexbox and grid are great solutions for positioning. We simply attach a layout to each element.

Our elements also need structure. They need to live somewhere, and that structure needs to be nestable.

For this, we introduce a view.

Views provide structure for grouping other elements. They don’t draw anything themselves. In that sense, they are similar to a <div> in HTML.

Element Description
<view> groups elements

Views can also transform everything inside them. They can translate, rotate and scale their content. These transformations are independent of layout.

The layout engine sees the view’s layout geometry, while the renderer sees its transformed coordinate space. Transformations like these are exactly the kind of work GPUs are good at.

Where else?

We now know what to draw, how to paint it, and where to put it. Or do we?

Imagine something as simple as a box with a background color and some text on top. We need a rectangle, and we need text. But we also need to control their positions relative to each other. A layout engine has an answer to this: absolute positioning. But we would be (ab)using the layout engine for something that should be simple and fast.

So what if an element could simply opt out of layout?

And that is exactly what detached elements are. They are the same primitives we already have, but without participating in layout:

Element Description
<d-view> detached groups primitives
<d-text> detached text
<d-rect> detached areas
<d-oval> detached ellipses and circles
<d-line> detached straight lines
<d-path> detached arbitrary shapes
<d-texture> detached textures

Detached elements are still part of the view they live in. They can be translated, rotated and scaled within that view. The only difference is that the layout engine is completely unaware of them.

When?

We know what to draw, how to paint it and where to put it. What we don’t know is when any of it needs to change.

The elements live in a render tree. That tree needs to be constructed, updated and torn down. Properties need to change as application state changes.

This is where SolidJS comes in.

SolidJS does exactly this: it manages the tree and updates the things that actually changed. The result is a direct path from application state to the render tree.

So what would HTML look like if it had started with the pixels?

Six elements, each in a laid-out and a detached variant. A span that lives only inside text. A paint. A view, which may itself be laid out or detached. And a way to say when things change.

That is the whole vocabulary. Its fundamental objects are not documents, but the things we draw.

And it exists.

This is the foundation of SolidRT, the Solid Runtime. It is developed in the open: https://github.com/wellawaretech/solidrt

And if you’re thinking, “Hang on, isn’t this just HTML, SVG and Canvas?” — yes. Pretty much.

We just started from the other end.