{"id":18,"date":"2026-10-15T19:16:35","date_gmt":"2026-10-15T19:16:35","guid":{"rendered":"https:\/\/refracttools.com\/blog\/?p=18"},"modified":"2026-10-15T21:07:02","modified_gmt":"2026-10-15T21:07:02","slug":"glassmorphism-css-backdrop-filter","status":"publish","type":"post","link":"https:\/\/refracttools.com\/blog\/css-techniques\/glassmorphism-css-backdrop-filter\/","title":{"rendered":"Glassmorphism in CSS: how backdrop-filter works"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Glassmorphism in CSS comes down to one property, <code>backdrop-filter<\/code>, plus a few supporting lines that decide whether the result looks like frosted glass or a smudged window. The effect is easy to copy from a snippet and surprisingly easy to get wrong.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide explains what <code>backdrop-filter<\/code> actually does, walks through a working glass panel line by line, and covers the parts snippets usually skip: browser support, contrast, performance and the nesting quirk that catches people out.<\/p>\n\n\n\n<div class=\"wp-block-group is-style-refract-takeaways is-layout-constrained wp-block-group-is-layout-constrained\">\n<h3 class=\"wp-block-heading\">Key takeaways<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>backdrop-filter<\/code> blurs what sits <em>behind<\/em> an element, so the element needs a semi-transparent background to show it.<\/li>\n\n\n<li>A blur of 10\u201320px with a tint opacity of 0.1\u20130.25 reads as frosted glass. Adding <code>saturate()<\/code> stops colours going grey.<\/li>\n\n\n<li>It works in all current browsers. Keep the <code>-webkit-<\/code> line for Safari versions before 18.<\/li>\n\n\n<li>Check text contrast against the lightest and darkest parts of the background, and give people who reduce transparency a solid fallback.<\/li>\n<\/ul>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">What glassmorphism needs to work<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Glassmorphism is a UI style where panels look like frosted glass: you can see colour and shape through them, but softened. It became mainstream through macOS Big Sur and Windows 11, and it suits cards, navigation bars, modals and overlays that sit on top of imagery.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The catch is that glass only looks like glass when there is something interesting behind it. Over a flat colour, a blurred panel is indistinguishable from a transparent box. A photo, a colourful gradient or a few soft shapes give the blur something to work with. The <a href=\"https:\/\/refracttools.com\/css-gradient-generator\/\">CSS gradient generator<\/a> and <a href=\"https:\/\/refracttools.com\/blob-generator\/\">blob generator<\/a> are quick ways to build that backdrop.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How backdrop-filter works<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The ordinary <code>filter<\/code> property applies effects to the element itself and its contents. <code>backdrop-filter<\/code> applies them to everything painted behind the element, within the element&#8217;s own shape. The panel&#8217;s text and icons stay sharp while the page underneath goes soft.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two things follow from that. First, the element&#8217;s own background must be at least partly transparent, otherwise it covers the blurred backdrop completely. Second, the effect follows <code>border-radius<\/code>, so rounded glass cards need no extra clipping.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It accepts the same functions as <code>filter<\/code>: <code>blur()<\/code>, <code>saturate()<\/code>, <code>brightness()<\/code>, <code>contrast()<\/code> and so on. In practice blur does the heavy lifting and saturation repairs the colour that blurring drains out.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Glassmorphism CSS, line by line<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a solid starting point for a glass card:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.glass {\n  background: rgba(255, 255, 255, 0.15);\n  -webkit-backdrop-filter: blur(14px) saturate(160%);\n  backdrop-filter: blur(14px) saturate(160%);\n  border: 1px solid rgba(255, 255, 255, 0.4);\n  border-radius: 20px;\n  box-shadow: 0 20px 50px rgba(8, 10, 30, 0.25);\n}<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>background<\/strong>: a white tint between 0.1 and 0.25 opacity. Lower looks clearer, higher looks frostier and helps text contrast. On dark designs, try a dark tint such as <code>rgba(15, 20, 40, 0.35)<\/code> instead.<\/li>\n\n\n<li><strong>backdrop-filter<\/strong>: 10\u201320px of blur reads as frosted glass. Below about 6px the background stays recognisable; above 30px it turns into a colour wash.<\/li>\n\n\n<li><strong>saturate(160%)<\/strong>: blurring averages colours together, which greys them out. A saturation boost keeps the glass looking lit from behind.<\/li>\n\n\n<li><strong>border<\/strong>: a thin, semi-transparent white edge catches the light and separates the panel from the backdrop. Without it the card edge disappears on light areas.<\/li>\n\n\n<li><strong>box-shadow<\/strong>: a soft, low-opacity shadow lifts the panel. The <a href=\"https:\/\/refracttools.com\/box-shadow-generator\/\">box shadow generator<\/a> is handy for layering a couple of shadows for a more natural depth.<\/li>\n<\/ul>\n\n\n<aside class=\"tool-card tool-card--inline\"><span class=\"swatch\" style=\"background:linear-gradient(135deg,#5ce1c6,#7a5cff)\" aria-hidden=\"true\"><\/span><div class=\"tool-card__body\"><p class=\"tool-card__eyebrow\">Free tool<\/p><p class=\"tool-card__name\">Glassmorphism generator<\/p><p class=\"tool-card__blurb\">Frosted glass panels with backdrop-filter, previewed over real backgrounds.<\/p><\/div><a class=\"btn primary\" href=\"https:\/\/refracttools.com\/glassmorphism-generator\/\">Try it free <span aria-hidden=\"true\">\u2192<\/span><\/a><\/aside>\n\n\n\n<h2 class=\"wp-block-heading\">Browser support and the -webkit- prefix<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><code>backdrop-filter<\/code> is supported in every current major browser. Chrome has supported it unprefixed since version 76 and Firefox since version 103. Safari supported only the <code>-webkit-backdrop-filter<\/code> form for years and added the unprefixed property in Safari 18 (2024), which is when the feature became Baseline.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Keeping both lines covers older iPhones and Macs that have not updated. If a browser cannot blur at all, you want a readable panel rather than a see-through one, so wrap the transparent version in a feature query:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.glass {\n  background: rgba(30, 34, 60, 0.9); \/* solid fallback *\/\n}\n\n@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {\n  .glass {\n    background: rgba(255, 255, 255, 0.15);\n    -webkit-backdrop-filter: blur(14px) saturate(160%);\n    backdrop-filter: blur(14px) saturate(160%);\n  }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">The nesting quirk<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A common surprise is a glass element that stops blurring when it is placed inside another element. Under the current spec, an ancestor with a <code>filter<\/code>, an <code>opacity<\/code> below 1, a <code>mask<\/code> or its own <code>backdrop-filter<\/code> acts as a boundary, and the inner glass only blurs what is inside that ancestor. If your glass looks transparent but unblurred, check the parents for one of those properties.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Accessibility: contrast and reduced transparency<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Text on glass is the biggest risk with this style. The colours behind the panel change as the page scrolls or the hero image changes, so contrast that passes in one spot can fail a few pixels away. Test text against the lightest and the darkest areas the panel can sit over, and raise the tint opacity behind body text until both pass.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Some people turn on &#8220;Reduce transparency&#8221; in their operating system because translucent layers are hard for them to read. The <code>prefers-reduced-transparency<\/code> media query lets you respect that. It is supported in Chrome and Edge but not yet everywhere, so treat it as an enhancement on top of good default contrast:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@media (prefers-reduced-transparency: reduce) {\n  .glass {\n    background: rgb(30, 34, 60);\n    -webkit-backdrop-filter: none;\n    backdrop-filter: none;\n  }\n}<\/code><\/pre>\n\n\n\n<div class=\"wp-block-group is-style-refract-callout is-layout-constrained wp-block-group-is-layout-constrained\">\n<p class=\"wp-block-paragraph\"><strong>Tip:<\/strong> Put text on a slightly more opaque inner layer than the card itself. The card keeps its glassy edges and the words sit on a calmer surface.<\/p>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Performance on real devices<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Blurring is handled by the graphics hardware and a few glass panels are fine on any modern device. Costs rise with the area being blurred, the blur radius and how often the browser has to redraw it.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use glass on a handful of elements, not on every card in a long grid.<\/li>\n\n\n<li>Avoid animating the blur radius. Fading the panel&#8217;s opacity or moving it with <code>transform<\/code> is much cheaper.<\/li>\n\n\n<li>Be careful with full-screen glass over video or constantly animating backgrounds, especially on low-end Android phones.<\/li>\n\n\n<li>A sticky glass header is a common pattern and usually fine, but test scrolling on a real mid-range phone rather than a desktop.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">When to use glass, and when not to<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><div class=\"table-scroll\" tabindex=\"0\" role=\"region\" aria-label=\"Scrollable table\"><table><thead><tr><th>Good fit<\/th><th>Better avoided<\/th><\/tr><\/thead><tbody><tr><td>Navigation bars over a hero image<\/td><td>Long-form reading areas<\/td><\/tr><tr><td>Modals and popovers over busy content<\/td><td>Dense data tables and forms<\/td><\/tr><tr><td>Feature cards on a colourful section<\/td><td>Pages with plain white or flat backgrounds<\/td><\/tr><tr><td>Media player controls over video<\/td><td>Dozens of repeated cards in a grid<\/td><\/tr><\/tbody><\/table><\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If the design is mostly flat, a soft shadow style may suit it better. The <a href=\"https:\/\/refracttools.com\/neumorphism-generator\/\">neumorphism generator<\/a> and <a href=\"https:\/\/refracttools.com\/claymorphism-generator\/\">claymorphism generator<\/a> cover two alternatives that work without a busy backdrop.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Build your own glass panel<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The quickest way to find settings that suit your design is to try them over a real background. The <a href=\"https:\/\/refracttools.com\/glassmorphism-generator\/\">glassmorphism generator<\/a> lets you adjust blur, tint and highlight over three different backdrops, then copy the CSS with the <code>-webkit-<\/code> line already included. Start at 14px blur and 0.15 opacity, then tune from there.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How backdrop-filter creates frosted glass in CSS, the settings that look right, and the support, contrast and performance details most snippets leave out.<\/p>\n","protected":false},"author":1,"featured_media":33,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_refract_tool":"glassmorphism-generator","footnotes":""},"categories":[8],"tags":[20,12,4,11,13],"class_list":["post-18","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-css-techniques","tag-accessibility","tag-backdrop-filter","tag-css-generators","tag-glassmorphism","tag-ui-design"],"_links":{"self":[{"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/posts\/18","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":1,"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/posts\/18\/revisions"}],"predecessor-version":[{"id":28,"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/posts\/18\/revisions\/28"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/media\/33"}],"wp:attachment":[{"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/media?parent=18"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/categories?post=18"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/refracttools.com\/blog\/wp-json\/wp\/v2\/tags?post=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}