pattern() in FSCSS 1.1.25

pattern() in FSCSS 1.1.25

1 14
calendar_today agoschedule3 min read
— Originally published at dev.to

FSCSS v1.1.25 ships a new core method: pattern().

You describe what you want in plain language, and FSCSS matches the closest pattern at compile time.

pattern(0.5: "Hello World Card", `
  border-radius: 12px;
  padding: 24px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: #fff;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
`)

.card {
  hello world card
}

Compiles to:

.card {
  border-radius: 12px;
  padding: 24px;
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: #fff;
  box-shadow: 0 8px 24px rgba(0,0,0,0.25);
}

Notice .card doesn't call anything — it just contains a phrase close enough to "Hello World card" to trigger the match.

Why this exists

@define is precise but rigid. You call it by exact name, with exact arguments. That's great for a library you built yourself, but it breaks down in a few real situations:

  • Design handoffs. A designer or junior dev writes dark card with rounded corners inside a rule instead of hunting through your define library for the right call signature.
  • AI-generated markup. Tools that generate FSCSS from natural-language prompts can emit descriptive phrases instead of needing to know your exact mixin names.
  • Fast prototyping. You don't always remember what you named something six months ago. pattern() lets close-enough phrasing still resolve correctly.

pattern() doesn't replace other variable methods — it sits next to it, for cases where flexibility matters more than precision.

The syntax

pattern(threshold: "description", `
  css to inject
`)
  • threshold — a number from 0 to 1. The minimum similarity score a phrase must reach to trigger this pattern. Omit it and it defaults to 1 (near-exact match only).
  • description — the plain-language phrase you're matching against.
  • css — what gets injected when a phrase matches. Use backticks so the CSS can freely contain single or double quotes.

Threshold uses a colon, deliberately — 0.5: reads as a labeled parameter, distinct from a plain comma-separated argument. It's there so the number's purpose is visually obvious to anyone reading your stylesheet.

How matching works

Every phrase in your code gets compared against every pattern description using similarity scoring (Dice coefficient, if you're curious — it compares word overlap between the phrase and the description). The pattern with the highest score that also clears its own threshold wins.

That means:

pattern(0.8: "dark background and light color", `
  background: #212121;
  color: #ffffff;
`)

.chip {
  style dark background and light color
}

.tooltip {
  dark background light color
}

Both .chip and .tooltip resolve to the same CSS, even though neither phrase matches the description word-for-word. That's the point — you're not looking up a name, you're describing an outcome.

Tuning the threshold

  • High threshold (0.8–1) → strict. Good for short, generic descriptions where you don't want accidental matches ("button" alone would be too easy to trigger by accident).
  • Low threshold (0.4–0.6) → forgiving. Good for longer, more specific descriptions where a few words might vary but the intent is clearly the same.

If two patterns could plausibly match the same phrase, the highest-scoring one wins — so keep descriptions distinct from each other, especially at lower thresholds.

Property patterns vs. block patterns

Same split as @define:

Property patterns inject a group of declarations inside a rule:

pattern(0.6: "rounded primary button", `
  border: none;
  border-radius: 8px;
  padding: 10px 20px;
  background: #ffffff;
  color: #764ba2;
  font-weight: 600;
  cursor: pointer;
`)

.btn {
  rounded primary button
}

Block patterns inject full structures — keyframes, media queries, whole at-rules — and can stand alone outside any selector:

pattern(0.7: "Animated keyframe for spin", `
  @keyframes spin {
    0% { transform: rotate(0); }
    100% { transform: rotate(360deg); }
  }
`)

An Animated keyframe for spin

Content injection example

Because the CSS argument is just a string, pattern() isn't limited to properties — it can inject anything valid at that point in your stylesheet, including pseudo-element content:

pattern(0.9: "hello world heading", `h1:before{content: 'Hello World';}`)

  hello world heading

What's shipped in v1.1.25

  • CDN
  • API
  • CLI
  • VSCode Extention

Try it

pattern() is available on v1.1.25

Docs: fscss.devtem.org/pattern


🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Sovereign Intelligence: The Complete 25,000 Word Blueprint (Download)

Pocket Portfolio - Apr 1

The Sovereign Vault — A Comprehensive Guide to Protocol-Driven AI

Ken W. Algerverified - Jun 4

I built pure CSS 3D dice cube module: FSCSS

Figsh - Aug 7

Designing Stats UIs with FSCSS and st-core

Figsh - Apr 4

Write CSS in camelCase or snake_case — FSCSS

Figsh - Mar 28
chevron_left
862 Points15 Badges
6Posts
4Comments
4Connections
A full-stack web developer: Building smart solutions, designing meaningful experiences, and continuo... Show more

Related Jobs

View all jobs →

Commenters (This Week)

4 comments
2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!