HTML Compatibility Layer

eepp includes an HTML/CSS compatibility layer for rendering document-like content inside the UI system.

This layer is used primarily by:

  • UIWebView;

  • UIMarkdownView;

  • HTML-derived widgets such as UIRichText, UITextSpan, HTML tables, forms, images, and inputs.

It is intentionally distinct from normal eepp application UI authoring.

For ordinary application UI, use native eepp layouts such as vbox, hbox, UIRelativeLayout, UIGridLayout, UIFlowLayout, UISplitter, and UITabWidget. See `ui_authoring.md`, `ui_layout_reference.md`, and `ui_css_for_applications.md`.

This document describes the HTML compatibility model, the browser-style layout concepts it implements, and the important places where it differs from a full browser engine.

1. The most important boundary

eepp has two related but different layout worlds.

Native application UI

Normal eepp application interfaces use:

UILinearLayout / vbox / hbox
UIRelativeLayout
UIGridLayout
UIFlowLayout
UISplitter
UITabWidget
UIScrollView
layout-width
layout-height
layout-weight
layout-gravity

CSS can configure those widgets, but CSS does not replace their native layout algorithms.

HTML compatibility UI

HTML-derived widgets can instead participate in browser-style formatting contexts:

block
inline
inline-block
list-item

flex
inline-flex

grid
inline-grid

table

float / clear
absolute / fixed / sticky positioning

The same CSS parser and property system are shared by both worlds, but the layout semantics depend on the widget type and formatting context.

Do not use browser layout properties merely because the stylesheet parser accepts them.

2. <tt>UIWebView</tt> is the full document host

UIWebView is the main host for HTML documents.

It is implemented as a UIScrollView containing an embedded UISceneNode dedicated to the loaded document.

Conceptually:

UIWebView
    scroll viewport
        embedded UISceneNode
            document container
                html
                    head
                    body

The embedded scene gives the document its own:

  • widget tree;

  • stylesheet state;

  • document URI;

  • resource loading context;

  • font-face registrations;

  • navigation handling;

  • text-selection context.

Use:

auto* webView = UIWebView::New();
webView->loadURI( URI( "file:///path/document.html" ) );

or an HTTP/HTTPS URI.

UIWebView supports navigation history through:

goHistoryBack();
goHistoryForward();
refresh();
reload();
canGoBack();
canGoForward();

It also exposes navigation events for started, completed, and failed loads.

3. <tt>UIMarkdownView</tt> uses the HTML compatibility layer too

UIMarkdownView converts Markdown to XHTML and then loads the resulting body children as eepp HTML widgets.

Its pipeline is approximately:

Markdown
    -> Markdown::toXHTML()
    -> HTMLFormatter::HTMLBodyToXML()
    -> eepp HTML widgets

Unlike UIWebView, UIMarkdownView is not a standalone browsing context with document navigation and a dedicated embedded scene.

It is a native vertical layout hosting HTML-derived content and loads the basic HTML default styles needed for Markdown rendering.

Use UIMarkdownView for rendered Markdown content, not as a general browser replacement.

4. HTML is parsed before eepp widgets are created

UIWebView does not feed arbitrary HTML directly into the normal XML layout parser.

HTML is first parsed with Gumbo, then serialized into strict XML through Tools::HTMLFormatter.

This stage handles browser-style HTML parsing details such as:

  • malformed/non-XML HTML syntax;

  • omitted closing syntax where HTML permits it;

  • HTML void elements;

  • boolean attributes;

  • normalized tag names.

The resulting strict XML is then loaded through eepp’s widget creation system.

This architecture is important:

HTML source
    -> Gumbo HTML tree
    -> strict XML representation
    -> UIWidgetCreator
    -> eepp widget tree

The final rendered document is therefore still made of eepp widgets.

5. Only registered HTML elements are materialized

HTML compatibility is not based on a generic DOM element class that accepts every possible tag.

HTML tags are mapped through UIWidgetCreator.

Currently registered HTML elements include the major supported groups:

document:
    html
    head
    body

text and inline:
    a
    label
    span
    em
    b
    strong
    small
    i
    cite
    kbd
    sub
    sup
    time
    u
    ins
    s
    strike
    del
    font
    code
    abbr
    tt
    mark

blocks:
    div
    p
    blockquote
    h1 ... h6
    br
    hr
    pre

lists:
    ul
    ol
    dl
    dt
    dd
    li

semantic containers:
    header
    article
    figure
    figcaption
    footer
    main
    section
    nav
    aside
    center

interactive/details:
    details
    summary

media/replaced content:
    picture
    img
    svg

forms:
    form
    input
    textarea
    button

tables:
    table
    thead
    tbody
    tfoot
    tr
    th
    td

The exact set is defined in:

src/eepp/ui/uiwidgetcreator.cpp

An unregistered tag does not automatically become a transparent generic HTML container.

Applications can register additional widget creators if they need custom tags.

6. This is not a JavaScript browser runtime

<script> nodes are ignored by the UI layout loader.

The HTML compatibility layer should therefore be understood as:

HTML parsing
CSS styling
document layout
native interaction for supported elements
navigation/resource loading

not as:

HTML + DOM + JavaScript browser engine

There is no browser JavaScript environment or general DOM scripting model implied by UIWebView.

If application logic is required, implement it through eepp/C++ behavior.

7. Default HTML styles

eepp provides built-in HTML default styles.

The basic defaults cover conventional document presentation for elements such as:

body
h1 ... h6
p
pre
blockquote
hr
ul / ol / dl
b / strong
i / em
small
u / ins
s / strike / del
code / kbd
sub / sup
mark
a
summary

UIWebView also loads document-oriented defaults for controls and document colors, including inputs, textareas, buttons, checkboxes, and radio buttons.

These defaults are inserted with lower selector specificity so author styles can override them.

UIMarkdownView loads the basic HTML defaults rather than the complete standalone-document defaults.

The source of the defaults is:

src/eepp/ui/uiwidgetcreator.cpp

8. HTML attributes and native XML attributes have different cascade behavior

This is an important distinction.

For normal native eepp widgets, XML attributes are treated as inline-style properties with inline specificity.

For widgets marked as HTML elements, ordinary HTML attributes are loaded with low specificity so CSS can override them in the expected HTML-like way.

For example:

<img width="200" class="preview">

can still be overridden by author CSS:

.preview {
    width: 100px;
}

The explicit HTML style attribute remains inline style:

<img style="width: 200px">

and therefore has inline specificity.

This distinction exists specifically so HTML presentation attributes do not behave like native eepp XML configuration.

9. Attribute selectors are supported

The selector engine supports attribute selectors.

For HTML widgets, data-* attributes are stored as HTML data properties and can participate in attribute matching.

Examples:

input[type="text"] {
    ...
}

input[type="password"] {
    ...
}

[data-state="warning"] {
    ...
}

Supported attribute operators include:

[attr]
[attr=value]
[attr~=value]
[attr|=value]
[attr^=value]
[attr$=value]
[attr*=value]

For native widgets, attribute selectors operate through properties exposed by the widget property system.

For HTML widgets, data-* attributes are additionally available directly.

10. Block and inline formatting

The HTML layer implements separate formatting behavior for:

display: block;
display: inline;
display: inline-block;
display: list-item;
display: none;

Block and inline content is laid out through the HTML layouter system rather than native UILinearLayout.

Inline text and inline widgets are integrated into RichText line construction.

This includes:

  • text runs;

  • line wrapping;

  • inline boxes;

  • atomic inline boxes;

  • inline replaced elements;

  • baselines;

  • line-height;

  • vertical alignment;

  • inline background/text painting.

Block elements participate in vertical document flow and intrinsic sizing.

display: none removes the element from layout and hit testing.

11. Flexbox

HTML widgets support:

display: flex;
display: inline-flex;

with a dedicated FlexLayouter.

The currently implemented flex state includes:

flex-direction
flex-wrap
justify-content
align-items
align-content
align-self

flex-grow
flex-shrink
flex-basis
order

row-gap
column-gap
gap

Supported direction values include:

row
row-reverse
column
column-reverse

Wrapping includes:

nowrap
wrap
wrap-reverse

The layouter handles multiple flex lines, grow/shrink distribution, gaps, alignment, auto margins, baseline alignment, order, percentage flex bases, intrinsic measurement, and stretching.

Children of flex containers are blockified for layout, including inline children.

Important distinction

Flexbox belongs to the HTML formatting layer.

Do not replace a normal application <hbox> with:

display: flex;

unless the subtree is intentionally HTML content.

For normal application UI, UILinearLayout remains the canonical row/column layout.

12. CSS Grid

HTML widgets support:

display: grid;
display: inline-grid;

through GridLayouter.

The current grid model supports properties including:

grid-template-rows
grid-template-columns
grid-template-areas

grid-auto-rows
grid-auto-columns
grid-auto-flow

grid-row-start
grid-row-end
grid-column-start
grid-column-end

grid-row
grid-column
grid-area

justify-items
justify-self
align-items
align-self

row-gap
column-gap
gap

order

The track model supports:

fixed lengths
percentages
fr tracks
auto
min-content
max-content
fit-content(...)
minmax(...)
repeat(...)
auto-fill
auto-fit
named lines
template areas
implicit tracks

Grid items support definite placement, spans, automatic placement, dense auto-flow, intrinsic track sizing, and alignment.

Native <tt>UIGridLayout</tt> is unrelated

Do not confuse:

UIGridLayout

with:

display: grid

UIGridLayout is a native eepp repeated-cell layout.

CSS Grid is implemented by the HTML compatibility layer.

They have different APIs, sizing rules, and intended uses.

13. Tables

HTML tables use dedicated HTML widgets and TableLayouter.

Supported structural elements include:

table
thead
tbody
tfoot
tr
th
td

The table implementation includes:

intrinsic column sizing
table-layout: auto
table-layout: fixed
cell padding
cell spacing
colspan
row/cell sizing

Table layout is not implemented by native UIGridLayout.

If the source content is HTML tabular content, use HTML table semantics.

If the application is building an interactive application data view, prefer native widgets such as UITableView or UITreeView.

14. Floats and <tt>clear</tt>

HTML widgets support:

float: left;
float: right;
float: none;

clear: left;
clear: right;
clear: both;

Floats participate in block/inline document formatting and create text exclusions so following inline content can wrap around them.

Floated inline elements are blockified for layout.

Floats also establish a block formatting context where applicable.

These semantics exist for document layout and should not be used as a general native application placement system.

15. Positioned layout

The HTML property system recognizes:

position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;

Absolute positioning

absolute elements are removed from normal flow.

The containing block is selected from the nearest positioned HTML ancestor, with root fallback.

Insets are supported:

top
right
bottom
left

including percentage values where the containing block has the required definite size.

Opposing insets can determine the used size of an auto-sized positioned box.

Auto margins are also handled in the positioned constraint equation.

Fixed positioning

fixed elements are positioned against the relevant scroll/document viewport rather than ordinary normal flow and are updated when scrolling changes.

Sticky positioning

sticky participates in normal flow and is adjusted relative to a scroll viewport while respecting the containing block.

Current sticky handling focuses on vertical top/bottom constraints.

Relative positioning

relative currently participates in the positioned-element model, including containing-block and stacking behavior.

Do not assume complete browser parity for relative top/right/bottom/left displacement; the current implementation’s explicit inset positioning logic is primarily implemented for absolute/fixed and sticky positioning.

16. <tt>z-index</tt> and paint order

The HTML layer has CSS-aware paint ordering rather than relying only on raw widget child order.

The current model distinguishes categories broadly corresponding to the supported CSS stacking subset:

negative positioned/z-index content
normal-flow content
floats
positioned auto/zero content
positive positioned/z-index content

z-index applies to positioned elements and to flex/grid items where supported.

The implementation supports stacking groups for:

fixed/sticky elements
positioned elements with applicable z-index
flex/grid items with applicable z-index

This is intentionally a supported subset of browser stacking-context behavior, not a claim of full CSS Appendix E parity.

17. CSS sizing and the box model

HTML widgets support browser-style CSS sizing properties:

width
height
min-width
min-height
max-width
max-height

margin
padding
border
box-sizing

box-sizing supports:

content-box
border-box

For HTML widgets, width and height are interpreted through the CSS box model rather than merely as raw native widget dimensions.

This is one reason the HTML compatibility layer should remain conceptually separate from normal native application layout.

18. Percentage sizing uses containing blocks

HTML percentage sizing is resolved against CSS containing-block dimensions.

This applies to relevant properties such as:

width
height
margin
padding
position offsets
flex-basis
grid tracks

The implementation also distinguishes cases where percentage height cannot resolve because the containing block does not have a definite height.

In those cases, the HTML layer avoids treating the percentage as an ordinary fixed native dimension.

The root document uses the document viewport as the initial containing block for relevant root/body calculations.

19. Intrinsic sizing

The HTML layout layer has explicit intrinsic sizing support.

Concepts used internally include:

minimum intrinsic width
maximum intrinsic width
min-content
max-content
fit-content
shrink-to-fit

These are used by block, flex, grid, table, replaced-element, and out-of-flow layout.

This is different from native eepp WrapContent.

They may eventually produce similar-looking results, but they are not the same algorithm.

Do not explain HTML min-content or max-content in terms of native SizePolicy.

20. Auto margins

HTML formatting contexts implement context-specific auto-margin behavior.

Examples include:

  • horizontal centering of normal-flow blocks;

  • free-space absorption in flex layouts;

  • item alignment behavior in grid/flex;

  • auto margins in positioned constraint equations.

This is distinct from ordinary native-layout auto-margin handling.

The HTML layer resolves used margins for the current formatting role without treating every margin: auto as the same generic layout operation.

21. Overflow is only partially browser-equivalent

The CSS property is recognized:

overflow: visible;
overflow: hidden;
overflow: auto;
overflow: scroll;

For HTML widgets, non- visible overflow also establishes a block formatting context.

However, the underlying native widget behavior currently maps:

hidden
auto
scroll

to clipping of the widget content box.

It does not create an independent browser-like scroll container for every arbitrary HTML element.

UIWebView itself provides document scrolling through its native UIScrollView.

Also note that overflow-x and overflow-y currently alias the same overflow property; they are not independent axes yet.

This is an important compatibility limitation.

22. <tt>visibility</tt> is not fully browser-equivalent

HTML widgets recognize:

visibility: visible;
visibility: hidden;
visibility: collapse;

The current implementation maps hidden to native widget visibility.

As a result, visibility: hidden does not currently guarantee the browser behavior of preserving the element’s normal-flow geometry while suppressing painting.

Flex layout has specific handling for visibility: collapse, but this should not be interpreted as complete visibility parity across every formatting context.

When precise browser-compatible visibility geometry matters, verify the current behavior rather than assuming browser semantics.

23. Text formatting and inheritance

HTML text is rendered through UIRichText, UITextSpan, and UITextNode.

Supported text-oriented CSS includes concepts such as:

font-family
font-size
font-style
font-weight
color
text-decoration
text-align
text-indent
text-transform
line-height
white-space
white-space-collapse
tab-size
text shadow/stroke

Relevant properties participate in eepp’s current inheritance system.

HTML inline elements therefore behave much more like document text than ordinary independent native application widgets.

The exact supported property set is documented in `css_specification.md`.

24. Text selection is document-wide

UIWebView and UIMarkdownView both provide a UITextSelectionController.

Selection can cross individual rich-text/span widget boundaries rather than being limited to a single widget.

HTML widgets support:

user-select: auto;
user-select: text;
user-select: none;
user-select: contain;
user-select: all;

-webkit-user-select is accepted as an alias.

The default used behavior is text-selectable unless inherited none or all semantics change it.

This is one of the important differences between document content and ordinary isolated text widgets.

26. Forms

The compatibility layer includes basic form support.

Supported form-oriented widgets currently include:

form
input
textarea
button
label

UIHTMLInput hosts native eepp controls internally.

Recognized input types include:

button
checkbox
color
date
datetime-local
email
file
hidden
image
month
number
password
radio
range
reset
search
submit
tel
text
time
url
week

Not every type has a specialized native implementation. Unsupported/specialized types fall back to the generic text-input implementation unless explicitly mapped otherwise.

Current explicit native mappings include:

button / submit / reset -> UIPushButton
checkbox                -> UICheckBox
hidden                  -> no visible child
number                  -> UISpinBox
password                -> password text input
radio                   -> UIRadioButton
other text-like types   -> UIHTMLTextInput

textarea uses a UITextEdit -based implementation with rows and cols intrinsic sizing.

Forms collect named control values and can submit navigation requests.

Supported submission encodings include:

application/x-www-form-urlencoded
multipart/form-data
text/plain

GET and POST submission paths are implemented.

27. Labels

<label for="..."> is interactive.

The label resolves the referenced widget and can activate supported controls such as checkboxes and radio buttons.

Keyboard activation is also supported.

This behavior is implemented natively rather than through JavaScript.

28. Images and SVG

HTML images use UIHTMLImage.

They participate as replaced elements with intrinsic sizing and CSS width/height behavior.

<svg> is backed by UISvg marked as an HTML element so it can participate in HTML sizing/layout.

Resource URLs can be:

file URLs
HTTP/HTTPS URLs
data URLs where supported
eepp resource locators

Relative document/style resources are resolved against the relevant document or stylesheet base URI.

29. Stylesheets and resource loading

HTML documents can contain:

<style>
...
</style>

and stylesheet links:

<link rel="stylesheet" href="...">

UIWebView can load local and HTTP/HTTPS stylesheets.

Relative stylesheet resource URLs are resolved against the stylesheet/document base URI when one is available.

Supported stylesheet at-rules include those documented in `css_specification.md`, including:

@import
@media
@font-face
@keyframes

@font-face can load local, data-backed, and HTTP/HTTPS font resources through the document scene.

30. Media queries

The same media-query engine used elsewhere in eepp is available to HTML document styles.

Supported features are documented in `css_specification.md`.

Document layout should still rely primarily on normal CSS layout mechanisms such as:

block flow
flex wrapping
grid tracks
intrinsic sizing

rather than reproducing layout entirely with breakpoint-specific absolute dimensions.

31. HTML visibility and document extent inside <tt>UIWebView</tt>

UIWebView maintains document viewport and content extent separately.

The document scene is updated when:

  • the web view changes size;

  • scrollbars appear/disappear;

  • HTML layout changes;

  • resources load and alter geometry;

  • viewport-dependent percentages need recomputation.

The root html and body boxes are synchronized with the document viewport while still allowing content to grow beyond it.

Out-of-flow content can contribute to the final scrollable document extent when appropriate.

Fixed-position content is treated separately from normal scrollable document extent.

32. Root <tt>html</tt> / <tt>body</tt> behavior is special

The root document boxes have browser-oriented special handling.

body maintains a minimum height based on:

viewport height
its local min-height
document content extent

The root html box is kept at least large enough to cover the document viewport/content.

The body’s background may propagate to the root HTML element when the root background is otherwise transparent.

These rules should not be inferred from ordinary native UILayout behavior.

33. Paint order and hit testing follow the HTML layer

HTML positioned/floating content can be painted in an order different from raw widget child order.

Hit testing follows the corresponding HTML paint traversal when required.

This matters for:

z-index
positioned descendants
floats
overlapping HTML content
flex/grid order

Do not debug overlapping HTML content by looking only at the native child insertion order.

Use the actual HTML layout/paint state.

34. Structural CSS selectors can react to document structure

The selector engine supports structural selectors such as:

:first-child
:last-child
:nth-child(...)
:nth-last-child(...)
:first-of-type
:last-of-type
:nth-of-type(...)
:nth-last-of-type(...)
:only-child
:only-of-type
:empty
:not(...)

Structural and relationship-dependent selectors are treated as volatile where needed so relevant widgets can be restyled when structure/state changes.

This is especially important for HTML-like document styling.

35. CSS state rollback still uses eepp’s common style engine

HTML widgets share the same UIStyle implementation as native widgets.

That means the current limitation around properties that stop matching a pseudo-class/volatile selector also applies to HTML content.

eepp currently preserves prior values through a best-effort stateless/current-value fallback rather than a complete browser-style computed-cascade rollback model.

36. Compatibility does not mean complete browser parity

The HTML layer intentionally implements a useful subset of browser layout and interaction behavior.

It should not be described as a fully compliant browser engine.

Examples of known boundaries include:

no JavaScript runtime
only registered HTML elements are materialized
overflow does not create arbitrary per-element scroll containers
overflow-x / overflow-y are not independent yet
visibility semantics are not fully browser-equivalent
relative positioning should not be assumed to implement every browser offset behavior
stacking/paint order is a supported subset
form controls map onto native eepp widgets
CSS state rollback is not a complete computed-style rollback model

Other browser features should be considered supported only when they are implemented and tested in eepp.

When compatibility behavior matters, the implementation and HTML-specific unit tests are the source of truth.

37. Where to look in the source

The main implementation is concentrated in:

HTML host / navigation:
    include/eepp/ui/uiwebview.hpp
    src/eepp/ui/uiwebview.cpp

HTML widget semantics:
    include/eepp/ui/uihtmlwidget.hpp
    src/eepp/ui/uihtmlwidget.cpp

HTML parsing:
    include/eepp/ui/tools/htmlformatter.hpp
    src/eepp/ui/tools/htmlformatter.cpp

formatting contexts:
    src/eepp/ui/blocklayouter.cpp
    src/eepp/ui/inlinelayouter.cpp
    src/eepp/ui/flexlayouter.cpp
    src/eepp/ui/gridlayouter.cpp
    src/eepp/ui/tablelayouter.cpp

text:
    src/eepp/ui/uirichtext.cpp
    src/eepp/ui/uitextspan.cpp

HTML widgets:
    src/eepp/ui/uihtmlimage.cpp
    src/eepp/ui/uihtmlinput.cpp
    src/eepp/ui/uihtmltextarea.cpp
    src/eepp/ui/uihtmlform.cpp
    src/eepp/ui/uihtmltable.cpp
    src/eepp/ui/uihtmldetails.cpp
    src/eepp/ui/uihtmllistitem.cpp

Markdown:
    src/eepp/ui/uimarkdownview.cpp

HTML element registration/default CSS:
    src/eepp/ui/uiwidgetcreator.cpp

The most useful tests are under:

src/tests/unit_tests/uihtml_tests.cpp
src/tests/unit_tests/uihtml_flex_test.cpp
src/tests/unit_tests/uihtml_grid_test.cpp
src/tests/unit_tests/uihtml_float_tests.cpp
src/tests/unit_tests/uihtml_position_tests.cpp
src/tests/unit_tests/uihtmlform_tests.cpp
src/tests/unit_tests/uiwebview_tests.cpp