Tag: CSS Tools

  • CSS Pattern Generator: Pure-CSS Backgrounds [2026]

    CSS Pattern Generator: Pure-CSS Backgrounds [2026]

    TL;DR: A CSS pattern generator outputs pure-CSS code for repeating background patterns — dots, grids, stripes, checks, isometric, halftone — with no image files needed. The technique uses repeating-linear-gradient, radial-gradient, and (modern browsers) image() + masks to draw geometric tiles directly in CSS. Result: tiny payloads (often under 100 bytes), infinite scaling, and styles that change with CSS variables. Our free CSS pattern generator ships 30+ presets with size, color, and angle controls.

    Background patterns used to mean a 1KB tileable PNG. Modern CSS makes most of them unnecessary — a dot grid is two short lines of radial-gradient; diagonal stripes are one repeating-linear-gradient; a graph-paper grid is two layered linear gradients. The CSS approach beats raster images on every axis: smaller payload, perfectly crisp on retina displays, theme-aware (use CSS variables for colors), and editable in DevTools without rebuilding assets.

    Our CSS pattern generator ships 30+ tested patterns across categories: dots (uniform dot grid, scattered, halftone), lines (horizontal, diagonal, crosshatch), grids (graph paper, isometric, hex), geometric (zigzag, chevron, scales). Adjust pattern size, foreground/background color, and angle. Outputs production-ready CSS with the canonical pattern declaration plus a fallback for older browsers.

    Pattern types and what each looks like

    Pattern Technique Best for
    Dot grid radial-gradient tile Subtle background, hero sections
    Graph paper Two linear-gradient layers Notebook / sketch UIs, illustrations
    Diagonal stripes repeating-linear-gradient Caution / warning blocks, accents
    Checkerboard Two linear-gradient layers at 45° offset Transparency indicator, retro aesthetic
    Isometric grid Three linear-gradient layers at 60° 3D illustrations, blueprint look
    Crosshatch Two diagonal repeating-linear-gradient Editorial, illustration backgrounds
    Halftone Sized radial-gradient with background-size Comic / pop-art aesthetic

    A simple dot-grid example

    The minimal CSS for a 2px dot every 24px:

    .dot-grid {
      background-color: #fffdf8;
      background-image: radial-gradient(circle, #635BFF 1px, transparent 1px);
      background-size: 24px 24px;
    }

    Two lines plus background color = a perfect dot grid. Resize the background-size to change spacing, swap the colors for different themes. No image, no PNG asset, scales infinitely.

    How to generate a CSS pattern

    1. Open the CSS pattern generator
    2. Pick a pattern type from the gallery
    3. Adjust pattern size (the spacing of the repeat), foreground color, background color, and angle (where supported)
    4. Watch the live preview update across the full panel
    5. Click Copy CSS for the production-ready declaration with comments and CSS variables

    Why CSS patterns beat image tiles

    • Tiny payload. A dot grid is ~80 characters of CSS. The same as an image is 0.8–2 KB after PNG compression.
    • Infinitely scalable. A 24px tile renders crisp on a 5K display because the gradient is rasterised at the actual pixel density. PNG tiles need 2× / 3× variants for retina.
    • Theme-aware. Use CSS variables for colors and the same pattern adapts automatically to dark mode without separate assets.
    • Editable in DevTools. Tweak background-size live without rebuilding any image.
    • Server caching is irrelevant. No separate request — the pattern is part of the CSS file.

    Common gotchas

    • Performance on huge fills. A repeating-gradient pattern on a full-page background performs fine. Stacking 4+ pattern layers on the same element can slow down older mobile devices — keep complex patterns to small areas.
    • Background-attachment fixed + patterns. Using background-attachment: fixed with a CSS pattern can cause repaints on scroll. Use scroll (default) for performance unless the parallax effect is essential.
    • Patterns don’t shift with mouse / scroll. If you want a “parallax” pattern effect, you need JavaScript or transform-based motion — pure CSS patterns are static relative to their element.
    • Print stylesheets. Browsers often disable background images and patterns for print to save toner. Set -webkit-print-color-adjust: exact if printing the pattern matters.
    • Edge alignment. Pattern tiles align to the element’s background-origin. If you have padding or border-radius, the pattern continues underneath them — useful for seamless backgrounds, but watch for asymmetric clipping at corners.
    • Color overlap. When stacking multiple gradient layers (e.g., grid = horizontal lines + vertical lines), check that they blend correctly. Use the + blend mode or rgba() colors with appropriate transparency.

    When NOT to use a CSS pattern

    For organic, illustrated, or photographic patterns (watercolor textures, fabric, paper grain), use a real image — CSS gradients can’t produce non-geometric shapes. For animated patterns (slowly drifting backgrounds), use SVG with smil animations or a canvas — CSS background-position animation is choppy. For SEO-relevant images (where the pattern is content, not decoration), use a real image with proper alt text. For very complex patterns (snowflakes, paisley, custom logos repeated), use a tileable SVG instead — more efficient than 10+ stacked gradients.

    Frequently asked questions

    Are CSS patterns supported in all browsers?

    Yes — radial-gradient and repeating-linear-gradient have been supported since Chrome 26, Firefox 16, Safari 7. Universal support in 2026. Even IE 11 had partial support (no repeating gradients but solid patterns work).

    Will CSS patterns slow down my page?

    Single patterns: no — they’re rendered at GPU speed and cached. Multiple stacked patterns on the same large element can slow paint times on older mobiles, but typical use (one pattern per page) has zero measurable impact.

    Can I animate a CSS pattern?

    Limited — you can animate background-position for a “scrolling” effect, or animate background-size for pulsing. More complex animation (morphing patterns, shape changes) requires SVG or canvas. Animating background-position is GPU-accelerated and smooth.

    How do I make the pattern darker / lighter?

    Adjust the foreground and background colors directly in the CSS. Pure black/dark patterns on light backgrounds maximise contrast; semi-transparent foregrounds (e.g., rgba(0,0,0,0.05)) produce subtle textures that don’t compete with content.

    Is my data uploaded?

    No. The generator runs in your browser. Pattern selections, customisations, and the generated CSS stay on your device.

    Can I export the pattern as an image?

    Yes — there’s a “Download as PNG” option that rasterises the pattern at chosen size (256×256, 512×512, or full-screen). Useful for fallbacks in old browsers, or when an image asset is required (CMS that doesn’t accept inline CSS, email templates, etc.).

    Related tools and guides

     

  • CSS Triangle Generator: Border Trick + Clip-Path [2026]

    CSS Triangle Generator: Border Trick + Clip-Path [2026]

    TL;DR: CSS triangles use one of two techniques: the classic border trick (a zero-size element with thick transparent borders, where one border has a color — that color shows as a triangle) or modern clip-path with a polygon(). Border trick has perfect browser support back to IE 6; clip-path is cleaner CSS but needs a real-sized box. Our free CSS triangle generator outputs both forms with size, color, and direction controls.

    CSS triangles solve a specific problem: drawing a small triangular shape (tooltip arrows, dropdown indicators, breadcrumb separators, accent shapes) without an SVG or image. The two techniques have been around forever — the border-trick variant is famously hacky CSS that works because of how browsers render border miters at the corners of an element. The clip-path variant is straightforward but needs more recent browser support.

    Our CSS triangle generator builds either form. Pick a direction (up, down, left, right, or one of four diagonals), set size and color, and copy the production CSS. Both versions are inline-able — no extra HTML elements needed beyond the triangle’s own div or span. This guide explains both techniques, when to use which, and the rendering quirks that make one or the other choice for specific contexts.

    Border trick vs clip-path — which to use

    Technique Pros Cons
    Border trick Universal browser support; zero-size element Hard to gradient-fill; smaller hit area
    clip-path polygon() Cleaner CSS; can have content; gradient-fillable Modern only; needs real-size box

    For tooltip arrows and dropdown indicators (decoration only): use the border trick. For triangular badges, decorative shapes, or any triangle that needs gradients, text inside, or animation: use clip-path.

    The border-trick technique explained

    An element with width: 0; height: 0; and thick borders renders as four diagonal-mitered triangles meeting at the centre. Make three of those borders transparent and you’re left with a single triangle in the colour of the visible border:

    /* Triangle pointing up — 30px wide, 20px tall */
    .triangle-up {
      width: 0;
      height: 0;
      border-left: 15px solid transparent;
      border-right: 15px solid transparent;
      border-bottom: 20px solid #635BFF;
    }
    
    /* Triangle pointing down */
    .triangle-down {
      width: 0;
      height: 0;
      border-left: 15px solid transparent;
      border-right: 15px solid transparent;
      border-top: 20px solid #635BFF;
    }

    The size is implicit: the triangle’s width is twice the border-left/right width (30px above), and its height is whatever the visible border thickness is (20px). To change direction, change which border is solid and which are transparent.

    The clip-path technique explained

    A real-sized div clipped to a polygon shape produces an editable, fill-able triangle:

    /* Triangle pointing up */
    .triangle-up {
      width: 60px;
      height: 60px;
      background: #635BFF;
      clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
    }
    
    /* Add gradient or border easily */
    .triangle-gradient {
      width: 60px;
      height: 60px;
      background: linear-gradient(45deg, #635BFF, #00D4FF);
      clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
    }

    Bonus: clip-path triangles can have text inside (it’s a real div), can be flex/grid containers, and can be animated. The cost is needing modern browser support (Chrome 23+, Firefox 54+, Safari 7+ — universal in 2026 except IE).

    How to generate a CSS triangle

    1. Open the CSS triangle generator
    2. Pick direction (up, down, left, right, top-left/top-right/bottom-left/bottom-right diagonals)
    3. Set width and height
    4. Pick color, plus a stroke for the clip-path version
    5. Toggle between Border trick and clip-path output
    6. Click Copy CSS

    When you’d use a triangle in real CSS

    • Tooltip arrows. A triangle pointing at the trigger element. The classic use — small (8–12px), border-trick, positioned absolutely against the tooltip body.
    • Dropdown carets. The little ▼ next to “More” buttons. Often replaced by SVG icons in modern UIs but still common in plain-CSS contexts.
    • Breadcrumb separators. The “›” between items. Often a real character, but a CSS triangle gives precise control over color and angle.
    • Speech-bubble pointers. Chat-bubble UIs use a triangle pointing at the speaker. Border trick or clip-path both work.
    • Decorative section dividers. A wide, flat triangle as a wedge between page sections. Use clip-path on a full-width div for this.
    • Custom badges. Triangular accent on the corner of a card. clip-path with text inside.

    Common gotchas

    • Sub-pixel rendering. Triangles smaller than 8px can look blurry on non-retina displays because the diagonal isn’t a clean pixel boundary. Either use larger triangles or accept slight anti-aliasing artefacts.
    • Background colour bleeds. The transparent borders in the border trick still occupy hit-test area. The visible triangle’s clickable region extends to the full bounding box, not just the visible part.
    • Inline element issues. A border-trick triangle on a <span> may render with line-height padding around it. Use display: inline-block or wrap in a container.
    • Right-to-left layouts. A triangle pointing “left” should flip to point “right” in RTL layouts. CSS logical properties (margin-inline-start etc.) help, but border-direction names don’t have logical equivalents — handle the flip manually with [dir="rtl"] selectors.
    • Animation cost. Border-trick triangles can be expensive to animate (changing border width triggers layout). clip-path triangles animate cheaply (transform-only).
    • Don’t try to gradient-fill a border-trick triangle. Borders take a single solid color. For gradients, use clip-path; for the border trick, use a wrapper element with the gradient and the triangle as a mask.

    When NOT to use a CSS triangle

    For complex shapes (chevron with rounded corners, triangular logos, multi-color triangles), use SVG inline — much more flexible. For a triangle with shadows, drop-shadow, or stroke effects, use clip-path with filter: drop-shadow(). For very tiny triangles (under 4px), consider Unicode characters (▲ ▼ ◀ ▶) which are font-rendered and crisp at small sizes. For animated character indicators (like a pulse arrow), an SVG with proper SVG animations is smoother than a CSS-only approach.

    Frequently asked questions

    Why does the border trick work?

    Browsers render borders with diagonal miters at corners. An element with zero width and height is just a point — the corners meet at the centre — and each border becomes a triangle pointing inward. Make three transparent and one solid coloured, and you see only the solid triangle.

    Which technique should I use?

    For tooltip arrows and small UI triangles: border trick (universal support, simpler positioning). For decorative triangles with content, gradients, or animation: clip-path. Both are universally supported in 2026 except IE (retired).

    Can I make a triangle with rounded corners?

    Not with the border trick. With clip-path, the polygon corners are sharp by default — for rounded triangles, use SVG with stroke-linejoin or a custom path. There’s a CSS proposal for shape-radius but it’s not implemented yet.

    How do I rotate a triangle?

    For arbitrary angles, generate a “pointing-up” triangle and apply transform: rotate(45deg). The triangle rotates around its centre. Combine with transform-origin to rotate around a different point.

    Is my data uploaded?

    No. The generator runs in your browser. Triangle settings, the live preview, and the generated CSS stay on your device.

    Can I have text inside a CSS triangle?

    Yes — only with the clip-path version. The border-trick triangle has zero width and height, so no content fits. clip-path triangles are real divs with full layout properties — text, flex, grid, anything.

    Related tools and guides

     

  • CSS Checkbox Generator: Custom Style, Accessible [2026]

    CSS Checkbox Generator: Custom Style, Accessible [2026]

    TL;DR: A CSS checkbox generator outputs custom-styled checkboxes that wrap a native <input type="checkbox"> for accessibility — keyboard navigation, screen reader announcements, form-submit semantics — while letting you control every visual aspect. The technique uses appearance: none to strip the default style, then renders a custom check via ::before pseudo-element. Our free CSS checkbox generator ships 20+ presets (rounded, bordered, animated, brand-colored), custom check icons, and the indeterminate state.

    HTML checkboxes look the same on every site by default — and every site replaces them. Bootstrap, Tailwind UI, Material Design, every CMS, every shadcn-ui clone has a custom checkbox component. The challenge isn’t visual — it’s keeping the accessibility intact while restyling. A custom div-based checkbox loses keyboard support, form submission, screen-reader announcements, and pointer-events behaviour. The trick: keep the native <input> for accessibility, hide it visually, and style a sibling element that responds to its state.

    Our CSS checkbox generator outputs the canonical pattern: a hidden native input + an associated label with a custom-styled box. Keyboard Space still toggles, Tab still navigates, screen readers still announce “checkbox, checked”, and the form still submits the value. This guide explains the accessibility-preserving CSS pattern, the gotchas with :focus-visible rings, and how to add the indeterminate state correctly.

    The accessibility-preserving CSS pattern

    The pattern uses appearance: none on the input to strip default OS styling, then customises every visual aspect with CSS — without losing the underlying <input>:

    input[type="checkbox"] {
      appearance: none;
      -webkit-appearance: none;
      width: 24px;
      height: 24px;
      border: 2px solid #d0d5dd;
      border-radius: 6px;
      background: white;
      cursor: pointer;
      position: relative;
      transition: all 150ms ease;
    }
    
    input[type="checkbox"]:checked {
      background: #635BFF;
      border-color: #635BFF;
    }
    
    input[type="checkbox"]:checked::after {
      content: "";
      position: absolute;
      inset: 4px 6px;
      border-right: 2px solid white;
      border-bottom: 2px solid white;
      transform: rotate(45deg);
    }
    
    input[type="checkbox"]:focus-visible {
      outline: 2px solid #635BFF;
      outline-offset: 2px;
    }

    That’s it — a fully custom-styled checkbox with keyboard support, form support, and accessibility intact. The native <input> still receives focus, still toggles on space, still submits. appearance: none works in every modern browser since 2020.

    Visual variations and presets

    Preset Look Best for
    Rounded square 8px corner radius (default in 2026 design) Modern web apps
    Sharp square No radius Brutalist or technical UIs
    Circle 50% radius — like a radio button Soft, friendly UIs
    Animated check Stroke-dash animation on toggle Premium feel
    Material ripple Tap-feedback ripple animation Material Design apps
    iOS-style Filled fill on check iOS-feel UIs

    How to generate a custom checkbox

    1. Open the CSS checkbox generator
    2. Pick a preset shape (rounded square, sharp, circle)
    3. Set border color, fill color, check icon style
    4. Toggle features: animation, ripple, indeterminate-state support, focus ring style
    5. Click Copy CSS for the production code (includes :focus-visible for accessibility)

    The indeterminate state — what most generators skip

    HTML checkboxes have three states: unchecked, checked, and indeterminate. Indeterminate is set programmatically (via JavaScript: el.indeterminate = true;) and represents “partially selected” — common in tree views where a parent is partially-but-not-fully checked among children.

    The CSS selector for indeterminate is :indeterminate. Our generator outputs a third visual state for it (typically a horizontal bar instead of a checkmark):

    input[type="checkbox"]:indeterminate {
      background: #635BFF;
      border-color: #635BFF;
    }
    
    input[type="checkbox"]:indeterminate::after {
      content: "";
      position: absolute;
      left: 4px;
      right: 4px;
      top: 50%;
      height: 2px;
      background: white;
      transform: translateY(-50%);
    }

    Common gotchas

    • Don’t replace the input with a div. Common mistake: hide the input entirely and use a custom <div> for the visual. You lose all accessibility — keyboard nav, screen-reader, form submit. Always keep the real input and style it.
    • :focus-visible vs :focus. Use :focus-visible for the focus ring — it shows only on keyboard focus, not on click. Without this, every click also shows the focus ring, which looks bad. :focus-visible is supported everywhere except the very oldest browsers.
    • Disabled state. A custom checkbox needs :disabled styling — usually 50% opacity and cursor: not-allowed. Don’t forget this state; users who don’t notice a disabled checkbox will tap it repeatedly in frustration.
    • Hover-only feedback isn’t enough. Touch users don’t have hover. Make sure your checked / unchecked / focus states all work without depending on hover.
    • Don’t forget the label. A bare checkbox without a label is unusable for screen readers. Wrap your checkbox + text in a <label> or use aria-labelledby. Most accessibility audits flag missing checkbox labels first.
    • iOS Safari and -webkit-appearance. Older Safari needs -webkit-appearance: none alongside appearance: none. Both prefixes work in Safari 14+; for iOS 12 and below, you need -webkit-appearance first.

    When NOT to use a CSS checkbox

    For toggle switches (on/off), use a switch component instead — visually different from checkboxes, semantically same. For radio buttons (mutually exclusive options), use type="radio" with the same custom-CSS pattern. For custom multi-select UIs (chip-style filters, tag pickers), button + aria-pressed is more appropriate than a checkbox. For very heavy custom interactions (slider toggles with drag gestures), a JS-driven component beats CSS-only — but for the 95% case, the native checkbox + custom CSS is the right call.

    Frequently asked questions

    Will custom CSS break accessibility?

    Not if you keep the native <input type="checkbox">. The element handles all accessibility — keyboard, screen reader, form submission. Hide its default visual with appearance: none and style it. Don’t replace the input with a div.

    Does this support the indeterminate state?

    Yes — set via JavaScript (checkbox.indeterminate = true) and styled via the :indeterminate CSS pseudo-class. Our generator outputs a third visual state for indeterminate (typically a bar instead of a checkmark).

    How do I make the focus ring keyboard-only?

    Use :focus-visible instead of :focus. :focus-visible only triggers on keyboard navigation, not on click. Supported in Chrome 86+, Firefox 85+, Safari 15.4+ — universal in 2026.

    Can I animate the check appearing?

    Yes — animate the ::after pseudo-element’s transform or stroke-dasharray. Generator presets include “animated check” with stroke-dashoffset that draws the checkmark on toggle. Performance is fine for hundreds of checkboxes.

    Is my data uploaded?

    No. The generator runs in your browser. Settings, the live preview, and the exported CSS stay on your device.

    What’s the difference between a checkbox and a switch?

    Semantically the same (binary on/off), visually different. Checkboxes are for forms with multiple selections (filter lists, terms-acceptance). Switches are for settings that take effect immediately (notifications on/off, dark mode). Native HTML doesn’t have a switch — use a checkbox + ARIA role="switch" for the same accessibility behaviour with switch styling.

    Related tools and guides

     

  • CSS Toggle Switch Generator: iOS-Style Switches [2026]

    CSS Toggle Switch Generator: iOS-Style Switches [2026]

    TL;DR: A CSS toggle switch is the iOS-style “slider” UI for binary on/off settings. Built around a hidden native checkbox (for accessibility), with a custom-styled track and thumb that animates between off and on positions. Different from a checkbox visually, but semantically the same. Use switches for “settings that take effect immediately” (notifications on/off, dark mode); use checkboxes for forms with multi-select. Our free CSS switch generator ships 12+ presets — iOS, Material, brutalist — with full keyboard / screen-reader support.

    The toggle switch became the standard UI element for boolean settings around 2010 when iOS popularised it on iPhone. Compared to a checkbox, the switch communicates “this setting takes effect right now” rather than “this is part of a form”. By 2026, every settings screen uses switches; checkboxes are reserved for forms with multiple options to select.

    The implementation challenge: keep keyboard support, screen-reader announcements, and form behaviour while replacing the visual entirely. The pattern: a native <input type="checkbox"> hidden visually but kept in the DOM, plus a CSS-styled track and thumb that respond to :checked. Add ARIA role="switch" for the correct screen-reader announcement (“switch, on” vs “checkbox, checked”), and you have a switch that’s accessible by default. Our CSS switch generator outputs this pattern with 12+ visual presets.

    Switch vs checkbox — when to use which

    Use case Switch Checkbox
    Settings that change immediately (notifications) Yes No
    Form with submit button (newsletter signup) No Yes
    Multi-select filter No Yes
    Dark mode toggle Yes No
    Accept terms of service No (it’s a form input) Yes
    Visibility setting (public / private) Yes (immediate effect) No

    Rule: switch = immediate-effect binary; checkbox = form input.

    The accessible CSS switch pattern

    /* HTML: native input, ARIA role */
    <label class="switch">
      <input type="checkbox" role="switch">
      <span class="track"></span>
    </label>
    
    /* CSS: hide native input, style the track */
    .switch input {
      position: absolute;
      opacity: 0;
      pointer-events: none;
    }
    
    .switch .track {
      display: inline-block;
      width: 44px;
      height: 24px;
      background: #d0d5dd;
      border-radius: 999px;
      position: relative;
      transition: background 200ms;
      cursor: pointer;
    }
    
    .switch .track::after {
      content: "";
      position: absolute;
      top: 2px;
      left: 2px;
      width: 20px;
      height: 20px;
      background: white;
      border-radius: 50%;
      transition: transform 200ms;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    }
    
    .switch input:checked + .track {
      background: #635BFF;
    }
    
    .switch input:checked + .track::after {
      transform: translateX(20px);
    }
    
    .switch input:focus-visible + .track {
      outline: 2px solid #635BFF;
      outline-offset: 2px;
    }

    The native input is hidden visually but kept in the DOM — keyboard Space still toggles it, screen readers announce “switch, on / off” because of role="switch", and form submission still works.

    Visual presets

    • iOS Default: rounded pill, white thumb, blue/green when on. Apple’s HIG style.
    • Material Design: wider thumb, slightly different proportions, M3 colour tokens.
    • Brutalist: sharp rectangular track, no border-radius, bold colours.
    • Outlined: visible border on the track, transparent track when off.
    • Squared: slight border-radius (8px) instead of pill — modern web app style.
    • Compact: 32×16 (smaller than default 44×24) for dense UI.
    • Animated icon: sun/moon icons fade in the thumb based on state.
    • 5 more presets in the gallery.

    How to generate a CSS switch

    1. Open the CSS switch generator
    2. Pick a preset (iOS, Material, brutalist, etc.)
    3. Adjust track color, thumb color, animation duration, and switch size
    4. Click Copy CSS + HTML for a complete drop-in component

    Common gotchas

    • Don’t replace the input with a div. Common bug: hide the input entirely, replace with custom div. Loses keyboard support, screen-reader announcements, form submission. Always keep the native input and style around it.
    • role=”switch” on input vs label. ARIA role="switch" goes on the input, not the wrapping label. Screen readers announce “switch, on / off” instead of “checkbox, checked / unchecked”.
    • :focus-visible is mandatory. Use :focus-visible for the focus ring, not :focus — otherwise every click shows the focus ring, looks bad. Universal browser support in 2026.
    • Don’t trap focus inside the switch. A common bug: pointer-events: none on the input but no clear focusable target. Result: keyboard users can’t tab to the switch. Verify keyboard navigation across all switches.
    • Animation can be disabled. Respect @media (prefers-reduced-motion: reduce) and skip the thumb-slide animation for users with vestibular disorders. Toggle still works; just snaps instantly.
    • Don’t make switches too small. Minimum touch target is 44×44 px (Apple HIG) or 48×48 px (Material). The visible track can be smaller, but the clickable area must hit minimum.

    When NOT to use a CSS switch

    For form inputs that submit with a button (newsletter signup, accept-terms, multi-select filters), use a checkbox — switches imply immediate effect. For binary settings that take significant action (deleting account, publishing content), use a button with confirmation, not a switch — accidental switch toggles are too easy. For three-way state (off / on / mixed), use a button group or radio. For very dense settings panels (10+ switches per screen), consider grouped settings with subheadings rather than a flat wall of switches.

    Frequently asked questions

    Switch or checkbox — what’s the difference?

    Semantically the same (binary state); visually and behaviourally different. Switch = immediate-effect setting (notifications on/off). Checkbox = form input that requires submit. Native HTML doesn’t have a switch element — use a checkbox + ARIA role="switch".

    Will custom CSS break accessibility?

    Not if you keep the native input. Hide it visually with positioning + opacity, but leave it in the DOM. Keyboard, screen reader, form submission all work. Don’t replace the input with a div.

    Is role=”switch” supported by screen readers?

    Yes — VoiceOver (iOS / macOS), TalkBack (Android), NVDA, JAWS all announce “switch, on” or “switch, off”. Older readers fall back to “checkbox, checked / unchecked”, which is acceptable.

    How do I prevent accidental toggles?

    For high-stakes actions, use a button with confirmation rather than a switch. For sensitive settings (e.g., “make profile public”), pair the switch with a confirmation modal on first use. Switches are designed for fast, reversible toggles — high-stakes actions deserve more friction.

    Is my data uploaded?

    No. The generator runs in your browser. Settings, the live preview, and the exported CSS stay on your device.

    Can I animate the switch differently?

    Yes — pick a “Bounce” or “Snap” preset, or write your own cubic-bezier() easing. Smooth slide is the default; bouncy animations feel playful but should respect prefers-reduced-motion.

    Related tools and guides

     

  • CSS Glitch Effect: Cyberpunk Text Animation [2026]

    CSS Glitch Effect: Cyberpunk Text Animation [2026]

    TL;DR: A CSS glitch effect creates the cyberpunk RGB-split look — text rendered three times in red, cyan, and white, with each layer offset slightly and animated to create a “broken display” feel. Used for hero text on cyberpunk-themed sites, gaming UIs, error states, and brand identities that want a “glitchy” aesthetic. Our free CSS glitch generator ships 8+ presets, animation controls, and respects prefers-reduced-motion for accessibility.

    The “glitch text” aesthetic peaked in the late 2010s alongside cyberpunk’s design revival — Cyberpunk 2077 marketing, gaming UIs, vaporwave Tumblr blogs, hacker-aesthetic indie sites all leaned on RGB-split text. The technique mimics a CRT display with misaligned colour channels. The CSS implementation: render the text three times — one layer in red shifted left, one in cyan shifted right, one in white at original position — then animate the offsets randomly to create the “stuttering” feel.

    Our CSS glitch effect generator ships 8+ tested presets ranging from subtle (a steady RGB split with no animation) to chaotic (rapidly stuttering text with clip-path slices). All output is pure CSS with no JavaScript dependency, and includes a @media (prefers-reduced-motion) branch that disables the animation for accessibility-sensitive users. This guide covers the technique, the accessibility considerations, and when the glitch aesthetic is the wrong choice.

    Glitch effect anatomy

    The classic RGB-split glitch uses CSS pseudo-elements and absolute positioning:

    .glitch {
      position: relative;
      color: white;
      font-weight: 700;
    }
    .glitch::before,
    .glitch::after {
      content: attr(data-text);
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    .glitch::before {
      color: #ff0080;
      transform: translate(-2px, 0);
      mix-blend-mode: screen;
      animation: glitch-1 2s infinite;
    }
    .glitch::after {
      color: #00fff0;
      transform: translate(2px, 0);
      mix-blend-mode: screen;
      animation: glitch-2 2s infinite;
    }
    @keyframes glitch-1 {
      0%, 100% { transform: translate(-2px, 0); }
      20% { transform: translate(-3px, 1px); }
      40% { transform: translate(-1px, -1px); }
    }
    @keyframes glitch-2 {
      0%, 100% { transform: translate(2px, 0); }
      20% { transform: translate(3px, -1px); }
      40% { transform: translate(1px, 1px); }
    }
    @media (prefers-reduced-motion: reduce) {
      .glitch::before, .glitch::after { animation: none; }
    }

    The HTML uses data-text="GLITCH" on the element and the pseudo-elements pull that via content: attr(data-text). This avoids duplicating text in the DOM (which would break screen readers). Result: visually three layers of text; semantically just one.

    Glitch presets and what each looks like

    Preset Style Best for
    Static RGB-split No animation, just colour offsets Logo / wordmark with subtle effect
    Smooth glitch 2s sine-wave animation Hero headlines, soft cyberpunk
    Stuttering Discrete jumps with steps() Aggressive cyberpunk aesthetic
    Slice glitch clip-path random horizontal slices Error states, dramatic effect
    Color burst Hue-rotate animation on top Vaporwave, retro-tech
    Hover-only Glitch activates on hover Buttons, navigation links

    How to generate a glitch effect

    1. Open the CSS glitch effect generator
    2. Type the text you want to glitch (default: “GLITCH”)
    3. Pick a preset (static, smooth, stuttering, slice, etc.)
    4. Adjust intensity, speed, and the two RGB-split colours
    5. Click Copy CSS + HTML for a complete drop-in component

    Accessibility — glitch effects can cause harm

    Animated glitch effects can trigger problems for users with vestibular disorders, photosensitive epilepsy, and cognitive disabilities. Build them carefully:

    • Always include @media (prefers-reduced-motion: reduce). Disable animation entirely for users who set this preference. Keep the static colour offset (which is harmless).
    • Avoid rapid flashing. WCAG 2.1 prohibits content that flashes more than 3 times per second over an area larger than ~25% of the viewport. Stuttering glitch animations risk crossing this — keep frame jumps below 3/second or limit to small text areas.
    • Use aria-hidden on pseudo-elements. The duplicated text in pseudo-elements is decorative — screen readers shouldn’t read it three times. ::before and ::after are excluded from accessibility tree by default.
    • High contrast underneath. The base text colour must meet WCAG contrast against the background (4.5:1 for body, 3:1 for large text). The RGB-split layers are decoration; readability comes from the base.
    • Don’t glitch entire paragraphs. Reserve the effect for headlines, single words, or short labels. A glitching paragraph of body text is unreadable.

    Common gotchas

    • Pseudo-elements need data-text or duplicate content. If you skip data-text="GLITCH" and try to use a CSS variable, browsers don’t support content: var(--text) as text content. Use data-text + attr().
    • mix-blend-mode requires a stacking context. The RGB-split layers blend correctly only when their parent has its own stacking context. If colours look wrong, add position: relative; isolation: isolate; to the parent.
    • Animation easing matters. Smooth easing (cubic-bezier) produces a “vibrating” feel; steps(N) easing produces discrete glitchy jumps. Match easing to the aesthetic.
    • Custom colours must contrast. Pure red and pure cyan on white text reads as glitch; muted reds and cyans look like a printing error. Use saturated complementary colours.
    • Hover-only is best for navigation. Always-animated text in nav menus distracts from page content. Reserve hover-only glitch for interactive elements; full animation for hero headlines.
    • SEO impact. Glitched text is fully indexed (the base text is real DOM content). Pseudo-element duplication doesn’t pollute the index — search engines ignore ::before / ::after content.

    When NOT to use a glitch effect

    For text that needs to communicate clearly (body content, instructions, error messages), the glitch aesthetic interferes with readability. For brands targeting accessibility-conscious audiences (healthcare, education, government), the effect can be off-brand. For long-running UIs (dashboards, settings panels) where the same animation plays for hours, it gets distracting. For sites in regulated industries (financial, medical) where seriousness matters, choose calmer typography. The glitch effect is for hero moments — short, attention-grabbing, decorative — not for everyday UI.

    Frequently asked questions

    Will the glitch effect work in all browsers?

    Yes — the technique uses CSS pseudo-elements, transforms, and animations, all of which have been universally supported since 2015. mix-blend-mode is supported in Chrome 41+, Firefox 32+, Safari 8+. Even mobile browsers handle it cleanly.

    Can I disable the animation for accessibility?

    Yes — our generated CSS includes a @media (prefers-reduced-motion: reduce) branch that turns off the animation. Users who set this OS preference get the static RGB split without movement. Always include this; never assume motion is universally welcome.

    Does the glitch effect break SEO?

    No. The base text is real DOM content, fully indexed. Pseudo-element duplication via data-text + attr() doesn’t pollute the index — search engines ignore generated content.

    Can I use this on more than one element per page?

    Yes — but be conservative. Multiple glitching elements on the same page compete for attention and can feel chaotic. One hero glitch is plenty; reserve the effect for emphasis.

    Is my data uploaded?

    No. The generator runs in your browser. Your text, the live preview, and the exported CSS stay on your device.

    How do I customise the glitch colours?

    Pick any two complementary colours for the RGB-split layers. The defaults (pink-red #ff0080 and cyan #00fff0) are the cyberpunk classic. For brand-on-brand effects, use your brand’s accent colours — but verify they’re saturated enough to read as “glitch” rather than “blur”.

    Related tools and guides

     

  • CSS Clip Path Generator: Visual Polygon Editor [2026]

    CSS Clip Path Generator: Visual Polygon Editor [2026]

    TL;DR: CSS clip-path defines a region that an element is rendered inside — anything outside that region is clipped (transparent). Shapes can be a polygon (polygon(0 0, 100% 0, 100% 50%)), circle (circle(50% at 50% 50%)), ellipse, or inset rectangle. Our free CSS clip-path generator ships 18 presets (hexagon, arrow, talk bubble, parallelogram, chevron, star), a draggable-vertex editor, and one-click copy of the production CSS.

    CSS clip-path is the modern way to give an element a non-rectangular outline without resorting to SVG masks or background images. A clipped <img> stays a real <img> — accessible, responsive, link-able, and crisp at every device pixel ratio — while looking like a hexagon, arrow, parallelogram, or talk bubble. It’s used for hero-section diagonals, avatar masks, sticky badge tags, and the angled section breaks designers love and developers used to hate.

    The reason developers used to hate it: writing polygon() coordinates by hand is tedious and the syntax is unforgiving. polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%) is a pentagon — but you wouldn’t guess that from the numbers. Our CSS clip-path generator solves that with a visual editor: drag the vertices on a live preview and the CSS updates in real time. This guide covers every shape function, the gotchas with overflow and box-sizing, and the browser support story in 2026.

    The 4 clip-path shape functions

    Function Syntax Best for
    polygon() polygon(x1 y1, x2 y2, ...) Custom shapes with corners (hexagon, arrow, talk bubble)
    circle() circle(50% at 50% 50%) Avatar masks, circular thumbnails
    ellipse() ellipse(50% 25% at 50% 50%) Stretched circles, oval avatars
    inset() inset(10px 20px 30px 40px round 8px) Rounded-rect with inset edges (asymmetric)
    path() path("M 0 0 L 100 50 ...") SVG-grade complex shapes (curves, arcs)
    shape() (CSS Shapes 2) shape(from 0 0, line to 100% 0, ...) 2026 syntax — readable polygon alternative

    Coordinate system and units

    Clip-path coordinates are measured from the top-left of the element. The X axis grows rightward; Y grows downward. Both axes accept percentages (relative to the element’s box) or absolute units (px, em, rem). Mixed units work: polygon(0 0, 100% 0, 100% calc(100% - 20px), 50% 100%, 0 calc(100% - 20px)) creates a banner with a 20px wave at the bottom regardless of card height.

    The default reference box is the border-box (the element’s outer edge). You can change this with clip-path: polygon(...) padding-box or other box keywords — useful when you want the clip to follow the padding zone instead of the border.

    How to design a clip-path with the visual editor

    1. Open the clip-path generator
    2. Pick a preset shape (hexagon, talk bubble, arrow, etc.) — or start from a rectangle
    3. Drag the vertices on the live preview to fine-tune the shape
    4. Add or remove vertices with the + / buttons
    5. Toggle the test image (your image or one of the demo photos) to see the clip in context
    6. Copy the generated CSS, including the clip-path declaration and a fallback for older browsers

    18 production-ready presets

    The generator ships these presets so you can grab a working shape in one click:

    • Polygons: Triangle, Trapezoid, Parallelogram, Rhombus, Pentagon, Hexagon, Heptagon, Octagon, Nonagon, Decagon, Star
    • Arrows: Right Arrow, Left Arrow, Chevron Right
    • UI shapes: Talk Bubble, Cross / Plus, Slash Cut, Frame

    Each preset is named in the dropdown — click and the editor loads the polygon coordinates. Customise from there.

    Browser support and the IE legacy

    clip-path with all shape functions is supported in every modern browser: Chrome 23+ (2012), Firefox 54+, Safari 7+, Edge 79+. The path() function landed slightly later (Chrome 88, Safari 13.1). The new shape() function from CSS Shapes 2 is Chrome 116+ and Safari 17.4+ — partial support in 2026, so generate polygon() as the canonical output and add shape() as a progressive enhancement only for sites with a modern audience.

    Internet Explorer never supported clip-path. Microsoft retired IE in June 2022; if your analytics show under 0.5% IE traffic (typical in 2026), use clip-path without a fallback. For the rare site that still serves IE traffic (some government and Asia-region B2B), provide a rectangular fallback with a CSS feature query.

    Common gotchas

    • Box shadows are clipped too. A box-shadow on a clipped element appears inside the clip path, not extending outward. Use filter: drop-shadow() on a wrapping element if you need the shadow to follow the clipped silhouette.
    • Hover events still respect the original rectangle. CSS clip-path only changes paint — the click target is still the original rectangle. To make hover follow the visible shape, use shape-outside on the element or a transparent SVG overlay.
    • Animating clip-path is fast. Modern browsers GPU-accelerate clip-path animations. Animating between two polygon() shapes only works when both have the same number of vertices.
    • Children that overflow the clip are still clipped. A child element positioned outside the clip path is invisible, even if it has position: absolute. To “break out” of the clip, the child must live outside the clipped element entirely.
    • SVG-style fill-rule: for self-intersecting polygons, the default rule is nonzero. Use polygon(evenodd, ...) for the alternate fill rule when you have a knot or figure-8 shape.
    • Mobile Safari has historical bugs. Clip-path on a transformed element used to flicker on iOS 12 and earlier — fixed in iOS 13 and now stable. If you support iOS 12, test before deploying complex animations.

    When NOT to use clip-path

    For complex shapes with curves and gradients (think: a logo, illustration, or character silhouette), use SVG with the actual paths inline — clip-path is for relatively simple geometric outlines on rectangular content. For animated reveal effects across many elements, CSS masking (mask-image) plus an SVG mask gives you finer control. For extracting a non-rectangular region from an image where the result is the new image, use a raster crop tool — clip-path doesn’t change the underlying file, just how the browser paints it.

    Frequently asked questions

    Can I animate clip-path?

    Yes — modern browsers GPU-accelerate clip-path animations. Animating between two polygon() shapes works when both have the same vertex count. Different shape types (polygon to circle) need a path-conversion approach via the new shape() function or a JavaScript animation library.

    Does clip-path work in all browsers in 2026?

    Yes for the four core functions (polygon, circle, ellipse, inset). The path() function works in Chrome 88+ and Safari 13.1+. The new shape() function is partial — Chrome 116+ and Safari 17.4+. Generate polygon() as canonical output and use shape() as progressive enhancement.

    How do I make a clipped image clickable on the visible region only?

    By default the click target is the rectangular bounding box. To restrict clicks to the visible shape, use shape-outside with the same path or layer a transparent SVG with the actual path on top of the image, taking the click via the SVG.

    What’s the difference between clip-path and mask-image?

    clip-path uses geometric shape functions and produces hard edges; mask-image uses an image (typically PNG or SVG) and supports soft edges, gradients, and complex artwork. For a hexagon avatar, use clip-path. For a logo silhouette mask, use mask-image.

    Why does my box-shadow disappear with clip-path?

    Because clip-path clips the entire painted output, including shadows. The fix: wrap the clipped element in a parent and apply filter: drop-shadow() to the parent. drop-shadow follows the clipped silhouette, unlike box-shadow which uses the rectangular box.

    Is my data uploaded?

    No. The generator runs in your browser. The shape coordinates and the demo image you upload to test live only in your tab — they’re never sent to our servers.

    Related tools and guides

     

  • Cubic Bezier Generator: CSS Easing Curves [2026]

    Cubic Bezier Generator: CSS Easing Curves [2026]

    TL;DR: CSS cubic-bezier() defines a custom easing curve for transitions and animations using four numbers — the X and Y of two control handles. cubic-bezier(0.25, 0.1, 0.25, 1) is the default “ease” keyword. Our free cubic-bezier generator ships a draggable visual editor, a live ball-and-square animation that plays the curve, and 14 named presets (ease, ease-in, ease-out, plus the Material Design and iOS spring curves).

    The default CSS easing keyword (ease) starts slow, accelerates, then slows down — fine for most quick state transitions, but bland for hero animations and microinteractions. cubic-bezier() lets you define an easing curve precisely. Drag the curve to start fast and end slow, overshoot the target, anticipate before moving, or stay still then snap into place. The right easing turns a generic UI into one that feels intentional.

    The challenge is that bezier coordinates are unreadable. cubic-bezier(0.4, 0, 0.2, 1) is Material Design’s standard curve. cubic-bezier(0.68, -0.55, 0.265, 1.55) is “back” easing with overshoot. You can’t picture either by reading the numbers. Our cubic-bezier generator shows the curve graphically with two draggable handles, animates a sample element with each curve change, and outputs the CSS in real time.

    The 14 named presets and what they feel like

    Preset Bezier values Feel
    linear 0, 0, 1, 1 Constant speed — for indeterminate spinners
    ease 0.25, 0.1, 0.25, 1 Default — smooth, slightly weighted near end
    ease-in 0.42, 0, 1, 1 Slow start, fast end — for elements leaving
    ease-out 0, 0, 0.58, 1 Fast start, slow end — for elements entering
    ease-in-out 0.42, 0, 0.58, 1 Symmetric — for back-and-forth movement
    Material Standard 0.4, 0, 0.2, 1 Material Design 3 default
    iOS Default 0.25, 0.46, 0.45, 0.94 Native iOS feel — close to ease-out
    Back (overshoot) 0.68, -0.55, 0.265, 1.55 Anticipates and overshoots — playful
    Snap 0.9, 0, 0.1, 1 Holds, then snaps in — for confident states

    How the curve works (in human terms)

    The four numbers in cubic-bezier(x1, y1, x2, y2) are the X and Y of two control handles between the start (always 0,0) and end (always 1,1) of the curve. The X axis is time (0 = start, 1 = end of the duration). The Y axis is progress (0 = initial position, 1 = final position). The handles pull the curve in the direction of their position — drag a handle up and the curve overshoots; drag it down and the curve eases.

    X must be between 0 and 1; Y can go above 1 (overshoot) or below 0 (anticipate). The visual editor enforces the X constraint and lets Y go outside the box for those expressive curves.

    How to design a bezier curve in your browser

    1. Open the cubic-bezier generator
    2. Pick a preset (or start from ease) and drag the two handles to shape the curve
    3. Watch the live preview — a square moves left-to-right with the easing applied
    4. Adjust the duration (250ms to 2s) and the curve in tandem to land on the right feel
    5. Click Copy CSS to grab the transition-timing-function declaration

    Where the bezier value goes in real CSS

    Two places use it: transition-timing-function and animation-timing-function. Inside the transition shorthand:

    .button {
      transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
    }
    .button:hover {
      transform: translateY(-2px);
    }

    For keyframe animations, set the timing function on the animation as a whole or per keyframe (@keyframes entries can have their own timing function for staged easing).

    Common gotchas

    • linear-with-overrides for staged motion. If you need different easing per phase of an animation, use linear() (CSS Easing 2 — Chrome 113+) which lets you describe a polyline of stops, or chain multiple keyframes with their own timing functions.
    • Overshoot Y values can break perceived motion. A curve with Y > 1 returns the element past its target, then back. For “natural” overshoot, keep the second Y between 1.05 and 1.2; higher than 1.5 looks cartoony.
    • Don’t animate top, left, or width. These trigger layout. Always animate transform and opacity for 60fps performance, regardless of the easing curve.
    • iOS spring physics aren’t bezier curves. Native iOS uses spring-physics easing (mass, stiffness, damping). The closest CSS approximation is cubic-bezier(0.25, 0.46, 0.45, 0.94) for the standard iOS feel, but real spring curves bounce; bezier curves don’t.
    • steps() is not bezier. The steps() timing function produces discrete jumps for sprite animations. It’s a different family from cubic-bezier() — pick one based on whether you want continuous motion or a frame-by-frame walk cycle.
    • Match curve to direction. Use ease-out for elements entering the viewport (they decelerate into place); use ease-in for elements leaving (they accelerate away). Symmetric curves (ease, ease-in-out) are best for scrubbed timelines and back-and-forth states.

    When NOT to use cubic-bezier

    For physical-feeling spring animations (think iOS sheet open/close), use a JavaScript spring physics library — Framer Motion, react-spring, GSAP — rather than fighting bezier curves to approximate spring damping. For frame-perfect sprite animations, use steps(). For purely linear progress (loading bars, unbounded spinners), linear is simpler and renders identically. For micro-interactions where the curve is barely noticed (under 200ms transitions), the default ease works fine — bezier customisation matters most for animations between 250ms and 1s.

    Frequently asked questions

    What’s the difference between cubic-bezier and ease keywords?

    The keywords (ease, ease-in, ease-out, ease-in-out, linear) are predefined cubic-bezier curves. cubic-bezier() lets you define any curve. The keywords cover 80% of cases; you reach for cubic-bezier() when you want a specific feel like Material Design’s standard curve or playful overshoot.

    Can the bezier handles go outside the 0–1 box?

    Y can — values above 1 produce overshoot; below 0 produce anticipation (the element moves backward briefly before going forward). X cannot — it must be between 0 and 1, since X represents time. The visual editor enforces this constraint.

    Should I use cubic-bezier for everything?

    No. Use ease-out for entering elements, ease-in for leaving, ease-in-out for symmetric motion, and reach for custom cubic-bezier() when you need a specific brand feel (Material, iOS) or expressive overshoot. Most apps standardise on 1–3 custom curves project-wide for consistency.

    What’s the new linear() function?

    CSS Easing 2’s linear() (Chrome 113+, Safari 17.2+) lets you describe a polyline of stops — useful for approximating spring physics or staged motion in a single CSS rule. It’s not a replacement for cubic-bezier() for typical UI transitions; it’s a new tool for complex timelines.

    Is my data uploaded?

    No. The generator runs in your browser. Your curve values, preview animation, and downloaded CSS stay on your device.

    Does cubic-bezier work on all browsers?

    Yes — universal support since Chrome 4 (2010), Firefox 4, Safari 4. It’s one of the safest CSS features. Even mobile browsers have stable rendering.

    Related tools and guides