Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Built-in HTML Elements

The view! macro maps lowercase HTML tags to gpui element builders. Most elements expand to gpui::div() with appropriate default styling. This page lists every supported tag and its behavior.

Container Elements

All of these expand to gpui::div() with no additional default styling:

| Tag | Notes | | <div>, <span>, <p>, <output> | Generic containers. | | <header>, <footer>, <nav>, <main> | Semantic sectioning. | | <section>, <article>, <aside>, <address> | Semantic sectioning. | | <form> | Form context: on:submit / on:reset + child submit/reset buttons. | | <fieldset>, <legend> | Form containers (pure div aliases). | | <figure>, <figcaption> | Figure containers. | | <pre>, <blockquote>, <q> | Text containers. |

Text Elements

TagDefault styling
<h1>font-size 2.0rem, font-weight 600
<h2>font-size 1.5rem, font-weight 600
<h3>font-size 1.25rem, font-weight 600
<h4>font-size 1.0rem, font-weight 600
<h5>font-size 0.875rem, font-weight 600
<h6>font-size 0.85rem, font-weight 500
<strong>, <b>font-weight: bold
<em>, <i>font-style: italic
<u>text-decoration: underline
<s>, <del>, <strike>text-decoration: line-through
<mark>background: yellow
<small>font-size: 0.875rem
<code>, <kbd>, <samp>, <var>font-family: monospace
<cite>, <abbr>, <dfn>, <bdi>, <bdo>, <time>Plain div (no defaults)

List Elements

TagDefault styling
<ul>flex column
<ol>flex column
<li>plain div
<dl>flex column
<dt>font-weight: bold
<dd>padding-left: 16px

gpui has no list-style; draw numbering or bullets with text prefixes yourself.

TagDefault styling
<a>cursor: pointer, text-color: blue (hsla 220, 100%, 50%)

<a> supports the href attribute (accepted but not navigable in vgui v1 — use on:click for navigation actions).

Button Elements

<button> expands to gpui::div().cursor_pointer() and defaults to tabindex={0} so it is in Tab order. An explicit tabindex overrides that default. Keyboard activation of on:click is handled by gpui.

Media Elements

TagAttributesBehavior
<img>src (required), object_fit, alt, on:load, on:errorgpui::img(src). object_fit accepts fill, contain, cover, scale-down, none. alt is accepted and unused for a11y. on:load/on:error take Fn(&mut App) and fire when the image finishes loading or fails.
<svg>src (required)gpui::svg().path(src)

Void elements

TagBehavior
<br>A 1-line-height empty div.
<hr>Full-width 1px gray divider.
<wbr>Renders nothing (gpui::Empty).

No-op elements

<colgroup> and <col> are accepted (they compile) but render nothing (gpui::Empty). Column widths are controlled per-cell via class or style.

<datalist> renders nothing (gpui::Empty) but registers its id and options in a thread-local map so text inputs with list=<id> can show autocomplete suggestions. It requires an id attribute and accepts options={Vec<String>}. See Input Elements.

<option> and <optgroup> are accepted as standalone tags (they compile as pure <div> aliases) but are not read by <select>. Use the options or groups prop on <select> instead.

Tables

Tables use a flex-based layout — gpui has no native table layout:

TagLayout behavior
<table>flex column
<thead>flex column
<tbody>flex column
<tfoot>flex column
<caption>plain div
<tr>flex row, full width
<td>flex_1 (shares row width equally)
<th>flex_1, bold, centered text

colspan on <td>/<th> is mapped to flex_grow, so a cell with colspan={2} grows 2× relative to colspan=1 cells. rowspan is accepted but has no visual effect.

#![allow(unused)]
fn main() {
view! {
    <table class="w-full">
        <thead>
            <tr class="bg-[#333]">
                <th class="p-2 text-white">{"Name"}</th>
                <th class="p-2 text-white">{"Age"}</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="p-2">{"Alice"}</td>
                <td class="p-2">{"30"}</td>
            </tr>
            <tr>
                <td class="p-2" colspan={2u32}>{"Bob (spanned)"}</td>
            </tr>
        </tbody>
    </table>
}
}

For specific column widths, apply class="w-[200px]" or a style width on individual cells.

Common Attributes

All built-in elements support these attributes:

AttributeSyntaxDescription
stylestyle={css!{...}}CSS-in-Rust styles.
classclass="..."Tailwind utility classes (expanded via tw!).
hoverhover={css!{...}}Styles applied on mouse hover.
activeactive={css!{...}}Styles applied on mouse-down.
focusfocus={css!{...}}Styles applied on keyboard focus.
idid="my-id"Sets the gpui element id.
tabindextabindex={0}≥0 sets tab order; <0 is focusable only.
on:eventon:click={handler}Event handler (see view! macro).
refref={node_ref}Binds a NodeRef handle for imperative ops (focus, scroll, bounds). See Refs.
rolerole="button"Sets ARIA role via __resolve_aria_role.
aria:namearia:label="..."Sets ARIA attribute (aria:label, aria:description, aria:keyshortcuts, aria:selected, aria:expanded, aria:toggled, aria:valuenow/aria:numeric_value, aria:value, aria:placeholder, aria:numeric_value_step).

Elements that have on:click, hover, active, focus, class, tabindex, or ref but no explicit id automatically receive a stable auto-generated id (see Auto IDs).

Radio Group

<radiogroup> wraps child <input type="radio"> elements and enables roving tabindex with arrow-key navigation. It has no attributes — it establishes a scope (via __radiogroup_scope_enter/__radiogroup_scope_exit) that child radio buttons read to coordinate focus and selection. See Input Elements for details.

Form

<form> wraps children in a form context. The on:submit and on:reset attributes take FnMut(&mut App) closures. Child submit/reset buttons auto-invoke the form handler when activated. Pressing Enter in a single-line text input triggers on:submit. See Input Elements for details.