Labs ICT
Pro Login

Dynamic Attributes

th:attr and custom attribute expressions.

Dynamic Attributes in Thymeleaf

Sometimes you need to set HTML attributes dynamically. Thymeleaf gives you several ways to do this, from simple value replacements to complex multi-valued attributes.

th:attr for Any Attribute

The th:attr attribute sets any HTML attribute dynamically. Use it when there's no specific Thymeleaf attribute for what you need.


<img th:attr="src=@{/img/product.png}, alt=${product.name}"/>
    

This sets both src and alt at once. The @{...} syntax handles the context path for the source.

Custom Attributes

Custom HTML attributes work the same way. Use th:attr to set them based on model data.


<div th:attr="data-user-id=${user.id}"></div>
<button th:attr="data-action=${actionUrl}">Click</button>
    

This generates data-user-id="42" and data-action="/api/process". JavaScript can read these with dataset.

th:altappend and Similar

Some attributes like altappend let you add to an existing value instead of replacing it.


<img src="base.png" th:altappend=" - Product Image" th:text="${product.name}"/>
    

The alt becomes "Base Product - Product Image". Useful for building on existing attribute values.

Try it Yourself →

Multi-Valued Attributes

For attributes that accept multiple values (like CSS classes), separate them with commas in th:attr.


<div th:attr="class=${isActive} ? 'active highlighted' : 'inactive'"></div>
    

This conditionally sets multiple classes. You can also use th:classappend for adding classes without removing existing ones.

Practical Example: Product Card

Here's a real-world example using multiple dynamic attributes.


<div class="product-card">
    <img th:attr="src=@{/images/} + ${product.image},
                    alt=${product.name},
                    data-price=${product.price}"/>
    <h3 th:text="${product.name}">Product</h3>
    <button th:attr="data-product-id=${product.id},
                     disabled=${product.stock == 0}">
        Add to Cart
    </button>
</div>
    

Each attribute pulls its value from the model. The template stays clean while the output adapts to the data.