Buttons that feel alive.
A toggle with a real flame inside. It is drawn live on canvas from its own state and dressed in embers, heat and a little bit of chaos.
One flame, many moods.
Every variant is the same element configured with data attributes, from a primary call to action to a habit tracker that earns its fire.
What's burning inside.
Three layers work together: the canvas flame, the interaction model and a shared ember engine.
Living flame
Layered teardrops, licking tongues and additive particles, redrawn every frame from four inputs. ON mirrors aria-pressed; Hover follows the pointer and keyboard focus.
Tap vs. hold
A quick press toggles. Hold past 250ms and a ring charges around the socket; complete it in 900ms to supercharge.
Ember engine
One fixed canvas serves every button: additive-blended embers, smoke on extinguish, and an ambient trickle while lit.
Drop it in. Light it up.
Write a plain button with data attributes. FireButton.upgradeAll() builds the socket, label and flame canvas for you.
<!-- Declarative: the script builds the inside -->
<button class="fb" type="button"
data-size="lg"
data-off="Ignite" data-on="On fire"></button>
<script src="fire-button.js"></script>
<script>
const [button] = FireButton.upgradeAll();
button.el.addEventListener("firebutton:change", (e) => {
console.log("lit?", e.detail.on);
});
button.set(true); // ignite from code
button.supercharge(); // or go all in
</script>
Attributes
data-sizesm · md · lg · xldata-off / data-onLabel for each statedata-varianticondata-surfacelightaria-pressedInitial stateMethods & events
set(on)Ignite or extinguishtoggle()Flip statesupercharge()Big burst, lights if offfirebutton:changedetail: { on }firebutton:superchargeFires after a full chargeGo on, set it off.
Hold the button until the ring closes. We promise nothing actually catches fire.