sercrod

:class

Summary

:class is an attribute binding directive that computes the class attribute from a Sercrod expression. It writes directly to the element’s className property and supports three main value shapes:

The binding is one way: Sercrod updates the element’s classes from data, but changes to className in the DOM are not written back to data.

Basic example

A simple conditional class:

<serc-rod id="app" data='{
  "isActive": true,
  "isDisabled": false
}'>
  <button :class="[
    'btn',
    isActive && 'btn-active',
    isDisabled && 'btn-disabled'
  ]">
    Click me
  </button>
</serc-rod>

Behavior:

Behavior

Core rules for :class:

Value forms in detail

String form:

<button :class="'btn btn-primary'">Save</button>

Array form:

<button :class="[
  'btn',
  size === 'large' && 'btn-lg',
  variant === 'danger' && 'btn-danger'
]">
  Delete
</button>

Object form:

<button :class="{
  'btn': true,
  'btn-active': active,
  'btn-disabled': disabled
}">
  Submit
</button>

Evaluation timing

:class is evaluated in the attribute binding phase of element rendering.

Rough order:

There is no separate scheduling for :class. It participates in the normal render update process like other colon bindings.

Execution model

Conceptually, when Sercrod processes an element with :class, the steps are:

  1. It encounters an attribute with name :class and reads its value as an expression string.
  2. It evaluates that expression using eval_expr with the current scope, and a context where:
    • el is the source template node for this element,
    • mode is "attr:class".
  3. It inspects the type of the returned value:
    • string, array, or object are handled as described above.
    • Any other type yields an empty className.
  4. It writes the computed class list into el.className, replacing any previous className on that element.
  5. If evaluation throws, Sercrod sets el.className to an empty string as a defensive default.
  6. If cleanup.handlers is enabled, Sercrod removes the original :class attribute from the rendered element.

Important detail:

Scope and data access

The :class expression is evaluated in the same scope as other Sercrod expressions:

There is no special scope for :class beyond what the element would normally see in its context.

Use with static class attributes and other directives

Static class attributes:

<button class="btn" :class="isPrimary ? 'btn btn-primary' : 'btn btn-secondary'">
  Save
</button>

Best practice:

Interaction with other directives:

Best practices

Additional examples

Classes driven by item state in a loop:

<serc-rod id="list" data='{
  "items": [
    { "label": "Alpha", "active": true,  "disabled": false },
    { "label": "Beta",  "active": false, "disabled": false },
    { "label": "Gamma", "active": false, "disabled": true  }
  ]
}'>
  <ul>
    <li *each="item of items"
        :class="{
          'item': true,
          'item-active': item.active,
          'item-disabled': item.disabled
        }">
      <span :text="item.label"></span>
    </li>
  </ul>
</serc-rod>

Responsive classes:

<serc-rod id="layout" data='{
  "compact": true
}'>
  <div :class="compact ? 'layout layout-compact' : 'layout layout-wide'">
    <!-- content -->
  </div>
</serc-rod>

Notes