HTML
The html!
macro allows you to write HTML and SVG code declaratively. It is similar to JSX
(an extension to JavaScript which allows you to write HTML-like code inside of JavaScript).
Important notes
- The
html!
macro only accepts a single root HTML node (this obstacle is easily overcome by using fragments or iterators) - An empty
html! {}
invocation is valid and will not render anything - Literals must always be wrapped in quotes as well as braces (i.e.
html! { <p>{"Hello, World"}</p> }
is valid, but nothtml! { <p>Hello, World</p> }
orhtml! { <p>"Hello, World"</p> }
).
The requirement to need braces and quotes was not a deliberate design choice (just in case you're
wondering)! It's needed in order to make parsing the tokens fed into the html!
macro possible.
The html!
macro can cause problems because it makes a lot of recursive calls. This means that it
can exceed the default recursion limit of the compiler. If you encounter a compilation error
(which might say something about "overflow" or "recursion limit reached") adding an attribute like
#![recursion_limit="1024"]
to your crate root should fix the problem.
Tag Structure
Tags inside the html!
macros are heavily inspired by HTML tags. Components, elements, and lists
all use the tag syntax.
Every tag must either either close itself (e.g. <br/>
) or there must be a corresponding closing
tag for each opening tag (e.g. <div></div>
).
- Open - Close
- Invalid
use yew::html;
html! {
<div id="my_div"></div>
};
use yew::html;
html! {
<div id="my_div"> // <- MISSING CLOSE TAG
};
- Self-closing
- Invalid
use yew::html;
html! {
<input id="my_input" />
};
use yew::html;
html! {
<input id="my_input"> // <- MISSING SELF-CLOSE
};
For convenience, elements which usually require a closing tag can be declared using the
self-closing syntax (e.g. html! { <div class="placeholder" /> }
is valid).
Children
Tags become much more powerful once we start to nest them. Tags may have children (which can be other standard HTML tags or other Yew components).
- HTML
- SVG
use yew::html;
html! {
<div>
<div data-key="abc"></div>
<div class="parent">
<span class="child" value="anything"></span>
<label for="first-name">{ "First Name" }</label>
<input type="text" id="first-name" value="placeholder" />
<input type="checkbox" checked=true />
<textarea value="write a story" />
<select name="status">
<option selected=true disabled=false value="">{ "Selected" }</option>
<option selected=false disabled=true value="">{ "Unselected" }</option>
</select>
</div>
</div>
};
use yew::html;
html! {
<svg width="149" height="147" viewBox="0 0 149 147" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M60.5776 13.8268L51.8673 42.6431L77.7475 37.331L60.5776 13.8268Z" fill="#DEB819"/>
<path d="M108.361 94.9937L138.708 90.686L115.342 69.8642" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<g filter="url(#filter0_d)">
<circle cx="75.3326" cy="73.4918" r="55" fill="#FDD630"/>
<circle cx="75.3326" cy="73.4918" r="52.5" stroke="black" stroke-width="5"/>
</g>
<circle cx="71" cy="99" r="5" fill="white" fill-opacity="0.75" stroke="black" stroke-width="3"/>
<defs>
<filter id="filter0_d" x="16.3326" y="18.4918" width="118" height="118" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
</filter>
</defs>
</svg>
};