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.
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