What Are FSCSS Modules?

An FSCSS module is simply a stylesheet that contains reusable style definitions. Think of them as building blocks for your CSS architecture.

Example Module
@define radius-util(){`
@arr radius[count(200)]

.radius-@arr.radius[]{
  border-radius:@arr.radius[]px;
}
`}

This module defines a reusable utility called radius-util. It doesn't run automatically. Instead, you import it and execute it when you want.

Usage
@import((radius-util) from spacing-utils/fscss)

@radius-util()

This generates all the radius utilities from 1px to 200px.

What is @define? Core Concept

The Foundation of Reusable Code

@define creates a reusable block of FSCSS code. Think of it like:

A Function

Takes parameters, returns generated CSS

A Macro

Expands into multiple CSS rules

A Code Generator

Produces CSS on demand

Simple @define Example
@define card(){`
.card{
  padding:20px;
  border-radius:10px;
}
`}

/* Then run it: */
@card()

/* Outputs the CSS */
.card{
  padding:20px;
  border-radius:10px;
}

Why FSCSS Requires @define

FSCSS does not automatically run imported code. This design has several important benefits:

1. Performance

If every import executed immediately, large libraries would generate thousands of unused styles. With @define, nothing runs unless you call it.

@radius-util()

This keeps styles smaller and more efficient.

2. Control

Developers choose exactly which modules to run.

@import((radius-util, margin-util) from spacing-utils/fscss)

@radius-util()

Only radius utilities are generated.

3. Customization

You can overwrite the array used for the specific function

@arr radius[count(100)]
@radius-util()

Which might generate utilities only up to 100.

Named Imports vs Wildcard *

Why Import by Name Instead of *

Named Import (Recommended)
@import((radius-util) from spacing-utils/fscss)

This imports only that specific definition.

Wildcard Import (Use with Caution)
@import((*) from spacing-utils/fscss)

This imports everything from the module.

Disadvantages of *

  • All utilities are loaded, even if you don't use them
  • Larger compiled CSS output
  • Slower compile time
  • Potential naming conflicts

Example problem: @import((*) from huge-library) might generate 10,000+ unused classes.

Advantages of Named Imports

@import((radius-util, padding-util) from spacing-utils/fscss)
  • Smaller CSS output
  • Faster compilation
  • Better project organization
  • Predictable output

Why FSCSS Libraries Are Usually Remote

Remote Import Example
@import((icon-base, icon-home) from icon-mask_v2)
/* Resolves to: */
https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/icon-mask_v2.fscss

FSCSS encourages remote modular libraries because:

1. Sharing

Libraries can be reused across multiple projects without copying files.

2. Updates

When the library improves, users automatically get improvements without manual updates.

3. Distribution

Easy distribution through CDNs and package managers.

What FSCSS Does NOT Allow

Direct Style Imports Without @define

FSCSS does NOT allow:

@import(body from module) ❌ Not allowed

If raw styles were imported directly, it would create several problems:

1. No Control Over Execution

Everything would load automatically, whether you need it or not.

2. Name Collisions

Multiple modules could overwrite each other's styles.

3. Large CSS Output

Unused styles would still be generated, bloating your CSS.

Advantages of @define in Your Own Stylesheet

You can build your own reusable components with parameters:

Parameterized Module
@define button(color:#6366f1){`
.btn{
  background:@use(color);
  color:white;
  padding:10px 20px;
  border-radius:6px;
}
`}

/* Usage with default color */
@button()

/* Usage with custom color */
@button(red)

Building Your Own Modular FSCSS System

Organize Your Modules

You can organize files like this:

fscss-modules/utils.fscss

@define spacing-utils(){/*... */} 
@define radius-utils(){/*... */}
@define flex-utils(){/*... */} 
@define grid-utils(){/*... */} 
@define typography-utils(){/*...*/} 

Then import them selectively:

@import((spacing-utils, flex-utils) from "fscss-modules/utils.fscss")

And run them when needed:

@spacing-utils()
@flex-utils()

Module File

Contains @define blocks

Import

Select what you need

Initialize

@module-name()

Is Initializing with @name() Necessary?

Yes, Initialization Is Required

This step executes the defined module. Without it, nothing happens.

@import((radius-util) from spacing-utils/fscss)

If you do not run:

@radius-util()

Then no utilities are generated. The module is imported but not executed.

Why This Design Matters

The FSCSS modular system provides:

Feature Benefit
Better Control Choose exactly which styles to generate
Smaller CSS Output Only generate what you actually use
Reusable Style Generators Build once, use everywhere
Scalable Architecture Grows from small projects to large design systems

FSCSS allows developers to build CSS generators. This makes it possible to create entire utility frameworks using just a few reusable definitions.

Summary

FSCSS modules allow you to treat styles like reusable building blocks. By combining FSCSS methods, developers can create flexible style systems that scale from small projects to large design systems.

Key Takeaway 1

Use @define to create reusable style generators

Key Takeaway 2

Always initialize modules with @name()

Key Takeaway 3

Use named imports instead of * for smaller CSS

The modular approach keeps code organized, reusable, and efficient.