Skip to content

CSS

CSS (Cascading Style Sheets) is the styling layer of the web. It controls layout, color, typography, motion and responsiveness. Where HTML gives a page structure and JavaScript gives it behavior, CSS gives it form.

This document is an all-in-one reference: modern CSS features that ship in evergreen browsers today, the TailwindCSS utility framework, and a library of copy-paste custom components (buttons, forms, text effects, glassmorphism and more).


Modern CSS removed the need for many preprocessor tricks and JavaScript hacks. The features below are baseline across current Chrome, Firefox, Safari and Edge.

Native CSS nesting works without Sass. Selectors nest with & for the parent reference.

.card {
padding: 1rem;
border-radius: 0.5rem;
& h2 {
margin: 0;
}
&:hover {
box-shadow: 0 4px 12px rgb(0 0 0 / 0.15);
}
}

:has() selects an element based on its descendants. It enables parent and previous-sibling styling that once required JavaScript.

/* Style a card that contains an image */
.card:has(img) {
grid-template-rows: auto 1fr;
}
/* Style a label whose input is checked */
label:has(input:checked) {
font-weight: 700;
}
/* Form with an invalid field */
form:has(:invalid) button[type="submit"] {
opacity: 0.5;
pointer-events: none;
}

Container queries style an element based on the size of its container, not the viewport. This makes components truly reusable across layouts.

.sidebar {
container-type: inline-size;
container-name: sidebar;
}
@container sidebar (min-width: 400px) {
.widget {
display: grid;
grid-template-columns: 1fr 1fr;
}
}

clamp(MIN, PREFERRED, MAX) builds responsive typography and spacing without breakpoints.

h1 {
/* Never smaller than 1.5rem, never larger than 3rem, scales with viewport */
font-size: clamp(1.5rem, 1rem + 3vw, 3rem);
}

oklch() is a perceptually uniform color space — lightness stays consistent across hues. color-mix() blends two colors in any space.

:root {
--brand: oklch(0.7 0.15 200);
/* 80% brand, 20% white — a tint without a second variable */
--brand-tint: color-mix(in oklch, var(--brand) 80%, white);
--brand-shade: color-mix(in oklch, var(--brand) 80%, black);
}

@property registers a custom property with a type, enabling animation of values CSS could not previously interpolate (like gradient stops or angles).

@property --angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
.spinner {
background: conic-gradient(from var(--angle), cyan, magenta, cyan);
animation: rotate 2s linear infinite;
}
@keyframes rotate {
to { --angle: 360deg; }
}

subgrid lets a nested grid inherit the track sizing of its parent, aligning content across cards.

.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid; /* header / body / footer line up across all cards */
}

Animate elements as the user scrolls — no scroll-event JavaScript, runs on the compositor.

@keyframes reveal {
from { opacity: 0; transform: translateY(2rem); }
to { opacity: 1; transform: translateY(0); }
}
.section {
animation: reveal linear both;
animation-timeline: view();
animation-range: entry 0% cover 40%;
}

The View Transitions API animates between two DOM states — the browser snapshots before and after, then cross-fades or morphs between them. It works for in-page state changes (same-document) and across page navigations (cross-document / MPA).

Same-document. Wrap the DOM mutation in startViewTransition. The browser captures, applies your callback, then animates old → new. A default cross-fade comes free.

function toggle() {
if (!document.startViewTransition) return update(); // graceful fallback
document.startViewTransition(() => update()); // animated path
}

Shared-element morph. Give the same view-transition-name to an element in both states and the browser tweens it between positions — a thumbnail growing into a hero, a card expanding into a detail page.

.thumbnail { view-transition-name: hero; }
/* On the next view, the large image carries the SAME name → it morphs */
.detail-image { view-transition-name: hero; }

Customizing. The transition exposes pseudo-elements you can target with normal @keyframes::view-transition-old(name) (outgoing) and ::view-transition-new(name) (incoming).

@keyframes slide-from-right { from { transform: translateX(40px); opacity: 0; } }
@keyframes fade-out { to { opacity: 0; } }
::view-transition-old(root) { animation: fade-out 0.2s both; }
::view-transition-new(root) { animation: slide-from-right 0.3s both; }

Cross-document (MPA). One CSS rule opts an entire multi-page site into transitions — no JavaScript, no SPA router.

@view-transition { navigation: auto; }

Always gate non-essential motion behind prefers-reduced-motion. Users who set the OS “reduce motion” flag get a static experience; everyone else gets the animation.

@media (prefers-reduced-motion: no-preference) {
.card {
animation: reveal linear both;
animation-timeline: view();
}
}
/* Or kill all motion as a blanket safety net */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
h1, h2, h3 {
text-wrap: balance; /* even line lengths for headings */
}
p {
text-wrap: pretty; /* avoids orphans / single-word last lines */
}

Logical properties adapt to writing direction (LTR / RTL) automatically.

.box {
margin-inline: auto; /* left+right in LTR, swaps in RTL */
padding-block: 1rem; /* top+bottom */
border-inline-start: 2px solid; /* "left" border that flips for RTL */
}

The two layout engines — Flexbox (one dimension) and Grid (two dimensions) — cover almost every layout. A handful of patterns recur constantly.

auto-fit + minmax() reflows columns to fit the container. Cards wrap on their own as space shrinks.

.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
gap: 1rem;
}
.center {
display: grid;
place-items: center;
}

Footer sits at the bottom on short pages, pushed down on tall ones — no fixed heights.

body {
min-height: 100dvh; /* dvh = dynamic viewport, accounts for mobile URL bars */
display: flex;
flex-direction: column;
}
main {
flex: 1; /* grows to fill, footer follows */
}
/* Even vertical rhythm between children */
.stack > * + * {
margin-block-start: 1.5rem;
}
/* Sidebar that collapses below content when space runs out */
.with-sidebar {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.with-sidebar > .sidebar { flex: 1 1 15rem; }
.with-sidebar > .content { flex: 999 1 60%; }

@layer gives you explicit control over specificity ordering — later layers always win over earlier ones, regardless of selector strength. This tames override wars and is how Tailwind v4 organizes its own output (theme, base, components, utilities).

@layer reset, base, components, utilities;
@layer base {
a { color: blue; }
}
@layer components {
/* Wins over base even though the selector is identical specificity */
.link { color: rebeccapurple; }
}

Readable type is mostly a few well-chosen defaults: a sensible measure, comfortable line height, and a scale that adapts to the viewport.

Combine clamp() with custom properties for a scale that breathes between phone and desktop without breakpoints.

:root {
--step--1: clamp(0.83rem, 0.78rem + 0.24vw, 0.96rem);
--step-0: clamp(1rem, 0.91rem + 0.43vw, 1.25rem);
--step-1: clamp(1.2rem, 1.07rem + 0.65vw, 1.56rem);
--step-2: clamp(1.44rem, 1.26rem + 0.93vw, 1.95rem);
--step-3: clamp(1.73rem, 1.47rem + 1.29vw, 2.44rem);
}
h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
p { font-size: var(--step-0); }
.prose {
max-width: 65ch; /* ~65 characters is the readable sweet spot */
line-height: 1.6; /* unitless — scales with font-size */
text-wrap: pretty; /* avoids orphaned last words */
}

One file, every weight and width. Animate the axes live with font-variation-settings.

@font-face {
font-family: "Inter var";
src: url("/fonts/inter.woff2") format("woff2");
font-weight: 100 900; /* the full axis range */
font-display: swap; /* show fallback text immediately, swap when loaded */
}
.heading {
font-family: "Inter var", sans-serif;
font-weight: 720; /* any value in range, not just 700 */
}
Preview

Single line that gets cut with an ellipsis when it overflows its container

Multi-line clamp limits a block to a fixed number of lines and adds an ellipsis. Useful for card descriptions and previews where you want a uniform height regardless of how much copy each item carries. Anything past the third line is hidden.

HTML
<div class="max-w-xs p-6 space-y-4 bg-white rounded-lg">
  <p class="font-medium text-gray-800 truncate">Single line that gets cut with an ellipsis when it overflows its container</p>
  <p class="text-sm text-gray-600 line-clamp-3">Multi-line clamp limits a block to a fixed number of lines and adds an ellipsis. Useful for card descriptions and previews where you want a uniform height regardless of how much copy each item carries. Anything past the third line is hidden.</p>
</div>

Two mechanisms: transition interpolates between two states (a hover, a class toggle), while @keyframes + animation runs a defined timeline that can loop and have many steps.

.button {
background: var(--brand);
/* property | duration | easing | delay */
transition: background 200ms ease-out, transform 200ms ease-out;
}
.button:hover {
transform: translateY(-2px);
}

ease-out for things entering, ease-in for things leaving, custom cubic-bezier() for character. Modern browsers also support linear() for spring and bounce curves without JavaScript.

:root {
--ease-snappy: cubic-bezier(0.2, 0, 0, 1);
/* A spring-like bounce, approximated with a linear() stop list */
--ease-spring: linear(0, 0.4 12%, 1.1 28%, 0.95 42%, 1.02 60%, 1);
}

A full timeline. This is the shimmer keyframe the gradient-text example earlier relies on — define it once globally (in your stylesheet or Tailwind @theme).

@keyframes shimmer {
to { background-position: 200% center; }
}
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-0.5rem); }
}
.badge {
animation: float 3s ease-in-out infinite;
}

Live, self-contained keyframe demos. Each snippet carries its own <style> block with a uniquely-named @keyframes, so you can copy one and drop it anywhere — no shared config required.

Preview
HTML
<style>
@keyframes kbve-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-14px); } }
.kbve-float { animation: kbve-float 3s ease-in-out infinite; }
</style>
<div class="flex items-center justify-center p-12 bg-gray-900">
  <div class="kbve-float w-20 h-20 shadow-xl rounded-2xl bg-gradient-to-br from-cyan-400 to-fuchsia-500"></div>
</div>

A notification dot with an expanding, fading ring — the classic “live” indicator.

Preview
HTML
<style>
@keyframes kbve-ping { 75%, 100% { transform: scale(2.4); opacity: 0; } }
.kbve-ping { animation: kbve-ping 1.4s cubic-bezier(0,0,0.2,1) infinite; }
</style>
<div class="flex items-center justify-center p-12 bg-gray-900">
  <span class="relative flex w-5 h-5">
    <span class="kbve-ping absolute inline-flex w-full h-full rounded-full bg-cyan-400"></span>
    <span class="relative inline-flex w-5 h-5 rounded-full bg-cyan-500"></span>
  </span>
</div>

The gradient shimmer referenced earlier — now running live via an embedded keyframe.

Preview

Shimmer

HTML
<style>
@keyframes kbve-shimmer { to { background-position: 200% center; } }
.kbve-shimmer {
  background: linear-gradient(90deg, #06b6d4, #d946ef, #06b6d4);
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  animation: kbve-shimmer 3s linear infinite;
}
</style>
<div class="flex items-center justify-center p-12 bg-gray-900">
  <h1 class="kbve-shimmer text-6xl font-black">Shimmer</h1>
</div>

steps() makes the reveal tick character-by-character; a second keyframe blinks the caret.

Preview
console.log(42)
HTML
<style>
@keyframes kbve-type { from { width: 0; } to { width: 16ch; } }
@keyframes kbve-caret { 50% { border-color: transparent; } }
.kbve-type {
  width: 16ch;
  font-family: ui-monospace, monospace;
  white-space: nowrap; overflow: hidden;
  border-right: 3px solid #06b6d4;
  animation: kbve-type 3s steps(16) infinite alternate, kbve-caret 0.7s step-end infinite;
}
</style>
<div class="flex items-center justify-center p-12 bg-gray-900">
  <span class="kbve-type text-2xl font-medium text-cyan-300">console.log(42)</span>
</div>

Seamless infinite scroll — duplicate the content and translate by -50%.

Preview
★ Astro★ TailwindCSS★ Rust★ Unity★ Supabase ★ Astro★ TailwindCSS★ Rust★ Unity★ Supabase
HTML
<style>
@keyframes kbve-marquee { to { transform: translateX(-50%); } }
.kbve-marquee { display: inline-flex; gap: 2rem; animation: kbve-marquee 12s linear infinite; }
.kbve-marquee:hover { animation-play-state: paused; }
</style>
<div class="p-8 overflow-hidden bg-gray-900 whitespace-nowrap">
  <div class="kbve-marquee text-lg font-semibold text-cyan-300">
    <span>★ Astro</span><span>★ TailwindCSS</span><span>★ Rust</span><span>★ Unity</span><span>★ Supabase</span>
    <span>★ Astro</span><span>★ TailwindCSS</span><span>★ Rust</span><span>★ Unity</span><span>★ Supabase</span>
  </div>
</div>

A 3D flip on hover with transform-style: preserve-3d and backface-visibility.

Preview
Hover me
Flipped!
HTML
<style>
.kbve-flip { perspective: 1000px; }
.kbve-flip-inner { position: relative; width: 100%; height: 100%; transition: transform 0.6s; transform-style: preserve-3d; }
.kbve-flip:hover .kbve-flip-inner { transform: rotateY(180deg); }
.kbve-flip-face { position: absolute; inset: 0; backface-visibility: hidden; display: flex; align-items: center; justify-content: center; border-radius: 1rem; font-weight: 700; color: #fff; }
.kbve-flip-back { transform: rotateY(180deg); }
</style>
<div class="flex items-center justify-center p-12 bg-gray-900">
  <div class="kbve-flip w-48 h-32">
    <div class="kbve-flip-inner">
      <div class="kbve-flip-face bg-cyan-600">Hover me</div>
      <div class="kbve-flip-face kbve-flip-back bg-fuchsia-600">Flipped!</div>
    </div>
  </div>
</div>

TailwindCSS is a utility-first CSS framework. Instead of writing custom CSS, you compose designs from low-level utility classes directly in your markup. This promotes consistency, reusability and speed, and the production build strips every class you do not use.

Tailwind v4 is CSS-first: configuration lives in your CSS via @theme instead of a tailwind.config.js file, the engine is faster, and many former plugins (container queries, text-shadow) are now built in.

  1. Create a project directory

    Terminal window
    mkdir my-tailwind-project
    cd my-tailwind-project
    pnpm init
  2. Install Tailwind v4

    v4 ships a dedicated Vite plugin (or the standalone CLI / PostCSS plugin).

    Terminal window
    pnpm add tailwindcss @tailwindcss/vite
  3. Wire up the Vite plugin

    vite.config.js
    import { defineConfig } from 'vite';
    import tailwindcss from '@tailwindcss/vite';
    export default defineConfig({
    plugins: [tailwindcss()],
    });
  4. Import Tailwind in your CSS

    One line replaces the old @tailwind base/components/utilities trio.

    src/styles.css
    @import "tailwindcss";
  5. Configure in CSS with @theme

    Design tokens live in CSS now. No tailwind.config.js required.

    @import "tailwindcss";
    @theme {
    --color-brand: oklch(0.7 0.15 200);
    --font-display: "Satoshi", sans-serif;
    --animate-spin-slow: spin 5s linear infinite;
    }

    These tokens auto-generate utilities like bg-brand, font-display and animate-spin-slow.

  6. Use it in markup

    <h1 class="text-3xl font-bold text-brand underline">Hello, TailwindCSS!</h1>

These are the Dojo buttons — live, rendered with the site’s Tailwind build. Each block is the exact markup to copy.


HTML
<a href="#_" class="relative inline-block text-lg group">
    <span class="relative z-10 block px-5 py-3 overflow-hidden font-medium leading-tight text-gray-800 transition-colors duration-300 ease-out border-2 border-gray-900 rounded-lg group-hover:text-white">
    <span class="absolute inset-0 w-full h-full px-5 py-3 rounded-lg bg-gray-50"></span>
    <span class="absolute left-0 w-48 h-48 -ml-2 transition-all duration-300 origin-top-right -rotate-90 -translate-x-full translate-y-12 bg-gray-900 group-hover:-rotate-180 ease"></span>
    <span class="relative">Button Text</span>
    </span>
    <span class="absolute bottom-0 right-0 w-full h-12 -mb-1 -mr-1 transition-all duration-200 ease-linear bg-gray-900 rounded-lg group-hover:mb-0 group-hover:mr-0" data-rounded="rounded-lg"></span>
</a>

HTML
<a href="#_" class="relative inline-flex items-center justify-start py-3 pl-4 pr-12 overflow-hidden font-semibold text-indigo-600 transition-all duration-150 ease-in-out rounded hover:pl-10 hover:pr-6 bg-gray-50 group">
    <span class="absolute bottom-0 left-0 w-full h-1 transition-all duration-150 ease-in-out bg-indigo-600 group-hover:h-full"></span>
    <span class="absolute right-0 pr-4 duration-200 ease-out group-hover:translate-x-12">
    <svg class="w-5 h-5 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
    </span>
    <span class="absolute left-0 pl-2.5 -translate-x-12 group-hover:translate-x-0 ease-out duration-200">
    <svg class="w-5 h-5 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
    </span>
    <span class="relative w-full text-left transition-colors duration-200 ease-in-out group-hover:text-white">Button Text</span>
</a>

HTML
<a href="#_" class="relative px-5 py-2 font-medium text-white group">
<span class="absolute inset-0 w-full h-full transition-all duration-300 ease-out transform translate-x-0 -skew-x-12 bg-cyan-500 group-hover:bg-cyan-700 group-hover:skew-x-12"></span>
<span class="absolute inset-0 w-full h-full transition-all duration-300 ease-out transform skew-x-12 bg-cyan-700 group-hover:bg-cyan-500 group-hover:-skew-x-12"></span>
<span class="absolute bottom-0 left-0 hidden w-10 h-20 transition-all duration-100 ease-out transform -translate-x-8 translate-y-10 bg-cyan-600 -rotate-12"></span>
<span class="absolute bottom-0 right-0 hidden w-10 h-20 transition-all duration-100 ease-out transform translate-x-10 translate-y-8 bg-cyan-400 -rotate-12"></span>
<span class="relative">Button Text</span>
</a>

Preview
HTML
<button class="rounded-md px-3.5 py-2 m-1 overflow-hidden relative group cursor-pointer border-2 font-medium border-cyan-600 text-cyan-600 text-white">
<span class="absolute w-64 h-0 transition-all duration-300 origin-center rotate-45 -translate-x-20 bg-cyan-600 top-1/2 group-hover:h-64 group-hover:-translate-y-32 ease"></span>
<span class="relative text-cyan-600 transition duration-300 group-hover:text-white ease">Button Text</span>
</button>

HTML
<a href="#_" class="px-5 py-2.5 relative rounded group font-medium !text-white font-medium inline-block">
<span class="absolute top-0 left-0 w-full h-full rounded opacity-50 filter blur-sm bg-gradient-to-br from-cyan-600 to-cyan-400"></span>
<span class="h-full w-full inset-0 absolute mt-0.5 ml-0.5 bg-gradient-to-br filter group-active:opacity-0 rounded opacity-50 from-cyan-600 to-cyan-400"></span>
<span class="absolute inset-0 w-full h-full transition-all duration-200 ease-out rounded shadow-xl bg-gradient-to-br filter group-active:opacity-0 group-hover:blur-sm from-cyan-600 to-cyan-400"></span>
<span class="absolute inset-0 w-full h-full transition duration-200 ease-out rounded bg-gradient-to-br to-cyan-600 from-cyan-300"></span>
<span class="relative">Button Text</span>
</a>

HTML
<a href="#_" class="px-5 py-2.5 relative rounded group overflow-hidden font-medium bg-cyan-50 text-cyan-600 inline-block">
<span class="absolute top-0 left-0 flex w-full h-0 mb-0 transition-all duration-200 ease-out transform translate-y-0 bg-cyan-600 group-hover:h-full opacity-90"></span>
<span class="relative group-hover:text-white">Button Text</span>
</a>

Preview
HTML
<button class="overflow-hidden rounded relative inline-flex group items-center justify-center px-3.5 py-2 m-1 cursor-pointer border-b-4 border-l-2 active:border-cyan-600 active:shadow-none shadow-lg bg-gradient-to-tr from-cyan-600 to-cyan-500 border-cyan-700 text-white">
<span class="absolute w-0 h-0 transition-all duration-300 ease-out bg-white rounded-full group-hover:w-32 group-hover:h-32 opacity-10"></span>
<span class="relative">Button Text</span>
</button>

HTML
<a href="#_" class="inline-flex overflow-hidden text-white bg-gray-900 rounded group">
<span class="px-3.5 py-2 text-white bg-cyan-500 group-hover:bg-cyan-600 flex items-center justify-center">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path></svg>
</span>
<span class="pl-4 pr-5 py-2.5">Button Text</span>
</a>

Preview
HTML
<button class="relative inline-flex items-center px-12 py-3 overflow-hidden text-lg font-medium text-cyan-600 border-2 border-cyan-600 rounded-full hover:text-white group hover:bg-transparent">
<span class="absolute left-0 block w-full h-0 transition-all bg-cyan-600 opacity-100 group-hover:h-full top-1/2 group-hover:top-0 duration-400 ease"></span>
<span class="absolute right-0 flex items-center justify-start w-10 h-10 duration-300 transform translate-x-full group-hover:translate-x-0 ease">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
</span>
<span class="relative">Button Text</span>
</button>

HTML
<a href="#_" class="relative px-6 py-3 font-bold text-black group">
<span class="absolute inset-0 w-full h-full transition duration-300 ease-out transform -translate-x-2 -translate-y-2 bg-cyan-300 group-hover:translate-x-0 group-hover:translate-y-0"></span>
<span class="absolute inset-0 w-full h-full border-4 border-black"></span>
<span class="relative">Button Text</span>
</a>

Preview
HTML
<button class="relative rounded px-5 py-2.5 overflow-hidden group bg-cyan-500 relative hover:bg-gradient-to-r hover:from-cyan-500 hover:to-cyan-400 text-white hover:ring-2 hover:ring-offset-2 hover:ring-cyan-400 transition-all ease-out duration-300">
<span class="absolute right-0 w-8 h-32 -mt-12 transition-all duration-1000 transform translate-x-12 bg-white opacity-10 rotate-12 group-hover:-translate-x-40 ease"></span>
<span class="relative">Button Text</span>
</button>

HTML
<a href="#_" class="relative inline-flex items-center justify-center p-4 px-5 py-3 overflow-hidden font-medium text-indigo-600 transition duration-300 ease-out rounded-full shadow-xl group hover:ring-1 hover:ring-cyan-500">
<span class="absolute inset-0 w-full h-full bg-gradient-to-br from-cyan-600 via-yellow-600 to-cyan-700"></span>
<span class="absolute bottom-0 right-0 block w-64 h-64 mb-32 mr-4 transition duration-500 origin-bottom-left transform rotate-45 translate-x-24 bg-cyan-500 rounded-full opacity-30 group-hover:rotate-90 ease"></span>
<span class="relative text-white">Button Text</span>
</a>

Preview
HTML
<button class="overflow-hidden relative px-10 py-3 font-medium text-white transition duration-300 bg-cyan-400 rounded-md hover:bg-cyan-500 ease">
<span class="absolute bottom-0 left-0 h-full -ml-2">
<svg viewBox="0 0 487 487" class="w-auto h-full opacity-100 object-stretch" xmlns="http://www.w3.org/2000/svg"><path d="M0 .3c67 2.1 134.1 4.3 186.3 37 52.2 32.7 89.6 95.8 112.8 150.6 23.2 54.8 32.3 101.4 61.2 149.9 28.9 48.4 77.7 98.8 126.4 149.2H0V.3z" fill="#FFF" fill-rule="nonzero" fill-opacity=".1"></path></svg>
</span>
<span class="absolute top-0 right-0 w-12 h-full -mr-3">
<svg viewBox="0 0 487 487" class="object-cover w-full h-full" xmlns="http://www.w3.org/2000/svg"><path d="M487 486.7c-66.1-3.6-132.3-7.3-186.3-37s-95.9-85.3-126.2-137.2c-30.4-51.8-49.3-99.9-76.5-151.4C70.9 109.6 35.6 54.8.3 0H487v486.7z" fill="#FFF" fill-rule="nonzero" fill-opacity=".1"></path></svg>
</span>
<span class="relative">Button Text</span>
</button>

Preview
HTML
<button class="relative px-5 py-3 overflow-hidden font-medium text-gray-600 bg-gray-100 border border-gray-100 rounded-lg shadow-inner group">
<span class="absolute top-0 left-0 w-0 h-0 transition-all duration-200 border-t-2 border-gray-600 group-hover:w-full ease"></span>
<span class="absolute bottom-0 right-0 w-0 h-0 transition-all duration-200 border-b-2 border-gray-600 group-hover:w-full ease"></span>
<span class="absolute top-0 left-0 w-full h-0 transition-all duration-300 delay-200 bg-gray-600 group-hover:h-full ease"></span>
<span class="absolute bottom-0 left-0 w-full h-0 transition-all duration-300 delay-200 bg-gray-600 group-hover:h-full ease"></span>
<span class="absolute inset-0 w-full h-full duration-300 delay-300 bg-gray-900 opacity-0 group-hover:opacity-100"></span>
<span class="relative transition-colors duration-300 delay-200 group-hover:text-white ease">Button Text</span>
</button>

Preview
HTML
<button class="box-border relative z-30 inline-flex items-center justify-center w-auto px-8 py-3 overflow-hidden font-bold text-white transition-all duration-300 bg-indigo-600 rounded-md cursor-pointer group ring-offset-2 ring-1 ring-indigo-300 ring-offset-indigo-200 hover:ring-offset-indigo-500 ease focus:outline-none">
<span class="absolute bottom-0 right-0 w-8 h-20 -mb-8 -mr-5 transition-all duration-300 ease-out transform rotate-45 translate-x-1 bg-white opacity-10 group-hover:translate-x-0"></span>
<span class="absolute top-0 left-0 w-20 h-8 -mt-1 -ml-12 transition-all duration-300 ease-out transform -rotate-45 -translate-x-1 bg-white opacity-10 group-hover:translate-x-0"></span>
<span class="relative z-20 flex items-center text-sm">
<svg class="relative w-5 h-5 mr-2 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
Button Text
</span>
</button>

Preview
HTML
<button class="relative z-30 inline-flex items-center justify-center w-auto px-8 py-3 overflow-hidden font-bold text-gray-500 transition-all duration-500 border border-gray-200 rounded-md cursor-pointer group ease bg-gradient-to-b from-white to-gray-50 hover:from-gray-50 hover:to-white active:to-white">
<span class="w-full h-0.5 absolute bottom-0 group-active:bg-transparent left-0 bg-gray-100"></span>
<span class="h-full w-0.5 absolute bottom-0 group-active:bg-transparent right-0 bg-gray-100"></span>
Button Text
</button>

Preview
HTML
<button class="relative inline-block px-4 py-2 font-medium group">
<span class="absolute inset-0 w-full h-full transition duration-200 ease-out transform translate-x-1 translate-y-1 bg-black group-hover:-translate-x-0 group-hover:-translate-y-0"></span>
<span class="absolute inset-0 w-full h-full bg-white border-2 border-black group-hover:bg-black"></span>
<span class="relative text-black group-hover:text-white">Button Text</span>
</button>

HTML
<a href="#_" class="relative inline-flex items-center justify-center p-4 px-6 py-3 overflow-hidden font-medium text-cyan-600 transition duration-300 ease-out border-2 border-cyan-500 rounded-full shadow-md group">
<span class="absolute inset-0 flex items-center justify-center w-full h-full text-white duration-300 -translate-x-full bg-cyan-500 group-hover:translate-x-0 ease">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"></path></svg>
</span>
<span class="absolute flex items-center justify-center w-full h-full text-cyan-500 transition-all duration-300 transform group-hover:translate-x-full ease">Button Text</span>
<span class="relative invisible">Button Text</span>
</a>

HTML
<a href="#_" class="relative inline-flex items-center justify-center inline-block p-4 px-5 py-3 overflow-hidden font-medium text-cyan-600 rounded-lg shadow-2xl group">
<span class="absolute top-0 left-0 w-40 h-40 -mt-10 -ml-3 transition-all duration-700 bg-red-500 rounded-full blur-md ease"></span>
<span class="absolute inset-0 w-full h-full transition duration-700 group-hover:rotate-180 ease">
<span class="absolute bottom-0 left-0 w-24 h-24 -ml-10 bg-cyan-500 rounded-full blur-md"></span>
<span class="absolute bottom-0 right-0 w-24 h-24 -mr-10 bg-pink-500 rounded-full blur-md"></span>
</span>
<span class="relative text-white">Button Text</span>
</a>

HTML
<a href="#_" class="relative inline-flex items-center justify-start px-6 py-3 overflow-hidden font-medium transition-all bg-red-500 rounded-xl group">
<span class="absolute top-0 right-0 inline-block w-4 h-4 transition-all duration-500 ease-in-out bg-red-700 rounded group-hover:-mr-4 group-hover:-mt-4">
<span class="absolute top-0 right-0 w-5 h-5 rotate-45 translate-x-1/2 -translate-y-1/2 bg-white"></span>
</span>
<span class="absolute bottom-0 left-0 w-full h-full transition-all duration-500 ease-in-out delay-200 -translate-x-full translate-y-full bg-red-600 rounded-2xl group-hover:mb-12 group-hover:translate-x-0"></span>
<span class="relative w-full text-left text-white transition-colors duration-200 ease-in-out group-hover:text-white">Button Text</span>
</a>

Preview
HTML
<button class="relative px-6 py-3 font-bold text-white rounded-lg group">
<span class="absolute inset-0 w-full h-full transition duration-300 transform -translate-x-1 -translate-y-1 bg-cyan-600 ease opacity-80 group-hover:translate-x-0 group-hover:translate-y-0"></span>
<span class="absolute inset-0 w-full h-full transition duration-300 transform translate-x-1 translate-y-1 bg-orange-600 ease opacity-80 group-hover:translate-x-0 group-hover:translate-y-0 mix-blend-screen"></span>
<span class="relative">Button Text</span>
</button>

HTML
<a href="#_" class="relative inline-flex items-center justify-center px-6 py-3 overflow-hidden font-bold text-white rounded-md shadow-2xl group">
<span class="absolute inset-0 w-full h-full transition duration-300 ease-out opacity-0 bg-gradient-to-br from-red-600 via-orange-700 to-cyan-400 group-hover:opacity-100"></span>
<!-- Top glass gradient -->
<span class="absolute top-0 left-0 w-full bg-gradient-to-b from-white to-transparent opacity-5 h-1/3"></span>
<!-- Bottom gradient -->
<span class="absolute bottom-0 left-0 w-full h-1/3 bg-gradient-to-t from-white to-transparent opacity-5"></span>
<!-- Left gradient -->
<span class="absolute bottom-0 left-0 w-4 h-full bg-gradient-to-r from-white to-transparent opacity-5"></span>
<!-- Right gradient -->
<span class="absolute bottom-0 right-0 w-4 h-full bg-gradient-to-l from-white to-transparent opacity-5"></span>
<span class="absolute inset-0 w-full h-full border border-white rounded-md opacity-10"></span>
<span class="absolute w-0 h-0 transition-all duration-300 ease-out bg-white rounded-full group-hover:w-56 group-hover:h-56 opacity-5"></span>
<span class="relative">Button Text</span>
</a>

HTML
<a href="#_" class="relative p-0.5 inline-flex items-center justify-center font-bold overflow-hidden group rounded-md">
<span class="w-full h-full bg-gradient-to-br from-[#ff8a05] via-[#ff5478] to-[#ff00c6] group-hover:from-[#ff00c6] group-hover:via-[#ff5478] group-hover:to-[#ff8a05] absolute"></span>
<span class="relative px-6 py-3 transition-all ease-out bg-gray-900 rounded-md group-hover:bg-opacity-0 duration-400">
<span class="relative text-white">Button Text</span>
</span>
</a>

HTML
<a href="#_" class="relative inline-flex items-center justify-start inline-block px-5 py-3 overflow-hidden font-bold rounded-full group">
<span class="w-32 h-32 rotate-45 translate-x-12 -translate-y-2 absolute left-0 top-0 bg-white opacity-[3%]"></span>
<span class="absolute top-0 left-0 w-48 h-48 -mt-1 transition-all duration-500 ease-in-out rotate-45 -translate-x-56 -translate-y-24 bg-white opacity-100 group-hover:-translate-x-8"></span>
<span class="relative w-full text-left text-white transition-colors duration-200 ease-in-out group-hover:text-gray-900">Button Text</span>
<span class="absolute inset-0 border-2 border-white rounded-full"></span>
</a>

HTML
<a href="#_" class="relative inline-flex items-center justify-start inline-block px-5 py-3 overflow-hidden font-medium transition-all bg-cyan-600 rounded-full hover:bg-white group">
<span class="absolute inset-0 border-0 group-hover:border-[25px] ease-linear duration-100 transition-all border-white rounded-full"></span>
<span class="relative w-full text-left text-white transition-colors duration-200 ease-in-out group-hover:text-cyan-600">Button Text</span>
</a>

Preview
HTML
<button class="relative inline-flex items-center justify-start px-6 py-3 overflow-hidden font-medium transition-all bg-white rounded hover:bg-white group">
<span class="w-48 h-48 rounded rotate-[-40deg] bg-cyan-600 absolute bottom-0 left-0 -translate-x-full ease-out duration-500 transition-all translate-y-full mb-9 ml-9 group-hover:ml-0 group-hover:mb-32 group-hover:translate-x-0"></span>
<span class="relative w-full text-left text-black transition-colors duration-300 ease-in-out group-hover:text-white">Button Text</span>
</button>

HTML
<a href="#_" class="relative inline-flex items-center justify-center px-6 py-3 text-lg font-medium tracking-tighter text-white bg-gray-800 rounded-md group">
<span class="absolute inset-0 w-full h-full mt-1 ml-1 transition-all duration-300 ease-in-out bg-cyan-600 rounded-md group-hover:mt-0 group-hover:ml-0"></span>
<span class="absolute inset-0 w-full h-full bg-white rounded-md "></span>
<span class="absolute inset-0 w-full h-full transition-all duration-200 ease-in-out delay-100 bg-cyan-600 rounded-md opacity-0 group-hover:opacity-100 "></span>
<span class="relative text-cyan-600 transition-colors duration-200 ease-in-out delay-100 group-hover:text-white">Button Text</span>
</a>

Preview
HTML
<button class="relative inline-flex items-center justify-center px-10 py-4 overflow-hidden font-mono font-medium tracking-tighter text-white bg-gray-800 rounded-lg group">
<span class="absolute w-0 h-0 transition-all duration-500 ease-out bg-cyan-500 rounded-full group-hover:w-56 group-hover:h-56"></span>
<span class="absolute inset-0 w-full h-full -mt-1 rounded-lg opacity-30 bg-gradient-to-b from-transparent via-transparent to-gray-700"></span>
<span class="relative">Button Text</span>
</button>

HTML
<a href="#_" class="relative inline-flex items-center justify-center px-6 py-3 font-medium text-white transition-all duration-300 bg-cyan-600 rounded-full group">
    <span class="absolute inset-0 w-full h-full transition-all duration-300 ease-in-out bg-gradient-to-br from-cyan-600 to-cyan-400 rounded-full blur-md opacity-75 group-hover:blur-none group-hover:opacity-100"></span>
    <span class="relative">Button Text</span>
</a>

HTML
<a href="#_" class="relative inline-flex items-center justify-center px-8 py-3 font-semibold text-white transition-all duration-300 bg-transparent border border-white rounded-lg backdrop-filter backdrop-blur-lg bg-opacity-10 border-opacity-30 hover:bg-opacity-30 hover:border-opacity-100">
    <span class="absolute inset-0 w-full h-full transition-all duration-300 ease-in-out bg-gradient-to-r from-cyan-400 to-cyan-600 opacity-50 blur-md rounded-lg group-hover:opacity-100"></span>
    <span class="relative">Button Text</span>
</a>

Preview
HTML
<button class="relative inline-flex items-center justify-center px-8 py-3 font-semibold text-white transition-transform duration-300 bg-gradient-to-r from-cyan-500 via-red-500 to-yellow-500 rounded-lg shadow-lg hover:shadow-xl hover:scale-105 hover:rotate-2">
    <span class="absolute inset-0 w-full h-full bg-[radial-gradient(ellipse_at_top_left,_var(--tw-gradient-stops))] from-red-500 via-red-500 to-cyan-500 opacity-70 blur-xl"></span>
    <span class="absolute inset-0 w-full h-full transition-opacity duration-300 bg-white opacity-0 group-hover:opacity-10"></span>
    <span class="relative z-10">Button Text</span>
</button>

TailBlocks Contact Form with an embedded map:

Preview

Feedback

This is just an example contact form with a map.

Where is Dora the Explorer going? What is she shipping?

HTML

<section class="text-gray-600 body-font relative">
  <div class="absolute inset-0 bg-gray-600">
    <iframe class="min-h-screen" width="100%" height="100%" frameborder="0" marginheight="0" marginwidth="0" title="map" scrolling="no" src="https://maps.google.com/maps?width=100%&amp;height=600&amp;hl=en&amp;q=%C4%B0zmir+(My%20Business%20Name)&amp;ie=UTF8&amp;t=&amp;z=14&amp;iwloc=B&amp;output=embed" style="filter: grayscale(1) contrast(1.2) opacity(0.4);"></iframe>
  </div>
  <div class="container px-5 py-24 mx-auto flex">
    <div class="lg:w-1/3 md:w-1/2 bg-white rounded-lg p-8 flex flex-col md:ml-auto w-full mt-10 md:mt-0 relative z-10 shadow-md">
      <h2 class="text-gray-900 text-lg mb-1 font-medium title-font">Feedback</h2>
      <p class="leading-relaxed mb-5 text-gray-600">This is just an example contact form with a map.</p>
      <div class="relative mb-4">
        <label for="email" class="leading-7 text-sm text-gray-600">Email</label>
        <input type="email" id="email" name="email" class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out">
      </div>
      <div class="relative mb-4">
        <label for="message" class="leading-7 text-sm text-gray-600">Message</label>
        <textarea id="message" name="message" class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 h-32 text-base outline-none text-gray-700 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out"></textarea>
      </div>
      <button class="text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg">Button</button>
      <p class="text-xs text-gray-500 mt-3">Where is Dora the Explorer going? What is she shipping?</p>
    </div>
  </div>
</section>

Animation utilities animate elements, and can be extended or layered through Rive / Lottie.

The default animations are:

  • animate-spin : Uses a keyframes spin to transform / rotate the object. Primary use case is loading indicators.

  • animate-ping : Uses transform to slowly scale out the element and create a radar / ripple effect. Primary use case is notifications.

  • animate-pulse : Alters the opacity of the element to create a fading effect. Primary use case is skeleton loaders.

  • animate-bounce : Transforms the Y axis of the element. Primary use case is aesthetics.

  • hover:$animation : Conditional — if the mouse is over the element, perform the animation.

A custom animation. In v4, register it as a theme token in CSS — no tailwind.config.js needed.

@theme {
--animate-spin-slow: spin 5s linear infinite;
}

That generates the animate-spin-slow utility. The v3 equivalent was extending the config:

/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
animation: {
'spin-slow': 'spin 5s linear infinite',
},
},
},
};

Tailwind styles mobile-first: an unprefixed utility applies everywhere, and a breakpoint prefix applies at that width and up.

PrefixMin widthTypical device
sm:40rem (640px)large phone / small tablet
md:48rem (768px)tablet
lg:64rem (1024px)laptop
xl:80rem (1280px)desktop
2xl:96rem (1536px)large desktop
<!-- 1 column on mobile, 2 on tablet, 4 on desktop -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4"></div>

State and feature variants stack the same way — hover:, focus-visible:, active:, disabled:, group-hover:, peer-checked:, motion-safe:, motion-reduce:, rtl:.

Tailwind’s dark: variant toggles on either the OS preference or a .dark class on a root element. v4 selects the strategy in CSS:

@import "tailwindcss";
/* class strategy — toggle <html class="dark"> yourself */
@custom-variant dark (&:where(.dark, .dark *));
<div class="bg-white text-gray-900 dark:bg-gray-900 dark:text-gray-100">
Adapts to the active theme.
</div>

Pure CSS equivalent, no framework:

:root { color-scheme: light dark; }
@media (prefers-color-scheme: dark) {
:root { --bg: #0a0a0a; --fg: #fafafa; }
}

Good CSS is accessible CSS. A few patterns carry most of the weight.

Never remove focus outlines outright. Use :focus-visible so a ring shows for keyboard users without flashing on mouse click.

.button:focus-visible {
outline: 2px solid var(--brand);
outline-offset: 2px;
}
<!-- Tailwind -->
<button class="focus:outline-none focus-visible:ring-2 focus-visible:ring-cyan-500 focus-visible:ring-offset-2">
Accessible
</button>

Visually hide content while keeping it in the accessibility tree (Tailwind ships sr-only).

.sr-only {
position: absolute;
width: 1px; height: 1px;
padding: 0; margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}

Forms carry the most CSS edge cases — native controls, focus states and validation feedback. Modern CSS handles most of it without JavaScript.

accent-color recolors checkboxes, radios, range sliders and progress bars in one line — no custom markup.

Preview
HTML
<form class="flex flex-col gap-4 p-8 max-w-sm bg-white rounded-lg" style="accent-color:#06b6d4">
  <label class="flex items-center gap-2 text-gray-800"><input type="checkbox" checked> Remember me</label>
  <div class="flex gap-4 text-gray-800">
    <label class="flex items-center gap-2"><input type="radio" name="plan" checked> Free</label>
    <label class="flex items-center gap-2"><input type="radio" name="plan"> Pro</label>
  </div>
  <input type="range" min="0" max="100" value="60">
  <progress value="0.6"></progress>
</form>

:user-invalid and :user-valid only react after the user has interacted with a field — unlike :invalid, which fires on page load before anyone has typed. This is the correct hook for inline error styling.

Preview
HTML
<form class="flex flex-col gap-4 p-8 max-w-sm bg-white rounded-lg">
  <div class="flex flex-col gap-1">
    <label class="text-sm font-medium text-gray-700">Email (try an invalid one)</label>
    <input type="email" required placeholder="[email protected]"
      class="px-3 py-2 text-gray-800 bg-white border-2 rounded-md outline-none border-gray-300 focus:border-cyan-500 user-invalid:border-red-500 user-valid:border-green-500">
  </div>
</form>
Preview
HTML
<form class="p-8 max-w-sm bg-gray-50 rounded-lg">
  <div class="relative">
    <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-400">
      <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
    </span>
    <input type="search" placeholder="Search…"
      class="w-full py-2 pl-10 pr-4 text-gray-800 bg-white border border-gray-300 rounded-lg outline-none focus:border-cyan-500 focus:ring-2 focus:ring-cyan-200">
  </div>
</form>

A label that rides above the field once it has focus or content — driven by :placeholder-shown and peer, no JavaScript.

Preview
HTML
<form class="p-8 max-w-sm bg-white rounded-lg">
  <div class="relative">
    <input id="name" type="text" placeholder=" "
      class="block w-full px-3 pt-5 pb-2 text-gray-800 bg-transparent border-2 rounded-md outline-none peer border-gray-300 focus:border-cyan-500">
    <label for="name"
      class="absolute text-gray-500 duration-200 transform -translate-y-3 scale-75 top-3 left-3 origin-[0] peer-placeholder-shown:translate-y-0 peer-placeholder-shown:scale-100 peer-focus:-translate-y-3 peer-focus:scale-75 peer-focus:text-cyan-600">
      Full name
    </label>
  </div>
</form>

Reusable visual effects. Text-effect snippets use arbitrary values ([text-shadow:...]) so they render on any Tailwind build, with the native v4 utility noted alongside.

Tailwind v4 ships native text-shadow-* utilities (text-shadow-2xs through text-shadow-lg). For full control, arbitrary values still work.

Preview
Soft Drop Hard Offset Neon Glow
HTML
<div class="flex flex-wrap items-center gap-8 p-8 bg-gray-900 text-white">
  <span class="text-4xl font-bold [text-shadow:_2px_2px_0_rgb(0_0_0_/_40%)]">Soft Drop</span>
  <span class="text-4xl font-bold [text-shadow:_4px_4px_0_#06b6d4]">Hard Offset</span>
  <span class="text-4xl font-bold text-cyan-300 [text-shadow:_0_0_8px_#06b6d4,_0_0_20px_#06b6d4]">Neon Glow</span>
</div>

Preview

GLOW

HTML
<div class="flex items-center justify-center p-10 bg-black">
  <h1 class="text-5xl font-extrabold text-white animate-pulse [text-shadow:_0_0_10px_#fff,_0_0_20px_#06b6d4,_0_0_40px_#06b6d4,_0_0_80px_#06b6d4]">
    GLOW
  </h1>
</div>

Clip a background gradient to the text shape with bg-clip-text text-transparent.

Preview

Gradient

HTML
<div class="flex items-center justify-center p-10 bg-gray-900">
  <h1 class="text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-fuchsia-500 to-amber-400">
    Gradient
  </h1>
</div>

Pair the clipped gradient with a moving background position for a shimmer.

Preview

Shimmer

HTML
<div class="flex items-center justify-center p-10 bg-gray-900">
  <h1 class="text-6xl font-black text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-fuchsia-500 to-cyan-400 bg-[length:200%_auto] animate-[shimmer_3s_linear_infinite]" style="background-position:0% center;">
    Shimmer
  </h1>
</div>

Frosted-glass surface via backdrop-blur over a translucent background.

Preview

Glassmorphism

A frosted-glass panel using a translucent background and a backdrop blur. Place it over a colorful or image background for the effect to read.

HTML
<div class="flex items-center justify-center p-10 bg-gradient-to-br from-cyan-500 to-fuchsia-600">
  <div class="max-w-sm p-6 border shadow-xl rounded-2xl bg-white/10 backdrop-blur-lg border-white/20">
    <h3 class="text-xl font-bold text-white">Glassmorphism</h3>
    <p class="mt-2 text-sm text-white/80">A frosted-glass panel using a translucent background and a backdrop blur. Place it over a colorful or image background for the effect to read.</p>
  </div>
</div>

Preview

Neon Card

Outer and inner box-shadow in the same hue creates the neon tube look. Pairs well with a dark background.

HTML
<div class="flex items-center justify-center p-10 bg-black">
  <div class="max-w-sm p-6 rounded-2xl bg-gray-950 border-2 border-cyan-400 shadow-[0_0_15px_#06b6d4,inset_0_0_15px_#06b6d4]">
    <h3 class="text-xl font-bold text-cyan-300 [text-shadow:_0_0_8px_#06b6d4]">Neon Card</h3>
    <p class="mt-2 text-sm text-cyan-100/70">Outer and inner box-shadow in the same hue creates the neon tube look. Pairs well with a dark background.</p>
  </div>
</div>

A spinner from a single bordered element — transparent on three sides, colored on one, spun with animate-spin.

Preview
HTML
<div class="flex items-center justify-center gap-6 p-10 bg-gray-900">
  <div class="w-10 h-10 border-4 rounded-full border-cyan-500 border-t-transparent animate-spin"></div>
  <div class="w-10 h-10 border-4 border-dashed rounded-full border-fuchsia-500 animate-spin"></div>
  <div class="w-10 h-10 border-2 rounded-full border-amber-400 border-b-transparent border-l-transparent animate-spin"></div>
</div>

Placeholder shapes with animate-pulse while content streams in.

Preview
HTML
<div class="max-w-sm p-6 bg-white rounded-lg shadow">
  <div class="flex items-center gap-4">
    <div class="w-12 h-12 bg-gray-200 rounded-full animate-pulse"></div>
    <div class="flex-1 space-y-3">
      <div class="w-3/4 h-3 bg-gray-200 rounded animate-pulse"></div>
      <div class="w-1/2 h-3 bg-gray-200 rounded animate-pulse"></div>
    </div>
  </div>
  <div class="mt-6 space-y-3">
    <div class="h-3 bg-gray-200 rounded animate-pulse"></div>
    <div class="h-3 bg-gray-200 rounded animate-pulse"></div>
    <div class="w-5/6 h-3 bg-gray-200 rounded animate-pulse"></div>
  </div>
</div>

A pure-CSS switch — a hidden peer checkbox drives the track and knob with peer-checked: variants. No JavaScript.

Preview
HTML
<div class="flex items-center gap-6 p-10 bg-gray-100">
  <label class="relative inline-flex items-center cursor-pointer">
    <input type="checkbox" class="sr-only peer" checked>
    <div class="w-11 h-6 bg-gray-300 rounded-full peer-checked:bg-cyan-500 transition-colors after:content-[''] after:absolute after:top-0.5 after:left-0.5 after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:after:translate-x-5"></div>
    <span class="ml-3 text-sm font-medium text-gray-700">Enabled</span>
  </label>
</div>

CSS-only tooltip — group-hover reveals an absolutely positioned label. Pair with aria-label for assistive tech.

Preview
Tooltip text
HTML
<div class="flex items-center justify-center p-16 bg-gray-900">
  <div class="relative inline-block group">
    <button class="px-4 py-2 font-medium text-white rounded-md bg-cyan-600">Hover me</button>
    <span class="absolute z-10 px-3 py-1.5 text-sm text-white -translate-x-1/2 bg-gray-800 rounded-md opacity-0 pointer-events-none bottom-full left-1/2 mb-2 whitespace-nowrap transition-opacity duration-200 group-hover:opacity-100">
      Tooltip text
      <span class="absolute -translate-x-1/2 border-4 border-transparent top-full left-1/2 border-t-gray-800"></span>
    </span>
  </div>
</div>

Status chips with a leading dot.

Preview
Online Pending Offline New
HTML
<div class="flex flex-wrap items-center gap-3 p-10 bg-gray-50">
  <span class="inline-flex items-center gap-1.5 px-3 py-1 text-sm font-medium rounded-full text-green-700 bg-green-100">
    <span class="w-2 h-2 rounded-full bg-green-500"></span> Online
  </span>
  <span class="inline-flex items-center gap-1.5 px-3 py-1 text-sm font-medium rounded-full text-amber-700 bg-amber-100">
    <span class="w-2 h-2 rounded-full bg-amber-500"></span> Pending
  </span>
  <span class="inline-flex items-center gap-1.5 px-3 py-1 text-sm font-medium rounded-full text-red-700 bg-red-100">
    <span class="w-2 h-2 rounded-full bg-red-500"></span> Offline
  </span>
  <span class="inline-flex items-center px-2.5 py-0.5 text-xs font-semibold tracking-wide uppercase rounded text-white bg-gradient-to-r from-cyan-500 to-fuchsia-500">
    New
  </span>
</div>

The native <details> / <summary> element is an accordion with zero JavaScript — open state, keyboard support and accessibility are built in. Style the marker and the open state with the open attribute and details[open].

Preview
What is TailwindCSS?

A utility-first CSS framework for composing designs directly in your markup.

Does it need JavaScript?

No — this accordion is pure HTML and CSS via the details element.

HTML
<div class="max-w-md p-4 space-y-2 bg-gray-50 rounded-lg">
  <details class="p-4 bg-white rounded-lg shadow-sm group" open>
    <summary class="flex items-center justify-between font-medium text-gray-800 cursor-pointer list-none">
      What is TailwindCSS?
      <svg class="w-5 h-5 transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
    </summary>
    <p class="mt-3 text-sm text-gray-600">A utility-first CSS framework for composing designs directly in your markup.</p>
  </details>
  <details class="p-4 bg-white rounded-lg shadow-sm group">
    <summary class="flex items-center justify-between font-medium text-gray-800 cursor-pointer list-none">
      Does it need JavaScript?
      <svg class="w-5 h-5 transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
    </summary>
    <p class="mt-3 text-sm text-gray-600">No — this accordion is pure HTML and CSS via the details element.</p>
  </details>
</div>

Preview

Saved successfully.

!

Your session expires soon.

Something went wrong.

HTML
<div class="max-w-md p-6 space-y-3 bg-gray-50">
  <div class="flex gap-3 p-4 border-l-4 rounded-md bg-green-50 border-green-500">
    <span class="font-bold text-green-600">✓</span>
    <p class="text-sm text-green-800">Saved successfully.</p>
  </div>
  <div class="flex gap-3 p-4 border-l-4 rounded-md bg-amber-50 border-amber-500">
    <span class="font-bold text-amber-600">!</span>
    <p class="text-sm text-amber-800">Your session expires soon.</p>
  </div>
  <div class="flex gap-3 p-4 border-l-4 rounded-md bg-red-50 border-red-500">
    <span class="font-bold text-red-600">✕</span>
    <p class="text-sm text-red-800">Something went wrong.</p>
  </div>
</div>

Preview
88%
HTML
<div class="max-w-md p-8 space-y-5 bg-white">
  <div class="w-full h-2 overflow-hidden bg-gray-200 rounded-full">
    <div class="h-full rounded-full bg-cyan-500" style="width:70%"></div>
  </div>
  <div class="w-full h-3 overflow-hidden bg-gray-200 rounded-full">
    <div class="h-full rounded-full bg-gradient-to-r from-cyan-500 to-fuchsia-500" style="width:45%"></div>
  </div>
  <div class="relative w-full h-4 overflow-hidden bg-gray-200 rounded-full">
    <div class="flex items-center justify-end h-full pr-2 text-xs font-medium text-white rounded-full bg-emerald-500" style="width:88%">88%</div>
  </div>
</div>

Preview

Revenue

$48.2k

↑ 12.5%

Users

2,318

↑ 4.1%

Churn

1.2%

↓ 0.3%

HTML
<div class="grid grid-cols-1 gap-4 p-6 sm:grid-cols-3 bg-gray-50">
  <div class="p-5 bg-white rounded-xl shadow-sm">
    <p class="text-sm text-gray-500">Revenue</p>
    <p class="mt-1 text-3xl font-bold text-gray-900">$48.2k</p>
    <p class="mt-1 text-sm font-medium text-green-600">↑ 12.5%</p>
  </div>
  <div class="p-5 bg-white rounded-xl shadow-sm">
    <p class="text-sm text-gray-500">Users</p>
    <p class="mt-1 text-3xl font-bold text-gray-900">2,318</p>
    <p class="mt-1 text-sm font-medium text-green-600">↑ 4.1%</p>
  </div>
  <div class="p-5 bg-white rounded-xl shadow-sm">
    <p class="text-sm text-gray-500">Churn</p>
    <p class="mt-1 text-3xl font-bold text-gray-900">1.2%</p>
    <p class="mt-1 text-sm font-medium text-red-600">↓ 0.3%</p>
  </div>
</div>

Preview
KB

KBVE Dev

Platform Engineer

HTML
<div class="flex items-center justify-center p-10 bg-gradient-to-br from-cyan-500 to-fuchsia-600">
  <div class="max-w-xs overflow-hidden text-center bg-white shadow-xl rounded-2xl">
    <div class="h-20 bg-gradient-to-r from-cyan-400 to-fuchsia-400"></div>
    <div class="px-6 pb-6 -mt-10">
      <div class="flex items-center justify-center w-20 h-20 mx-auto text-2xl font-bold text-white border-4 border-white rounded-full bg-gray-800">KB</div>
      <h3 class="mt-3 text-lg font-bold text-gray-900">KBVE Dev</h3>
      <p class="text-sm text-gray-500">Platform Engineer</p>
      <button class="px-4 py-2 mt-4 text-sm font-medium text-white rounded-lg bg-cyan-600 hover:bg-cyan-700">Follow</button>
    </div>
  </div>
</div>

Preview
Pro

$12/mo

  • Unlimited projects
  • Priority support
  • Custom domains
HTML
<div class="flex items-center justify-center p-10 bg-gray-900">
  <div class="max-w-xs p-8 border-2 bg-gray-950 border-cyan-500 rounded-2xl shadow-[0_0_30px_rgba(6,182,212,0.3)]">
    <span class="inline-block px-3 py-1 text-xs font-semibold tracking-wide text-cyan-300 uppercase rounded-full bg-cyan-500/10">Pro</span>
    <p class="mt-4 text-4xl font-extrabold text-white">$12<span class="text-base font-medium text-gray-400">/mo</span></p>
    <ul class="mt-6 space-y-2 text-sm text-gray-300">
      <li class="flex gap-2"><span class="text-cyan-400">✓</span> Unlimited projects</li>
      <li class="flex gap-2"><span class="text-cyan-400">✓</span> Priority support</li>
      <li class="flex gap-2"><span class="text-cyan-400">✓</span> Custom domains</li>
    </ul>
    <button class="w-full py-2.5 mt-8 font-medium text-white rounded-lg bg-cyan-600 hover:bg-cyan-500">Choose Pro</button>
  </div>
</div>