Skip to content

Nested Elements

A block often consists of several parts: a button has an icon and text, a card has a header and body. Such parts are declared with the @element directive inside the block.

ecss
@block Button {
  @param --variant Variant;

  display: inline-flex;
  align-items: center;
  gap: 8px;

  @element Icon {
    width: 1em;
    height: 1em;
  }

  @element Text {
    font-weight: 600;
  }
}

The element name is in PascalCase and unique within the block. Elements have no @param of their own — they style parts of the block, while the state is set by the block's own parameters.

Elements as sub-components

In the generated component, elements are available as nested components via dot notation:

tsx
import { EButton } from './Button.ecss';

<EButton as="button" params={{ variant: 'primary' }}>
  <EButton.Icon>★</EButton.Icon>
  <EButton.Text>Click me</EButton.Text>
</EButton>;

Sub-components support the as prop (<div> by default) but do not accept params.

Element styles depending on the block

An element can be styled based on the block's parameters — to do this, place @element inside an @if or a nested rule:

ecss
@block Button {
  @param --variant Variant;

  @if (--variant == "primary") {
    @element Icon {
      color: #fff;
    }
  }
}

Next steps