mirror of https://github.com/sveltejs/svelte
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
8.0 KiB
219 lines
8.0 KiB
---
|
|
title: Basic markup
|
|
---
|
|
|
|
- [basically what we have in the Svelte docs today](https://svelte.dev/docs/basic-markup)
|
|
|
|
## Tags
|
|
|
|
A lowercase tag, like `<div>`, denotes a regular HTML element. A capitalised tag, such as `<Widget>` or `<Namespace.Widget>`, indicates a _component_.
|
|
|
|
```svelte
|
|
<script>
|
|
import Widget from './Widget.svelte';
|
|
</script>
|
|
|
|
<div>
|
|
<Widget />
|
|
</div>
|
|
```
|
|
|
|
## Attributes and props
|
|
|
|
By default, attributes work exactly like their HTML counterparts.
|
|
|
|
```svelte
|
|
<div class="foo">
|
|
<button disabled>can't touch this</button>
|
|
</div>
|
|
```
|
|
|
|
As in HTML, values may be unquoted.
|
|
|
|
<!-- prettier-ignore -->
|
|
```svelte
|
|
<input type=checkbox />
|
|
```
|
|
|
|
Attribute values can contain JavaScript expressions.
|
|
|
|
```svelte
|
|
<a href="page/{p}">page {p}</a>
|
|
```
|
|
|
|
Or they can _be_ JavaScript expressions.
|
|
|
|
```svelte
|
|
<button disabled={!clickable}>...</button>
|
|
```
|
|
|
|
Boolean attributes are included on the element if their value is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and excluded if it's [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy).
|
|
|
|
All other attributes are included unless their value is [nullish](https://developer.mozilla.org/en-US/docs/Glossary/Nullish) (`null` or `undefined`).
|
|
|
|
```svelte
|
|
<input required={false} placeholder="This input field is not required" />
|
|
<div title={null}>This div has no title attribute</div>
|
|
```
|
|
|
|
Quoting a singular expression does not affect how the value is parsed yet, but in Svelte 6 it will:
|
|
|
|
<!-- prettier-ignore -->
|
|
```svelte
|
|
<button disabled="{number !== 42}">...</button>
|
|
```
|
|
|
|
When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.
|
|
|
|
```svelte
|
|
<button {disabled}>...</button>
|
|
<!-- equivalent to
|
|
<button disabled={disabled}>...</button>
|
|
-->
|
|
```
|
|
|
|
By convention, values passed to components are referred to as _properties_ or _props_ rather than _attributes_, which are a feature of the DOM.
|
|
|
|
As with elements, `name={name}` can be replaced with the `{name}` shorthand.
|
|
|
|
```svelte
|
|
<Widget foo={bar} answer={42} text="hello" />
|
|
```
|
|
|
|
_Spread attributes_ allow many attributes or properties to be passed to an element or component at once.
|
|
|
|
An element or component can have multiple spread attributes, interspersed with regular ones.
|
|
|
|
```svelte
|
|
<Widget {...things} />
|
|
```
|
|
|
|
> The `value` attribute of an `input` element or its children `option` elements must not be set with spread attributes when using `bind:group` or `bind:checked`. Svelte needs to be able to see the element's `value` directly in the markup in these cases so that it can link it to the bound variable.
|
|
|
|
> Sometimes, the attribute order matters as Svelte sets attributes sequentially in JavaScript. For example, `<input type="range" min="0" max="1" value={0.5} step="0.1"/>`, Svelte will attempt to set the value to `1` (rounding up from 0.5 as the step by default is 1), and then set the step to `0.1`. To fix this, change it to `<input type="range" min="0" max="1" step="0.1" value={0.5}/>`.
|
|
|
|
> Another example is `<img src="..." loading="lazy" />`. Svelte will set the img `src` before making the img element `loading="lazy"`, which is probably too late. Change this to `<img loading="lazy" src="...">` to make the image lazily loaded.
|
|
|
|
## Events
|
|
|
|
Listening to DOM events is possible by adding attributes to the element that start with `on`. For example, to listen to the `click` event, add the `onclick` attribute to a button:
|
|
|
|
```svelte
|
|
<button onclick={() => console.log('clicked')}>click me</button>
|
|
```
|
|
|
|
Event attributes are case sensitive. `onclick` listens to the `click` event, `onClick` listens to the `Click` event, which is different. This ensures you can listen to custom events that have uppercase characters in them.
|
|
|
|
Because events are just attributes, the same rules as for attributes apply:
|
|
|
|
- you can use the shorthand form: `<button {onclick}>click me</button>`
|
|
- you can spread them: `<button {...thisSpreadContainsEventAttributes}>click me</button>`
|
|
- component events are just (callback) properties and don't need a separate concept
|
|
|
|
Timing-wise, event attributes always fire after events from bindings (e.g. `oninput` always fires after an update to `bind:value`). Under the hood, some event handlers are attached directly with `addEventListener`, while others are _delegated_.
|
|
|
|
When using `onwheel`, `onmousewheel`, `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) to align with browser defaults. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`.
|
|
|
|
In the very rare cases that you need to prevent these event defaults, you should use [`on`](https://svelte-5-preview.vercel.app/docs/imports#svelte-events) instead (for example inside an action).
|
|
|
|
### Event delegation
|
|
|
|
To reduce memory footprint and increase performance, Svelte uses a technique called event delegation. This means that for certain events — see the list below — a single event listener at the application root takes responsibility for running any handlers on the event's path.
|
|
|
|
There are a few gotchas to be aware of:
|
|
|
|
- when you manually dispatch an event with a delegated listener, make sure to set the `{ bubbles: true }` option or it won't reach the application root
|
|
- when using `addEventListener` directly, avoid calling `stopPropagation` or the event won't reach the application root and handlers won't be invoked. Similarly, handlers added manually inside the application root will run _before_ handlers added declaratively deeper in the DOM (with e.g. `onclick={...}`), in both capturing and bubbling phases. For these reasons it's better to use the `on` function imported from `svelte/events` rather than `addEventListener`, as it will ensure that order is preserved and `stopPropagation` is handled correctly.
|
|
|
|
The following event handlers are delegated:
|
|
|
|
- `beforeinput`
|
|
- `click`
|
|
- `change`
|
|
- `dblclick`
|
|
- `contextmenu`
|
|
- `focusin`
|
|
- `focusout`
|
|
- `input`
|
|
- `keydown`
|
|
- `keyup`
|
|
- `mousedown`
|
|
- `mousemove`
|
|
- `mouseout`
|
|
- `mouseover`
|
|
- `mouseup`
|
|
- `pointerdown`
|
|
- `pointermove`
|
|
- `pointerout`
|
|
- `pointerover`
|
|
- `pointerup`
|
|
- `touchend`
|
|
- `touchmove`
|
|
- `touchstart`
|
|
|
|
## Text expressions
|
|
|
|
A JavaScript expression can be included as text by surrounding it with curly braces.
|
|
|
|
```svelte
|
|
{expression}
|
|
```
|
|
|
|
Curly braces can be included in a Svelte template by using their [HTML entity](https://developer.mozilla.org/docs/Glossary/Entity) strings: `{`, `{`, or `{` for `{` and `}`, `}`, or `}` for `}`.
|
|
|
|
If you're using a regular expression (`RegExp`) [literal notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#literal_notation_and_constructor), you'll need to wrap it in parentheses.
|
|
|
|
<!-- prettier-ignore -->
|
|
```svelte
|
|
<h1>Hello {name}!</h1>
|
|
<p>{a} + {b} = {a + b}.</p>
|
|
|
|
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
|
|
```
|
|
|
|
The expression will be stringified and escaped to prevent code injections. If you want to render HTML, use the `{@html}` tag instead.
|
|
|
|
```svelte
|
|
{@html potentiallyUnsafeHtmlString}
|
|
```
|
|
|
|
> Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent [XSS attacks](https://owasp.org/www-community/attacks/xss/)
|
|
|
|
## Comments
|
|
|
|
You can use HTML comments inside components.
|
|
|
|
```svelte
|
|
<!-- this is a comment! --><h1>Hello world</h1>
|
|
```
|
|
|
|
Comments beginning with `svelte-ignore` disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you're disabling them for a good reason.
|
|
|
|
```svelte
|
|
<!-- svelte-ignore a11y-autofocus -->
|
|
<input bind:value={name} autofocus />
|
|
```
|
|
|
|
You can add a special comment starting with `@component` that will show up when hovering over the component name in other files.
|
|
|
|
````svelte
|
|
<!--
|
|
@component
|
|
- You can use markdown here.
|
|
- You can also use code blocks here.
|
|
- Usage:
|
|
```html
|
|
<Main name="Arethra">
|
|
```
|
|
-->
|
|
<script>
|
|
let { name } = $props();
|
|
</script>
|
|
|
|
<main>
|
|
<h1>
|
|
Hello, {name}
|
|
</h1>
|
|
</main>
|
|
````
|