Theme Framework How the LeaseLeads theme frontend works

Fields → CSS

How App\Fields\* classes emit the editor's style settings as inline custom properties and utility classes the colocated SCSS consumes.

On this page 4

The first two bridges carry data to JS. The third carries the editor's style choices — background, spacing, border, navigation colors — to SCSS, and it does so without a front-end dev ever touching PHP. A App\Fields\* class turns each editor setting into either an inline CSS custom property or a utility class on the element. The colocated SCSS reads those variables. That's the whole seam.

Fields emit --vars + classes

A Field is a PHP class under App\Fields\ with static render helpers. Border emits one custom property for the chosen color:

php
public static function cssVars(array $data): string
{
    return '--border-color: '.ColorSelect::getCssColor($data['color']).';';
}

Spacing emits utility classes instead — one per edge, encoding the toggle and its size choice:

php
public static function spacingClasses($data)
{
    // ...
    if ($data['padding_top']) {
        $classes[] = 'padding-top-'.$data['padding_top_size'];
    } else {
        $classes[] = 'padding-top-none';
    }
    // margin_top, padding_bottom, margin_bottom …
    return implode(' ', $classes);   // e.g. "has-spacing padding-top-lg margin-top-none …"
}

Background does both at once — a marker class when any layer exists, plus a block of per-device custom properties:

php
public static function backgroundClasses(?array $data): string
{
    return empty($data ?? []) ? '' : 'has-background';
}

public static function backgroundVars(?array $data, string $size = 'xxlarge'): string
{
    // ...per device: desktop / tablet / mobile
    $vars[] = "--bg-images--{$device}: ".implode(', ', $images).';';
    $vars[] = "--bg-positions--{$device}: ".implode(', ', $positions).';';
    $vars[] = "--bg-repeats--{$device}: ".implode(', ', $repeats).';';
    $vars[] = "--bg-sizes--{$device}: ".implode(', ', $sizes).';';
    return implode("\n\t\t", $vars);
}

The view stitches them onto the element

The Module's view calls the class helpers into the class and style attributes. Classes go in class, custom properties go in style:

php
<section
  class="module intro animate <?= Background::backgroundClasses($options['background']); ?> <?= Spacing::spacingClasses($advanced['spacing']); ?>"
  style="
    <?= Background::backgroundVars($options['background']); ?>
    <?= Border::cssVars($options['border']); ?>
    <?= Navigation::cssVars($options['navigation']); ?>
  ">

The rendered element carries everything the SCSS needs — has-background, padding-top-lg, --bg-images--desktop: …, --border-color: … — with no JavaScript in the loop.

The SCSS consumes the variables

The colocated stylesheet reads the emitted properties. The editor's choice reaches the pixel purely through the custom property:

scss
.notched-border {
  border-color: var(--border-color);
}

Spacing's utility classes hook into the rhythm system: the Spacing Field's padding-* / margin-* classes override the Module's default --vertical-* rhythm variables, so an editor's size choice retunes the fluid spacing scale without new CSS.

Note

Why custom properties, not compiled CSS. Editor settings are per-instance and unbounded — you can't compile a class for every color a user might pick. A custom property is the one CSS primitive that carries a runtime value into a static stylesheet, so the SCSS is authored once against var(--border-color) and each element supplies its own value inline. Utility classes handle the enumerable choices (a fixed set of spacing sizes); custom properties handle the open-ended ones (any color, any image).

Important

This page is the conceptual seam only — Field emits, SCSS consumes. How the SCSS actually consumes each variable, and the rhythm/gutter scale behind Spacing, lives in Styling. Don't duplicate the consumption details here.

  • The rhythm system — the --vertical-* scale the Spacing Field overrides.
  • data-* options — the bridge for scalar config that reaches JS instead of SCSS.
  • Data islands — the bridge for collections and structured payloads.