Skip to content

@block

The @block directive declares a named style component. This is the core construct of ECSS.

Syntax

ecss
@block Name {
  /* content */
}

With inheritance:

ecss
@block Child extends Parent {
  /* content */
}

Block name

A @block name must start with a capital letter (PascalCase): Button, Card, NavItem. All @block names within a single file must be unique.

Block body

Inside a @block, the following are allowed:

ElementDescription
CSS declarationscolor: red;, display: flex;, etc.
CSS rules&:hover { }, & > .child { }
@paramParameter declaration
@elementNested element declaration
@if / @elseif / @elseConditional styles
@constLocal constant
@debugConsole output when debugging
@externalContextual styles for another block

Parameters

Parameters are declared with @param inside the block body. They control which CSS rules are applied to the component.

ecss
@enum Variant {
  values: "primary", "secondary";
}

@block Card {
  @param --variant Variant;
  @param --elevated boolean;

  padding: 24px;
  border-radius: 12px;
  background: #fff;

  @if (--elevated) {
    box-shadow: 0 4px 16px rgb(0 0 0 / 0.1);
  }

  @if (--variant == "primary") {
    border: 2px solid #646cff;
  }
}

For more on parameter syntax, see the @param reference.

Inheritance (extends)

A @block can extend another block — the descendant gets all the parent's styles plus its own. The parent block must be declared in the same file or imported via @import.

ecss
@block Pressable {
  cursor: pointer;
  user-select: none;

  &:active {
    transform: scale(0.98);
  }
}

@block Button extends Pressable {
  @param --variant Variant;

  display: inline-flex;
  padding: 8px 16px;
  border-radius: 6px;
  border: none;
}

The parent's parameters are inherited by the descendant — you cannot declare a @param with the same name in the child block:

ecss
@block Pressable {
  @param --disabled boolean;
}

@block Button extends Pressable {
  @param --disabled boolean; // error: --disabled is already inherited from Pressable
}

Inheritance chain

Blocks can be arranged in a chain — each next one extends the previous:

ecss
@block Base { /* ... */ }
@block Enhanced extends Base { /* ... */ }
@block Specialized extends Enhanced { /* ... */ }

Example

ecss
// Alert.ecss
@enum Status {
  values: "default", "success", "warning", "error";
}

/** Notification card. */
@block Alert {
  @param --status Status;
  @param --dismissible boolean;

  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px;
  border-radius: 8px;
  border: 1px solid transparent;

  @if (--status == "success") {
    background: #f0fff4;
    border-color: #68d391;
    color: #276749;
  }

  @if (--status == "warning") {
    background: #fffaf0;
    border-color: #f6ad55;
    color: #7b341e;
  }

  @if (--status == "error") {
    background: #fff5f5;
    border-color: #fc8181;
    color: #9b2c2c;
  }

  @if (--dismissible) {
    padding-right: 40px;
  }
}
tsx
import { EAlert } from './Alert.ecss';

function App() {
  return (
    <EAlert params={{ status: 'success', dismissible: true }}>
      Operation completed successfully
    </EAlert>
  );
}

See also

  • @param — declaring parameters
  • @element — nested elements
  • @if — conditional styles
  • @import — importing blocks from other files