Ui kit

Installation

Option 1: All-in-one CSS

Use it if you don't have Tailwind CSS installed and don't want to.

The quickest way to get started is to use the ready-to-use CDN link. It includes all components.


<link rel="stylesheet" href="https://ui.micka.dev/cdn/cdn.min.css" />

Self-hosting

If you prefer to host the CSS yourself, you can download the CSS file and include it from the appropriate path.

Option 2: With Tailwind

Recommended if you already have Tailwind CSS installed, produce the smallest CSS file.

Just download the Tailwind-based CSS file and import it in your app stylesheet.


@import "tailwindcss";
@import "./framework.css";

Components

Accordion

A vertically stacked set of interactive headings that each reveal a section of content.


Product Information

Our flagship product combines cutting-edge technology with sleek design. Built with premium materials, it offers unparalleled performance and reliability.

Shipping Details

We offer worldwide shipping through trusted courier partners. Standard delivery takes 3-5 business days, while express shipping ensures delivery within 1-2 business days.

All orders are carefully packaged and fully insured. Track your shipment in real-time through our dedicated tracking portal.

Return Policy

We stand behind our products with a comprehensive 30-day return policy. If you're not completely satisfied, simply return the item in its original condition.

<details class="accordion">
    <summary class="accordion__summary">Product Information</summary>
    <div class="accordion__content">
        <p class="muted">
            Our flagship product combines cutting-edge technology with sleek
            design. Built with premium materials, it offers unparalleled
            performance and reliability.
        </p>
    </div>
</details>
<details class="accordion">
    <summary class="accordion__summary">Shipping Details</summary>
    <div class="accordion__content">
        <p class="muted">
            We offer worldwide shipping through trusted courier partners.
            Standard delivery takes 3-5 business days, while express
            shipping ensures delivery within 1-2 business days.
            <br /><br />
            All orders are carefully packaged and fully insured. Track your
            shipment in real-time through our dedicated tracking portal.
        </p>
    </div>
</details>
<details class="accordion">
    <summary class="accordion__summary">Return Policy</summary>
    <div class="accordion__content">
        <p class="muted">
            We stand behind our products with a comprehensive 30-day return
            policy. If you're not completely satisfied, simply return the
            item in its original condition.
        </p>
    </div>
</details>

Product Information

Our flagship product combines cutting-edge technology with sleek design. Built with premium materials, it offers unparalleled performance and reliability.

Shipping Details

We offer worldwide shipping through trusted courier partners. Standard delivery takes 3-5 business days, while express shipping ensures delivery within 1-2 business days.

All orders are carefully packaged and fully insured. Track your shipment in real-time through our dedicated tracking portal.

Return Policy

We stand behind our products with a comprehensive 30-day return policy. If you're not completely satisfied, simply return the item in its original condition.

<!-- UNIQUE IDENTIFIER: yourAccordion1Name -->

<details class="accordion" name="yourAccordion1Name" open>
    <summary class="accordion__summary">Product Information</summary>
    <div class="accordion__content">
        <p class="muted">
            Our flagship product combines cutting-edge technology with sleek
            design. Built with premium materials, it offers unparalleled
            performance and reliability.
        </p>
    </div>
</details>
<details class="accordion" name="yourAccordion1Name">
    <summary class="accordion__summary">Shipping Details</summary>
    <div class="accordion__content">
        <p class="muted">
            We offer worldwide shipping through trusted courier partners.
            Standard delivery takes 3-5 business days, while express
            shipping ensures delivery within 1-2 business days.
            <br /><br />
            All orders are carefully packaged and fully insured. Track your
            shipment in real-time through our dedicated tracking portal.
        </p>
    </div>
</details>
<details class="accordion" name="yourAccordion1Name">
    <summary class="accordion__summary">Return Policy</summary>
    <div class="accordion__content">
        <p class="muted">
            We stand behind our products with a comprehensive 30-day return
            policy. If you're not completely satisfied, simply return the
            item in its original condition.
        </p>
    </div>
</details>

Product Information

Our flagship product combines cutting-edge technology with sleek design. Built with premium materials, it offers unparalleled performance and reliability.

Shipping Details

We offer worldwide shipping through trusted courier partners. Standard delivery takes 3-5 business days, while express shipping ensures delivery within 1-2 business days.

All orders are carefully packaged and fully insured. Track your shipment in real-time through our dedicated tracking portal.

Return Policy

We stand behind our products with a comprehensive 30-day return policy. If you're not completely satisfied, simply return the item in its original condition.

<details class="accordion accordion--border" open>
    <summary class="accordion__summary">Product Information</summary>
    <div class="accordion__content">
        <p class="muted">
            Our flagship product combines cutting-edge technology with sleek
            design. Built with premium materials, it offers unparalleled
            performance and reliability.
        </p>
    </div>
</details>
<details class="accordion accordion--border">
    <summary class="accordion__summary">Shipping Details</summary>
    <div class="accordion__content">
        <p class="muted">
            We offer worldwide shipping through trusted courier partners.
            Standard delivery takes 3-5 business days, while express
            shipping ensures delivery within 1-2 business days.
            <br /><br />
            All orders are carefully packaged and fully insured. Track your
            shipment in real-time through our dedicated tracking portal.
        </p>
    </div>
</details>
<details class="accordion accordion--border">
    <summary class="accordion__summary">Return Policy</summary>
    <div class="accordion__content">
        <p class="muted">
            We stand behind our products with a comprehensive 30-day return
            policy. If you're not completely satisfied, simply return the
            item in its original condition.
        </p>
    </div>
</details>

Aspect ratio

Displays content within a desired ratio.


Aspect ratio 16:9 example
<img
    class="aspect-ratio"
    style="aspect-ratio: 16/9"
    src="/home/aspect-ratio_example.webp"
    loading="lazy"
    alt="Aspect ratio 16:9 example"
/>

Avatar

A basic avatar component with an image and a fallback.


Avatar of John Doe JD
<div class="avatar">
    <img
        class="avatar__img"
        src="/home/avatar_example.webp"
        loading="lazy"
        alt="Avatar of John Doe"
        onerror="this.parentElement.classList.add('avatar--empty')"
    />
    <span class="avatar__fallback">JD</span>
</div>

JD
<div class="avatar avatar--empty">
    <span class="avatar__fallback">JD</span>
</div>

<button class="avatar" aria-label="John Doe's profile">
    <img
        class="avatar__img"
        src="/home/avatar_example.webp"
        loading="lazy"
        alt=""
        onerror="this.parentElement.classList.add('avatar--empty')"
    />
    <span class="avatar__fallback">JD</span>
</button>

Avatar of John Doe
Avatar of John Doe
Avatar of John Doe
<div class="avatar-group" role="group" aria-label="Stacked avatars">
    <div class="avatar">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
</div>

Avatar of John Doe
Avatar of John Doe
Avatar of John Doe
Avatar of John Doe
Avatar of John Doe
<div
    class="avatar-group avatar-group--space-2"
    role="group"
    aria-label="Avatars with different sizes"
>
    <div class="avatar avatar--xs">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--sm">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--md">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--lg">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--xl">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
</div>

Alert

Displays a callout for user attention.


<div class="alert" role="alert">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="m9 12 2 2 4-4" /></svg>
    <strong class="alert__title">
        Success! Your changes have been saved
    </strong>
    <p class="alert__content">
        This is an alert with icon, title and description.
    </p>
</div>

<div class="alert alert--destructive" role="alert">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-x-icon lucide-circle-x"><circle cx="12" cy="12" r="10" /><path d="m15 9-6 6" /><path d="m9 9 6 6" /></svg>
    <strong class="alert__title"> Unable to process your payment.</strong>
    <div class="alert__content">
        <p>Please verify your billing information and try again.</p>
    </div>
</div>

Alert dialog

A modal dialog that interrupts the user with important content and expects a response.


Are you absolutely sure?

This action cannot be undone. This will permanently delete your account and remove your data from our servers.

<!-- UNIQUE IDENTIFIER: myAlertDialog1 -->

<button
    class="button button--destructive"
    type="button"
    onclick="document.getElementById('myAlertDialog1').showModal()"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash-icon lucide-trash"><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M3 6h18"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
    Delete my account
</button>

<dialog
    class="dialog"
    id="myAlertDialog1"
    aria-labelledby="myAlertDialog1Title"
    aria-describedby="myAlertDialog1Desc"
>
    <form class="dialog__content" method="dialog">
        <header class="dialog__content__header">
            <h2 class="dialog__content__title" id="myAlertDialog1Title">
                Are you absolutely sure?
            </h2>
            <p class="dialog__content__desc" id="myAlertDialog1Desc">
                This action cannot be undone. This will permanently delete
                your account and remove your data from our servers.
            </p>
        </header>

        <footer class="dialog__content__footer">
            <button
                class="button button--outline"
                value="cancel"
                formnovalidate
            >
                Cancel
            </button>
            <button class="button button--destructive" value="submit">
                Delete
            </button>
        </footer>
    </form>
</dialog>

<script type="module">
    const dialog = document.getElementById("myAlertDialog1");
    const output = document.getElementById("myAlertDialog1Output");
    const form = dialog.querySelector("form");
    // Handle close → distinguish cancel / save
    dialog.addEventListener("close", () => {
        if (dialog.returnValue === "submit") {
            output.textContent = "✅ Submitted!";
        } else {
            output.textContent = "❌ Cancelled!";
        }
        // Reset form
        dialog.returnValue = "";
        form.reset();
    });
    // Optional: reset scroll position on submit attempt
    form.addEventListener("submit", (e) => {
        form.querySelector(".dialog__content")?.scrollTo(0, 0);
    });
</script>

<output id="myAlertDialog1Output"></output>

Appearance select

A component that allows the user to switch between light, dark and auto mode.


<!-- UNIQUE IDENTIFIER: myAppearanceSelect1 -->

<!-- Inline this inside <head> to avoid flash of unstyled content -->
<script>
    try {
        const storedAppearance = localStorage.getItem("appearance");
        applyAppearance(storedAppearance);

        function applyAppearance(value) {
            if (value === "dark" || value === "light") {
                document.documentElement.classList.toggle(
                    "dark",
                    value === "dark"
                );
                localStorage.setItem("appearance", value);
            } else {
                const isDeviceDark = window.matchMedia(
                    "(prefers-color-scheme: dark)"
                ).matches;
                document.documentElement.classList.toggle(
                    "dark",
                    isDeviceDark
                );
                localStorage.removeItem("appearance");
            }
            applyMetaColor();
        }

        function applyMetaColor() {
            const meta = document.querySelector("meta[name=theme-color]");
            if (meta == null) return;
            const appHeader = document.querySelector("body > header");
            if (appHeader == null) return;
            const newColor =
                window.getComputedStyle(appHeader).backgroundColor;
            meta.setAttribute("content", newColor);
        }

        window
            .matchMedia("(prefers-color-scheme: dark)")
            .addEventListener("change", (e) => {
                if (storedAppearance) return;
                document.documentElement.classList.toggle(
                    "dark",
                    e.matches
                );
            });

        document.addEventListener("app:appearance", (e) => {
            applyAppearance(e.detail);
        });
    } catch (err) {
        console.error(err);
    }
</script>

<!-- Usage example -->
<select class="select" id="myAppearanceSelect1" aria-label="Appearance">
    <option value="" selected>🖥️ Auto</option>
    <option value="light">☀️ Light</option>
    <option value="dark">🌙 Dark</option>
</select>
<script type="module">
    const el = document.getElementById("myAppearanceSelect1");
    el.value = localStorage.getItem("appearance") || "";
    el.onchange = (e) => {
        document.dispatchEvent(
            new CustomEvent("app:appearance", {
                detail: e.target.value,
            })
        );
    };
</script>

Badge

Displays a badge or a component that looks like a badge.


Badge Secondary Destructive Outline
<span class="badge">Badge</span>
<span class="badge badge--secondary">Secondary</span>
<span class="badge badge--destructive">Destructive</span>
<span class="badge badge--outline">Outline</span>

Verified
<span class="badge">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5" /></svg>
    Verified
</span>

Busy

Render a busy state containing a spinner indicator.



<form class="busy" id="myBusy1Form">
    <span class="busy__indicator"></span>

    <div class="field">
        <label class="field__label" for="myBusy1FormEmail">
            Email address
        </label>
        <input
            class="input"
            id="myBusy1FormEmail"
            name="busy1"
            type="email"
            placeholder="Email"
        />
    </div>
    <br />
    <button class="button" type="submit">Submit</button>
</form>

<script type="module">
    const form = document.getElementById("myBusy1Form");
    form.addEventListener("submit", (e) => {
        e.preventDefault();
        form.setAttribute("inert", "");
        form.setAttribute("aria-busy", "true");
        setTimeout(() => {
            form.removeAttribute("inert");
            form.removeAttribute("aria-busy");
        }, 2000);
    });
</script>

Button

Displays a button or a component that looks like a button.


<button class="button" type="button">Primary</button>
<button class="button button--secondary" type="button">Secondary</button>
<button class="button button--outline" type="button">Outline</button>
<button class="button button--ghost" type="button">Ghost</button>
<button class="button button--destructive" type="button">Destructive</button>

<button class="button" type="button" disabled>Disabled</button>

<button class="button" type="button">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5" /></svg>
    With icon
</button>

<button class="button button--icon" type="button" aria-label="Settings">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings-icon lucide-settings"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"/><circle cx="12" cy="12" r="3"/></svg>
</button>

<a class="button" href="#">
    Link
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-external-link-icon lucide-external-link"><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
</a>

<label class="button button--outline">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-upload-icon lucide-upload"><path d="M12 3v12"/><path d="m17 8-5-5-5 5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg>
    Upload
    <input class="button__fake" type="file" />
</label>

Button group

A container that groups related buttons together with consistent styling.


<div class="button-group" role="group" aria-label="Button group example">
    <button class="button" type="button">Copy</button>
    <span class="button-group__separator"></span>
    <button class="button" type="button">Paste</button>
</div>

<div class="button-group" role="group" aria-label="Button group example">
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Go back"
    >
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-left-icon lucide-arrow-left"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg>
    </button>

    <div
        class="button-group"
        role="group"
        aria-label="Button subgroup example"
    >
        <button class="button button--outline" type="button">
            Archive
        </button>
        <button class="button button--outline" type="button">Report</button>
    </div>
</div>



<div
    class="button-group"
    role="group"
    aria-label="Button group example in small size"
>
    <button class="button button--outline button--sm" type="button">
        Small
    </button>
    <button class="button button--outline button--sm" type="button">
        Button
    </button>
    <button class="button button--outline button--sm" type="button">
        Group
    </button>
    <button
        class="button button--outline button--sm button--icon"
        type="button"
        aria-label="Add"
    >
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
    </button>
</div>

<br />

<div
    class="button-group"
    role="group"
    aria-label="Button group example in medium size"
>
    <button class="button button--outline" type="button">Default</button>
    <button class="button button--outline" type="button">Button</button>
    <button class="button button--outline" type="button">Group</button>
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Add"
    >
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
    </button>
</div>

<br />

<div
    class="button-group"
    role="group"
    aria-label="Button group example in large size"
>
    <button class="button button--outline button--lg" type="button">
        Large
    </button>
    <button class="button button--outline button--lg" type="button">
        Button
    </button>
    <button class="button button--outline button--lg" type="button">
        Group
    </button>
    <button
        class="button button--outline button--lg button--icon"
        type="button"
        aria-label="Add"
    >
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
    </button>
</div>

Button swap

A control that allows the user to toggle between two states.


<label class="button button--ghost button--icon">
    <input class="button__swap" type="checkbox" aria-label="Mute" />
    <span class="button__swap-off" aria-hidden="true">
        <!-- prettier-ignore --><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-volume2-icon lucide-volume-2"><path d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z"/><path d="M16 9a5 5 0 0 1 0 6"/><path d="M19.364 18.364a9 9 0 0 0 0-12.728"/></svg>
    </span>
    <span class="button__swap-on" aria-hidden="true">
        <!-- prettier-ignore --><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-volume-off-icon lucide-volume-off"><path d="M16 9a5 5 0 0 1 .95 2.293"/><path d="M19.364 5.636a9 9 0 0 1 1.889 9.96"/><path d="m2 2 20 20"/><path d="m7 7-.587.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298V11"/><path d="M9.828 4.172A.686.686 0 0 1 11 4.657v.686"/></svg>
    </span>
</label>

Card

Displays a card with header, content, and footer.


<article class="card">
    <header class="card__header">
        <h3 class="card__title">Card</h3>
        <p class="card__desc">Card content</p>
    </header>
    <div class="card__content">
        <p>Card content</p>
    </div>
    <footer class="card__footer">
        <a href="#" aria-label="card action">Card action</a>
    </footer>
</article>

Chart 🚧

Beautiful charts. Built using Recharts. Copy and paste into your apps.


Work in progress...

Checkbox

Displays a checkbox or a component that looks like a checkbox.


<label class="label">
    <input class="checkbox" name="checkbox1" type="checkbox" />
    <span>Remember me</span>
</label>

Checkbox group 🚧 Element

Provides shared state to a series of checkboxes.


I want to receive
<script
    type="module"
    src="https://ui.micka.dev/cdn/elements/checkbox-group.element.js"
></script>

<fieldset class="fieldset">
    <legend class="fieldset__legend">I want to receive</legend>

    <label class="label">
        <input
            class="checkbox checkbox--master"
            type="checkbox"
            id="checkboxGroupMaster1"
        />
        <strong>All</strong>
    </label>
    <x-checkbox-group class="checkbox-group" for="checkboxGroupMaster1">
        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name1"
                checked
            />
            The weekly newsletter
        </label>
        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name2"
            />
            Offers from the company
        </label>

        <label class="label">
            <input
                class="checkbox checkbox--master"
                type="checkbox"
                id="checkboxGroupMaster2"
            />
            <strong>Partner Communications</strong>
        </label>
        <x-checkbox-group
            class="checkbox-group"
            for="checkboxGroupMaster2"
        >
            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name1"
                    checked
                />
                Partner newsletters
            </label>

            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name2"
                />
                Offers from associated companies
            </label>

            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name3"
                />
                Third-party promotions
            </label>

            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name4"
                    disabled
                />
                Premium partner offers (unavailable)
            </label>
        </x-checkbox-group>

        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name4"
                disabled
            />
            Special offers (unavailable)
        </label>
        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name5"
            />
            Product updates
        </label>
    </x-checkbox-group>
</fieldset>

Combobox 🚧 Element

Autocomplete input and command palette with a list of suggestions.


Work in progress...

Copy text Element

Copy text to clipboard.


This is some text to copy.

<script
    type="module"
    src="https://ui.micka.dev/cdn/elements/copy-text.element.js"
></script>

<p id="myTextToCopy">This is some text to copy.</p>

<x-copy-text for="myTextToCopy">
    <button
        class="button button--icon tooltip tooltip--start"
        aria-label="Copy to clipboard"
    ></button>
</x-copy-text>

Dialog

A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.


Edit profile

Make changes to your profile here. Click save when you're done.

<button
    class="button"
    type="button"
    onclick="document.getElementById('myDialog1').showModal()"
>
    Show dialog
</button>

<dialog
    class="dialog"
    id="myDialog1"
    aria-labelledby="myDialog1Title"
    aria-describedby="myDialog1Desc"
>
    <form class="dialog__content" method="dialog">
        <header class="dialog__content__header">
            <h2 class="dialog__content__title" id="myDialog1Title">
                Edit profile
            </h2>
            <p class="dialog__content__desc" id="myDialog1Desc">
                Make changes to your profile here. Click save when
                you're done.
            </p>
        </header>

        <fieldset class="dialog__content__main fieldset">
            <div class="field">
                <label class="field__label" for="myDialog1Name">
                    Name
                </label>
                <input
                    class="input"
                    id="myDialog1Name"
                    name="name"
                    autocomplete="name"
                    minlength="3"
                    required
                    aria-invalid="false"
                    aria-errormessage="myDialog1NameError"
                />
            </div>
            <div class="field">
                <label class="field__label" for="myDialog1Username">
                    Username
                </label>
                <input
                    class="input"
                    id="myDialog1Username"
                    name="username"
                    autocomplete="username"
                    required
                    aria-invalid="false"
                    aria-errormessage="myDialog1UsernameError"
                />
            </div>
        </fieldset>

        <footer class="dialog__content__footer">
            <button class="button button--outline" formnovalidate>
                Cancel
            </button>
            <button class="button" value="submit">Save changes</button>
        </footer>

        <button
            class="dialog__content__cancel"
            aria-label="Cancel"
            formnovalidate
        >
            <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18" /><path d="m6 6 12 12" /></svg>
        </button>
    </form>
</dialog>

<script type="module">
    const dialog = document.getElementById("myDialog1");
    const output = document.getElementById("myDialog1Output");
    const form = dialog.querySelector("form");
    // Optional: Close on click outside
    dialog.addEventListener("click", (e) => {
        if (e.target === dialog) dialog.close();
    });
    // Handle close → distinguish cancel / save
    dialog.addEventListener("close", () => {
        if (dialog.returnValue === "submit") {
            output.textContent =
                "✅ " +
                JSON.stringify(
                    Object.fromEntries(new FormData(form).entries())
                );
        } else {
            output.textContent = "❌ Cancelled!";
        }
        // Reset form
        dialog.returnValue = "";
        form.reset();
    });
    // Optional: reset scroll position on submit attempt
    form.addEventListener("submit", (e) => {
        dialog.querySelector(".dialog__content__main")?.scrollTo(0, 0);
    });
</script>

<output id="myDialog1Output"></output>

Diff Element

A diff component that allows the user to compare two items.


Diff example first image Diff example second image
<script type="module" src="https://ui.micka.dev/cdn/elements/slider.element.js"></script>

<x-slider class="diff aspect-ratio" style="aspect-ratio: 16/9">
    <input
        class="diff__range"
        type="range"
        min="0"
        max="100"
        value="50"
        aria-label="Image comparison slider"
        ondblclick="this.value = this.defaultValue"
    />
    <div class="diff__line">
        <div class="diff__line__thumb">
            <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-grip-vertical-icon lucide-grip-vertical"><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
        </div>
    </div>
    <img
        class="diff__content"
        src="/home/aspect-ratio_example.webp"
        loading="lazy"
        alt="Diff example first image"
    />
    <img
        class="diff__content"
        style="filter: blur(1.5rem);"
        src="/home/aspect-ratio_example.webp"
        loading="lazy"
        alt="Diff example second image"
    />
</x-slider>

Field 🚧

Combine labels, controls, and help text to compose accessible form fields and grouped inputs.


Payment Method

All transactions are secure and encrypted

Name on card is required
Enter your 16-digit card number

Billing address

The billing address associated with your payment method

<form>
    <fieldset class="fieldset">
        <legend class="fieldset__legend">Payment Method</legend>
        <p class="fieldset__desc">
            All transactions are secure and encrypted
        </p>

        <div class="field-group">
            <div class="field">
                <label class="field__label" for="myField1Label">
                    Name on card
                </label>
                <input
                    class="input"
                    id="myField1Label"
                    name="nameOnCard"
                    type="text"
                    placeholder="Evil Rabbit"
                    required
                />
                <div class="field__error" aria-live="polite">
                    Name on card is required
                </div>
            </div>

            <div class="field">
                <label class="field__label" for="myField2Label"
                    >Card number</label
                >
                <input
                    class="input"
                    id="myField2Label"
                    name="cardNumber"
                    type="text"
                    placeholder="1234 5678 9012 3456"
                    required
                />
                <div class="field__desc">
                    Enter your 16-digit card number
                </div>
            </div>

            <div
                class="field-group field-group__horizontal"
                role="group"
            >
                <div class="field">
                    <label class="field__label" for="expiryMonth"
                        >Month</label
                    >
                    <select
                        class="select"
                        name="expiryMonth"
                        id="expiryMonth"
                        required
                    >
                        <option value="" selected disabled>MM</option>
                        <option value="1">January</option>
                        <option value="2">February</option>
                        <option value="3">March</option>
                        <option value="4">April</option>
                        <option value="5">May</option>
                        <option value="6">June</option>
                        <option value="7">July</option>
                        <option value="8">August</option>
                        <option value="9">September</option>
                        <option value="10">October</option>
                        <option value="11">November</option>
                        <option value="12">December</option>
                    </select>
                </div>

                <div class="field">
                    <label class="field__label" for="expiryYear">
                        Year
                    </label>
                    <select
                        class="select"
                        name="myField4"
                        id="expiryYear"
                        required
                    >
                        <option value="" selected disabled>YYYY</option>
                        <option value="2022">2024</option>
                        <option value="2023">2025</option>
                        <option value="2022">2026</option>
                        <option value="2021">2027</option>
                        <option value="2020">2028</option>
                        <option value="2019">2029</option>
                    </select>
                </div>

                <div class="field">
                    <label class="field__label" for="cvv">CVV</label>
                    <input
                        class="input"
                        id="cvv"
                        name="cvv"
                        type="text"
                        placeholder="123"
                        required
                    />
                </div>
            </div>

            <hr />

            <fieldset class="fieldset">
                <legend class="fieldset__legend">
                    Billing address
                </legend>
                <p class="fieldset__desc">
                    The billing address associated with your payment
                    method
                </p>

                <div class="field-group">
                    <div class="field field--horizontal">
                        <input
                            id="mySameAsShipping1"
                            class="checkbox"
                            name="sameAsShipping"
                            type="checkbox"
                        />
                        <label
                            for="mySameAsShipping1"
                            class="field__label field__label--normal"
                        >
                            Same as shipping address
                        </label>
                    </div>
                    <div class="field">
                        <label for="myComments1" class="field__label">
                            Comments
                        </label>
                        <textarea
                            class="textarea"
                            id="myComments1"
                            name="myComments1"
                            placeholder="Add any additional comments"
                        ></textarea>
                    </div>
                </div>
            </fieldset>
        </div>
    </fieldset>
</form>

Hover card 🚧 Element

For sighted users to preview content available behind a link.


@nextjs
<script
    type="module"
    src="https://ui.micka.dev/cdn/elements/floating.element.js"
></script>

<a
    class="link"
    href="https://nextjs.org"
    aria-describedby="myHoverCard1"
>
    @nextjs
</a>

<x-hover-card
    id="myHoverCard1"
    class="hover-card hover-card--bottom hover-card--center"
    aria-hidden="true"
>
    <!-- Your content -->
    <div
        style="display: flex; gap: 1rem; justify-content: space-between; max-width: 320px"
    >
        <div class="avatar">
            <img
                class="avatar__img"
                alt="Avatar of John Doe"
                src="/home/avatar_example.webp"
            />
        </div>
        <div
            style="display: flex; flex-direction: column; gap: 0.25rem"
        >
            <h4
                style="font-size: var(--text-sm); font-weight: var(--font-weight-semibold)"
            >
                @nextjs
            </h4>
            <br />
            <p style="font-size: var(--text-sm)">
                The React Framework – created and maintained by @vercel.
            </p>
            <div class="muted">Joined December 2021</div>
        </div>
    </div>
    <!-- / Your content -->
</x-hover-card>

Indicator 🚧

Place an element on the corner of another element.


<button class="button button--outline" type="button" aria-label="Top end">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-inbox-icon lucide-inbox"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>
    Inbox
    <span class="indicator">6</span>
</button>


<div
    style="display: grid; gap: calc(var(--spacing) * 2); grid-template: repeat(3, min-content) / repeat(3, min-content); width: fit-content;"
>
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Top start"
    >
        ↖
        <span class="indicator indicator--top indicator--start">1</span>
    </button>
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Top"
    >
        ↑
        <span class="indicator indicator--top">2</span>
    </button>
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Top end"
    >
        ↗
        <span class="indicator">3</span>
    </button>

    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Left"
    >
        ←
        <span class="indicator indicator--left">4</span>
    </button>
    <br />
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Right"
    >
        →
        <span class="indicator indicator--right">5</span>
    </button>

    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Bottom end"
    >
        ↙
        <span class="indicator indicator--bottom indicator--start">6</span>
    </button>
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Bottom"
    >
        ↓
        <span class="indicator indicator--bottom">7</span>
    </button>
    <button
        class="button button--outline button--icon"
        type="button"
        aria-label="Right"
    >
        ↘
        <span class="indicator indicator--bottom indicator--end">8</span>
    </button>
</div>



<button class="avatar">
    <img
        class="avatar__img"
        src="/home/avatar_example.webp"
        loading="lazy"
        alt="Avatar of John Doe"
    />
    <span class="avatar__fallback">JD</span>
    <span
        class="indicator indicator--sm indicator--ping"
        role="status"
        aria-label="Is online"
    ></span>
</button>

<br />

<button class="avatar">
    <img
        class="avatar__img"
        src="/home/avatar_example.webp"
        loading="lazy"
        alt="Avatar of John Doe"
    />
    <span class="avatar__fallback">JD</span>
    <span
        class="indicator indicator--primary indicator--sm indicator--ping"
        role="status"
        aria-label="Is online"
    ></span>
</button>

<br />

<button class="avatar">
    <img
        class="avatar__img"
        src="/home/avatar_example.webp"
        loading="lazy"
        alt="Avatar of John Doe"
    />
    <span class="avatar__fallback">JD</span>
    <span
        class="indicator indicator--secondary indicator--sm indicator--ping"
        role="status"
        aria-label="Is online"
    ></span>
</button>

Product Information

Our flagship product combines cutting-edge technology with sleek design. Built with premium materials, it offers unparalleled performance and reliability.

Shipping Details 4

We offer worldwide shipping through trusted courier partners. Standard delivery takes 3-5 business days, while express shipping ensures delivery within 1-2 business days.

All orders are carefully packaged and fully insured. Track your shipment in real-time through our dedicated tracking portal.

<details class="accordion">
    <summary class="accordion__summary">Product Information</summary>
    <div class="accordion__content">
        <p class="muted">
            Our flagship product combines cutting-edge technology with sleek
            design. Built with premium materials, it offers unparalleled
            performance and reliability.
        </p>
    </div>
</details>
<details class="accordion">
    <summary class="accordion__summary">
        <span style="position: relative">
            Shipping Details
            <span class="indicator indicator--right indicator--offset">
                4
            </span>
        </span>
    </summary>
    <div class="accordion__content">
        <p class="muted">
            We offer worldwide shipping through trusted courier partners.
            Standard delivery takes 3-5 business days, while express
            shipping ensures delivery within 1-2 business days.
            <br /><br />
            All orders are carefully packaged and fully insured. Track your
            shipment in real-time through our dedicated tracking portal.
        </p>
    </div>
</details>

Input 🚧

Displays a form input field or a component that looks like an input field.


<input
    class="input"
    name="email"
    type="email"
    placeholder="Email"
    autocomplete="email"
    aria-label="Email"
/>

Input group 🚧

Display additional information or actions to an input or textarea.


Work in progress...

Kbd

Used to display textual user input from keyboard.




+K


Use Ctrl + B Cmd + K to open the command palette


<div
    class="kbd-group"
    role="group"
    aria-label="Keyboard shortcuts example"
>
    <kbd class="kbd">⌘</kbd>
    <kbd class="kbd">⇧</kbd>
    <kbd class="kbd">⌥</kbd>
    <kbd class="kbd">⌃</kbd>
</div>

<br /><br />

<div
    class="kbd-group"
    role="group"
    aria-label="Search command shortcut"
>
    <kbd class="kbd">⌘</kbd>+<kbd class="kbd">K</kbd>
</div>

<br /><br />

<p class="muted">
    Use
    <kbd class="kbd">Ctrl + B</kbd> <kbd class="kbd">Cmd + K</kbd>
    to open the command palette
</p>

<br />

<button class="button button--outline">
    <span>Accept</span><kbd class="kbd">⏎</kbd>
</button>

Label 🚧

Renders an accessible label associated with controls.


<label class="label label--required">
    <input class="checkbox" name="label1" type="checkbox" required />
    <span>Accept terms and conditions</span>
</label>

<a class="link" href="#">Link</a>

<br /><br />

<a class="link" href="#">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-globe-icon lucide-globe"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>
    Visit Website
</a>

<br />

<a
    class="link"
    href="mailto:hello@example.com?subject=Hello&body=How%20are%20you?"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail-icon lucide-mail"><path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"/><rect x="2" y="4" width="20" height="16" rx="2"/></svg>
    hello@example.com
</a>

<br />

<a class="link" href="tel:+1234567890">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-phone-icon lucide-phone"><path d="M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384"/></svg>
    +1 (234) 567-890
</a>

<br />

<a
    class="link"
    href="https://maps.app.goo.gl/Pjt8Km7YAW6vR6L99"
    data-href-apple="maps://maps.apple.com/place?place-id=IDBCCCA2A9059133"
    target="_blank"
    rel="noopener noreferrer"
    onclick="if (/iPhone|iPad|Mac/.test(navigator.userAgent))this.href=this.dataset.hrefApple;this.onclick=null"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-map-pin-icon lucide-map-pin"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/></svg>
    Av. Gustave Eiffel, 75007 Paris
</a>

Popover 🚧 Element

Displays rich content in a portal, triggered by a button. Use Floating UI under the hood.


My content
<button class="button" type="button" popovertarget="myPopover1">
    Open popover
</button>

<x-popover
    id="myPopover1"
    class="popover popover--bottom popover--center"
>
    <dialog
        class="popover__dialog"
        onclick="if (event.target === this) this.close()"
    >
        <form class="popover__dialog__shape" method="dialog">
            <!-- Your content -->
            My content
            <!-- ? Your content -->
        </form>
    </dialog>
</x-popover>

Progress

Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.


<progress
    class="progress"
    value="50"
    max="100"
    aria-label="Content loading…"
></progress>

QR code Element

A link as a QR code, generated with paulmillr/qr .


<script type="module" src="https://ui.micka.dev/cdn/elements/qr-code.element.js"></script>

<input
    type="text"
    class="input"
    placeholder="https://urlr.me/YghyXA"
    oninput="document.querySelector('x-qr-code a').href = this.value || this.placeholder"
/>
<br />

<x-qr-code style="aspect-ratio: 1/1; max-width: 210px">
    <a href="https://urlr.me/YghyXA"> My website </a>
</x-qr-code>

Radio group

A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.


Notify me about...

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do

<fieldset class="fieldset">
    <legend class="fieldset__legend fieldset__legend--label">
        Notify me about...
    </legend>
    <p class="fieldset__desc">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
    </p>

    <div class="radio-group">
        <label class="label label--normal">
            <input
                class="radio"
                type="radio"
                name="radioGroup2"
                value="1"
                checked
            />
            All new messages
        </label>
        <label class="label label--normal">
            <input
                class="radio"
                type="radio"
                name="radioGroup2"
                value="2"
                disabled
            />
            Direct messages and mentions
        </label>
        <label class="label label--normal">
            <input
                class="radio"
                type="radio"
                name="radioGroup2"
                value="3"
            />
            Nothing
        </label>
    </div>
</fieldset>

Select

Displays a list of options for the user to pick from—triggered by a button.


<select class="select" id="mySelect" aria-label="Choose a dinosaur">
    <option value="" selected disabled>Select a dinosaur</option>
    <hr />
    <optgroup label="Theropods">
        <option value="tyrannosaurus">Tyrannosaurus</option>
        <option value="velociraptor">Velociraptor</option>
        <option value="deinonychus">Deinonychus</option>
    </optgroup>
    <hr />
    <optgroup label="Sauropods">
        <option value="diplodocus">Diplodocus</option>
        <option value="saltasaurus">Saltasaurus</option>
        <option value="apatosaurus">Apatosaurus</option>
    </optgroup>
</select>

Slider Element

An input where the user selects a value from within a given range.








<script
    type="module"
    src="https://ui.micka.dev/cdn/elements/slider.element.js"
></script>

<x-slider class="slider">
    <input
        class="slider__range"
        name="mySlider1"
        type="range"
        min="0"
        max="100"
        aria-label="Volume"
    />
</x-slider>

<br /><br />

<x-slider class="slider">
    <input
        class="slider__range"
        name="mySlider2"
        type="range"
        min="0"
        max="3"
        value="3"
        aria-label="Volume"
    />
    <div class="slider__datalist" aria-hidden="true">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
</x-slider>

<br /><br />

<x-slider class="slider">
    <input
        class="slider__range"
        name="mySlider3"
        type="range"
        min="0"
        max="2"
        value="0"
        aria-label="Size"
    />
    <div class="slider__datalist" aria-hidden="true">
        <div>Small</div>
        <div>Medium</div>
        <div>Large</div>
    </div>
</x-slider>

<br /><br />

<form>
    <div class="field">
        <label class="field__label" for="mySlider4">Volume</label>
        <x-slider class="slider">
            <input
                class="slider__range"
                id="mySlider4"
                name="mySlider4"
                type="range"
                min="0"
                max="100"
                step="10"
                aria-label="Volume"
            />
        </x-slider>
        <div role="group" aria-label="Slider controls">
            <button
                class="button"
                type="button"
                onclick="document.getElementById('mySlider4').stepDown()"
                aria-label="Decrement"
            >
                <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minus-icon lucide-minus"><path d="M5 12h14"/></svg>
            </button>
            <button
                class="button"
                type="button"
                onclick="document.getElementById('mySlider4').stepUp()"
                aria-label="Increment"
            >
                <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
            </button>
            <button class="button" type="reset" aria-label="Reset">
                <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-ccw-icon lucide-rotate-ccw"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
            </button>
        </div>
    </div>
</form>

Snippet

A code snippet rendered with PrismJS.


// Program to display fibonacci sequence using recursion
function fibonacci(num) {
    if (num < 2) {
        return num;
    }
    else {
        return fibonacci(num - 1) + fibonacci(num - 2);
    }
}

for (let i = 0; i < 5; i++) {
    console.log(fibonacci(i));
}
<script
    type="module"
    src="https://ui.micka.dev/cdn/elements/snippet.element.js"
></script>

<x-snippet class="snippet snippet--typescript">
    <pre id="mySnippet1">// Program to display fibonacci sequence using recursion
function fibonacci(num) {
    if (num &lt; 2) {
        return num;
    }
    else {
        return fibonacci(num - 1) + fibonacci(num - 2);
    }
}

for (let i = 0; i &lt; 5; i++) {
    console.log(fibonacci(i));
}</pre>
    <x-copy-text for="mySnippet1">
        <button
            class="button button--outline button--icon tooltip tooltip--end"
            aria-label="Copy to clipboard"
        ></button>
    </x-copy-text>
</x-snippet>

Spinner 🚧

An indicator that can be used to show a loading state.




<div
    class="spinner"
    aria-live="polite"
    role="status"
    aria-label="Loading"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
</div>

<br />

<div
    class="spinner spinner--sm"
    aria-live="polite"
    role="status"
    aria-label="Loading"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
</div>

<div
    class="spinner"
    aria-live="polite"
    role="status"
    aria-label="Loading"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
</div>

<div
    class="spinner spinner--lg"
    aria-live="polite"
    role="status"
    aria-label="Loading"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
</div>

<div
    class="spinner spinner--xl"
    aria-live="polite"
    role="status"
    aria-label="Loading"
>
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
</div>

<br />

<button class="button button--sm" type="button" disabled>
    <span
        class="spinner"
        aria-live="polite"
        role="status"
        aria-label="Loading"
    >
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
    </span>
    Loading...
</button>
<button class="button button--sm" type="button" disabled>
    <span
        class="spinner"
        aria-live="polite"
        role="status"
        aria-label="Loading"
    >
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
    </span>
    Loading...
</button>
<button
    class="button button--secondary button--sm"
    type="button"
    disabled
>
    <span
        class="spinner"
        aria-live="polite"
        role="status"
        aria-label="Loading"
    >
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle-icon lucide-loader-circle"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
    </span>
    Loading...
</button>

Switch

A control that allows the user to toggle between checked and not checked.


<label class="label">
    <input class="switch" name="switch1" type="checkbox" />
    Airplane mode
</label>

Table 🚧

An opinionated toast component.


Work in progress...

Tabs 🚧

A set of layered sections of content—known as tab panels—that are displayed one at a time.


This is the Overview panel.

Details panel content.

Resources panel content.

<script
    type="module"
    src="https://ui.micka.dev/cdn/elements/tabs.element.js"
></script>

<x-tabs class="tabs">
    <div
        class="tabs__list"
        role="tablist"
        aria-orientation="horizontal"
        aria-label="Example Tabs"
    >
        <button
            id="myTabs1Tab1"
            role="tab"
            aria-controls="myTabs1Panel1"
        >
            Overview
        </button>
        <button
            id="myTabs1Tab2"
            role="tab"
            aria-controls="myTabs1Panel2"
            aria-selected="true"
        >
            Details
        </button>
        <button
            id="myTabs1Tab3"
            role="tab"
            aria-controls="myTabs1Panel3"
        >
            Resources
        </button>
    </div>

    <div
        class="tabs__panel"
        id="myTabs1Panel1"
        role="tabpanel"
        aria-labelledby="myTabs1Tab1"
    >
        <p>This is the Overview panel.</p>
    </div>
    <div
        class="tabs__panel"
        id="myTabs1Panel2"
        role="tabpanel"
        aria-labelledby="myTabs1Tab2"
    >
        <p>Details panel content.</p>
    </div>
    <div
        class="tabs__panel"
        id="myTabs1Panel3"
        role="tabpanel"
        aria-labelledby="myTabs1Tab3"
    >
        <p>Resources panel content.</p>
    </div>
</x-tabs>

Textarea

Displays a form textarea or a component that looks like a textarea.


<div class="field">
    <label class="field__label" for="myTextarea1">My message</label>
    <textarea
        class="textarea"
        id="myTextarea1"
        name="message1"
        placeholder="Type your message here"
    ></textarea>
</div>

Toggle

A two-state button that can be either on or off.


<label class="button button--outline">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic-icon lucide-italic"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
    Italic
    <input class="button__toggle" type="checkbox" />
</label>

<label class="button button--outline">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bold-icon lucide-bold"><path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8"/></svg>
    Bold
    <input class="button__toggle" type="checkbox" />
</label>

<label class="button button--outline">
    <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bookmark-icon lucide-bookmark"><path d="m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z"/></svg>
    <input
        class="button__toggle"
        type="checkbox"
        onchange="this.previousElementSibling.querySelector('path').setAttribute('fill', this.checked ? 'currentColor' : 'none')"
    />
    Bookmark
</label>

<label class="button button--ghost">
    Disabled
    <input class="button__toggle" type="checkbox" disabled />
</label>

<label class="button button--outline">
    Disabled
    <input class="button__toggle" type="checkbox" disabled />
</label>

Toggle group

A set of two-state buttons that can be toggled on or off.


<div class="button-group" role="group" aria-label="Toggle group example">
    <label class="button button--outline button--icon">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bold-icon lucide-bold"><path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8"/></svg>
        <span class="sr-only">Toggle bold</span>
        <input class="button__toggle" type="checkbox" />
    </label>

    <label class="button button--outline button--icon">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic-icon lucide-italic"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
        <span class="sr-only">Toggle italic</span>
        <input class="button__toggle" type="checkbox" />
    </label>

    <label class="button button--outline button--icon">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-underline-icon lucide-underline"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" x2="20" y1="20" y2="20"/></svg>
        <span class="sr-only">Toggle underline</span>
        <input class="button__toggle" type="checkbox" />
    </label>
</div>

<div
    class="button-group"
    role="group"
    aria-label="Text formatting controls"
>
    <label class="button button--ghost button--icon">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bold-icon lucide-bold"><path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8"/></svg>
        <span class="sr-only">Toggle bold</span>
        <input class="button__toggle" type="checkbox" />
    </label>

    <span class="button-group__separator"></span>

    <label class="button button--ghost button--icon">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic-icon lucide-italic"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
        <span class="sr-only">Toggle italic</span>
        <input class="button__toggle" type="checkbox" />
    </label>

    <span class="button-group__separator"></span>

    <label class="button button--ghost button--icon">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-underline-icon lucide-underline"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" x2="20" y1="20" y2="20"/></svg>
        <span class="sr-only">Toggle underline</span>
        <input class="button__toggle" type="checkbox" />
    </label>
</div>

<div
    class="button-group button-group--space-2"
    role="group"
    aria-label="Toggle group with spaces example"
>
    <label class="button button--outline button--sm">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-star-icon lucide-star"><path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"/></svg>
        <input
            class="button__toggle"
            type="checkbox"
            onchange="this.previousElementSibling.querySelector('path').setAttribute('fill', this.checked ? 'currentColor' : 'none')"
        />
        Star
    </label>

    <label class="button button--outline button--sm">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-heart-icon lucide-heart"><path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/></svg>
        <input
            class="button__toggle"
            type="checkbox"
            onchange="this.previousElementSibling.querySelector('path').setAttribute('fill', this.checked ? 'currentColor' : 'none')"
        />
        Heart
    </label>

    <label class="button button--outline button--sm">
        <!-- prettier-ignore --><svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bookmark-icon lucide-bookmark"><path d="m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z"/></svg>
        <input
            class="button__toggle"
            type="checkbox"
            onchange="this.previousElementSibling.querySelector('path').setAttribute('fill', this.checked ? 'currentColor' : 'none')"
        />
        Bookmark
    </label>
</div>

Tooltip

A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.




<button
    class="button button--outline button--icon tooltip tooltip--right"
    type="button"
    aria-label="Right"
>
    →
</button>

<button
    class="button button--outline button--icon tooltip tooltip--bottom"
    type="button"
    aria-label="Bottom"
>
    ↓
</button>

<button
    class="button button--outline button--icon tooltip tooltip--left"
    type="button"
    aria-label="Left"
>
    ←
</button>

<br /><br />

<button
    class="button button--outline button--icon tooltip tooltip--top"
    type="button"
    aria-label="Top"
>
    ↑
</button>

<button
    class="button button--outline button--icon tooltip tooltip--top tooltip--start"
    type="button"
    aria-label="Top start"
>
    ↖
</button>

<button
    class="button button--outline button--icon tooltip tooltip--top tooltip--end"
    type="button"
    aria-label="Top end"
>
    ↗
</button>

Typography

Styles for headings, paragraphs, lists...etc


Taxing Laughter: The Joke Tax Chronicles

Once upon a time, in a far-off land, there was a very lazy king who spent all day lounging on his throne. One day, his advisors came to him with a problem: the kingdom was running out of money.

The King's Plan

The king thought long and hard, and finally came up with a brilliant plan: he would tax the jokes in the kingdom.

"After all," he said, "everyone enjoys a good joke, so it's only fair that they should pay for the privilege."

The Joke Tax

The king's subjects were not amused. They grumbled and complained, but the king was firm:

  • 1st level of puns: 5 gold coins
  • 2nd level of jokes: 10 gold coins
  • 3rd level of one-liners : 20 gold coins

As a result, people stopped telling jokes, and the kingdom fell into a gloom. But there was one person who refused to let the king's foolishness get him down: a court jester named Jokester.

Jokester's Revolt

Jokester began sneaking into the castle in the middle of the night and leaving jokes all over the place: under the king's pillow, in his soup, even in the royal toilet. The king was furious, but he couldn't seem to stop Jokester.

And then, one day, the people of the kingdom discovered that the jokes left by Jokester were so funny that they couldn't help but laugh. And once they started laughing, they couldn't stop.

The People's Rebellion

The people of the kingdom, feeling uplifted by the laughter, started to tell jokes and puns again, and soon the entire kingdom was in on the joke.


King's Treasury People's happiness
Empty Overflowing
Modest Satisfied
Full Ecstatic

The king, seeing how much happier his subjects were, realized the error of his ways and repealed the joke tax. Jokester was declared a hero, and the kingdom lived happily ever after.

The moral of the story is: never underestimate the power of a good laugh and always be careful of bad ideas.

<div class="typography">
    <h1>Taxing Laughter: The Joke Tax Chronicles</h1>
    <p class="lead">
        Once upon a time, in a far-off land, there was a very lazy king who
        spent all day lounging on his throne. One day, his advisors came to
        him with a problem: the kingdom was running out of money.
    </p>
    <h2>The King's Plan</h2>
    <p>
        The king thought long and hard, and finally came up with<!-- -->
        <a href="#">a brilliant plan</a>: he would tax the jokes in the
        kingdom.
    </p>
    <blockquote>
        "After all," he said, "everyone enjoys a good joke, so it's only
        fair that they should pay for the privilege."
    </blockquote>
    <h3>The Joke Tax</h3>
    <p>
        The king's subjects were not amused. They grumbled and complained,
        but the king was firm:
    </p>
    <ul>
        <li>1st level of puns: 5 gold coins</li>
        <li>2nd level of jokes: 10 gold coins</li>
        <li>3rd level of one-liners : 20 gold coins</li>
    </ul>
    <p>
        As a result, people stopped telling jokes, and the kingdom fell into
        a gloom. But there was one person who refused to let the king's
        foolishness get him down: a court jester named Jokester.
    </p>
    <h3>Jokester's Revolt</h3>
    <p>
        Jokester began sneaking into the castle in the middle of the night
        and leaving jokes all over the place: under the king's pillow, in
        his soup, even in the royal toilet. The king was furious, but he
        couldn't seem to stop Jokester.
    </p>
    <p>
        And then, one day, the people of the kingdom discovered that the
        jokes left by Jokester were so funny that they couldn't help but
        laugh. And once they started laughing, they couldn't stop.
    </p>
    <h3>The People's Rebellion</h3>
    <p>
        The people of the kingdom, feeling uplifted by the laughter, started
        to tell jokes and puns again, and soon the entire kingdom was in on
        the joke.
    </p>

    <br />

    <table>
        <thead>
            <tr>
                <th>King's Treasury</th>
                <th>People's happiness</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Empty</td>
                <td>Overflowing</td>
            </tr>
            <tr>
                <td>Modest</td>
                <td>Satisfied</td>
            </tr>
            <tr>
                <td>Full</td>
                <td>Ecstatic</td>
            </tr>
        </tbody>
    </table>

    <p>
        The king, seeing how much happier his subjects were, realized the
        error of his ways and repealed the joke tax. Jokester was declared a
        hero, and the kingdom lived happily ever after.
    </p>
    <p>
        The moral of the story is: never underestimate the power of a good
        laugh and always be careful of bad ideas.
    </p>
</div>