Arr::toCssClasses

Compiles an array of conditional classes into a single CSS class string.

Signature
public static function toCssClasses($array)

Parameters

ParameterTypeDescription
$$arrayarray<string, bool>|array<int, string|int>|stringClasses to compile. String keys are included when their value is truthy; numeric keys always contribute their value. A bare string is wrapped and returned as-is.

Return value

stringA space-separated class string containing the always-on entries and every conditional entry whose value was truthy.

Arr::toCssClasses is the PHP-side engine behind Blade's @class directive and the class attribute merging on components. The rule is short: numeric key means "always include the value", string key means "include the key when the value is truthy".

When to reach for it

  • Building a class attribute in a view composer, a component's PHP class, or an HTML string assembled outside Blade.
  • Returning a class string from a model accessor, such as a status badge colour.
  • Any spot where you would otherwise concatenate with a chain of ternaries.

What trips people up

Truthiness is PHP's, not JavaScript's. The string '0' is falsy in PHP, so ['sr-only' => '0'] drops the class. Cast conditions to real booleans when they come from request input or a database column stored as a string.

A numeric-looking string key flips the meaning. The check is is_numeric($class) against the key, so ['100' => $condition] is read as an always-on entry and pushes the value — a bool — into the class list. Rename such classes or write them positionally.

Nothing is escaped or de-duplicated. Repeating a class emits it twice, and interpolated values pass through unescaped, so escape anything user-supplied yourself.

When every condition is false the result is an empty string, which renders as class="" unless you check for it.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Assemble a badge's class string from a model's status inside an accessor.
  • Merge base classes with conditional state classes in a Blade component's PHP class.
  • Build a class attribute for HTML generated outside of a Blade template.

Frequently asked questions

How is Arr::toCssClasses related to Blade's @class directive?

@class compiles directly to Arr::toCssClasses, so the two accept the same array and produce the same string. Use the helper when you are building a class list in PHP rather than in a template.

Why is one of my classes missing from the output?

Its condition evaluated falsy under PHP's rules — the string '0', an empty string, 0, and null all drop the class. Cast the condition with (bool) or filter_var first.

Does Arr::toCssClasses remove duplicate classes?

No. Every entry that passes its condition is emitted, so a class listed twice appears twice. De-duplicate with array_unique beforehand if that matters.

More examples

The @class directive in Blade

Shows the two forms side by side. @class in a template and Arr::toCssClasses in PHP compile to exactly the same logic, so a component can expose a classes() method that a template consumes with {{ $classes }} and behave identically.

Example · php
<?php

// resources/views/components/alert.blade.php
//
// @class compiles straight down to Arr::toCssClasses.
//
// <div @class([
//     'alert',
//     'alert-danger' => $level === 'danger',
//     'alert-warning' => $level === 'warning',
//     'alert-dismissible' => $dismissible,
// ])>
//     {{ $slot }}
// </div>

// The equivalent in a component class:

namespace App\View\Components;

use Illuminate\Support\Arr;
use Illuminate\View\Component;

class Alert extends Component
{
    public function __construct(
        public string $level = 'info',
        public bool $dismissible = false,
    ) {}

    public function classes(): string
    {
        return Arr::toCssClasses([
            'alert',
            'alert-danger' => $this->level === 'danger',
            'alert-warning' => $this->level === 'warning',
            'alert-dismissible' => $this->dismissible,
        ]);
    }

    public function render()
    {
        return view('components.alert');
    }
}

Casting conditions so they behave

Both lines produce the same output here, which is the point: the naive version works by accident. filter_var with FILTER_VALIDATE_BOOL makes the conversion explicit so a value like 'false' or 'off' is handled correctly rather than being treated as truthy.

Example · php
<?php

use Illuminate\Support\Arr;

// Values coming from a form post or a legacy database column are strings.
$row = ['featured' => '0', 'archived' => '1', 'draft' => ''];

// Naive: '0' and '' are falsy, '1' is truthy — which happens to be right here,
// but a value of '0.0' or 'false' would not be.
echo Arr::toCssClasses([
    'card',
    'card-featured' => $row['featured'],
    'card-archived' => $row['archived'],
]), PHP_EOL;

// Explicit: filter_var makes the intent unambiguous.
$bool = fn (string $v) => filter_var($v, FILTER_VALIDATE_BOOL);

echo Arr::toCssClasses([
    'card',
    'card-featured' => $bool($row['featured']),
    'card-archived' => $bool($row['archived']),
    'card-draft' => $bool($row['draft']),
]), PHP_EOL;

/*
card card-archived
card card-archived
*/

Discussion

  • Be the first to comment on this lesson.