Introduction to FSCSS Events
FSCSS @event brings logic and dynamic behavior into your stylesheets. Instead of repeating values, you can create reusable functions that return different results based on conditions.
Conditional Logic
Use if/el-if/el blocks for decision making
Reusable Functions
Create parameterized events for reuse
Dynamic Calculations
Combine with num() for mathematical operations
Comparison Operators
Use ==, >, <, >=, <= for value comparisons
Basic @event Usage
Simple Event Function
@eventThe simplest form of @event creates a function that returns values based on parameters and conditions.
/* Basic event function */
@event theme(mode) {
if mode: dark {
return: #111111;
}
el {
return: #ffffff;
}
}
/* Using the event in styles */
body {
background: @event.theme(dark);
color: @event.theme(light);
}
.container {
background: @event.theme(light);
color: @event.theme(dark);
}
Conditional Logic
Using if, el-if, and el Blocks
Conditional LogicEvents support multiple conditional blocks: if, el-if, and el for comprehensive decision making.
/* Event with multiple conditions */
@event size(type) {
if type: small {
return: 12px;
}
el-if type: medium {
return: 16px;
}
el-if type: large {
return: 20px;
}
el {
return: 24px;
}
}
/* Applying the event */
p {
font-size: @event.size(small);
}
h1 {
font-size: @event.size(large);
}
h2 {
font-size: @event.size(medium);
}
Small Text (12px)
Medium Heading (16px)
Large Heading (20px)
Return forms
return: vs return| … |
Block conditions
@event branches still use if / el-if / el.
What you return can be either one value or a whole declaration block.
| Form | Use when | Result |
|---|---|---|
return: value; |
One color, size, keyword, or expression | Substitutes a single token at the call site |
return| … | |
Several property: value lines (theme packs, token sets) |
Injects the full block where the event is called |
Single value
@event theme(mode) {
if mode: dark {
return: #111111;
}
el {
return: #ffffff;
}
}
body {
background: @event.theme(dark);
}
Block return (multi property)
Use return| to open a block and | to close it.
Inside: normal CSS custom properties (or any declarations you want emitted).
@event theme-mode(mode) {
if mode: dark {
return|
--tt-bg: #0f172a;
--tt-surface: #1e293b;
--tt-surface-2: #334155;
--tt-text: #f1f5f9;
--tt-muted: #94a3b8;
--tt-border: #334155;
--tt-border-strong: #475569;
--tt-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);
--tt-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.5), 0 2px 4px -2px rgb(0 0 0 / 0.4);
--tt-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.5), 0 4px 6px -4px rgb(0 0 0 / 0.4);
|
}
el-if mode: high-contrast {
return|
--tt-bg: #000000;
--tt-surface: #000000;
--tt-surface-2: #111111;
--tt-text: #ffffff;
--tt-muted: #ffff00;
--tt-border: #ffffff;
--tt-border-strong: #ffffff;
--tt-primary: #00ffff;
--tt-primary-fg: #000000;
--tt-secondary: #ff00ff;
--tt-secondary-fg: #000000;
--tt-success: #00ff00;
--tt-success-fg: #000000;
--tt-warning: #ffff00;
--tt-warning-fg: #000000;
--tt-danger: #ff0000;
--tt-danger-fg: #ffffff;
--tt-focus-ring: 0 0 0 3px #ffff00;
|
}
el {
return|
--tt-bg: #ffffff;
--tt-surface: #f8fafc;
--tt-surface-2: #f1f5f9;
--tt-text: #0f172a;
--tt-muted: #64748b;
--tt-border: #e2e8f0;
--tt-border-strong: #cbd5e1;
|
}
}
:root {
@event.theme-mode(light)
}
:root.dark-theme {
@event.theme-mode(dark)
}
:root.hc-theme {
@event.theme-mode(high-contrast)
}
Calling @event.theme-mode(dark) inside a rule expands to every
--tt-* line from that branch — one event, a full theme surface.
When to use which
return:— colors, font sizes, spacing steps, single keywordsreturn|…|— design-token packs, mode switches, multi-shadow sets
Prefer focused events (e.g. theme-mode only sets tokens).
Keep one responsibility per event even when the block is large.
Comparison Operators
Using Mathematical Comparisons
Comparison OperatorsEvents support comparison operators for numeric values: ==, >, <, >=, <=.
/* Event with comparison operators */
@event rating(score) {
if score >= 90 {
return: #10b981; /* Success green */
}
el-if score >= 70 {
return: #f59e0b; /* Warning yellow */
}
el-if score >= 50 {
return: #f97316; /* Orange */
}
el {
return: #ef4444; /* Danger red */
}
}
/* Applying the rating event */
.user-score-95 {
color: @event.rating(95);
}
.user-score-75 {
color: @event.rating(75);
}
.user-score-60 {
color: @event.rating(60);
}
.user-score-30 {
color: @event.rating(30);
}
Math and num() Function
Dynamic Calculations
num() FunctionCombine events with the num() function for dynamic mathematical calculations.
/* Event with mathematical calculations */
@event spacing(level) {
if level == 1 {
return: num(4*2)px;
}
el-if level == 2 {
return: num(8*2)px;
}
el-if level == 3 {
return: num(16*2)px;
}
el {
return: num(32*2)px;
}
}
/* Applying the spacing event */
.card-small {
padding: @event.spacing(1);
}
.card-medium {
padding: @event.spacing(2);
}
.card-large {
padding: @event.spacing(3);
}
.card-xlarge {
padding: @event.spacing(4);
}
Advanced Composition
Events with Variables
AdvancedEvents can work with variables for even more flexibility and reusability.
/* Define variables */
$dark-bg: #111111;
$light-bg: #ffffff;
$dark-text: #333333;
$light-text: #f8fafc;
/* Event using variables */
@event themedBackground(mode) {
if mode: dark {
return: $dark-bg!;
}
el {
return: $light-bg!;
}
}
@event themedText(mode) {
if mode: dark {
return: $light-text!;
}
el {
return: $dark-text!;
}
}
/* Applying the themed events */
body {
background: @event.themedBackground(dark);
color: @event.themedText(dark);
}
.container {
background: @event.themedBackground(light);
color: @event.themedText(light);
}
Creative Examples
Real-World Use Cases
Practical ApplicationsExplore practical ways to use @event in real-world projects.
Responsive Breakpoints
@event device(width) {
if width <= 480 {
return: mobile;
}
el-if width <= 1024 {
return: tablet;
}
el {
return: desktop;
}
}
.container {
flex-direction: @event.device(768);
}
Accessibility Levels
@event accessibility(level) {
if level: high {
return: 1.5;
}
el-if level: medium {
return: 1.25;
}
el {
return: 1;
}
}
body {
line-height: @event.accessibility(high);
}
Component States
@event button(state) {
if state: primary {
return: #3b82f6;
}
el-if state: success {
return: #10b981;
}
el-if state: warning {
return: #f59e0b;
}
el-if state: danger {
return: #ef4444;
}
el {
return: #64748b;
}
}
.btn {
background: @event.button(primary);
}
Best Practices
Using @event Effectively
Follow these guidelines to make the most of @event in your projects.
Clear Naming
Use descriptive names like theme, spacing, device
Single Responsibility
Keep events focused on one specific task
Reusability
Design events to be reusable across your project
Documentation
Always use block comments (/* */) for documentation
return|…| for token packs; use return: for one-off values/* Good - focused on one responsibility */
@event spacing(level) {
if level: small { return: 8px; }
el-if level: medium { return: 16px; }
el { return: 24px; }
}
/* Avoid - doing too many things */
@event everything(type, size, color) {
/* Complex nested conditions... */
}