Style Directive

The style: directive binds a single CSS property to a value. Change the value, the property updates.

Everything else about the element's look stays in CSS where it belongs.

Basic Usage

Write the property name after the colon, and the value in braces:

<script>
let textColor = 'royalblue'
let bgColor = '#4f46e5'
</script>

<div style:color={textColor}>Colored text</div>
<div class="badge" style:background-color={bgColor}>With background</div>
output
Colored text
With background

Property names are kebab-case, exactly as in CSS (background-color, font-size, border-radius).

Set a property to null, undefined or '' and JAF removes it from the element.

Units are yours to write. JAF never appends px. style:width={200} sets nothing, because the browser rejects a length with no unit - write style:width={200 + 'px'}. Unitless properties (opacity, z-index, flex-grow) take a plain number.

Values That Change

The value is any expression. When something it reads changes, the property is reset - no re-render, no string building:

<script>
let opacity = 100
let size = 140
</script>

<div class="controls">
  <label>
    Opacity <strong>{opacity}%</strong>
    <input type="range" min="0" max="100" bind:value={opacity} />
  </label>

  <label>
    Width <strong>{size}px</strong>
    <input type="range" min="80" max="260" bind:value={size} />
  </label>
</div>

<div class="swatch" style:opacity={opacity / 100} style:width={size + 'px'}>
  drag a slider
</div>
output
drag a slider

opacity takes the number straight; width gets + 'px'. That is the whole rule from the callout above, in one example.

With Tailwind

Utility classes cover everything you know at author time. They cannot express a number your app computes at runtime - so keep the classes for the look, and use style: for the one value that moves:

source
<script>
let progress = 40

function step(amount) {
	progress = Math.min(100, Math.max(0, progress + amount))
}
</script>

<div class="max-w-sm text-sm">
  <div class="flex justify-between font-medium">
    <span>Uploading</span>
    <span>{progress}%</span>
  </div>

  <!-- Tailwind draws the track and the bar. style: supplies the one
       value a utility class cannot know: today's number. -->
  <div class="mt-2 h-3 overflow-hidden rounded-full bg-slate-200 dark:bg-slate-700">
    <div class="h-full rounded-full bg-sky-500 transition-[width] duration-300" style:width={progress + '%'}></div>
  </div>

  <div class="mt-3 flex gap-2">
    <button class="rounded-md border border-slate-300 px-3 py-1.5 dark:border-slate-600" onclick="step(-10)">
      -10%
    </button>
    <button class="rounded-md bg-sky-500 px-3 py-1.5 text-white hover:bg-sky-600" onclick="step(10)">
      +10%
    </button>
  </div>
</div>
output
Uploading 40%

The track, the colours, the rounding and even the transition are Tailwind utilities. Only style:width is dynamic.

Reaching for w-[40%] here would not work: Tailwind generates classes by scanning your source, so it can only produce widths you have literally written down.

CSS Custom Properties

style: also sets custom properties, which is the tidiest way to feed a value to CSS that already knows what to do with it - including child elements:

source
<script>
let brandColor = '#3B82F6'
let spacing = 16
</script>

<div style:--primary={brandColor} style:--spacing={spacing + 'px'}>
  <p style="color: var(--primary); margin: var(--spacing)">
    Styled with CSS variables
  </p>
</div>
output

Styled with CSS variables