Most of the time a clear separation between data flowing down and events going up is worthwhile and results in more robust apps. But in some cases - especially when interacting with form elements - it's more ergonomic to declare a two way binding. Svelte provides many element bindings out of the box, and also allows component bindings.
## bind:_property_ for elements
```svelte
<!--- copy: false --->
bind:property={variable}
```
Data ordinarily flows down, from parent to child. The `bind:` directive allows data to flow the other way, from child to parent. Most bindings are specific to particular elements.
The simplest bindings reflect the value of a property, such as `input.value`.
```svelte
<inputbind:value={name}/>
<textareabind:value={text}/>
<inputtype="checkbox"bind:checked={yes}/>
```
If the name matches the value, you can use a shorthand.
```svelte
<inputbind:value/>
<!-- equivalent to
<inputbind:value={value}/>
-->
```
Numeric input values are coerced; even though `input.value` is a string as far as the DOM is concerned, Svelte will treat it as a number. If the input is empty or invalid (in the case of `type="number"`), the value is `undefined`.
On `<input>` elements with `type="file"`, you can use `bind:files` to get the [`FileList` of selected files](https://developer.mozilla.org/en-US/docs/Web/API/FileList). When you want to update the files programmatically, you always need to use a `FileList` object. Currently `FileList` objects cannot be constructed directly, so you need to create a new [`DataTransfer`](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer) object and get `files` from there.
`FileList` objects also cannot be modified, so if you want to e.g. delete a single file from the list, you need to create a new `DataTransfer` object and add the files you want to keep.
> `DataTransfer` may not be available in server-side JS runtimes. Leaving the state that is bound to `files` uninitialized prevents potential errors if components are server-side rendered.
Here we were binding to the value of a text input, which uses the `input` event. Bindings on other elements may use different events such as `change`.
## Binding `<select>` value
A `<select>` value binding corresponds to the `value` property on the selected `<option>`, which can be any value (not just strings, as is normally the case in the DOM).
```svelte
<selectbind:value={selected}>
<optionvalue={a}>a</option>
<optionvalue={b}>b</option>
<optionvalue={c}>c</option>
</select>
```
A `<select multiple>` element behaves similarly to a checkbox group. The bound variable is an array with an entry corresponding to the `value` property of each selected `<option>`.
```svelte
<selectmultiplebind:value={fillings}>
<optionvalue="Rice">Rice</option>
<optionvalue="Beans">Beans</option>
<optionvalue="Cheese">Cheese</option>
<optionvalue="Guac (extra)">Guac (extra)</option>
</select>
```
When the value of an `<option>` matches its text content, the attribute can be omitted.
```svelte
<selectmultiplebind:value={fillings}>
<option>Rice</option>
<option>Beans</option>
<option>Cheese</option>
<option>Guac (extra)</option>
</select>
```
Elements with the `contenteditable` attribute support the following bindings:
There are slight differences between each of these, read more about them [here](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#Differences_from_innerText).
<!-- for some reason puts the comment and html on same line -->
<!-- prettier-ignore -->
```svelte
<divcontenteditable="true"bind:innerHTML={html}/>
```
`<details>` elements support binding to the `open` property.
```svelte
<detailsbind:open={isOpen}>
<summary>Details</summary>
<p>Something small enough to escape casual notice.</p>
</details>
```
## Media element bindings
Media elements (`<audio>` and `<video>`) have their own set of bindings — seven _readonly_ ones...
-`duration` (readonly) — the total duration of the video, in seconds
-`buffered` (readonly) — an array of `{start, end}` objects
-`played` (readonly) — ditto
-`seekable` (readonly) — ditto
-`seeking` (readonly) — boolean
-`ended` (readonly) — boolean
-`readyState` (readonly) — number between (and including) 0 and 4
...and five _two-way_ bindings:
-`currentTime` — the current playback time in the video, in seconds
-`playbackRate` — how fast or slow to play the video, where 1 is 'normal'
-`paused` — this one should be self-explanatory
-`volume` — a value between 0 and 1
-`muted` — a boolean value indicating whether the player is muted
Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
```svelte
<video
src={clip}
bind:duration
bind:buffered
bind:played
bind:seekable
bind:seeking
bind:ended
bind:readyState
bind:currentTime
bind:playbackRate
bind:paused
bind:volume
bind:muted
bind:videoWidth
bind:videoHeight
/>
```
## Image element bindings
Image elements (`<img>`) have two readonly bindings:
-`naturalWidth` (readonly) — the original width of the image, available after the image has loaded
-`naturalHeight` (readonly) — the original height of the image, available after the image has loaded
```svelte
<img
bind:naturalWidth
bind:naturalHeight
></img>
```
## Block-level element bindings
Block-level elements have 4 read-only bindings, measured using a technique similar to [this one](http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/):
// All instance exports are available on the instance object
export function empty() {
// ...
}
</script>
```
> Note that we can't do `{cart.empty}` since `cart` is `undefined` when the button is first rendered and throws an error.
## bind:_property_ for components
```svelte
bind:property={variable}
```
You can bind to component props using the same syntax as for elements.
```svelte
<Keypadbind:value={pin}/>
```
While Svelte props are reactive without binding, that reactivity only flows downward into the component by default. Using `bind:property` allows changes to the property from within the component to flow back up out of the component.
To mark a property as bindable, use the `$bindable` rune:
```svelte
<script>
let { readonlyProperty, bindableProperty = $bindable() } = $props();
</script>
```
Declaring a property as bindable means it _can_ be used using `bind:`, not that it _must_ be used using `bind:`.
Bindable properties can have a fallback value:
```svelte
<script>
let { bindableProperty = $bindable('fallback value') } = $props();
</script>
```
This fallback value _only_ applies when the property is _not_ bound. When the property is bound and a fallback value is present, the parent is expected to provide a value other than `undefined`, else a runtime error is thrown. This prevents hard-to-reason-about situations where it's unclear which value should apply.