Inline Style Processing
From v1.2.0, style="..." attributes go through the same pipeline as <style> blocks
What's new
Before v1.2.0, FSCSS syntax only fully resolved inside <style> elements. From v1.2.0 onward, boot also runs the compiler against every element's style attribute, so @define mixins, variables, arrays, and the rest of the pipeline work directly inline — no separate stylesheet needed for one-off or per-element styling.
This matters most when paired with the JS API: an inline mixin call can be re-compiled and swapped in at runtime with xfscss.process(), giving you dynamic, FSCSS-powered updates without hand-writing CSS in JavaScript.
How boot handles it
On runtime.js auto-boot (or a manual xfscss.reboot() / xfscss.assign() call), FSCSS:
- Processes every
<style>element, as before. - Then walks every element carrying a
styleattribute, runs it throughxfscss.process(), flattens the result withxfscss.inline(), and writes it back withsetAttribute("style", ...).
Because both passes share the same compiler, anything valid in a <style> block — @define calls, variables, arrays, patterns — is valid in a style attribute too.
Example
A @define mixin called directly from style
<script src="https://cdn.jsdelivr.net/npm/fscss@1.2.0/runtime.min.js" async></script>
<style>
@define btn-style(bg: #636EE7){
padding: 10px 20px;
color: color-mix(#dddddd, @use(bg));
background: @use(bg);
border: 2px solid;
border-radius: 25px;
font-weight: 700;
}
</style>
<button style="@btn-style(#1a2a4f)">Search</button>
<button style="@btn-style(#f00f00)">Search</button>
<button style="@btn-style(#4f4f4f)">Search</button>
Each button's style attribute compiles independently on boot, using the shared @define declared in the <style> block.
Declarations placed inline still persist after cleanup
Once a style attribute is processed, the compiled output replaces it — the original FSCSS source (including any @arr or other declaration written inline) is no longer visible in the attribute. But the array itself was registered page-wide during that processing pass, so it stays available for later calls in the same page session, even though its declaration line is gone from the DOM.
<button style="
@arr colors[#1E2783, #8C29B2, #C41348, #0098d0]
@btn-style(@arr.colors!.randint)
" onclick="update(this)">Click</button>
After boot, this button's visible style attribute is just the compiled declarations — the @arr colors[...] line is stripped — but @arr.colors is still resolvable afterward, which is what makes the dynamic update below work.
Dynamic updates with xfscss.process()
Because xfscss.process() runs the full compiler on demand, you can recompute a mixin call at any time — on a click, an interval, a data change — and write the result straight back to the element.
const update = async (btn) => {
const newStyle = await xfscss.process("@btn-style(@arr.colors!.randint)");
btn.setAttribute("style", newStyle); // flat with: xfscss.inline(newStyle)
};
Clicking the button re-resolves @arr.colors!.randint to a new random color from the array each time, then recompiles the @btn-style mixin against it — no rewritten CSS, no framework state, just FSCSS re-run on demand.
flat the result (newStyle) with xfscss.inline(newStyle) if the result includes ...{...}
Works with library mixins too
Since boot treats every style attribute the same way it treats a <style> block, mixins from imported plugin modules resolve inline as well — for example calling an st-core mixin like @st-container() directly from a style attribute works the same as calling it inside a stylesheet.
<div class="chart-line line-2" style="background: #E8A030; @st-chart-points(10, 20, 16, 15, 66, 50, 80, 54)"></div>
runtime.js vs esm.js for inline processing
runtime.js is the natural fit for pages that want this working automatically — it boots, processes every <style> and style attribute on the page, and exposes xfscss globally so you can still call process() yourself afterward for dynamic updates, as in the click example above.
esm.js fits better when you only want the compiler as a tool — for example an FSCSS-to-CSS conversion utility, or a custom pipeline that decides which elements to process and when — since it never touches the page or the DOM unless you call xfscss.reboot(), run(), or process() yourself.
See the full API
process(), inline(), assign()/reboot() and the rest are documented in full on the API reference.