State-Animations.css

Ready-made CSS animations for interactive UIs with State.js. Perfect for dashboards, web apps, games, and more. Just copy and paste!

Progress Bar with Animations

A complete progress indicator that automatically changes color and animations based on value. Perfect for health bars in games, download progress, storage meters, or any value-based UI.

Live Demo

Health: 100

How This Demo Works

<!-- Health bar container -->
<div id="healthDemo"
     data-state
     data-state-watch="health"
     data-health="100"
     data-health-min="0"
     data-health-max="100">

    <div class="health-bar">
        <div class="health-fill"></div>
    </div>
    <div>Health: <span data-state-display="health">100</span></div>

    <!-- Slider that auto-updates the health -->
    <input type="range"
           data-state
           data-state-bind="healthDemo"
           data-state-attr="health"
           min="0" max="100" value="100">
</div>

<style>
.health-bar {
    width: 100%;
    height: 40px;
    background: #333;
    border-radius: 20px;
    overflow: hidden;
}
.health-fill {
    height: 100%;
    background: linear-gradient(90deg, #ff0000 0%, #ffff00 50%, #00ff00 100%);
    width: var(--state-health-percent);
    transition: width 0.3s ease-out;
}
</style>

What happens automatically:

Counter with Milestone Animations

Dynamic counter that celebrates milestones automatically. Great for scores, points, views, likes, download counts, or any numeric metric.

Live Demo

Score: 0

How This Demo Works

<!-- Score container -->
<div id="scoreDemo"
     data-state
     data-state-watch="score"
     data-score="0"
     data-score-min="0"
     data-score-max="1000">

    <div class="score-display">
        Score: <span data-state-display="score">0</span>
    </div>

    <!-- Slider to test different scores -->
    <input type="range"
           data-state
           data-state-bind="scoreDemo"
           data-state-attr="score"
           min="0" max="1000" step="10" value="0">
</div>

<style>
.score-display {
    font-size: 48px;
    font-family: 'Bebas Neue', sans-serif;
}
</style>

What happens automatically:

Boolean State Toggles

Visual effects for active/inactive states using boolean toggles. Perfect for power-ups in games, feature flags, premium status, active subscriptions, or any on/off state.

Live Demo

PLAYER

How This Demo Works

<!-- Player with power-up states -->
<div id="powerDemo"
     data-state
     data-state-toggles="powered,invincible,shielded,stunned"
     data-powered="false"
     data-invincible="false"
     data-shielded="false"
     data-stunned="false">
    PLAYER
</div>

<!-- Buttons that toggle power-ups -->
<button data-state
        data-state-trigger
        data-state-bind="powerDemo"
        data-state-toggle="powered">
    Toggle Powered
</button>

<button data-state
        data-state-trigger
        data-state-bind="powerDemo"
        data-state-toggle="invincible">
    Toggle Invincible
</button>

Available power-up classes:

Tier/Level Change Animation

Celebrate tier changes, level ups, or rank promotions with a bright flash animation. Great for games, achievement systems, subscription tiers, or user rankings.

Live Demo

Level 5

How This Demo Works

<!-- Level display -->
<div id="levelDemo"
     data-state
     data-state-toggles="level-up"
     data-level-up="false">
    Level 5
</div>

<!-- Button to trigger animation -->
<button data-state
        data-state-trigger
        data-state-bind="levelDemo"
        data-state-toggle="level-up">
    Trigger Level Up
</button>

Status Indicators

Visual effects for different status states. Perfect for game effects (poisoned, frozen, burning, healing), system states (processing, syncing, error), or any conditional visual feedback.

Live Demo

PLAYER

How This Demo Works

<!-- Player with status effects -->
<div id="statusDemo"
     data-state
     data-state-toggles="poisoned,frozen,burning,healing,cursed,blessed"
     data-poisoned="false"
     data-frozen="false"
     data-burning="false"
     data-healing="false"
     data-cursed="false"
     data-blessed="false">
    PLAYER
</div>

<!-- Buttons to toggle status effects -->
<button data-state
        data-state-trigger
        data-state-bind="statusDemo"
        data-state-toggle="poisoned">
    Poisoned
</button>

<button data-state
        data-state-trigger
        data-state-bind="statusDemo"
        data-state-toggle="frozen">
    Frozen
</button>

Available status effects:

UI Notifications

Feedback animations for success, error, warning messages.

Live Demo

NOTIFICATION

How This Demo Works

<!-- Notification element -->
<div id="notificationDemo"
     data-state
     data-state-toggles="success,error,warning"
     data-success="false"
     data-error="false"
     data-warning="false">
    NOTIFICATION
</div>

<!-- Buttons to trigger animations -->
<button data-state
        data-state-trigger
        data-state-bind="notificationDemo"
        data-state-toggle="success">
    Success
</button>

<button data-state
        data-state-trigger
        data-state-bind="notificationDemo"
        data-state-toggle="error">
    Error
</button>

Available notification classes:

Complete UI System Examples

Ready-to-use interactive components built with State.js alone. These examples demonstrate game mechanics, but the same patterns work for any interactive UI. Copy, paste, and customize!

Health System

Health: 50 / 100
Show Code
<div id="player"
     data-state-watch="health"
     data-state-var="true"
     data-health="100"
     data-health-min="0"
     data-health-max="100">

    <!-- Health Display -->
    <div>Health: <span data-state-display="health">100</span> / 100</div>

    <!-- Health Bar -->
    <div class="health-bar-container">
        <div class="health-bar" style="width: var(--state-health-percent);"></div>
    </div>

    <!-- Controls -->
    <button data-state data-state-trigger data-state-bind="player"
            data-state-attr="health" data-state-value="50">Take Damage</button>
    <button data-state data-state-trigger data-state-bind="player"
            data-state-attr="health" data-state-value="100">Heal</button>
</div>

<style>
    .health-bar-container {
        background: #444;
        height: 30px;
        border-radius: 15px;
        overflow: hidden;
    }
    .health-bar {
        background: linear-gradient(90deg, red 0%, yellow 50%, green 100%);
        height: 100%;
        transition: width 0.3s;
    }

    /* Auto-regeneration animation */
    .state-regenerating .health-bar {
        animation: regen-pulse 2s infinite;
    }

    @keyframes regen-pulse {
        0%, 100% { filter: brightness(1); }
        50% { filter: brightness(1.5); }
    }
</style>

Clicker/Counter System (Zero JavaScript)

0
Milestones at 25, 50, 75, and 100!
Show Code
<div id="clicker"
     data-state
     data-state-watch="score"
     data-state-var="true"
     data-score="0"
     data-score-max="100">

    <!-- Display -->
    <div class="score-display"><span data-state-display="score">0</span></div>

    <!-- Progress Bar -->
    <div class="progress-bar" style="width: var(--state-score-percent);"></div>

    <!-- Increment Buttons -->
    <button data-state data-state-trigger data-state-bind="clicker"
            data-state-attr="score" data-state-increment="1">+1</button>

    <button data-state data-state-trigger data-state-bind="clicker"
            data-state-attr="score" data-state-increment="5">+5</button>

    <button data-state data-state-trigger data-state-bind="clicker"
            data-state-attr="score" data-state-increment="10">+10</button>

    <!-- Reset Button -->
    <button data-state data-state-trigger data-state-bind="clicker"
            data-state-attr="score" data-state-value="0">Reset</button>
</div>

<style>
    /* Milestone celebrations using CSS alone */
    #clicker[data-score="20"],
    #clicker[data-score="30"],
    #clicker[data-score="40"] {
        animation: milestone-pulse 0.5s ease-out;
    }

    #clicker[data-score="50"] {
        animation: milestone-burst 0.8s ease-out;
    }

    #clicker[data-score="100"] {
        animation: victory-flash 1s ease-out;
    }

    @keyframes milestone-pulse {
        0%, 100% { transform: scale(1); }
        50% { transform: scale(1.05); }
    }

    @keyframes milestone-burst {
        0% { transform: scale(1); filter: brightness(1); }
        50% { transform: scale(1.1); filter: brightness(1.5); }
        100% { transform: scale(1); filter: brightness(1); }
    }

    @keyframes victory-flash {
        0%, 100% { filter: brightness(1); }
        20%, 60% { filter: brightness(2) hue-rotate(90deg); }
        40%, 80% { filter: brightness(0.5); }
    }
</style>

Inventory Toggle System

Inventory

โš”๏ธ
Sword
Status: false
๐Ÿ›ก๏ธ
Shield
Status: false
๐Ÿงช
Potion
Status: false
๐Ÿ”‘
Key
Status: false
Show Code
<div id="inventory"
     data-state-toggles="sword,shield,potion,key"
     data-sword="false"
     data-shield="false"
     data-potion="false"
     data-key="false">

    <div class="item" id="sword-slot">
        <div class="icon">โš”๏ธ</div>
        <div>Sword: <span data-state-display="sword">false</span></div>
    </div>

    <div class="item" id="shield-slot">
        <div class="icon">๐Ÿ›ก๏ธ</div>
        <div>Shield: <span data-state-display="shield">false</span></div>
    </div>

    <!-- Buttons to collect items -->
    <button data-state data-state-trigger data-state-bind="inventory"
            data-state-toggle="sword">Toggle Sword</button>
    <button data-state data-state-trigger data-state-bind="inventory"
            data-state-toggle="shield">Toggle Shield</button>
</div>

<style>
    .item {
        background: #333;
        padding: 15px;
        border-radius: 8px;
        transition: all 0.3s;
    }

    /* Highlight collected items */
    .state-sword #sword-slot,
    .state-shield #shield-slot,
    .state-potion #potion-slot,
    .state-key #key-slot {
        background: #700c0c;
        transform: scale(1.05);
        box-shadow: 0 0 20px rgba(112, 12, 12, 0.6);
    }
</style>

Game Menu System

Show Code
<div id="gameMenu"
     data-state-toggles="menuOpen,settingsOpen,creditsOpen"
     data-menuOpen="false"
     data-settingsOpen="false"
     data-creditsOpen="false">

    <button data-state data-state-trigger data-state-bind="gameMenu"
            data-state-toggle="menuOpen">Toggle Menu</button>

    <div id="mainMenu">
        <h3>Main Menu</h3>
        <button>New Game</button>
        <button>Continue</button>
        <button data-state data-state-trigger data-state-bind="gameMenu"
                data-state-toggle="settingsOpen">Settings</button>
        <button data-state data-state-trigger data-state-bind="gameMenu"
                data-state-toggle="creditsOpen">Credits</button>
    </div>

    <div id="settingsMenu">
        <h3>Settings</h3>
        <!-- Settings content -->
        <button data-state data-state-trigger data-state-bind="gameMenu"
                data-state-toggle="settingsOpen">Back</button>
    </div>
</div>

<style>
    #mainMenu, #settingsMenu, #creditsMenu {
        display: none;
        opacity: 0;
        transform: translateY(-20px);
        transition: all 0.3s;
    }

    /* Show menu when menuOpen is true */
    .state-menuOpen #mainMenu {
        display: block;
        animation: menu-slide-in 0.3s forwards;
    }

    .state-settingsOpen #settingsMenu {
        display: block;
        animation: menu-slide-in 0.3s forwards;
    }

    .state-creditsOpen #creditsMenu {
        display: block;
        animation: menu-slide-in 0.3s forwards;
    }

    @keyframes menu-slide-in {
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }
</style>

Dialogue System

Show Code
<div id="dialogue"
     data-state-toggles="dialogueActive,choice1,choice2"
     data-dialogueActive="false"
     data-choice1="false"
     data-choice2="false">

    <button data-state data-state-trigger data-state-bind="dialogue"
            data-state-toggle="dialogueActive">Talk to NPC</button>

    <div id="dialogueBox">
        <div class="npc-name">NPC:</div>
        <div class="dialogue-text">
            "Welcome, traveler! How can I help you?"
        </div>

        <button data-state data-state-trigger data-state-bind="dialogue"
                data-state-toggle="choice1">Ask about quest</button>
        <button data-state data-state-trigger data-state-bind="dialogue"
                data-state-toggle="choice2">Ask about town</button>
        <button data-state data-state-trigger data-state-bind="dialogue"
                data-state-toggle="dialogueActive">Goodbye</button>
    </div>

    <div id="response1">
        <div class="dialogue-text">"Ah yes, the ancient ruins..."</div>
        <button data-state data-state-trigger data-state-bind="dialogue"
                data-state-toggle="choice1">Back</button>
    </div>

    <div id="response2">
        <div class="dialogue-text">"This town has stood for centuries..."</div>
        <button data-state data-state-trigger data-state-bind="dialogue"
                data-state-toggle="choice2">Back</button>
    </div>
</div>

<style>
    #dialogueBox, #response1, #response2 {
        display: none;
        opacity: 0;
    }

    /* Show dialogue box when active */
    .state-dialogueActive #dialogueBox {
        display: block;
        animation: dialogue-fade-in 0.3s forwards;
    }

    /* Show responses when choices selected */
    .state-choice1 #response1,
    .state-choice2 #response2 {
        display: block;
        animation: dialogue-fade-in 0.3s forwards;
    }

    /* Hide main dialogue when viewing responses */
    .state-choice1 #dialogueBox,
    .state-choice2 #dialogueBox {
        display: none;
    }

    @keyframes dialogue-fade-in {
        to { opacity: 1; }
    }

    .dialogue-text {
        background: #1a1a1a;
        padding: 20px;
        border-radius: 10px;
        margin: 10px 0;
        border-left: 4px solid #700c0c;
    }
</style>

Enemy State Machine

๐Ÿ‘พ
Enemy Health: 100
Show Code
<div id="enemy"
     data-state-toggles="idle,attacking,stunned,defeated"
     data-state-watch="enemyHealth"
     data-state-var="true"
     data-idle="true"
     data-attacking="false"
     data-stunned="false"
     data-defeated="false"
     data-enemyHealth="100"
     data-enemyHealth-min="0"
     data-enemyHealth-max="100">

    <div class="enemy-sprite">๐Ÿ‘พ</div>

    <div class="health-bar-container">
        <div class="health-bar" style="width: var(--state-enemyHealth-percent);"></div>
    </div>

    <button data-state data-state-trigger data-state-bind="enemy"
            data-state-attr="enemyHealth" data-state-value="50">Attack</button>
    <button data-state data-state-trigger data-state-bind="enemy"
            data-state-toggle="stunned">Stun</button>
</div>

<style>
    .enemy-sprite {
        font-size: 64px;
        transition: all 0.3s;
    }

    /* Idle state - gentle bounce */
    .state-idle .enemy-sprite {
        animation: enemy-idle 2s ease-in-out infinite;
    }

    /* Attacking state - shake */
    .state-attacking .enemy-sprite {
        animation: enemy-attack 0.5s linear infinite;
    }

    /* Stunned state - dizzy */
    .state-stunned .enemy-sprite {
        animation: stunned-dizzy 0.3s linear infinite;
    }

    /* Defeated state */
    [data-enemyHealth="0"] .enemy-sprite {
        animation: death 2s ease-out forwards;
    }

    @keyframes enemy-idle {
        0%, 100% { transform: translateY(0); }
        50% { transform: translateY(-10px); }
    }

    @keyframes enemy-attack {
        0%, 100% { transform: translateX(0); }
        25% { transform: translateX(-10px); }
        75% { transform: translateX(10px); }
    }
</style>

Installation

1. Include the files

<script src="state.js"></script>
<link rel="stylesheet" href="state-animations.css">

2. Add data-state to elements

<div data-state data-state-watch="health" data-health="100">
    <!-- Your game UI -->
</div>

3. Use CSS variables or add classes

/* Use CSS variables */
.health-bar {
    width: var(--state-health-percent);
}

/* Or add animation classes */
element.classList.add('state-powered');