FSCSS Documentation

Figured Shorthand CSS is a powerful CSS preprocessor that simplifies your stylesheets with intuitive shorthand syntax, reusable patterns, and enhanced functionality.

Get Started

Why Use FSCSS?

FSCSS streamlines your CSS workflow with features designed to reduce repetition, improve readability, and enhance maintainability of your stylesheets.

Faster Development

Write complex CSS with significantly less code using intuitive shorthand syntax

Improved Maintainability

Reuse styles and variables across your project for consistent updates

Enhanced Readability

Clear, concise syntax makes your stylesheets easier to understand

Variables

FSCSS variables give you flexible ways to store and reuse values across your stylesheets. They can be inline, scoped to elements, global, or even store entire blocks of styles. Define once, reuse anywhere.

Key Features

  • Inline variables: $name: value; β†’ used with $name!
  • Global variables: $global: value; β†’ available everywhere
  • Local (scoped) variables: defined inside a selector, used only in that block
  • Block variables: str(name, "block of styles") β†’ store whole chunks of CSS
  • All variables compile down to native CSS --custom-properties

Inline & Global Variables

fscss
// Inline & global variables
$primary: #3b82f6;
$secondary: #8b5cf6;
$global-font: 'Inter', sans-serif;

.button {
  background: $primary!;
  border: 2px solid $secondary!;
  font-family: $global-font!;
}

Local Variables (Scoped)

fscss
.card {
  $local-bg: #f1f5f9;
  background: $local-bg!;
  padding: 1rem;
}

Block Value Variables

Block variables let you store reusable style snippets as text, then inject them wherever needed.

fscss
str(shadowBlock, "
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  border-radius: 0.75rem;
");

.card {
  background: white;
  shadowBlock
}

Style Replacement

Store reusable style patterns and inject them wherever needed. Perfect for maintaining consistent styles across components and reducing repetition in your stylesheets.

When to Use

- Creating reusable style patterns

- Maintaining consistent component styles

- Reducing repetition in your stylesheets

- Applying complex styles with a simple reference

Practical Example

fscss
// Store a card style pattern
str(cardStyle, "
  padding: 1.5rem;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  background: white;
  transition: transform 0.3s ease;
")

// Store a hover effect
str(cardHover, "
  transform: translateY(-5px);
  box-shadow: 0 10px 15px rgba(0,0,0,0.1);
")

// Apply stored styles
.product-card {
  cardStyle
  max-width: 300px;
  
  &:hover {
    cardHover
  }
}

.user-profile {
  cardStyle
  background: #f0f9ff;
}

Repeat Function rpt()

Need to generate repeating characters, units, or patterns without writing them manually? The rpt() function repeats any value a specified number of times. Great for content, backgrounds, and decorative effects.

Practical Example

fscss
// Decorative separator
.separator::after {
  content: "rpt(10, 'β€” ')";
  display: block;
  text-align: center;
  color: #94a3b8;
  margin: 1rem 0;
}

Copy Function copy()

The copy() function extracts part of a value or string and stores it as a variable. Perfect for working with design tokens, colors, or long values you only want to write once.

Practical Example

fscss
body {
  background: #4ff000 copy(4, primary-color);
  color: $primary-color!;
}

@ext() – Value & String Extractor

@ext() lets you slice strings or values by index and store them as variables. Think of it as substring extraction, but directly inside your CSS.

Example

fscss
body {
  property: "the red color @ext(4,3: myRed)";
  color: @ext.myRed;
}

mx() / mxs()

Use mx() and mxs() to quickly apply multiple properties with the same value. mxs() takes a shared value string, while mx() requires appending colons manually.

Use Cases

Consistent Box Sizes
.card {
  mxs(width, height, max-height, max-width, min-width, min-height, '200px')
}
Flexible Value Declaration
.box {
  mx(width, height, max-height, max-width, min-width, min-height, ': 200px;')
}

Practical Example

fscss
.card {
  mxs(width, height, max-height, max-width, min-width, min-height, '200px')
}
.box {
  mx(width, height, max-height, max-width, min-width, min-height, ': 200px;')
}

AD

Shared Properties (%1 - %6, %i)

Shared values let you assign a single value to multiple properties at once. Use %2, %3, up to %6 for 2–6 properties, or %i for custom counts. This helps you reduce repetition and keep your stylesheets concise.

Use Cases

%2 - Two Properties, One Value
div{%2(width, height[: 50px;])}
%3 - Three Properties, One Value
.box{%3(border-radius, outline-width, min-width[: 5px;])}
%4 - Four Properties, One Value
h1{%4(margin, padding, gap, inset[: 10px;])}
%5 - Five Properties, One Value
button{%5(border-width, font-size, line-height, letter-spacing, word-spacing[: 2px;])}
%6 - Six Properties, One Value
.grid{%6(row-gap, column-gap, padding, margin, top, left[: 1rem;])}
fscss Try it yourself
div {
  %2(width, height[: 50px;])
}

.box {
  %3(border-radius, outline-width, min-width[: 5px;])
}

h1 {
  %4(margin, padding, gap, inset[: 10px;])
}

button {
  %5(border-width, font-size, line-height, letter-spacing, word-spacing[: 2px;])
}

.grid {
  %6(row-gap, column-gap, padding, margin, top, left[: 1rem;])
}
css
div {
  width: 50px;
  height: 50px;
}

.box {
  border-radius: 5px;
  outline-width: 5px;
  min-width: 5px;
}

h1 {
  margin: 10px;
  padding: 10px;
  gap: 10px;
  inset: 10px;
}

button {
  border-width: 2px;
  font-size: 2px;
  line-height: 2px;
  letter-spacing: 2px;
  word-spacing: 2px;
}

.grid {
  row-gap: 1rem;
  column-gap: 1rem;
  padding: 1rem;
  margin: 1rem;
  top: 1rem;
  left: 1rem;
}
div (%2)
.box (%3)

h1 (%4)

1
2
3
4

Attribute Selector Shortcut

FSCSS makes attribute selectors faster to write. For example, $(type:submit) compiles to [type='submit']. This is handy for forms, input types, roles, and any attribute-based selection.

Use Case

Target Form Buttons
$(type:submit) {
  background: green;
  color: white;
}
fscss Try it yourself
$(type:submit) {
  background: green;
  color: white;
}
css
[type='submit'] {
  background: green;
  color: white;
}

Keyframes Compact

FSCSS lets you define and apply animations in one block with $(@keyframes name, selectors, &[duration timing options]). It generates both the @keyframes and applies the animation to your elements automatically.

Use Case

Slide Animation
$(@keyframes slideIn, .box, .card, &[3s linear infinite]) {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}
fscss Try it yourself
$(@keyframes slideIn, .box, .card, &[3s linear infinite]) {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}
css
.box, .card {
  animation: slideIn 3s linear infinite;
}
@keyframes slideIn {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}
.box
.card

Vendor Prefixing (-*-)

Use the -*- prefix to automatically apply vendor-specific properties across -webkit, -moz, -ms, and -o. This ensures cross-browser compatibility without writing each prefix manually.

Use Case

Cross-Browser Transforms
.box {
  -*-transform: rotate(45deg);
}
fscss Try it yourself
.box {
  -*-transform: rotate(45deg);
}
css
.box {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}
Rotated

Function Based (@fun)

FSCSS allows defining reusable groups of values with @fun(name){...}. These can store sizes, colors, or property sets and can be referenced anywhere using dot-notation.

Use Case

Reusable Palette & Sizes
@fun(e){
  a: 100px;
  b: 200px;
}
@fun(col){
  1: #550066;
  2: #005523;
}
.box {
  width: @fun.e.a.value;
  height: @fun.e.b.value;
  background: linear-gradient(@fun.col.1.value, @fun.col.2.value);
}
fscss Try it yourself
@fun(e){
  a: 100px;
  b: 200px;
}
@fun(col){
  1: #550066;
  2: #005523;
}
.box {
  width: @fun.e.a.value;
  height: @fun.e.b.value;
  background: linear-gradient(@fun.col.1.value, @fun.col.2.value);
}
css
.box {
  width: 100px;
  height: 200px;
  background: linear-gradient(#550066, #005523);
}
Box

AD

Array Method (@arr)

The @arr() directive lets you define reusable arrays of valuesβ€”ideal for staggered animations, theming, and scalable utilities. Arrays are 1-indexed (starting from [1]), and can store numbers, colors, strings, or any valid CSS value.

Use Case

Animating with Arrays
@arr(e[0.1, 2.5, 7]);
@arr(col[red, blue, green]);

section {
  background: @arr.col[2];
}

section :nth-child(@arr.e[]) {
  animation: spin 3s linear infinite;
  animation-delay: @arr.e[]s;
  background: @arr.col[3];
}
fscss Try it yourself
@arr(e[0.1, 2.5, 7]);
@arr(col[red, blue, green]);

section {
  background: @arr.col[2];
}

section :nth-child(@arr.e[]) {
  animation: spin 3s linear infinite;
  animation-delay: @arr.e[]s;
  background: @arr.col[3];
}

@keyframes spin {
  0%   { transform: rotate(0); }
  100% { transform: rotate(360deg); }
}
css
section {
  background: blue;
}

section :nth-child(1) {
  animation: spin 3s linear infinite;
  animation-delay: 0.1s;
  background: green;
}

section :nth-child(2) {
  animation: spin 3s linear infinite;
  animation-delay: 2.5s;
  background: green;
}

section :nth-child(3) {
  animation: spin 3s linear infinite;
  animation-delay: 7s;
  background: green;
}

@keyframes spin {
  0%   { transform: rotate(0); }
  100% { transform: rotate(360deg); }
}
1
2
3

🎲@random() Method

The @random() method lets you apply randomized values to CSS properties, enabling dynamic, ever-changing styles without JavaScript. When combined with @arr(), it becomes a powerful tool for reusable random styling.

πŸ”§ Syntax Overview

@random([value1, value2, value3, ...])

Returns a randomly selected value from the array on each stylesheet render.

✨ Example: Randomized Button Style


.btn {
  padding: 10px 20px;
  margin: 10px;
  background: @random([lightgreen, yellow, gray]);
  color: @random([midnightblue, blue, green]);
  border: 2px groove @random([#4361ee, #f72585, #7209b7]);
  transform: translate(@random([10,30,60])px);
  rotate: @random([0,90,150])deg;
}

Each page load applies a new combination of background, color, translation, and rotation to .btn.

🧩 What You Can Build With It

  • Random button colors or positions
  • Playful or animated UI elements
  • Fast prototyping with automatic variations

πŸš€ Benefits

  • Dynamic UI: Fresh styles every reload
  • Reusable: Combine with @arr()
  • No JS Needed: Pure FSCSS logic
  • Clean Syntax: Short and maintainable

πŸ”š Summary

FSCSS @random() makes randomized styling effortlessβ€”perfect for motion, contrast, or playful designs without relying on JavaScript.

βœ‚οΈcopy() Function

The copy() function is used to extract and reuse parts of string values, making it ideal for design tokens, dynamic variables, or text-based CSS manipulation.

πŸ”§ Syntax Overview

copy(length, variable)
  • length: Number of characters to extract
    • Positive β†’ from the start
    • Negative β†’ from the end
    • Larger than string β†’ returns full string
  • variable: The FSCSS variable name to store the extracted result

✨ Example Usage

body {
  /* primary-color = #4ff */
  background: #4ff000 copy(4, primary-color);
  color: $primary-color!;
}

a {
  color: $primary-color!;
}

span:before {
  content: "blue or midnightblue copy(-14, my-darkblue)";
  border: 2px solid $my-darkblue!;
}

🧠 How It Works

  • copy(4, primary-color) β†’ extracts first 4 chars of #4ff000 β†’ #4ff
  • Stores result in $primary-color, reusable anywhere
  • copy(-14, my-darkblue) β†’ extracts last 14 chars from the string β†’ midnightblue

βœ… Best Practices

  • Use descriptive variable names for extracted values
  • Double-check string length when using negative values
  • Perfect for color tokens, naming consistency, and reusability

πŸ”š Summary

FSCSS copy() enables powerful string slicing and variable reuse, bringing DRY principles and token-based design to your stylesheets.

@num() – String to Number

The @num() method allows inline numeric calculations directly in your stylesheets. You can perform arithmetic like num(40 * 2) β†’ 80, and append units such as num(4 * 6)px β†’ 24px.

πŸ”§ Syntax Overview

@num(expression)
  • expression: Any valid arithmetic using + - * /
  • Units: Append units like px, %, em, etc.

✨ Example Usage

1. Calculating max-height
selector {
  max-height: num(40 * 4); /* = 160 */
}
2. Mix with @random for dynamic values
textarea {
  max-height: num(@random([40, 10, 5, 0]) + 50);
}

See the @random() method β†’

🧠 How It Works

  • num(40 * 4) β†’ evaluates to 160
  • num(10 + 20)px β†’ compiles to 30px
  • num(@random([5, 15]) * 2) β†’ produces either 10 or 30

🧩 What You Can Build With It

  • Responsive calculations without JS
  • Dynamic values with @random() and @arr()
  • Reusable math for animations, spacing, and sizing

βœ… Best Practices

  • Keep expressions simple for readability
  • Pair with @random() and @arr() for dynamic patterns
  • Use variables for clarity: @num($spacing * 2)
  • Validate unit compatibility when mixing values

πŸ”š Summary

  • Lightweight Calculation: Compute values inline with + - * /
  • Supports Units: Works with px, %, em, etc.
  • Dynamic Pairing: Combine with @random(), @arr(), @fun(), and variables
  • Cleaner Code: Math in stylesheets, no JS required

Detailed Exploration of FSCSS

FSCSS, an acronym for Figured Shorthand Cascading Style Sheet, emerges as a promising methodology within the realm of web development, specifically aimed at enhancing the efficiency and readability of CSS (Cascading Style Sheets).

Definition and Purpose

FSCSS is defined as a styling approach designed to simplify CSS by introducing shorthand notations. The primary objective is to reduce repetitive code, thereby making styles more concise and easier to maintain.

This methodology rethinks traditional CSS writing, focusing on efficiency without compromising functionality. For instance, it aims to address the common challenge of bloated CSS files, which can hinder performance and readability, especially in large-scale projects.

The evidence leans toward FSCSS being particularly beneficial for developers seeking clean and maintainable CSS structures. This is supported by its emphasis on reducing redundancy, a common pain point in web development where stylesheets can become unwieldy over time.

Key Features and Functionality

These features collectively address modern development needs where performance and maintainability are critical.

Use Cases and Adoption

Introducing FSCSS: Figured Shorthand Cascading Style Sheet

We hope you have an excellent experience exploring its features and capabilities.

The FSCSS journey began in 2022, conceived by David Hux as a robust testing framework. Early development by Figsh focused on core concepts like %2 to %6, %i, and basic variable handling using $....

Building on this foundation, FSCSS quickly evolved. As outlined in the official documentation, the framework now includes:

2023 marked a significant milestone with the copy() function and the framework’s first public release for testing.

2024 introduced improved preprocessor memory and new functions, leading into 2025 with the official npm package release of fscss.

This latest release includes:

FSCSS is officially published under the Figsh organization as the fscss package on npm. Led by David Hux and managed through the fscss-ttr initiative, it promotes collaboration and learning in the developer community.

You can find tutorials and community support on:

FSCSS File Structure Overview