There’s something oddly satisfying about watching a progress circle fill up.
But most implementations today are either:
heavily JavaScript-driven, or
purely CSS with limited flexibility
So something different.
What if:
JavaScript only controls the value
and FSCSS handles everything visual — including logic?
The result is a small demo… but it reveals a much bigger idea.
What We’re Building
An interactive circular progress that:
updates with a range slider
changes color dynamically based on value
animates smoothly
keeps logic separated between JS and FSCSS
👉 JS = state
👉 FSCSS = styling + logic
Setup
Step 1: Import the Progress
@import((*) from circle-progress)
@progress-root()
@circle-progress(#progress[class^='p-'])
This connects FSCSS to any class like .p-50, .p-80, etc, with id='progress'.
Step 2: Add Dynamic Color Logic
@event range-color(range){
if range <=10{
return: #C86433
}
el-if range <= 30{
return: #D69308
}
el-if range <= 45{
return: #A1AC1C
}
el-if range <= 60{
return: #86CA1A
}
el-if range <= 80{
return: #1CAC52
}
el-if range <= 95{
return: #13B046
}
el{
return: #26FF00
}
}
Instead of hardcoding colors per class, we define a rule system.
Step 3: Generate All Progress States
@arr p-ranges[count(100)]
.p-0{
$range: 0;
@progress-range($range)
--progress-color-glow: @event.range-color($range);
--progress-color-arc: @event.range-color($range);
}
.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-0 → .p-99 automatically.
No manual classes. No repetition.
Step 4: Add Polish
#progress {
border-radius: 50%;
box-shadow: 0 0 20px var(--progress-color-glow);
transition: all 0.3s ease;
@progress-animate(4s)
}
Now we have:
glow effect
smooth transitions
animated progress
Step 5: JavaScript (Minimal)
const rangeInp = document.getElementById('range');
const progress = document.getElementById("progress");
rangeInp.addEventListener('input', e=>{
const percent = Math.min(Math.round(e.target.value), 100);
progress.className = `p-${percent}`;
progress.textContent = `${percent}%`;
});
That’s it.
No styling logic in JS.
This demo shows a subtle but important pattern:
Traditional approach:
JS controls everything (state + style)
This approach:
JS → updates value
FSCSS → decides appearance using logic
That means:
cleaner separation
reusable styling logic
less JS complexity
Live Demo
CodePen:
It’s just a demo…
But it hints at something bigger:
CSS is no longer just styling — it can think.
And when you combine that with JavaScript correctly,
you don’t get more complexity…
You get clarity.
Top comments (0)