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 →