Tag: CSS

  • CSS Formatter: Beautify CSS, SCSS, LESS in Browser [2026]

    CSS Formatter: Beautify CSS, SCSS, LESS in Browser [2026]

    TL;DR: A CSS formatter (or “CSS beautifier”) reformats minified, copied, or messy CSS into consistently-indented, readable rules. Use it on copied CSS from a CDN, AI-generated styles, or styles dumped from DevTools. Our free CSS formatter uses Prettier 3 in your browser with full support for modern CSS — custom properties, native nesting, container queries, @layer, OKLCH — plus SCSS, LESS, and PostCSS.

    Reading minified CSS is a productivity tax. Tailwind’s compiled stylesheet is one giant line; a copied snippet from CodePen often arrives as a single rule with no breaks; CSS dumped from DevTools’ “Copy all declarations” comes back without the selectors that gave each rule meaning. A formatter restores hierarchy: each rule on its own line, properties indented, @media blocks visible at a glance.

    Our CSS formatter runs Prettier 3 in your browser with the same parser used by VS Code’s “Format Document” command. It handles plain CSS, SCSS, LESS, PostCSS, and modern CSS features (CSS variables, native nesting, :has(), container queries, @layer, OKLCH, color-mix()). Outputs clean, idiomatic CSS that round-trips through any tool. This guide covers when to format vs minify, the SCSS-specific rules, and the gotchas with copied browser DevTools styles.

    Prettier CSS options that matter

    Option Default Notes
    printWidth 80 Affects wrapping of long selectors and value lists
    tabWidth 2 Standard for modern CSS; 4 for legacy stacks
    singleQuote false Strings in url() and content: values
    endOfLine “lf” “crlf” only for Windows-only repos
    Property sort off Optional — alphabetical, or by Idiomatic CSS groupings

    Prettier’s CSS formatter is deliberately small on options. Modern CSS toolchains add property sorting via separate plugins — stylelint-config-prettier + stylelint-order — rather than baking it into the formatter.

    SCSS, LESS, and PostCSS

    The same Prettier engine handles three preprocessor dialects:

    • SCSS: nested selectors, @mixin, @include, @if/@else, @function, dollar-prefixed variables. Indentation follows nesting depth.
    • LESS: mixins as classes, @variable syntax, guards. Slightly different rules than SCSS.
    • PostCSS: raw CSS plus plugin-specific syntax. Prettier formats whatever is valid CSS-AST — plugin syntax (e.g., @apply from Tailwind) passes through.

    Pick the parser explicitly when auto-detection fails. .scss file extension defaults to SCSS; .less defaults to LESS; .css defaults to plain CSS. Paste-mode without an extension defaults to plain CSS, which can produce odd output for SCSS code (mixin syntax becomes invalid CSS).

    How to format CSS in your browser

    1. Open the CSS formatter
    2. Paste your CSS or drop in a .css/.scss/.less file
    3. Pick the parser if auto-detect doesn’t catch it
    4. Adjust print width and indent style if needed
    5. Click Format — output appears with syntax highlighting
    6. Copy or download as .css

    Modern CSS that older formatters break

    Older CSS beautifiers (cssbeautify, online-beautify) corrupt several modern features:

    • Native nesting: .card { .title { color: red; } } — older formatters flatten or fail to parse. Prettier handles nesting correctly.
    • Container queries: @container (width > 400px) { … } — preserved with all syntax variants.
    • :has() selector: the parent selector is preserved without quote-mangling.
    • OKLCH and color-mix(): new colour formats pass through unchanged.
    • @layer: cascade layer ordering is preserved exactly — never reordered, since order has semantic meaning.
    • CSS custom properties: long fallback chains (var(--a, var(--b, red))) are preserved verbatim.

    Common gotchas

    • Tailwind utility class output is not formatted. Tailwind generates a flat list of single-rule classes; formatting won’t help. Format your custom CSS only — let Tailwind manage its own output.
    • DevTools “Copy all declarations” loses selectors. The clipboard gets color: red; padding: 8px; with no .btn { … } wrapper. Format won’t recover the selector — re-copy with the selector context.
    • Property order is preserved by default. CSS cascade-sensitive code relies on order for shorthand-then-override patterns (margin: 0; margin-top: 8px;). Don’t enable property sorting if you have that pattern.
    • SCSS @mixin formatting is opinionated. Prettier always inlines short mixin calls; long ones wrap. Your style guide may differ. Override locally with // prettier-ignore comments above specific blocks.
    • Don’t format minified CSS and re-deploy. Format your source files; let your build step minify the output. Formatted production CSS is 30% bigger and slower.
    • Older Prettier versions handle modern CSS poorly. Always use Prettier 3+ for native nesting, container queries, and the OKLCH colour space. Prettier 2.x will silently produce wrong output for these.

    When NOT to use a browser CSS formatter

    For a real codebase, install Prettier locally (npm i -D prettier), commit a .prettierrc, and let editors format on save. That eliminates style drift across collaborators. Use this browser tool for one-off snippets, copy-paste from CodePen / DevTools / AI assistants, third-party stylesheets you need to inspect, and quick previews of how Prettier would render styles in a project that doesn’t have it set up yet. For Stylelint integration, install stylelint-config-prettier alongside Prettier locally.

    Frequently asked questions

    Does this support SCSS, LESS, and PostCSS?

    Yes. Prettier 3 handles plain CSS, SCSS, LESS, and PostCSS. Auto-detection picks the parser from the file extension; you can override manually for paste-mode (file extension is unknown).

    Will the formatter sort my properties alphabetically?

    Not by default. Prettier preserves property order — important because some CSS relies on order for shorthand-then-override patterns. Property sorting is a separate Stylelint plugin (stylelint-order); install it locally if you want sorted output.

    Does it support modern CSS features like nesting and container queries?

    Yes. Prettier 3 handles native CSS nesting, container queries, :has(), @layer, OKLCH, color-mix(), and relative-colour syntax. Older formatters break these — always use Prettier 3+ for modern stylesheets.

    Can I unformat (minify) CSS with this tool?

    No — opposite operations. For minification, use the CSS Minifier. The typical pipeline: format while editing, minify before deploying.

    Is my CSS uploaded?

    No. Prettier runs in your browser via WebAssembly. Stylesheets never reach our servers — useful for proprietary or pre-release styles.

    Why does my SCSS look wrong after formatting?

    Most likely the parser was set to plain CSS instead of SCSS. SCSS-specific syntax (@mixin, @include, dollar variables) is invalid CSS. Switch the parser to SCSS and reformat.

    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

     

  • CSS Box Shadow Generator: Multi-Layer Depth [2026]

    CSS Box Shadow Generator: Multi-Layer Depth [2026]

    TL;DR: A CSS box shadow generator builds box-shadow declarations visually — drag offset, blur, spread, and colour sliders to design the shadow, copy the CSS. Modern UI uses multi-layer shadows (2-3 stacked) for realistic depth: a tight close shadow for grounding plus a soft far shadow for ambient. Our free generator handles inset, multi-layer stacks, and exports paste-ready CSS or Tailwind utilities.

    Shadows are the lazy designer’s depth cue. Drop a 4-pixel grey shadow under any card and the card looks “lifted” off the page. Drop the wrong shadow and the card looks like it’s from 2015. The difference between professional and amateur UI in 2026 isn’t whether you use shadows — it’s whether you stack two or three layers to mimic how real light works. A box-shadow generator with multi-layer support is the fastest way to get there.

    Our CSS box shadow generator ships with a live preview, multi-layer support, inset toggle, and export as either vanilla CSS or Tailwind arbitrary-value classes. This guide explains the five box-shadow parameters, why multi-layer shadows look more realistic than single-layer ones, the modern Material Design 3 elevation tokens, and the performance gotchas that make heavy-shadow pages laggy on mobile.

    The five parameters that define a box-shadow

    Parameter Effect Typical range
    Horizontal offset (x) Shadow shifted right (positive) or left (negative) −2 to 2 px (subtle), 0 for centred
    Vertical offset (y) Shadow shifted down (positive) — typical for “lifted” cards 2-30 px depending on elevation
    Blur radius How soft / diffuse the shadow edge is 2× the y-offset for natural softness
    Spread Expands or contracts the shadow before blur. Negative = tight; positive = halo −10 to 5 px typically
    Colour Shadow’s RGBA value rgba(0,0,0,0.04-0.18) for natural shadows

    The single most common mistake: using rgba(0,0,0,0.5) for the shadow colour. Real shadows are far more subtle — 0.04 to 0.18 alpha is the right range. Heavy shadows look like a 2008 web aesthetic. Use multi-layer composition for depth, not a single dark shadow.

    Multi-layer shadows — the modern technique

    Single shadows look flat. Real-world depth has two characteristics: a tight close shadow (the ambient occlusion right next to the object) and a soft far shadow (the diffused fall-off). Modern UI mimics this by stacking 2-3 shadow layers in one box-shadow declaration:

    /* Single shadow (looks flat) */
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    
    /* Two-layer (realistic depth) */
    box-shadow:
      0 1px 2px 0 rgba(10, 37, 64, 0.04),     /* close, tight */
      0 4px 12px -2px rgba(10, 37, 64, 0.08); /* far, soft */
    
    /* Three-layer (premium look — Stripe, Linear, Vercel use this) */
    box-shadow:
      0 1px 1px 0 rgba(10, 37, 64, 0.05),
      0 2px 4px -1px rgba(10, 37, 64, 0.08),
      0 12px 24px -8px rgba(10, 37, 64, 0.12);

    The progression from one to three layers is what separates default-looking buttons from premium-looking buttons. Most modern design systems (Material 3, Apple HIG, Tailwind’s shadow-xl) ship multi-layer shadows out of the box.

    Material Design elevation system — six standard levels

    Material Design’s elevation system maps real-world depth to six numerical levels. Each level uses a specific multi-layer shadow stack tuned for the apparent height. Useful as a starting point for your own design system:

    • Elevation 0: no shadow (flat surfaces, page background)
    • Elevation 1: subtle lift (cards at rest, table rows)
    • Elevation 2: raised (cards on hover, primary buttons)
    • Elevation 3: floating (FABs, contextual menus)
    • Elevation 4: overlaid (dialogs, drawers)
    • Elevation 5: very prominent (modal cover, navigation drawer)

    Pick three or four of these for your design system rather than letting designers invent custom shadows per component. Consistency is what makes a UI look polished.

    How to use the browser box-shadow generator

    1. Open the box shadow generator
    2. Drag the x, y, blur, spread sliders. Watch the live preview update
    3. Adjust the colour picker (alpha matters — keep it subtle)
    4. Toggle inset for inner shadows (useful for pressed-button states or “carved” effects)
    5. Click + Add layer to stack a second or third shadow for realistic depth
    6. Pick a preset (Material elevations 1-5, “Stripe-style” multi-layer, “carved”, “neon glow”)
    7. Copy CSS or Tailwind output

    Performance — when shadows hurt page speed

    Shadows are GPU-rendered, which is fast — but not free. A handful of shadows on hero elements is invisible cost. Hundreds of shadows in a feed-style listing produces visible jank on mid-range mobile devices.

    • Don’t apply heavy multi-layer shadows on 50+ scrolling cards. Use a single subtle shadow per card, save the multi-layer treatment for hero elements.
    • Avoid animating shadows. Animating the box-shadow property forces re-layout on every frame. Animate a wrapper’s transform: scale or translateZ instead, with a static shadow.
    • Inset shadows on text-heavy elements. Inset shadows trigger a different rendering path. Avoid stacking many on form inputs or text areas.
    • Use will-change: box-shadow sparingly. Promotes the element to its own layer, which uses memory. Reserve for elements you’ll definitely animate.

    Common box-shadow mistakes

    • Heavy single shadows. box-shadow: 0 8px 32px rgba(0,0,0,0.4) looks like a 2010 lightbox. Use multi-layer with low alpha for modern depth.
    • Coloured shadows by default. Black or near-black shadows are correct for ~95% of cases. Coloured shadows (matching the element) work for hero/marketing elements but look weird on body content.
    • Wrong blur-to-offset ratio. Blur should be roughly 2× the y-offset for natural softness. 0 4px 4px (1:1) looks tight and harsh; 0 4px 8px (1:2) looks natural; 0 4px 24px (1:6) looks dreamy/soft.
    • No spread on outset shadows. Negative spread tightens the shadow and prevents it bleeding past the element bounds — useful for cards in tight grids.
    • Forgetting dark mode. Black shadows on a dark background are invisible. Use slightly lighter shadows or rely on borders + brightness for depth in dark mode.

    Frequently asked questions

    What’s the difference between box-shadow and drop-shadow?

    box-shadow draws a shadow that follows the element’s bounding box (rectangle, even if the element has rounded corners). filter: drop-shadow() follows the element’s actual visual shape, including transparency in PNG images and SVG paths. For UI cards, box-shadow is correct. For PNG icons or SVG logos, drop-shadow is correct.

    Can I animate box-shadow smoothly?

    Browsers can transition box-shadow but it’s expensive. For smooth hover-state lifts, animate a wrapper’s transform: translateY(-2px) with a static shadow instead. The visual effect is identical but the GPU cost is much lower.

    Why does my shadow look pixelated on retina displays?

    This usually happens when blur is too small relative to retina pixel density. Increase blur to at least 4px (which becomes 8 retina pixels) for smooth edges. Sub-pixel blur is interpreted differently across browsers.

    How many shadow layers should I stack?

    Two for most cases (close + far). Three for hero/premium elements where realistic depth matters. Four+ rarely improves the visual and adds GPU cost. Material Design’s heaviest elevation uses three.

    Will the generator output Tailwind utilities?

    Yes — the tool exports both vanilla CSS and Tailwind arbitrary-value class strings. Tailwind v3 also has built-in shadow utilities (shadow-sm, shadow-md, shadow-lg, shadow-xl, shadow-2xl) that approximate Material elevations 1-5.

    Is the box-shadow data sent anywhere?

    No. The generator runs entirely in your browser — slider values, preview rendering, and the CSS output all stay on your device.

    Related tools and guides

     

  • RGB to HEX Converter: Convert Any Color [2026]

    RGB to HEX Converter: Convert Any Color [2026]

    TL;DR: RGB to HEX conversion takes a color expressed as three 0–255 channels (red, green, blue) and outputs a 6-digit hexadecimal code prefixed with #. rgb(99, 91, 255) becomes #635BFF. With an alpha channel, you get an 8-digit HEX: rgba(99, 91, 255, 0.5)#635BFF80. Our free RGB to HEX converter handles all common formats — RGB, RGBA, HSL, HSV, CMYK, OKLCH — with a live colour swatch, WCAG contrast scores, and named-colour matching.

    Web designers convert colours between RGB and HEX dozens of times a week. A designer hands you an RGB triplet from Figma; a stylesheet uses HEX; a UI library expects HSL; a print spec demands CMYK. Every framework picks its favourite and assumes you’ll convert the rest. Mental math works for greyscale (rgb(255,255,255) = #FFFFFF) but fails for anything in between — converting 91 to 5B in your head is a recipe for typos.

    Our RGB to HEX converter handles every direction (RGB ↔ HEX ↔ HSL ↔ HSV ↔ CMYK ↔ OKLCH), preserves alpha channels correctly, and shows a large colour preview alongside every value. Each output also includes the WCAG contrast ratio against pure black and pure white, so you can rule out colours that fail accessibility audits in one glance. This guide covers exactly how the conversion works, why 8-digit HEX matters in modern CSS, and the gotchas that turn a perfect conversion into a wrong one.

    Format reference: RGB, HEX, HSL, OKLCH

    Format Example Best for
    HEX (6-digit) #635BFF Brand colours, opaque CSS, copy-paste from Figma
    HEX (8-digit, with alpha) #635BFF80 Translucent overlays — same brevity as HEX
    RGB rgb(99, 91, 255) Programmatic generation, design tools
    RGBA rgba(99, 91, 255, 0.5) Translucent fills with explicit alpha
    HSL hsl(243, 100%, 68%) Dynamic shade adjustments (modify L only)
    HSV / HSB hsv(243, 64%, 100%) Photoshop / Sketch picker workflow
    CMYK cmyk(61%, 64%, 0%, 0%) Print specs only — never web
    OKLCH oklch(56% 0.27 270) Modern CSS, perceptually-uniform palettes

    How the math works

    RGB to HEX is a straight base-10 to base-16 conversion of three numbers, padded to 2 digits each:

    // rgb(99, 91, 255) → #635BFF
    const toHex = (n) => n.toString(16).padStart(2, "0").toUpperCase();
    const hex = `#${toHex(99)}${toHex(91)}${toHex(255)}`;
    // → "#635BFF"

    For 8-digit HEX with alpha, append a fourth pair scaled from 0–1 to 0–255: 0.5 × 255 = 127.5 → rounds to 128 → 0x80. Result: #635BFF80. Note that 8-digit HEX with alpha is widely supported (Chrome 62+, Firefox 49+, Safari 9.1+) — well over 95% of users in 2026 — so you can safely replace rgba(...) with 8-digit HEX in modern stylesheets.

    How to convert RGB to HEX in your browser

    1. Open the RGB to HEX converter
    2. Pick the colour with the visual picker, OR type a value in any format
    3. All other formats update in real time below the input
    4. Copy any result with one click; the colour preview matches what you’ll get on screen
    5. WCAG contrast scores against black and white show inline — useful for accessibility checks

    3-digit HEX shorthand and when it works

    CSS allows #FFF as shorthand for #FFFFFF, and #F0A for #FF00AA. Each digit duplicates: #ABC means #AABBCC. This works only when each channel pair has identical digits — #635BFF (no duplicate pairs) cannot be expressed in 3-digit form. The shorthand also has a 4-digit alpha variant: #FFF8 means #FFFFFF88 — an alpha of 0x88 (about 53%).

    Most minifiers expand 3-digit HEX to 6-digit during build, then the gzipped output ends up similar size. Don’t write code that depends on the format — semantically #FFF and #FFFFFF are identical.

    Common gotchas

    • HEX is case-insensitive but lowercase is conventional in CSS. #635BFF and #635bff render identically. Modern style guides (Airbnb, Google) lowercase by default; some teams uppercase for visual contrast against text.
    • Browser colors object accepts named colours. red#FF0000, cornflowerblue#6495ED. Our converter recognises all 147 CSS named colours and shows the matching name where one exists.
    • HSL is not perceptually uniform. Two HSL colours with identical L (lightness) can look very different in brightness — yellow at L=50% looks much brighter than blue at L=50%. Use OKLCH if you want perceptually-uniform palettes.
    • CMYK conversion is approximate. RGB and CMYK have different gamuts (printers can’t reproduce all RGB colours, and vice versa). Our CMYK output is a naive conversion, not an ICC-profile-based one. For print specs, pick CMYK in Adobe Illustrator with the right profile loaded.
    • Alpha precision differs. rgba(255,0,0,0.5) rounds to #FF000080, but 0.5 × 255 = 127.5 rounds up. Round-tripping #FF000080 back gives 0.502. The 1-in-256 quantisation is invisible to the eye.
    • OKLCH chroma maxes out around 0.4. Higher values either clamp to the gamut or produce out-of-gamut colours (which browsers display as the closest in-gamut equivalent). Our converter shows when an OKLCH value exceeds the sRGB gamut.

    When NOT to use a converter

    For programmatic conversion in code, use the language-native API: CSS Color Module 4 in modern browsers (CSS.color()), Color.js or chroma.js for batch conversion, or color npm for Node.js. For design tools (Figma, Sketch, Adobe XD), the built-in colour picker handles every conversion natively. Use this browser tool for one-off conversions, accessibility audits, brand-spec verifications, and learning the relationship between formats.

    Frequently asked questions

    What’s the difference between RGB and HEX?

    Same colour, different notation. RGB writes the three channels as decimal numbers (0–255 each) separated by commas. HEX concatenates the same three channels as 2-digit hexadecimal numbers prefixed with #. rgb(99, 91, 255) and #635BFF are identical to the browser.

    Can HEX represent transparency?

    Yes — 8-digit HEX includes an alpha channel as the last 2 digits. #635BFF80 is #635BFF at roughly 50% opacity. 8-digit HEX is supported in all modern browsers (Chrome 62+, Firefox 49+, Safari 9.1+) and in CSS Modules 4, so prefer it over rgba() for translucent values.

    Why does my converted HEX look slightly off?

    Probably alpha quantisation — converting rgba(R,G,B,0.5) to HEX rounds 127.5 to 128 (0x80), and back-conversion gives 0.502. The 1-in-256 step is invisible to the eye. If colours look different by more than a single shade, the issue is gamut conversion (RGB to CMYK or OKLCH out-of-gamut), not arithmetic.

    Should I use HEX, RGB, or HSL in my CSS?

    HEX for opaque brand colours (most concise). 8-digit HEX or rgba() for translucency. HSL when you want to dynamically adjust lightness with calc() or CSS variables. OKLCH for new design systems where perceptual uniformity matters. All work everywhere — pick what reads best in your codebase.

    Is my colour data uploaded?

    No. The converter runs in your browser via JavaScript. Colour values you enter never leave your device.

    What’s OKLCH and why do designers use it?

    OKLCH is a perceptually-uniform colour space (defined in CSS Color Module 4). Lightness, chroma, and hue map to how the eye perceives them — adjust L by 10% and the colour looks 10% lighter regardless of hue. HSL doesn’t have this property: yellow at L=50% looks much brighter than blue at L=50%. OKLCH is supported natively in Chrome 111+, Safari 15.4+, Firefox 113+ — production-safe in 2026.

    Related tools and guides

     

  • CSS Minifier: Shrink Stylesheets 30–45% in Browser [2026]

    CSS Minifier: Shrink Stylesheets 30–45% in Browser [2026]

    TL;DR: A CSS minifier strips whitespace and comments, shortens colour values (#ffffff#fff), merges duplicate @media blocks, and removes redundant rules. Typical stylesheets shrink 25–45% before gzip; gzipped they shrink 75–85% from raw. Our free CSS minifier runs csso in your browser with full support for modern CSS — custom properties, nesting, container queries, @layer, OKLCH colours.

    CSS is render-blocking by default. Until the browser downloads, parses, and applies your stylesheet, the page can’t paint a single pixel. Every kilobyte of CSS in the critical path adds latency. Minification is the cheapest fix: a 84 KB stylesheet with comments and indentation becomes a 52 KB minified file (−38%) and a 12 KB gzipped payload (−86%). For a Tailwind-based site that ships 200 KB of utility CSS, that’s a difference users notice on a 4G connection.

    Our CSS minifier uses csso (the engine behind Yandex’s stack) with optional clean-css fallback for legacy edge cases. It handles modern CSS — CSS variables, native nesting, container queries, @layer, the OKLCH colour space, and the new :has() selector — without breaking syntax. Paste any size, get instant minified output, and download or copy. This guide covers what minification does to CSS specifically, the size savings to expect, and the gotchas that turn a working stylesheet into a broken one.

    What CSS minification actually does

    Transform Example Savings
    Whitespace + comments remove all /* … */ and indentation 15–30%
    Hex shortening #ffffff#fff 2–4%
    Zero unit drop 0px0 1–2%
    Leading zero drop 0.5em.5em <1%
    Shorthand collapse margin: 0 0 0 0margin: 0 1–3%
    Selector dedupe merge two .btn{...} rules 2–8%
    @media merge two identical media queries → one block 3–10%
    Property merge border-top:0;border-right:0border:0 1–4%

    Total typical reduction: 25–45%. Hand-written stylesheets shrink more (lots of whitespace and comments); pre-minified frameworks shrink less (already optimised). Tailwind output, post-PurgeCSS, typically shrinks another 15–25% with csso on top.

    Modern CSS that minifiers used to break

    Older minifiers (clean-css 3.x and YUI Compressor) corrupt modern CSS in several ways. csso handles all of these correctly:

    • CSS custom properties: --brand: #635BFF values and var() references are preserved exactly. Old minifiers stripped fallbacks.
    • Native nesting: .card { .title { } } is preserved (modern browsers parse it natively without a preprocessor).
    • Container queries: @container (width > 400px) { … } is preserved with all syntax variants.
    • OKLCH and color-mix(): new colour formats are passed through; csso doesn’t try to “shorten” them since the format is already minimal.
    • :has() selector: the parent selector is preserved without quote-mangling.
    • @layer: cascade layer ordering is preserved exactly — never reordered.

    How to minify CSS in your browser

    1. Open the CSS minifier
    2. Paste your CSS or drop in a .css file
    3. Pick the engine: csso (default) or clean-css (legacy)
    4. Toggle options: dedupe selectors, merge @media, restructure (aggressive)
    5. Click Minify. Output appears with before/after sizes
    6. Copy or download as .min.css

    Common gotchas

    • “Restructure” is opt-in for a reason. The aggressive csso option reorders selectors that look equivalent. If your CSS relies on cascade order (later rules override earlier ones), restructuring can change which rule wins. Test the minified output visually before deploying.
    • Don’t minify a CSS file that’s imported with @import in another file. Some minifiers inline imports; csso doesn’t by default. Bundle first (PostCSS / esbuild), minify the output.
    • Vendor prefixes are preserved. Don’t expect minification to remove -webkit- prefixes — the minifier doesn’t know which browsers you target. Use Autoprefixer to add/strip prefixes based on your browserslist.
    • Source maps are essential for production debugging. Without them, every DevTools error points at line 1 column 240. Generate a .map alongside the minified file.
    • Don’t minify already-minified files. Files ending in .min.css rarely shrink more than 1–2% on a second pass. Skip them.
    • Critical CSS extraction is a different job. Minification reduces the size of all your CSS. Critical CSS extraction inlines only the rules needed for above-the-fold content. Use a tool like Critters or Penthouse for that.

    When NOT to use a browser CSS minifier

    If your build pipeline already includes Vite, Next.js, esbuild, Webpack, or Parcel, CSS minification is built in — you don’t need a separate tool. Use this browser minifier for one-off pages built without a build system, third-party stylesheets you’re embedding, snippets pasted into a CMS that doesn’t have a build step, or to inspect what csso does to a specific block of CSS. For Node automation, install csso directly (npm i -D csso-cli) and run it from a script.

    Frequently asked questions

    How much does gzip add on top of CSS minification?

    About 50% additional. A 52 KB minified CSS file gzips to roughly 12 KB. Brotli (modern CDN default) shrinks 8–15% beyond gzip. CSS responds especially well to compression because of repeated property names — always serve .css with a Content-Encoding header.

    Will minification break my Tailwind output?

    No. Tailwind’s JIT engine produces CSS that minifies cleanly with csso. Run PurgeCSS first (Tailwind does this automatically in production), then minify. Expected pipeline: Tailwind → PostCSS → cssnano/csso → gzip. Tailwind v4 includes Lightning CSS for both transformation and minification.

    Does the minifier support CSS variables and the new colour spaces?

    Yes. csso preserves CSS custom properties, var() references with fallbacks, OKLCH, OKLab, color-mix(), and relative-colour syntax exactly. It won’t try to shorten values it doesn’t fully understand — safer than aggressive optimisation.

    Can I minify SCSS or Less directly?

    No — minify only after compilation. SCSS and Less must compile to plain CSS first (via Sass, Dart Sass, or Less), then run through the minifier. Some build tools chain these automatically; for one-off files, paste the compiled output here.

    Is my CSS uploaded?

    No. csso runs in your browser via WebAssembly. Stylesheets are never uploaded — useful for proprietary or pre-release styles.

    What’s the difference between minify and prettify?

    Opposite jobs. Minify removes whitespace to shrink size for production. Prettify (CSS Formatter) adds whitespace and indentation for readability. Use a formatter when you’re editing; use a minifier as the final step before deploy.

    Related tools and guides

     

  • HEX to RGBA Converter: All Color Formats at Once [2026]

    HEX to RGBA Converter: All Color Formats at Once [2026]

    TL;DR: A HEX to RGBA converter translates between the hexadecimal colour notation (#635BFF) used by CSS and design tools and the alpha-aware RGBA notation (rgba(99, 91, 255, 0.5)) used for transparent overlays. Our free converter outputs HEX, RGB, RGBA, HSL, HSV, CMYK, and OKLCH all at once, with a live alpha slider and one-click copy on each format.

    Frontend developers translate between colour formats dozens of times a week. The brand book has HEX. The CSS needs RGBA when transparency is involved. The design tool wants HSL or HSV for the colour picker. The print spec needs CMYK. A multi-format colour converter is the kind of utility that sounds trivial until you’ve spent five minutes copy-pasting into a different tool for each format you need.

    Our HEX to RGBA converter takes any HEX value (3-digit shorthand, 6-digit, or 8-digit with alpha) and instantly outputs every common colour format simultaneously. Drag the alpha slider to add transparency without retyping. This guide explains the seven colour formats every web designer encounters, when each is the right choice, and the gotchas that produce subtly-wrong colour conversions.

    The seven colour formats and when each is right

    Format Example Best use
    HEX (6-digit) #635BFF CSS, brand books, design tools — universal web notation
    HEX (8-digit, with alpha) #635BFF80 CSS shorthand for RGBA; 80 = ~50% alpha. Less readable than rgba()
    RGB rgb(99, 91, 255) Programming (every image library uses RGB), some legacy CSS
    RGBA rgba(99, 91, 255, 0.5) CSS with explicit transparency — overlays, glassmorphism, backdrops
    HSL hsl(244, 100%, 68%) Building tints/shades by adjusting one value (lightness)
    HSV / HSB hsv(244, 64%, 100%) Photoshop/Affinity colour picker default — useful for design-tool match
    OKLCH oklch(63% 0.27 286) Modern CSS (Chrome 111+, Safari 15.4+, Firefox 113+); perceptually uniform
    CMYK cmyk(61%, 64%, 0%, 0%) Print only — magazine, brochure, business card

    Why HEX has 6 digits — and the 3-digit shorthand

    A 6-digit HEX encodes red, green, and blue channels at 8-bit precision (0-255 each), written as two hexadecimal digits. #635BFF means red=63 (hex) = 99 (decimal), green=5B = 91, blue=FF = 255.

    The 3-digit shorthand #FFF is equivalent to #FFFFFF — each digit is duplicated. Useful for pure colours but loses precision: only 4096 distinct colours fit in 3-digit shorthand vs 16.7 million in full 6-digit form. CSS accepts both, but designers prefer 6-digit for non-trivial colours.

    The 8-digit form (#635BFF80) adds an alpha channel: the last two hex digits represent transparency from 00 (fully transparent) to FF (fully opaque). 80 in hex is 128 in decimal, or 50% alpha. Most browsers (~98% support since 2018) understand 8-digit HEX, but it’s harder to read than the explicit rgba() form for the same value.

    How to use the browser HEX to RGBA converter

    1. Open the HEX to RGBA converter
    2. Type or paste a HEX value into the input — 3-digit, 6-digit, or 8-digit forms all accepted
    3. Every output format updates instantly: HEX, RGB, RGBA, HSL, HSV, OKLCH, CMYK
    4. Drag the alpha slider (0-100%) to add transparency. The RGBA, 8-digit HEX, HSLA, and HSVA outputs update with the new alpha
    5. Click any format’s copy icon to grab that exact value to your clipboard
    6. Use the inverse (RGBA → HEX) by entering values into the RGB or RGBA fields directly

    Every format also includes a small contrast-ratio readout against pure black and pure white, so you can quickly evaluate whether a colour will pass WCAG AA contrast for body text.

    Converting in code

    Plain JavaScript:

    function hexToRgba(hex, alpha = 1) {
      const m = hex.replace("#", "").match(/^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
      if (!m) return null;
      const [, r, g, b] = m.map((s, i) => i === 0 ? s : parseInt(s, 16));
      return `rgba(${r}, ${g}, ${b}, ${alpha})`;
    }
    
    hexToRgba("#635BFF", 0.5);
    // => "rgba(99, 91, 255, 0.5)"

    Modern CSS (no JavaScript needed):

    /* 8-digit HEX with alpha — supported since 2018 */
    .overlay { background: #635BFF80; }
    
    /* color-mix to add transparency to an existing variable */
    .overlay { background: color-mix(in srgb, var(--brand) 50%, transparent); }
    
    /* RGB notation with optional / alpha — modern CSS Color 4 syntax */
    .overlay { background: rgb(99 91 255 / 0.5); }

    JavaScript with colord:

    import { colord } from "colord";
    
    const c = colord("#635BFF");
    c.toRgb();        // { r: 99, g: 91, b: 255, a: 1 }
    c.toHsl();        // { h: 244, s: 100, l: 68, a: 1 }
    c.alpha(0.5).toRgbString();  // "rgba(99, 91, 255, 0.5)"

    Common gotchas in HEX conversion

    • Mixing up HSL and HSV. HSL’s lightness goes from 0% (black) to 100% (white) with the colour at 50%. HSV’s value goes from 0% (black) to 100% (full colour at maximum). They look similar but produce subtly different results when adjusted. Make sure your design tool uses the same one your CSS does.
    • Trusting CMYK conversion from a screen colour. RGB and CMYK have different gamuts. Vivid screen colours often can’t be reproduced in print. The CMYK output from any web tool is an approximation; use a print-aware tool with ICC profile management for production work.
    • Forgetting alpha in 8-digit HEX. #635BFF and #635BFFFF are identical (FF = 100% alpha). #635BFF80 has 50% alpha. Trim the alpha when you don’t need it for cleaner CSS.
    • Using HSL hue values incorrectly in code. CSS expects hsl(244, 100%, 68%) with hue in degrees. Some libraries store hue normalized to 0-1. Mixing the two produces colours that look right at a glance but are subtly off.

    When to choose RGBA vs 8-digit HEX vs color-mix

    • RGBA for explicit transparency in CSS where the value itself is meaningful (e.g., a 25% black overlay): rgba(0, 0, 0, 0.25) reads more clearly than #00000040.
    • 8-digit HEX for compact CSS when you have a known opaque colour and need a transparent variant: #635BFF80 is shorter than rgba(99, 91, 255, 0.5).
    • color-mix(in srgb, var(–brand) 50%, transparent) for derived transparency from a CSS variable. Lets your brand colour change once and all transparent variants update.
    • RGB with slash notation (CSS Color 4): rgb(99 91 255 / 0.5) — the modern standard, supported in 95%+ of browsers as of 2026.

    Frequently asked questions

    Why does my HEX colour look different in different applications?

    Three common causes: (1) your monitor’s colour profile differs from the source — calibrate displays for consistent results across devices; (2) the source uses Display P3 colour space (modern Macs, iPhones) and the target only renders sRGB; (3) image gamma or colour management differences between Photoshop, browsers, and print drivers. The HEX value is the same; the rendering varies.

    Should I use 6-digit or 8-digit HEX?

    6-digit for opaque colours — universal, readable, supported everywhere. 8-digit when transparency is essential — cleaner than rgba() in some cases. Avoid 8-digit if you’ll still need to support browsers older than 2018 (effectively zero modern audience, but rare legacy contexts exist).

    Does the converter handle CSS variables?

    The tool converts the resolved colour value, not CSS variable references themselves. To convert var(--brand) via the tool, look up the actual HEX value in your stylesheet first. For runtime variable conversion in JavaScript, use getComputedStyle(element).getPropertyValue('--brand') to read the resolved value.

    What’s the difference between HSL and OKLCH?

    HSL uses a cylindrical model with hue rotation, but its lightness isn’t perceptually uniform — equal numerical changes produce visually unequal changes (especially around yellow and cyan). OKLCH uses a perceptually uniform colour space, so equal lightness changes look equal regardless of hue. OKLCH is the modern best practice for design systems; HSL is fine for simple tints and shades within a single hue.

    Can the tool convert HEX to print-ready CMYK?

    The CMYK output is an approximation derived from sRGB → CMYK conversion. For production print, ask your printer for their colour-managed conversion using your specific ICC profile. The tool gets you within ~10% of the printer’s value, which is fine for proofs and mockups but not for final print specs.

    Is my colour data sent anywhere?

    No. The converter runs entirely in your browser using JavaScript. The HEX you type, the alpha you adjust, and the converted outputs all stay on your device. Verify in DevTools’ Network tab — there are no requests when you type or convert.

    Related tools and guides

     

  • Color Mixer Tool: Blend Two Colours in OKLCH [2026]

    Color Mixer Tool: Blend Two Colours in OKLCH [2026]

    TL;DR: A color mixer tool blends two colours by interpolating between them in RGB, HSL, or OKLCH colour space. Use it to find the perfect mid-point for gradients, build smooth ramps between brand colours, or pick a colour that splits the difference between two brand candidates. Our free color mixer outputs every interpolation point as HEX, with a 7-step preview ramp and copy-ready values.

    Mixing two colours mathematically is one of those operations everyone needs occasionally and few people do well by eye. Designers reach for it when picking a button hover state (“I need something between my brand purple and pure black”), when building gradient stops, when matching a competitor’s colour to a brand-adjacent variant. The naive approach — averaging the RGB values — works for greys but produces muddy results across distant hues. A good color mixer uses perceptually-uniform colour spaces to give you mid-points that look halfway between the two inputs.

    Our color mixer tool takes two HEX inputs and produces a 7-step interpolated ramp, with a slider you can drag for any specific blend ratio. Output formats include HEX, RGB, HSL, and OKLCH for the interpolation modes that support it. This guide explains what each interpolation mode does, when to pick which, and the workflows where colour mixing solves real design problems.

    Three interpolation modes — RGB, HSL, OKLCH

    Mode How it interpolates Best for
    RGB Linear blend of R, G, B channels independently Greys, subtle shifts between similar colours
    HSL Hue rotates through colour wheel; saturation + lightness blend linearly Rainbow-style mid-points, dramatic colour blends
    OKLCH Perceptually uniform — equal slider distance = equal visual change Most balanced ramps; the modern best practice for design systems

    Why the same input produces different mid-points in each mode. Mix red #FF0000 and blue #0000FF:

    • RGB mid-point: #800080 (purple) — the literal R/G/B average. Looks dark and muddy.
    • HSL mid-point (shorter hue arc): #FF00FF (magenta) — rotates through the magenta side of the wheel. Vivid.
    • HSL mid-point (longer hue arc): #00FF00 (green) — rotates through cyan and green the long way around. Wild.
    • OKLCH mid-point: #A53C7C (warm magenta-purple) — perceptually balanced, neither washed-out nor neon.

    For everyday design work, OKLCH produces the answer most designers would call “right”. RGB is fine for similar colours; HSL is best when you specifically want the mid-point to traverse vivid colours (rainbow gradients, cyberpunk aesthetics).

    Five workflows where a color mixer earns its keep

    • Picking a button hover state. Mix your brand colour with a darker variant (often pure black or your darkest neutral) at 15-25% to get a hover state that reads as “same colour, more pressed”.
    • Building gradient stops. A two-colour gradient with a manually-mixed middle stop reads better than a default browser gradient — especially for distant hues where browsers’ sRGB interpolation produces muddy mid-points.
    • Bridging brand colours. If your design system has two brand colours (primary blue + accent orange, say) and you need a third for a specific component, a 50/50 mix gives you a colour that “feels” like it belongs to both.
    • Match-mode A/B test colours. Mix your existing CTA colour with the test variant at 25%, 50%, 75% to design a smooth visual A/B test rather than a jarring switch.
    • Theme transition colours. When transitioning between light and dark mode, the mid-point colour for borders, surfaces, and shadows often needs to be hand-picked. A mixer between the two extremes gives you the right mid-tone.

    How to use the browser color mixer

    1. Open the color mixer
    2. Enter two HEX values (or use the colour pickers) — your start and end colours
    3. Pick the interpolation mode: RGB, HSL, or OKLCH (default OKLCH for balanced ramps)
    4. The 7-step ramp renders instantly. Each step shows its HEX value
    5. Drag the slider to any specific blend ratio (0% = start, 100% = end, 50% = midpoint) for fine control
    6. Click any swatch to copy its HEX. Or click “Copy all” to grab the entire ramp as comma-separated HEX values

    Switch interpolation mode with the same inputs — the ramp re-renders showing the difference. Doing this once visually clarifies why OKLCH is the modern default: the colours look more “evenly spread” between the start and end than either RGB or HSL.

    Mixing colours in code

    JavaScript (colord library):

    import { colord } from "colord";
    
    // 50/50 mix of red and blue
    const mid = colord("#FF0000").mix("#0000FF", 0.5).toHex();
    // => "#800080" (RGB blend)
    
    // Build a 5-step ramp
    const ramp = [0, 0.25, 0.5, 0.75, 1].map((t) =>
      colord("#FF6B6B").mix("#4ADE80", t).toHex()
    );

    Modern CSS (color-mix() function — supported in Chrome 111+, Safari 16.2+, Firefox 113+):

    /* 50/50 mix in OKLCH (perceptually uniform) */
    .button:hover {
      background: color-mix(in oklch, var(--brand) 75%, black 25%);
    }
    
    /* 30/70 mix in RGB */
    .divider {
      background: color-mix(in srgb, #635BFF 30%, white 70%);
    }

    Python (colormath):

    from colormath.color_objects import sRGBColor, LabColor
    from colormath.color_conversions import convert_color
    
    a = sRGBColor.new_from_rgb_hex("#FF6B6B")
    b = sRGBColor.new_from_rgb_hex("#4ADE80")
    la, lb = convert_color(a, LabColor), convert_color(b, LabColor)
    
    # 50/50 in Lab (perceptually uniform)
    mid_lab = LabColor(
        (la.lab_l + lb.lab_l) / 2,
        (la.lab_a + lb.lab_a) / 2,
        (la.lab_b + lb.lab_b) / 2,
    )
    print(convert_color(mid_lab, sRGBColor).get_rgb_hex())

    The color-mix() CSS function is the modern way — no JavaScript needed. Use it directly in your stylesheets and the browser computes the mix at render time. ~94% global support as of 2026.

    Common mistakes when mixing colours

    • Mixing two colours that produce a muddy mid-point. Distant hues (red-blue, yellow-purple) often have washed-out RGB mid-points. Switch to OKLCH or HSL for vibrant results.
    • Forgetting to test contrast at every step. A start colour that passes WCAG against your text and an end colour that also passes don’t guarantee every step in between passes. Audit accessibility across the full ramp before shipping.
    • Using HSL longer hue arc by default. The longer-arc rotation is dramatic and rarely what designers actually want. Default to shorter arc (the standard) and only switch to longer for explicit rainbow effects.
    • Mixing in the wrong colour space for print. Screen-to-print conversion already loses gamut accuracy. Don’t add interpolation noise on top — pick the print colours directly from a Pantone-aware palette.

    When NOT to mix colours

    • For your primary brand palette. Brand colours should be specified, not mixed. The mixer is for finding adjacent or transitional colours, not the brand itself.
    • For accessibility-critical text on coloured backgrounds. Mixed colours often hover near contrast thresholds. Use Tailwind’s pre-tuned ramps where every step is verified for contrast against neutral text.
    • For colour systems requiring CMYK accuracy. Mixing in RGB then converting to CMYK accumulates errors. Mix directly in CMYK in print-aware tools.

    Frequently asked questions

    What’s the difference between mixing colours and gradients?

    A colour mixer produces discrete colour values at specific blend ratios (good for picking exact colours for use in CSS or design tokens). A gradient produces a continuous visual transition between colours (good for backgrounds, hero sections, button fills). They use the same underlying interpolation math; the difference is whether the output is a discrete value or a smooth transition.

    Should I use RGB, HSL, or OKLCH for mixing?

    OKLCH for perceptual uniformity (the default modern best practice). HSL for vivid mid-points (the colours pass through more saturated regions). RGB for similar colours where the difference is small. For most design system work, OKLCH gives you the answer that matches “the eye’s average” and avoids muddy mid-points or unexpected hue shifts.

    Why does my CSS color-mix() result look different from the tool?

    The color-mix() CSS function defaults to in oklab if you don’t specify a colour space. Our tool defaults to oklch which produces slightly different results than oklab. Match the spaces explicitly: color-mix(in oklch, ...) in CSS for results identical to the tool.

    Can I mix more than two colours?

    Not in a single mix operation — colour mixing is fundamentally pairwise. To blend three colours, mix the first two together, then mix that result with the third. Or use a multi-stop gradient and sample colours from specific positions, which is what 3-colour gradient generators effectively do.

    Is the mixed colour the same as a 50% opacity overlay?

    Visually similar but mathematically different. Mixing produces a single new colour. A 50% opacity overlay shows whatever’s behind through the semi-transparent overlay, so the visual result depends on the background. For a fixed white background, an opacity-50 red overlay and a 50/50 mix of red and white look identical. Over a different background, the opacity overlay produces a different visible colour.

    Does the tool support the alpha channel?

    The current mixer focuses on opaque colour interpolation. For alpha-aware mixing (where you blend two semi-transparent colours), use color-mix() in CSS with explicit alpha values, or use the colord library’s .alpha() method in JavaScript.

    Related tools and guides

     

  • CSS Gradient Generator Tool: Linear, Radial & Conic [2026]

    CSS Gradient Generator Tool: Linear, Radial & Conic [2026]

    TL;DR: A CSS gradient generator tool builds linear-gradient, radial-gradient, and conic-gradient backgrounds with drag-and-drop colour stops. Use linear for hero sections, radial for spotlight effects, conic for pie charts and loaders. Modern CSS supports OKLCH interpolation for smoother results without the muddy mid-points of RGB. Our free generator gives you a live preview, six presets, and copy-ready CSS plus Tailwind output.

    CSS gradients have quietly become the default web background since flat design fell out of fashion around 2018. They show up on every modern SaaS hero, the corner of every productivity-app card, behind every “premium tier” callout. Building one by hand requires remembering whether 0deg is up or right, the syntax difference between radial-gradient and conic-gradient, and the perceptual-colour quirks that make a gradient look muddy in the middle. A generator tool does all that for you with a live preview.

    Our CSS gradient generator lets you switch between linear, radial, and conic types, drag colour stops to any position, set the angle, and copy the result as either vanilla CSS or a Tailwind arbitrary-value class. This guide explains when each gradient type is appropriate, the modern OKLCH interpolation feature most generators don’t expose, the banding that ruins amateur gradients, and the framework-specific quirks worth knowing.

    The three gradient types and when each is the right choice

    CSS supports exactly three gradient functions. Each has a distinct visual signature; matching the type to the use case is the difference between a gradient that reads as intentional and one that reads as random.

    Type Visual Best uses
    linear-gradient Colour transitions in a straight line at any angle Hero backgrounds, button fills, product cards, page-level overlays
    radial-gradient Spotlight effect emanating from a point or ellipse Vignettes, “glow” effects behind content, soft circular backdrops, focus highlights
    conic-gradient Colour rotation around a centre point (think pie chart) Loading spinners, pie charts and donuts, colour wheels, holographic effects, segmented progress

    The most common mismatch: using a linear gradient where a radial would read better. A button styled with a flat top-to-bottom linear gradient looks dated (it’s the 2010 web aesthetic). The same button with a subtle radial gradient — bright centre fading darker at the edges — looks 3D and intentional. When in doubt for any contained element under ~600px wide, try radial first.

    The minimal CSS for each type:

    /* Linear: 135 degrees from bottom-left to top-right */
    background: linear-gradient(135deg, #635BFF 0%, #00D4FF 50%, #FF80B5 100%);
    
    /* Radial: a circle from the centre, fading outward */
    background: radial-gradient(circle at center, #4ADE80 0%, #22D3EE 50%, #A78BFA 100%);
    
    /* Conic: starting at 0deg from top, sweeping clockwise */
    background: conic-gradient(from 0deg at 50% 50%,
      #8B5CF6 0%, #06B6D4 33%, #F59E0B 66%, #EC4899 100%);

    The angle convention for linear-gradient is the source of more confusion than any other gradient quirk. 0deg points up, 90deg points right, 180deg points down, 270deg points left. This is opposite to mathematical convention (where 0deg points right) and opposite to SVG (where 0deg also points right). 135deg, the most popular angle in modern web design, points from bottom-left to top-right.

    Colour stops — the difference between elegant and muddy

    A gradient is fully described by a list of colour stops. The simplest gradient has two: linear-gradient(red, blue). Three or four stops give the curved colour transitions you see on premium SaaS hero sections. More than five stops usually produces visual noise rather than richness.

    • Two stops: the classic web look. Works for buttons, simple backgrounds, hover states. Choose two colours far apart on the colour wheel for maximum impact, or two close ones for subtle.
    • Three stops at 0%/50%/100%: the “premium” look. The middle colour controls the perceived hue of the transition. Most modern SaaS hero gradients use this pattern.
    • Four+ stops: aurora-style effects, retro 80s synthwave gradients, holographic backgrounds. Risk: too much colour noise unless the stops are chosen with intent.
    • Hard stops (two colours at the same position): creates a sharp edge instead of a gradient. linear-gradient(red 0%, red 50%, blue 50%, blue 100%) produces a 50/50 split. Useful for stripes, split backgrounds, percentage-bar visuals.

    The middle-stop trick: when a gradient between two colours looks muddy in the middle (for example, blue-to-yellow producing dirty green-grey), add a third stop at 50% with a colour pulled from the actual rainbow path between them. Blue → cyan → yellow looks vibrant; blue → yellow alone looks washed out. The OKLCH interpolation method (covered next) solves this automatically, but the explicit middle-stop is the universal fix.

    OKLCH interpolation — the modern fix for muddy gradients

    By default, browsers interpolate between gradient stops in the sRGB colour space — the same colour space CSS has used since 1996. sRGB is mathematically convenient but perceptually broken: equal numerical steps in sRGB don’t produce equal visual changes. The result is the muddy mid-points you see when a default linear gradient passes through a colour-wheel diagonal.

    Modern CSS (Chrome 111+, Safari 16.4+, Firefox 113+) supports specifying the interpolation colour space directly. OKLCH and Oklab are perceptually uniform — equal numerical steps look like equal visual changes. The same gradient interpolated in OKLCH versus sRGB looks dramatically different through the middle.

    /* Default sRGB interpolation (potentially muddy mid-points) */
    background: linear-gradient(135deg, #0077B6 0%, #FFD93D 100%);
    
    /* OKLCH interpolation — vibrant, no muddy middle */
    background: linear-gradient(in oklch, 135deg, #0077B6 0%, #FFD93D 100%);
    
    /* Force the longer way around the colour wheel for hue rotation */
    background: linear-gradient(in oklch longer hue, 135deg, #0077B6 0%, #FFD93D 100%);

    The longer hue modifier is the dramatic one. By default, CSS picks the shorter rotation through the colour wheel between two stops. Forcing longer hue sweeps the long way around — perfect for rainbow hero backgrounds and synthwave aesthetics. Try it once and the visual difference is striking.

    Browser support caveat: ~93% global support as of 2026. Older Safari (pre-16.4, before March 2023) and older Edge will fall back to default sRGB interpolation, which means slightly muddier gradients but no broken layout. For production safety, design your gradients to look acceptable in both modes — a hue gap of less than 90° around the wheel keeps both renderings reasonably close.

    Banding — the subtle quality killer

    Gradient banding is the visible “stripes” of colour you sometimes see across a smooth gradient — most obvious on darker, lower-saturation gradients displayed on phone screens. It happens because 8-bit colour (the standard sRGB pixel format) only has 256 levels per channel. Across a 1920-pixel-wide gradient transitioning between two close shades, that’s only ~256 distinct colours stretched over 1920 pixels — not enough to look smooth.

    • Cause #1: low-contrast gradient on a wide area. A gradient from #0a2540 to #0c2a48 across a 1920-pixel hero will band visibly. Either widen the colour range or break up the gradient with subtle noise.
    • Cause #2: 8-bit colour rendering on devices that support 10-bit. Modern Macs, iPhones, and Android flagships have 10-bit display pipelines, but CSS still produces 8-bit output unless you specify color-profile: display-p3 or use Display P3 colour functions.
    • Fix #1: add subtle noise. A 50% opacity 1×1px PNG noise texture overlaid on the gradient hides banding completely. SVG <filter feTurbulence> works too.
    • Fix #2: use Display P3 colours. color(display-p3 0.5 0.4 1) instead of #7e66ff gives the GPU more precision to work with on capable displays.
    • Fix #3: reduce the gradient’s pixel area. A 600px gradient bands less than a 1920px gradient at the same colour range, because there are more colour levels per pixel of distance.

    How to use the browser tool

    1. Open the CSS gradient generator
    2. Pick a gradient type — Linear, Radial, or Conic — at the top
    3. Adjust the angle slider (linear, conic) — direction the gradient flows
    4. Click any colour stop to edit its colour. Drag the position handle to slide the stop along the gradient
    5. Use the + button to add a stop, the trash icon to remove one (minimum two stops required)
    6. Try a preset — Accent Pop, Sunset, Ocean, Aurora, Peach, or Cosmic — for inspiration or a starting point
    7. Click Copy CSS for vanilla CSS, or Copy Tailwind for the arbitrary-value class string