|  |  | ---
 | 
						
						
						
							|  |  | title: bind:
 | 
						
						
						
							|  |  | ---
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Data ordinarily flows down, from parent to child. The `bind:` directive allows data to flow the other way, from child to parent.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | The general syntax is `bind:property={expression}`, where `expression` is an _lvalue_ (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <!-- prettier-ignore -->
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <input bind:value={value} />
 | 
						
						
						
							|  |  | <input bind:value />
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Svelte creates an event listener that updates the bound value. If an element already has a listener for the same event, that listener will be fired before the bound value is updated.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Most bindings are _two-way_, meaning that changes to the value will affect the element and vice versa. A few bindings are _readonly_, meaning that changing their value will have no effect on the element.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<input bind:value>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | A `bind:value` directive on an `<input>` element binds the input's `value` property:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <!-- prettier-ignore -->
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <script>
 | 
						
						
						
							|  |  | 	let message = $state('hello');
 | 
						
						
						
							|  |  | </script>
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <input bind:value={message} />
 | 
						
						
						
							|  |  | <p>{message}</p>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | In the case of a numeric input (`type="number"` or `type="range"`), the value will be coerced to a number ([demo](/playground/untitled#H4sIAAAAAAAAE6WPwYoCMQxAfyWEPeyiOOqx2w74Hds9pBql0IllmhGXYf5dKqwiyILsLXnwwsuI-5i4oPkaUX8yo7kCnKNQV7dNzoty4qSVBSr8jG-Poixa0KAt2z5mbb14TaxA4OCtKCm_rz4-f2m403WltrlrYhMFTtcLNkoeFGqZ8yhDF7j3CCHKzpwoDexGmqCL4jwuPUJHZ-dxVcfmyYGe5MAv-La5pbxYFf5Z9Zf_UJXb-sEMquFgJJhBmGyTW5yj8lnRaD_w9D1dAKSSj7zqAQAA)):
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <script>
 | 
						
						
						
							|  |  | 	let a = $state(1);
 | 
						
						
						
							|  |  | 	let b = $state(2);
 | 
						
						
						
							|  |  | </script>
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <label>
 | 
						
						
						
							|  |  | 	<input type="number" bind:value={a} min="0" max="10" />
 | 
						
						
						
							|  |  | 	<input type="range" bind:value={a} min="0" max="10" />
 | 
						
						
						
							|  |  | </label>
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <label>
 | 
						
						
						
							|  |  | 	<input type="number" bind:value={b} min="0" max="10" />
 | 
						
						
						
							|  |  | 	<input type="range" bind:value={b} min="0" max="10" />
 | 
						
						
						
							|  |  | </label>
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <p>{a} + {b} = {a + b}</p>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | If the input is empty or invalid (in the case of `type="number"`), the value is `undefined`.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<input bind:checked>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Checkbox and radio inputs can be bound with `bind:checked`:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <label>
 | 
						
						
						
							|  |  | 	<input type="checkbox" bind:checked={accepted} />
 | 
						
						
						
							|  |  | 	Accept terms and conditions
 | 
						
						
						
							|  |  | </label>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<input bind:group>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Inputs that work together can use `bind:group`.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <script>
 | 
						
						
						
							|  |  | 	let tortilla = 'Plain';
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 	/** @type {Array<string>} */
 | 
						
						
						
							|  |  | 	let fillings = [];
 | 
						
						
						
							|  |  | </script>
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <!-- grouped radio inputs are mutually exclusive -->
 | 
						
						
						
							|  |  | <input type="radio" bind:group={tortilla} value="Plain" />
 | 
						
						
						
							|  |  | <input type="radio" bind:group={tortilla} value="Whole wheat" />
 | 
						
						
						
							|  |  | <input type="radio" bind:group={tortilla} value="Spinach" />
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <!-- grouped checkbox inputs populate an array -->
 | 
						
						
						
							|  |  | <input type="checkbox" bind:group={fillings} value="Rice" />
 | 
						
						
						
							|  |  | <input type="checkbox" bind:group={fillings} value="Beans" />
 | 
						
						
						
							|  |  | <input type="checkbox" bind:group={fillings} value="Cheese" />
 | 
						
						
						
							|  |  | <input type="checkbox" bind:group={fillings} value="Guac (extra)" />
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | > [!NOTE] `bind:group` only works if the inputs are in the same Svelte component.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<input bind:files>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 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.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <script>
 | 
						
						
						
							|  |  | 	let files = $state();
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 	function clear() {
 | 
						
						
						
							|  |  | 		files = new DataTransfer().files; // null or undefined does not work
 | 
						
						
						
							|  |  | 	}
 | 
						
						
						
							|  |  | </script>
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <label for="avatar">Upload a picture:</label>
 | 
						
						
						
							|  |  | <input accept="image/png, image/jpeg" bind:files id="avatar" name="avatar" type="file" />
 | 
						
						
						
							|  |  | <button onclick={clear}>clear</button>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | `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.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | > [!NOTE] `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.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<select bind: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
 | 
						
						
						
							|  |  | <select bind:value={selected}>
 | 
						
						
						
							|  |  | 	<option value={a}>a</option>
 | 
						
						
						
							|  |  | 	<option value={b}>b</option>
 | 
						
						
						
							|  |  | 	<option value={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
 | 
						
						
						
							|  |  | <select multiple bind:value={fillings}>
 | 
						
						
						
							|  |  | 	<option value="Rice">Rice</option>
 | 
						
						
						
							|  |  | 	<option value="Beans">Beans</option>
 | 
						
						
						
							|  |  | 	<option value="Cheese">Cheese</option>
 | 
						
						
						
							|  |  | 	<option value="Guac (extra)">Guac (extra)</option>
 | 
						
						
						
							|  |  | </select>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | When the value of an `<option>` matches its text content, the attribute can be omitted.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <select multiple bind:value={fillings}>
 | 
						
						
						
							|  |  | 	<option>Rice</option>
 | 
						
						
						
							|  |  | 	<option>Beans</option>
 | 
						
						
						
							|  |  | 	<option>Cheese</option>
 | 
						
						
						
							|  |  | 	<option>Guac (extra)</option>
 | 
						
						
						
							|  |  | </select>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<audio>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | `<audio>` elements have their own set of bindings — five two-way ones...
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - [`currentTime`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/currentTime)
 | 
						
						
						
							|  |  | - [`playbackRate`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/playbackRate)
 | 
						
						
						
							|  |  | - [`paused`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/paused)
 | 
						
						
						
							|  |  | - [`volume`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/volume)
 | 
						
						
						
							|  |  | - [`muted`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/muted)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ...and seven readonly ones:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - [`duration`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/duration)
 | 
						
						
						
							|  |  | - [`buffered`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered)
 | 
						
						
						
							|  |  | - [`paused`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/paused)
 | 
						
						
						
							|  |  | - [`seekable`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seekable)
 | 
						
						
						
							|  |  | - [`seeking`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/seeking_event)
 | 
						
						
						
							|  |  | - [`ended`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended)
 | 
						
						
						
							|  |  | - [`readyState`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/readyState)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <audio src={clip} bind:duration bind:currentTime bind:paused></audio>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<video>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | `<video>` elements have all the same bindings as [#audio] elements, plus readonly [`videoWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoWidth) and [`videoHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/videoHeight) bindings.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<img>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | `<img>` elements have two readonly bindings:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - [`naturalWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth)
 | 
						
						
						
							|  |  | - [`naturalHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalHeight)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## `<details bind:open>`
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | `<details>` elements support binding to the `open` property.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <details bind:open={isOpen}>
 | 
						
						
						
							|  |  | 	<summary>How do you comfort a JavaScript bug?</summary>
 | 
						
						
						
							|  |  | 	<p>You console it.</p>
 | 
						
						
						
							|  |  | </details>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Contenteditable bindings
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Elements with the `contenteditable` attribute support the following bindings:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - [`innerHTML`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)
 | 
						
						
						
							|  |  | - [`innerText`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText)
 | 
						
						
						
							|  |  | - [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | > [!NOTE] There are [subtle differences between `innerText` and `textContent`](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
 | 
						
						
						
							|  |  | <div contenteditable="true" bind:innerHTML={html} />
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Dimensions
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | All visible elements have the following readonly bindings, measured with a `ResizeObserver`:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | - [`clientWidth`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth)
 | 
						
						
						
							|  |  | - [`clientHeight`](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight)
 | 
						
						
						
							|  |  | - [`offsetWidth`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetWidth)
 | 
						
						
						
							|  |  | - [`offsetHeight`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <div bind:offsetWidth={width} bind:offsetHeight={height}>
 | 
						
						
						
							|  |  | 	<Chart {width} {height} />
 | 
						
						
						
							|  |  | </div>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## bind:this
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <!--- copy: false --->
 | 
						
						
						
							|  |  | bind:this={dom_node}
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | To get a reference to a DOM node, use `bind:this`. The value will be `undefined` until the component is mounted — in other words, you should read it inside an effect or an event handler, but not during component initialisation:
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <script>
 | 
						
						
						
							|  |  | 	/** @type {HTMLCanvasElement} */
 | 
						
						
						
							|  |  | 	let canvas;
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 	$effect(() => {
 | 
						
						
						
							|  |  | 		const ctx = canvas.getContext('2d');
 | 
						
						
						
							|  |  | 		drawStuff(ctx);
 | 
						
						
						
							|  |  | 	});
 | 
						
						
						
							|  |  | </script>
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <canvas bind:this={canvas} />
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Components also support `bind:this`, allowing you to interact with component instances programmatically.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <!--- file: App.svelte --->
 | 
						
						
						
							|  |  | <ShoppingCart bind:this={cart} />
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | <button onclick={() => cart.empty()}> Empty shopping cart </button>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <!--- file: ShoppingCart.svelte --->
 | 
						
						
						
							|  |  | <script>
 | 
						
						
						
							|  |  | 	// All instance exports are available on the instance object
 | 
						
						
						
							|  |  | 	export function empty() {
 | 
						
						
						
							|  |  | 		// ...
 | 
						
						
						
							|  |  | 	}
 | 
						
						
						
							|  |  | </script>
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## bind:_property_ for components
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | bind:property={variable}
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | You can bind to component props using the same syntax as for elements.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ```svelte
 | 
						
						
						
							|  |  | <Keypad bind: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`]($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.
 |