Skip to content

Glassmorphism Generator — C# 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 C# implementation — the same logic the interactive tool runs, in a shareable, citable form.

// =============================================================================
//  GlassmorphismGenerator.cs — CosmoDev polyglot showcase port of the
//  `glassmorphism-generator` tool
//  -----------------------------------------------------------------------------
//  Language : C# (12 / .NET 8, standard library only)
//  Source:   ported from src/lib/glassmorphism.ts (the canonical, live
//             TypeScript lib); mirrors
//             src/tool-sources/glassmorphism-generator/{python.py,rust.rs}
//  License  : display source — part of CosmoDev's polyglot tool pages
//             (dev.cosmolabs.org). Shown verbatim alongside the JS/TS/Go/Rust/
//             Python ports and the other language ports.
//  -----------------------------------------------------------------------------
//  Builds a frosted-glass CSS block from blur / opacity / tint / radius /
//  border_opacity (+ optional saturation). Hex tints (#rgb / #rrggbb) are
//  checked with Uri.IsHexDigit + int.TryParse(base 16) — no regex, stdlib
//  only; opacity is clamped to [0,1]; the alpha channel is rounded with
//  Math.Floor(x*100 + 0.5)/100 — JS Math.round (half-up) semantics — and
//  numbers render via double.ToString(InvariantCulture), which on .NET Core
//  3.0+ is the shortest round-tripping decimal (10.0 -> "10", 0.3 -> "0.3"),
//  exactly how JavaScript template literals render them. The output therefore
//  matches the live TypeScript lib byte-for-byte.
// =============================================================================

using System;
using System.Globalization;

namespace CosmoDev.GlassmorphismGenerator;

/// <summary>Configuration for one glassmorphism declaration block.</summary>
/// <param name="Saturation">
/// <c>null</c> => 180.0 (lib default).
/// </param>
public sealed record GlassConfig(
    double Blur = 0.0,
    double Opacity = 0.0,
    string Tint = "#ffffff",
    double Radius = 0.0,
    double BorderOpacity = 0.0,
    double? Saturation = null);

/// <summary>The rendered glassmorphism block plus its full CSS text.</summary>
public sealed record GlassCss(
    string Background,
    string BackdropFilter,
    string WebkitBackdropFilter,
    string Border,
    string BorderRadius,
    string BoxShadow,
    string FullCss);

public static class GlassmorphismGenerator
{
    /// <summary>
    /// Render a number like a JS template literal (10.0 -> "10", 0.3 -> "0.3").
    /// </summary>
    static string Num(double x) => x.ToString(CultureInfo.InvariantCulture);

    /// <summary>True when every character is an ASCII hex digit (0-9, a-f, A-F).</summary>
    static bool IsHexRun(string s)
    {
        if (s.Length == 0) return false;
        foreach (var c in s)
        {
            if (!Uri.IsHexDigit(c)) return false;
        }
        return true;
    }

    /// <summary>Parse a run of hex digits into its value (base 16).</summary>
    static int ParseHex(string s) =>
        int.Parse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture);

    /// <summary>
    /// Parse a #rgb or #rrggbb hex color into (R, G, B); <c>null</c> 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.
    /// </summary>
    public static (int R, int G, int B)? HexToRgb(string? hex)
    {
        var h = (hex ?? string.Empty).Trim();
        if (h.StartsWith('#')) h = h[1..];

        if (h.Length == 3 && IsHexRun(h))
        {
            // "a" -> 0xaa — each digit doubles into a pair, like CSS.
            int Expand(int i) => Uri.FromHex(h[i]) * 16 + Uri.FromHex(h[i]);
            return (Expand(0), Expand(1), Expand(2));
        }
        if (h.Length == 6 && IsHexRun(h))
        {
            return (ParseHex(h[..2]), ParseHex(h[2..4]), ParseHex(h[4..6]));
        }
        return null;
    }

    /// <summary>Clamp to [0,1], round with JS Math.round (half-up), and render.</summary>
    static string Alpha(double a)
    {
        var c = Math.Clamp(a, 0.0, 1.0);
        return Num(Math.Floor(c * 100.0 + 0.5) / 100.0);
    }

    /// <summary>Format rgba(), clamping + 2-decimal-rounding the alpha.</summary>
    public static string Rgba(int r, int g, int b, double a) =>
        $"rgba({r}, {g}, {b}, {Alpha(a)})";

    /// <summary>Build the full glassmorphism CSS for a config.</summary>
    public static GlassCss Build(GlassConfig cfg)
    {
        var blur = Math.Max(cfg.Blur, 0.0);
        var opacity = Math.Clamp(cfg.Opacity, 0.0, 1.0);
        var radius = Math.Max(cfg.Radius, 0.0);
        var borderOpacity = Math.Clamp(cfg.BorderOpacity, 0.0, 1.0);
        var saturation = cfg.Saturation ?? 180.0;
        var (r, g, b) = HexToRgb(cfg.Tint) ?? (255, 255, 255);

        var background = Rgba(r, g, b, opacity);
        var backdropFilter = $"blur({Num(blur)}px) saturate({Num(saturation)}%)";
        var border = $"1px solid {Rgba(255, 255, 255, borderOpacity)}";
        var borderRadius = $"{Num(radius)}px";
        const string boxShadow = "0 8px 32px 0 rgba(31, 38, 135, 0.37)";

        var fullCss = string.Join('\n',
            $"background: {background};",
            $"-webkit-backdrop-filter: {backdropFilter};",
            $"backdrop-filter: {backdropFilter};",
            $"border-radius: {borderRadius};",
            $"border: {border};",
            $"box-shadow: {boxShadow};");

        // Both prefixed and unprefixed backdrop-filter carry the same value.
        return new GlassCss(background, backdropFilter, backdropFilter, border,
                            borderRadius, boxShadow, fullCss);
    }

    public static void Main()
    {
        var css = Build(new GlassConfig(Blur: 10, Opacity: 0.3, Tint: "#ffffff",
                                        Radius: 12, BorderOpacity: 0.2));
        Console.WriteLine(css.FullCss);
    }
}

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 →