Svelte and SvelteKit course ยท Module 5: Bindings
Dimension Bindings and Special Bindings
In this lesson4
Element Dimensions
<script>
let w = $state(0);
let h = $state(0);
let text = $state('Resize the window!');
</script>
<div
bind:clientWidth={w}
bind:clientHeight={h}
class="box"
>
<p>{text}</p>
<p>Dimensions: {w} x {h}px</p>
</div>
<style>
.box {
width: 100%;
height: 200px;
background: #2a2a4a;
padding: 1rem;
}
</style>Available dimension bindings:
clientWidth/clientHeightoffsetWidth/offsetHeight
Scroll
<script>
let scrollY = $state(0);
</script>
<svelte:window bind:scrollY />
<div class="header" class:scrolled={scrollY > 50}>
Viking Saga
</div>
<style>
.header {
position: fixed;
top: 0;
transition: background 0.3s;
}
.header.scrolled {
background: rgba(0, 0, 0, 0.8);
}
</style>Online/Offline Status
<script>
let online = $state(true);
</script>
<svelte:window bind:online />
<p>Status: {online ? 'Online' : 'Offline'}</p>Practical Example: Viking Form
<script>
let warrior = $state({
name: '',
rank: 'drengr',
skills: [],
bio: ''
});
function submit(e) {
e.preventDefault(); // stop the page reload
console.log('Saved:', $state.snapshot(warrior));
}
</script>
<form onsubmit={submit}>
<label>
Name:
<input bind:value={warrior.name} required />
</label>
<label>
Rank:
<select bind:value={warrior.rank}>
<option value="drengr">Drengr</option>
<option value="jarl">Jarl</option>
</select>
</label>
<fieldset>
<legend>Skills:</legend>
<label>
<input type="checkbox" bind:group={warrior.skills} value="sailing" />
Sailing
</label>
<label>
<input type="checkbox" bind:group={warrior.skills} value="combat" />
Combat
</label>
</fieldset>
<label>
Biography:
<textarea bind:value={warrior.bio}></textarea>
</label>
<button type="submit">Save warrior</button>
</form>The form uses the onsubmit attribute, and e.preventDefault() stops the page reload (in Svelte 4 the |preventDefault modifier did this). $state.snapshot(warrior) turns the reactive object into a plain copy that reads well in the console.
Code for this lesson: App.svelte
<script>
// DOM bindings - bind:this, bind:clientWidth etc.
// bind:this only needs a plain variable (used in a function, not in the markup)
let inputRef;
// Values shown in the markup must be $state to update the view
let containerWidth = $state(0);
let containerHeight = $state(0);
let scrollY = $state(0);
function focusInput() {
inputRef?.focus();
}
$effect(() => {
console.log('Scroll position:', scrollY);
});
</script>
<svelte:window bind:scrollY />
<main class="dom-demo">
<h1>DOM Bindings</h1>
<section>
<h2>bind:this - element reference</h2>
<input
bind:this={inputRef}
type="text"
placeholder="Click button to focus"
/>
<button onclick={focusInput}>Focus input</button>
</section>
<section bind:clientWidth={containerWidth} bind:clientHeight={containerHeight}>
<h2>bind:clientWidth/Height</h2>
<p>Width: <strong>{Math.round(containerWidth)}px</strong></p>
<p>Height: <strong>{Math.round(containerHeight)}px</strong></p>
<p class="hint">Resize the window to see changes</p>
</section>
<section>
<h2>svelte:window - scroll</h2>
<p>Scroll Y: <strong>{Math.round(scrollY)}px</strong></p>
<div class="scroll-area">
<p>Scroll the page down...</p>
<div class="spacer"></div>
<p>...and observe the scrollY value</p>
</div>
</section>
</main>
<style>
.dom-demo {
font-family: 'Georgia', serif;
max-width: 600px;
margin: 0 auto;
padding: 2rem;
background: #1a0f0a;
color: #e8d5b7;
min-height: 150vh;
}
h1 {
color: #d4af37;
text-align: center;
position: sticky;
top: 0;
background: #1a0f0a;
padding: 1rem 0;
}
section {
background: rgba(212, 175, 55, 0.1);
border: 1px solid #d4af37;
border-radius: 8px;
padding: 1rem;
margin: 1rem 0;
}
h2 {
color: #d4af37;
font-size: 1rem;
margin-top: 0;
}
input {
width: 100%;
padding: 0.75rem;
background: rgba(0,0,0,0.3);
border: 1px solid #3d2914;
border-radius: 4px;
color: #e8d5b7;
margin-bottom: 0.5rem;
}
input:focus {
border-color: #d4af37;
outline: none;
}
button {
padding: 0.5rem 1rem;
background: #3d2914;
color: #e8d5b7;
border: 1px solid #d4af37;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #4d3924;
}
strong {
color: #ffd700;
}
.hint {
font-size: 0.85rem;
color: #8b7355;
font-style: italic;
}
.scroll-area {
padding: 1rem;
background: rgba(0,0,0,0.3);
border-radius: 4px;
}
.spacer {
height: 200px;
}
</style>Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. How do you track the window's scroll position?