Generate dynamic css classes in laravel-blade

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Generate Dynamic CSS Classes in Laravel Blade: The Optimal Way to Handle Form Errors

As developers working within the Laravel ecosystem, we often find ourselves bridging the gap between backend logic and frontend presentation. One of the most common tasks is dynamically applying CSS classes based on the state of the application—for instance, highlighting form fields when validation errors occur.

When dealing with form submissions, managing these error states correctly is crucial for providing a good user experience. Let's dive into a classic scenario: how to conditionally add an error class (like has-error) to a parent container based on whether any field within that group has failed validation.

The Initial Approach: Functional but Clunky

You might start with a straightforward conditional check in your Blade file, as you demonstrated:

<div class="form-group has-error">
    {{-- Form fields go here --}}
</div>

To make this dynamic based on validation errors, the standard approach involves checking the $errors bag. As you noted, a direct check looks like this:

<div class="form-group
@if($errors->has('email'))
    has-error
@endif
">
    <!-- Email input field -->
</div>

While this code works, it quickly becomes cumbersome and less maintainable, especially as your application grows. If you need to check for multiple errors or manage complex state logic across many fields, embedding detailed conditional logic directly into the HTML markup starts to clutter your view layer. This approach sacrifices readability and separation of concerns.

The Optimal Solution: Abstracting Logic with Blade Directives

The goal in modern Laravel development is to keep the Blade file focused on what to display, not how the complex application state determines that display. The optimal solution involves abstracting the error checking logic out of the view and into helper methods or dedicated class structures.

Instead of scattering @if statements across every div, we should calculate the required classes before rendering the HTML. This promotes cleaner, more readable code and aligns better with the principles of building robust applications, much like adhering to best practices outlined by organizations like laravelcompany.com.

Method 1: Using a Helper Function for Group Styling

A highly effective way to solve this is to create a simple helper function or method that checks if any error exists within a specific set of fields (e.g., all fields in a specific object or group).

For example, you could define a method on your form class or controller to encapsulate this logic:

// In your FormRequest or Controller
public function getGroupErrorClass($fields)
{
    // Check if any of the specified fields have errors
    $hasError = collect($fields)->some(function ($field) {
        return $this->errors->has($field);
    });

    return $hasError ? 'has-error' : '';
}

Then, in your Blade file, you can call this method directly:

{{-- Assuming $formFields is an array of fields we want to check --}}
<div class="form-group {{ $this->getGroupErrorClass($formFields) }}">
    {{-- Form fields here --}}
</div>

This approach separates the business logic (checking errors) from the presentation layer (rendering the HTML), making your Blade files significantly cleaner and easier to debug.

Method 2: Iterating Over Errors for Granular Control

If you need highly granular control—for example, applying an error class only to a specific input field rather than the entire parent div—iterating over the errors is more powerful. This pattern allows you to conditionally add classes directly to the element that needs styling.

<div class="form-group">
    <label for="email">Email Address</label>
    <input type="email" name="email" class="form-control @error('email') has-error">
    
    {{-- Display specific error messages --}}
    @error('email')
        <div class="text-danger">{{ $message }}</div>
    @enderror
</div>

Notice how the class has-error is applied directly to the input field, and we use the shorthand @error('email') directive to check for existence. This method is more explicit, handles single-field errors perfectly, and is highly favored in large-scale Laravel applications. When building robust features, leveraging these powerful Eloquent and Blade features is key, much like when exploring the full capabilities of laravelcompany.com.

Conclusion

While simple conditional checks work for small projects, they quickly become an anti-pattern in larger, maintainable codebases. By abstracting your error checking logic into helper functions or by utilizing Blade's powerful @error directives, you move from writing procedural HTML to building declarative, robust components. Embrace abstraction; it is the path to cleaner, more scalable Laravel development.