Description: The x-bind directive in AlpineJS allows you to dynamically set HTML element attributes such as class, style, disabled, src, value, and many others, based on the reactive data in your Alpine component. This is fundamental for creating dynamic and interactive user interfaces.
x-bind:attributeName="propertyNameOrExpression"
This is the explicit way to bind an attribute. For example, to bind the href attribute of an anchor tag:
<a x-bind:href="myUrl">Link</a>
Here, myUrl would be a property in your Alpine component's data.
:attributeName="propertyNameOrExpression"
AlpineJS offers a convenient shorthand, similar to Vue.js. This is the most common way you'll see x-bind used:
<img :src="imagePath" :alt="imageDescription">
:class="{ 'css-class-name': condition, 'another-class': anotherCondition }"
This is a powerful way to conditionally apply CSS classes. The class name (as a string key) is applied if its corresponding value (a boolean condition) is true.
<div :class="{ 'text-red-500 font-bold': hasError, 'bg-blue-100': isActive }">Message</div>
In this example, text-red-500 and font-bold are applied if hasError is true. bg-blue-100 is applied if isActive is true.
:style="{ color: 'red', display: 'block', fontWeight: 'bold' }"
You can bind an object to the style attribute to set multiple inline styles dynamically. Property names can be camelCased (e.g., fontWeight) or kebab-cased in quotes (e.g., 'font-weight').
<p :style="{ color: textColor, fontSize: textSize + 'px' }">Styled Text</p>
Here, textColor and textSize would be reactive properties in your component.
x-bind:value and x-model:
x-bind:value="myProperty" (or :value="myProperty") sets up one-way data binding. The input's value will reflect myProperty, but user changes to the input field will not update myProperty. If you need two-way binding for form inputs (where user input also updates the data property), use x-model="myProperty" instead. x-model is specifically designed for form elements like <input>, <select>, and <textarea>.
The object syntax for classes (:class="{ 'my-class': condition }") is powerful. Ensure the condition evaluates to a boolean (true or false). A common mistake is trying something like class="my-class: condition" or :class="'my-class': condition", which are incorrect. The correct syntax involves an object where keys are class names and values are boolean conditions.
<!-- Correct -->
<div :class="{ 'is-active': isActive, 'has-error': errorCount > 0 }">...</div>
<!-- Incorrect -->
<!-- <div class="is-active: isActive">...</div> -->
disabled or required not working as expected:
For HTML boolean attributes (e.g., disabled, readonly, required, checked), AlpineJS follows a specific behavior:
If the bound value is true (or any truthy JavaScript value like a non-empty string or a number other than 0), the attribute will be added to the element (e.g., <button disabled>).
If the bound value is false, null, or undefined, Alpine will remove the attribute entirely (e.g., <button>).
This is usually the desired behavior in HTML, as the mere presence of an attribute like disabled makes it active. However, it can be confusing if you expect to see disabled="false" literally in the DOM. Alpine handles this correctly by standard HTML conventions.
<button :disabled="isProcessing">Submit</button>
<!-- If isProcessing a: true, renders as: <button disabled>Submit</button> -->
<!-- If isProcessing a: false, renders as: <button>Submit</button> -->
One-way bind with :value. Use x-model for two-way. Input updates are manual here for demo.
Submit button disabled if name is less than 3 characters.
Current :src:
Current :style border:
Current :style color: