Modern UI development keeps pushing toward more dynamic, responsive, and intelligent interfaces. But what if some of that “logic” didn’t need JavaScript at all?
Today, I experimented with something interesting: building a fully dynamic circular progress system where values, colors, and styles are generated and computed directly inside CSS.
No loops in JS. No conditionals in JS.
Everything happens in styling.
⚡ The Goal
Create a circular progress component that:
- Supports values from 0 → 100
- Automatically generates classes like
.p-0,.p-1,.p-2, top-100 - Dynamically changes color based on the value
- Feels like a real UI component system
🧩 Setup
FSCSS CDN or it extention + npm
<script src="https://cdn.jsdelivr.net/npm/fscss@1.1.20/exec.min.js" async></script>
@import(exec(_init circle-progress))
@progress-root()
@circle-progress(.progress)
This initializes a reusable circular progress component.
🧠 Adding Logic to Styling
Instead of hardcoding colors, we define a reusable event:
@event range-color(range){
if range<=10{
return: #ff6b6b;
}
el-if range<=30{
return: #f7b267;
}
el-if range<=60{
return: #74c0fc;
}
el-if range<=99{
return: #63e6be;
}
el{
return: #38d9a9;
}
}
This acts like a function:
«Input → progress value
Output → corresponding UI color»
🔁 Generating 100 Classes Automatically
Instead of writing ".p-1", ".p-2", ".p-3" manually:
@arr p-ranges[count(100)]
Now we loop through them:
.p-@arr.p-ranges[]{
$range: @arr.p-ranges[];
@progress-range($range)
--progress-color-glow: @event.range-color($range);
--progress-color-arc: @event.range-color($range);
}
This generates:
.p-1 { ... }
.p-2 { ... }
...
.p-100 { ... }
Automatically.
🎨 Styling
body{
background: #131213;
}
🧪 Usage
<div class="progress p-10">10</div>
<div class="progress p-30">30</div>
<div class="progress p-55">55</div>
<div class="progress p-89">89</div>
<div class="progress p-100">100</div>
✨ What’s Happening Here?
Each element:
- Gets its value from the class ("p-55")
- That value is passed into "@progress-range"
- The same value is sent into "@event range-color"
- The UI updates automatically
So the system becomes:
Class → Value → Logic → Style → UI
💡 Why This Is Interesting
This fscss approach introduces a different way to think about styling:
- CSS with Logic
You’re not just styling — you’re deciding behavior
- No Repetition
No need to manually define 100 variations
- Reusable Patterns
The same "@event" can power multiple components
- Component Thinking
Styles start behaving like UI modules
Example
<script src="https://cdn.jsdelivr.net/npm/fscss@1.1.20/exec.min.js" async></script>
<style>
@import(exec(_init circle-progress))
@progress-root()
@circle-progress(.progress)
@event range-color(range){
if range<=10{
return: #ff6b6b; /* soft red */
}
el-if range<=30{
return: #f7b267; /* warm orange */
}
el-if range<=60{
return: #74c0fc; /* light blue */
}
el-if range<=99{
return: #63e6be; /* soft teal */
}
el{
return: #38d9a9; /* fresh green */
}
}
body{
background: #131213;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 20px;
gap: 15px;
}
@arr p-ranges[count(100)]
.p-0 {
@progress-range(0)
--progress-color-glow: @event.range-color(0);
--progress-color-arc: @event.range-color(0);
}
.p-@arr.p-ranges[]{
$range: @arr.p-ranges[];
@progress-range($range)
--progress-color-glow: @event.range-color($range);
--progress-color-arc: @event.range-color($range);
}
</style>
<div class="progress p-10">10</div>
<div class="progress p-30">30</div>
<div class="progress p-55">55</div>
<div class="progress p-89">89</div>
<div class="progress p-100">100</div>
🔥 Real Use Cases
This pattern can be extended to:
- Skill meters
- File upload progress
- Health/status indicators
- Dashboard analytics
- Gamification systems
We usually separate logic (JavaScript) and styling (CSS).
But this shows something interesting:
Styling itself can become expressive enough to handle structured logic.
Top comments (0)