Description: The x-bind directive in AlpineJS allows you to dynamically set HTML element attributes based on the reactive data in your Alpine component. This is incredibly useful for updating attributes like class, style, disabled, src, value, and many others in response to changes in your component's state.
Full Syntax: x-bind:attributeName="propertyNameOrExpression"
This is the standard way to bind an attribute. attributeName is the HTML attribute you want to set (e.g., class, href, disabled), and propertyNameOrExpression is a JavaScript expression or a property from your Alpine component's data that evaluates to the desired attribute value.
<img x-bind:src="imageUrl">
<button x-bind:disabled="isLoading">Submit</button>
Shorthand Syntax: :attributeName="propertyNameOrExpression"
AlpineJS offers a convenient shorthand for x-bind by simply prefixing the attribute name with a colon (:). This is the most common way you'll see x-bind used.
<a :href="userProfileUrl">Profile</a>
<div :title="tooltipText">Hover me</div>
Object Syntax for Classes: :class="{ 'css-class-name': booleanCondition, ... }"
Binding to the class attribute is very common. Alpine provides a special object syntax for conditionally applying CSS classes. Each key in the object is a class name, and its value is a boolean expression. If the expression is truthy, the class is applied; otherwise, it's not.
<div :class="{ 'text-red-500': hasError, 'bg-blue-100': isActive, 'font-bold': isImportant }">
Dynamic Classes
</div>
You can also mix this with static classes and array syntax for more complex scenarios:
<div class="base-class" :class="[isActive ? 'active-class' : '', { 'error-class': hasError }]">...</div>
Binding to the style Attribute: :style="{ cssProperty: 'value', ... }"
You can bind an object to the style attribute to dynamically set inline CSS styles. The keys of the object are CSS property names (camelCased, e.g., backgroundColor, or kebab-cased in quotes, e.g., 'background-color'), and the values are their corresponding CSS values.
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">
Dynamic Styles
</div>
<!-- With kebab-case properties (less common in JS objects unless quoted) -->
<div :style="{ 'background-color': bgColor, 'font-weight': 'bold' }">
Styled Content
</div>
Confusion between x-bind:value and x-model:
x-bind:value="dataProperty" (or :value="dataProperty") sets up a one-way binding. It pushes the value from your Alpine data property into the element's value attribute. Changes to dataProperty will update the element's value. However, if the user interacts with an input element and changes its value, this change will not automatically update dataProperty.
For two-way binding on form input elements (<input>, <select>, <textarea>), where user input should update the Alpine data property and vice-versa, you should use x-model="dataProperty" instead. x-model handles both setting the initial value and listening for changes to update the data.
x-bind:value is perfectly valid for setting the initial value of an input if you don't need two-way binding, or for binding the value attribute of non-input elements (like custom components or elements where value has a specific meaning, e.g., <li value="5"> in an <ol>, or a custom data-value attribute like :data-value="item.id").
Incorrect syntax for conditional classes:
The object syntax for classes (:class="{ 'my-class': condition }") is powerful but requires correct syntax. A common mistake is trying to use a colon within the class attribute value itself, like class="my-class: condition" or class="'my-class': condition". This is incorrect HTML/Alpine syntax.
Always use the object syntax where keys are class names (as strings) and values are boolean expressions: :class="{ 'active': isActive, 'has-error': formError }". Ensure the condition evaluates to a JavaScript boolean (true or false).
Boolean attributes (e.g., disabled, required, readonly, checked) not working as expected:
For HTML boolean attributes, their presence implies true, and their absence implies false. AlpineJS handles this correctly based on the bound value:
true (or any truthy JavaScript value like a non-empty string, a number other than 0, an object, an array), Alpine will add the attribute to the element (e.g., <button disabled>).false, null, or undefined (falsy JavaScript values), Alpine will remove the attribute from the element (e.g., <button>).This is usually the desired behavior. For example, <button :disabled="shouldBeDisabled"> will be <button disabled> if shouldBeDisabled is true, and <button> if shouldBeDisabled is false. You won't see disabled="false" in the HTML, as that's not how boolean attributes typically work (though some HTML contexts might interpret disabled="false" differently, Alpine's approach is standard for JavaScript-driven UIs).
Toggle classes on the box below:
Change styles on the text below:
This text has dynamic inline styles.
textColor: '')
Change image src:
Current:
Toggle button disabled state:
Binding value and max on a <progress> element:
The value attribute of the <progress> element is bound to progressValue.
Binding title and custom data-* attributes:
title. Inspect to see data-item-id and data-is-active.