Skip to content

Glassmorphism Generator — Python source

Create frosted-glass CSS - backdrop-blur, translucent background, subtle border, and soft shadow - with a copy-ready snippet and live preview.

This is the Python implementation — the same logic the interactive tool runs, in a shareable, citable form.

#!/usr/bin/env python3
# Pure glassmorphism CSS builder — deterministic, no DOM.
#
# Language: Python
# CosmoDev polyglot showcase port of the `glassmorphism-generator` tool.
# Ported from src/lib/glassmorphism.ts — display source, part of CosmoDev's
# polyglot tool pages.
#
# Builds a frosted-glass CSS block from blur / opacity / tint / radius /
# border_opacity (+ optional saturation). Hex tints (#rgb / #rrggbb) are
# matched with a stdlib regex; opacity is clamped to [0,1]; the alpha
# channel is rounded with floor(x*100 + 0.5)/100 — JS Math.round (half-up)
# semantics, NOT Python's banker's round() — so the output matches the live
# TypeScript lib byte-for-byte. Numbers are rendered like JS template
# literals (10.0 -> "10", 0.3 -> "0.3"). Pure stdlib: re + math.

import math
import re
from dataclasses import dataclass
from typing import Optional, Tuple

_HEX3 = re.compile(r'^[0-9a-fA-F]{3}$')
_HEX6 = re.compile(r'^[0-9a-fA-F]{6}$')


def hex_to_rgb(hex_color):
    """Parse a #rgb or #rrggbb hex color into (r, g, b); None if invalid.

    A 3-char hex expands each digit (e.g. "abc" -> "aabbcc"), like CSS.
    Exactly one leading '#' is stripped, matching the lib's /^#/ replace.
    """
    h = (hex_color or '').strip()
    if h.startswith('#'):
        h = h[1:]
    if _HEX3.match(h):
        return (int(h[0] * 2, 16), int(h[1] * 2, 16), int(h[2] * 2, 16))
    if _HEX6.match(h):
        return (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))
    return None


def _fmt_num(x):
    """Render a number like a JS template literal (10.0 -> '10', 0.3 -> '0.3')."""
    x = float(x)
    if x == int(x):
        return str(int(x))
    return repr(x)


def _alpha(a):
    """Clamp to [0,1], round with JS Math.round (half-up), and render."""
    c = max(0.0, min(1.0, float(a)))
    # math.floor(c*100 + 0.5) replicates Math.round for non-negative values.
    return _fmt_num(math.floor(c * 100.0 + 0.5) / 100.0)


def rgba(r, g, b, a):
    """Format an rgba() string, clamping + 2-decimal-rounding the alpha."""
    return 'rgba({}, {}, {}, {})'.format(round(r), round(g), round(b), _alpha(a))


@dataclass
class GlassConfig:
    blur: float = 0.0
    opacity: float = 0.0
    tint: str = '#ffffff'
    radius: float = 0.0
    border_opacity: float = 0.0
    saturation: Optional[float] = None  # None => 180.0 (lib default)


@dataclass
class GlassCss:
    background: str
    backdrop_filter: str
    webkit_backdrop_filter: str
    border: str
    border_radius: str
    box_shadow: str
    full_css: str


def build_glassmorphism(cfg):
    """Build the full glassmorphism CSS for a GlassConfig."""
    blur = max(0.0, float(cfg.blur))
    opacity = max(0.0, min(1.0, float(cfg.opacity)))
    radius = max(0.0, float(cfg.radius))
    border_opacity = max(0.0, min(1.0, float(cfg.border_opacity)))
    saturation = 180.0 if cfg.saturation is None else float(cfg.saturation)
    rgb = hex_to_rgb(cfg.tint) or (255, 255, 255)

    background = rgba(rgb[0], rgb[1], rgb[2], opacity)
    backdrop_filter = 'blur({}px) saturate({}%)'.format(_fmt_num(blur), _fmt_num(saturation))
    border = '1px solid {}'.format(rgba(255, 255, 255, border_opacity))
    border_radius = '{}px'.format(_fmt_num(radius))
    box_shadow = '0 8px 32px 0 rgba(31, 38, 135, 0.37)'

    full_css = '\n'.join([
        'background: {};'.format(background),
        '-webkit-backdrop-filter: {};'.format(backdrop_filter),
        'backdrop-filter: {};'.format(backdrop_filter),
        'border-radius: {};'.format(border_radius),
        'border: {};'.format(border),
        'box-shadow: {};'.format(box_shadow),
    ])

    return GlassCss(
        background=background,
        backdrop_filter=backdrop_filter,
        webkit_backdrop_filter=backdrop_filter,
        border=border,
        border_radius=border_radius,
        box_shadow=box_shadow,
        full_css=full_css,
    )


if __name__ == '__main__':
    cfg = GlassConfig(blur=10, opacity=0.3, tint='#ffffff', radius=12, border_opacity=0.2)
    print(build_glassmorphism(cfg).full_css)

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →