mirror of https://github.com/yewstack/yew
223 lines
6.4 KiB
Plaintext
223 lines
6.4 KiB
Plaintext
---
|
|
title: 'HTML'
|
|
sidebar_label: Introduction
|
|
description: 'The procedural macro for generating HTML and SVG'
|
|
slug: /concepts/html
|
|
---
|
|
|
|
import Tabs from '@theme/Tabs'
|
|
import TabItem from '@theme/TabItem'
|
|
|
|
The `html!` macro allows you to write HTML and SVG code declaratively. It is similar to JSX
|
|
(an extension to JavaScript that allows you to write HTML-like code inside of JavaScript).
|
|
|
|
**Important notes**
|
|
|
|
1. The `html!` macro only accepts one root html node (you can counteract this by using
|
|
[fragments](./fragments.mdx) or [iterators](./../html/lists.mdx))
|
|
2. An empty `html! {}` invocation is valid and will not render anything
|
|
3. Literals must always be quoted and wrapped in braces: `html! { <p>{ "Hello, World" }</p> }`
|
|
4. The `html!` macro will make all tag names lowercase. To use upper case characters (which are required for some SVG elements) use [dynamic tag names](concepts/html/elements.mdx#dynamic-tag-names): `html! { <@{"myTag"}></@> }`
|
|
|
|
:::note
|
|
The `html!` macro can reach the default recursion limit of the compiler. If you encounter compilation errors,
|
|
add an attribute like `#![recursion_limit="1024"]` in the crate root to overcome the problem.
|
|
:::
|
|
|
|
## Tag Structure
|
|
|
|
Tags are based on HTML tags. Components, Elements, and Lists are all based on this tag syntax.
|
|
|
|
Tags must either self-close `<... />` or have a corresponding end tag for each start tag.
|
|
|
|
<Tabs>
|
|
<TabItem value="Open - Close" label="Open - Close" default>
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
html! {
|
|
<div id="my_div"></div>
|
|
};
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="Invalid" label="Invalid">
|
|
|
|
```rust ,compile_fail
|
|
use yew::prelude::*;
|
|
|
|
html! {
|
|
<div id="my_div"> // <- MISSING CLOSE TAG
|
|
};
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
<Tabs>
|
|
<TabItem value="Self-closing" label="Self-closing">
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
html! {
|
|
<input id="my_input" />
|
|
};
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="Invalid" label="Invalid">
|
|
|
|
```rust ,compile_fail
|
|
use yew::prelude::*;
|
|
|
|
html! {
|
|
<input id="my_input"> // <- MISSING SELF-CLOSE
|
|
};
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
:::tip
|
|
For convenience, elements which _usually_ require a closing tag are **allowed** to self-close. For example, writing `html! { <div class="placeholder" /> }` is valid.
|
|
:::
|
|
|
|
## Children
|
|
|
|
Create complex nested HTML and SVG layouts with ease:
|
|
|
|
<Tabs>
|
|
<TabItem value="HTML" label="HTML">
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
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>
|
|
};
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="SVG" label="SVG">
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
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>
|
|
};
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
## Lints
|
|
|
|
If you compile Yew using a nightly version of the Rust compiler, the macro will warn you about some
|
|
common pitfalls that you might run into. Of course, you may need to use the stable compiler (e.g.
|
|
your organization might have a policy mandating it) for release builds, but even if you're using a
|
|
stable toolchain, running `cargo +nightly check` might flag some ways that you could improve your
|
|
HTML code.
|
|
|
|
At the moment the lints are mostly accessibility-related. If you have ideas for lints, please feel
|
|
free to [chime in on this issue](https://github.com/yewstack/yew/issues/1334).
|
|
|
|
## Specifying attributes and properties
|
|
|
|
Attributes are set on elements in the same way as in normal HTML:
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
let value = "something";
|
|
html! { <div attribute={value} /> };
|
|
```
|
|
|
|
Properties are specified with `~` before the element name:
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
html! { <my-element ~property="abc" /> };
|
|
```
|
|
|
|
:::tip
|
|
|
|
The braces around the value can be ommited if the value is a literal.
|
|
|
|
:::
|
|
|
|
:::note What classifies as a literal
|
|
|
|
Literals are all valid [literal expressions](https://doc.rust-lang.org/reference/expressions/literal-expr.html)
|
|
in Rust. Note that [negative numbers are **not** literals](https://users.rust-lang.org/t/why-are-negative-value-literals-expressions/43333)
|
|
and thus must be encosed in curly-braces `{-6}`
|
|
|
|
:::
|
|
|
|
:::note Component properties
|
|
Component properites are passed as Rust objects and are different from the element attributes/properties described here.
|
|
Read more about them at [Component Properties](../function-components/properties.mdx)
|
|
:::
|
|
|
|
### Special properties
|
|
|
|
There are special properties which don't directly influence the DOM but instead act as instructions to Yew's virtual DOM.
|
|
Currently, there are two such special props: `ref` and `key`.
|
|
|
|
`ref` allows you to access and manipulate the underlying DOM node directly. See [Refs](../function-components/node-refs.mdx) for more details.
|
|
|
|
`key` on the other hand gives an element a unique identifier which Yew can use for optimization purposes.
|
|
|
|
:::info
|
|
Read more at [Lists](./html/lists)
|
|
:::
|
|
|
|
## Conditional Rendering
|
|
|
|
Markup can be rendered conditionally by using Rust's conditional structures. ' +
|
|
'Currently only `if` and `if let` are supported.
|
|
|
|
```rust
|
|
use yew::prelude::*;
|
|
|
|
html! {
|
|
if true {
|
|
<p>{ "True case" }</p>
|
|
}
|
|
};
|
|
```
|
|
|
|
:::info
|
|
Read more at [Conditional Rendering](./conditional-rendering.mdx)
|
|
:::
|