
Material Design Buttons CSS
Published
14 hand-coded Material Design 3 components in pure CSS — the Material You aesthetic without MUI, Material Components Web, or a 50-100kb bundle — raised buttons with ripple, filled + outlined text fields with floating labels, top app bar with scroll shrink, navigation drawer, tab bar with sliding indicator, chip row with dismiss, snackbar with action, FAB with speed dial, extended FAB, expansion panel accordion, dialog with scrim, bottom sheet, switch with thumb depth, radio + checkbox with state layer, and a segmented button group. Every interactive uses :checked + :has() state machines — no JavaScript required — with Roboto typography, indigo + amber palette, and WCAG 2.5.5 44×44px touch targets on every control. Scoped under .md-NN for no-collision pasting (never clashes with MUI class names), prefers-reduced-motion guarded on every ripple and slide, framework-agnostic (drop into React, Vue, Astro, Next, Rails ERB, or plain HTML).
Related12 CSS Ripple Effects51 CSS Buttons34 CSS Floating Buttons

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published

Published
<span> is spawned at the click coordinate — that requires JavaScript and you have to recalculate positions on every click. This demo's pure-CSS approach: a ::after pseudo-element with position: absolute; inset: 0; background: radial-gradient(...) center / 0 0 no-repeat. On :hover and :focus-visible, the background-size animates from 0 0 to 200% 200% over 0.4s with ease-out — creating a ripple that radiates from the button center. On :active a separate keyframe runs a faster, more contained ripple for the press feedback. Tradeoff vs JS ripple: the ripple always originates from the BUTTON center, not the click coordinate. For ~95% of UI use cases (CTAs, primary actions, navigation buttons) this is indistinguishable from a JS ripple and saves you the entire JS implementation. The 5% case where ripple-at-cursor matters (interactive canvases, design tools): use the JS approach Demo 16 in CSS Floating Buttons.<label> sits absolutely positioned over the <input>'s placeholder area. The :placeholder-shown pseudo-class targets inputs that still show their placeholder (i.e., empty + not focused). When the input is :focus OR NOT :placeholder-shown (has content), the label translates up and scales down via transitions. The selector chain: .md-04__field input:focus + label, .md-04__field input:not(:placeholder-shown) + label { transform: translateY(-22px) scale(0.78); color: var(--md-primary); }. Three details most online tutorials get wrong: (1) Use placeholder=" " (single space) on the input, not empty — Chrome treats an empty placeholder as no placeholder and breaks the selector. (2) Animate transform not top/font-size — transform is GPU-accelerated and won't trigger layout reflow. (3) Set transform-origin: left center so the label scales from its left edge, matching Material's spec.<dialog> element. The pattern: <dialog id="md-05-dialog"> contains the dialog content; an open-trigger button has a <label for="md-05-open"> + hidden checkbox; CSS shows the dialog when #md-05-open:checked ~ * #md-05-dialog matches. The modern alternative (which Demo 05 also illustrates as a snippet): <dialog> opened by modal.showModal() automatically gets focus trap, Esc-to-close, scroll lock, and backdrop — but requires one line of JS. Why the checkbox-hack version exists alongside: zero JS, works on every browser since 2016, useful for marketing pages or static landing pages where adding a JS click handler feels like overkill. Three production gotchas: (a) Focus trap — the pure-CSS dialog doesn't trap focus (Tab can leave the dialog). For accessibility-critical UIs, use the native <dialog> + JS instead. (b) Scroll lock — body still scrolls behind the open dialog unless you add html:has(#md-05-open:checked) body { overflow: hidden } (requires :has() — Chrome 105+, Safari 15.4+, Firefox 121+). (c) Backdrop click to close — works via <label for="md-05-open"> on the backdrop element.:checked on the hidden toggle slides the drawer in via transform: translateX(-256px) → translateX(0). (3) Main content area to the right of the drawer, with a backdrop overlay on mobile when the drawer is open. (4) A bottom navigation bar on mobile breakpoints (below 768px) — the drawer becomes a modal overlay rather than always-visible. Three production-grade details: (a) Use CSS Grid for the shell: grid-template-columns: auto 1fr on desktop, 1fr on mobile. (b) Persist drawer state via localStorage if you wire one line of JS — visitors who close the drawer want it stay closed across page navigations. (c) Trap focus when the drawer is modal on mobile — Tab order should cycle within the drawer until Esc closes it. ~60 lines of CSS, 0 lines of JS.--md-primary, --md-secondary, --md-surface custom properties at the demo root, and the Material grammar carries your brand's identity. Substituting Roboto with your brand font (or with Inter, IBM Plex Sans, Geist) also differentiates the look. Most successful Material-derived products do exactly this — Slack's web app, Notion's settings panel, Linear's editor all use Material patterns with brand-specific color + typography substitutions.:focus-visible ring (typically outline: 2px solid var(--md-primary); outline-offset: 2px) that survives Material's ripple animation. (4) Semantic HTML. Real <button> / <input> / <dialog> / <nav> elements, not divs styled as buttons. Screen reader announcements work automatically. (5) aria-current, aria-expanded, aria-selected, aria-controls on interactive components (tabs, expansion panels, navigation links) so screen readers announce the current state. (6) prefers-reduced-motion media query on every demo — vestibular-sensitive visitors don't see ripples, slide-in panels, or other continuous motion.<dialog> dual implementation. Tabular data (orders, users, transactions): Demo 06 (Material Design Data Table CSS) — proper alignment, hover states, sortable column headers. Tabbed content panels: Demo 07 (Material Design Tabs CSS) — ripple-driven underline transitions. Filter / tag UI: Demo 08 (Material Design Chip CSS) — removable chips with leading icons. Multi-step form flows: Demo 09 (Material Design Stepper CSS) — vertical step indicator. Hover help / contextual info: Demo 10 (Material Design Tooltip CSS) — four directional variants. FAQ / collapsible content: Demo 11 (Material Design Expansion Panel CSS) — Material's accordion. Profile lists / contact lists / settings menus: Demo 12 (Material Design List CSS) — two-line list with avatars. Design system documentation page: Demo 13 (Material Design Color Palette CSS) — full 500-shade palette with theme switcher. Full-app skeleton: Demo 14 (Material Design App Shell Layout CSS) — drawer + top bar + content. All 14 are 100% pure CSS, MIT-licensed, framework-neutral.9 hand-coded CSS 3D scenes built with real transforms, perspective, and preserve-3d — iridescent flip cards, a midnight coverflow carousel, kinetic tilt pricing cards, a page-turn flipbook, a Bauhaus drag-cube navigator, a modular synth control panel, a luxury hover-flip product showcase, a 5×5 spinning cube matrix, and a 60-orb DNA double helix. No WebGL, no libraries.
22 hand-coded brutalist and neubrutalist CSS designs covering the full spectrum of the aesthetic — from the anti-design brutalism of 2014-2018 (raw system fonts, zero border radius, monochrome density, visible structure) through to the neubrutalism of 2021-present (bright pastel fills, thick black borders, hard offset shadows with zero blur, rounded blocks). The neubrutalist half ships SaaS pricing cards with sticker badges, a pastel admin dashboard, signup forms, rotated feature cards, an offset-shadow navbar, a playful button set, a native dialog modal, a testimonial wall, blog cards, chunky toggles, a landing hero, an image gallery, stats panels and a rounded footer. The brutalist half covers product grids, raw form controls, a monochrome data dashboard, a portfolio index, indie SaaS pricing, Windows 95 desktop chrome, editorial long-read and a streetwear catalog. Every design is scoped under a .brt-NN prefix for no-collision pasting, guards prefers-reduced-motion, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.
22 hand-coded CSS dark-mode UI patterns — prefers-color-scheme root strategy, data-theme attribute override, color-mix token system, light-dark() function, sidebar navigation, dashboard card grid, modal dialog, focus-ring contrast audit, three-state switcher, code editor surface, OLED true black, layered slate, aurora dim and more.