【CSS进阶】毛玻璃效果与代码解析

目录

一、毛玻璃特效效果

二、毛玻璃特效代码

1、使用 filter: blur();

bash 复制代码
<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>毛玻璃卡片 · 修正版</title>
  <style>
    html {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }

    body {
      background: url(./image.png) 0 / cover fixed;
      width: 100%;
      padding-top: 30px;
      margin: 0;
    }

    main {
      width: 800px;
      height: 300px;
      padding: 20px;
      border-radius: 10px;
      position: relative;
      background: hsla(0, 0%, 0%, 0.3);
      overflow: hidden;
      color: #fff;
      margin: auto;
      margin-bottom: 30px;
      transition: all 0.2s ease-in-out;
    }

    main:hover {
      box-shadow: 0 0 0 2px rgba(255,255,255,0.5), 0 8px 16px rgba(0,0,0,0.2);
    }

    main::before {
      content: "";
      background: url(./image.png) 0 / cover fixed;
      position: absolute;
      top: -30px;   
      right: -30px;
      bottom: -30px;
      left: -30px;
      filter: blur(20px);
      z-index: -1;
    }
  </style>
</head>
<body>
  <!-- 卡片 1 -->
  <main>
    <div class="card-content">
      <h1>Welcome to my website</h1>
      <p>
        This is a paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing
        elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet,
        adipiscing nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
      </p>
      <a href="https://blog.csdn.net/weixin_46589442/article/details/157837683">
        更多文章:https://blog.csdn.net/weixin_46589442/article/details/157837683
      </a>
    </div>
  </main>

  <!-- 卡片 2(内容与卡片1相同) -->
  <main>
    <div class="card-content">
      <h1>Welcome to my website</h1>
      <p>
        This is a paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing
        elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet,
        adipiscing nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
      </p>
      <a href="https://blog.csdn.net/weixin_46589442/article/details/157837683">
        更多文章:https://blog.csdn.net/weixin_46589442/article/details/157837683
      </a>
    </div>
  </main>

  <!-- 卡片 3(内容与卡片1相同) -->
  <main>
    <div class="card-content">
      <h1>Welcome to my website</h1>
      <p>
        This is a paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing
        elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet,
        adipiscing nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
      </p>
      <a href="https://blog.csdn.net/weixin_46589442/article/details/157837683">
        更多文章:https://blog.csdn.net/weixin_46589442/article/details/157837683
      </a>
    </div>
  </main>
</body>
</html>

2、使用backdrop-filter: blur()

bash 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            font-size: 16px;
            line-height: 1.5;
            margin: 0;
            padding: 0;
            background: url(./image.png) no-repeat;
            background-size: 100%;
        }
        .container {
            width: 50%;
            margin: 30px auto;
            padding: 20px;
            color: #fff;
            
        }
        a{
            color: #fff;
        }
        .gas {
            background: rgb(0, 0, 0,0.3); /* 半透明背景 */
            backdrop-filter: blur(10px); /* 模糊效果 */
            -webkit-backdrop-filter: blur(10px); /* Safari兼容 */
            border-radius: 15px; /* 圆角 */
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* 阴影效果 */
            transition: all 0.2s ease-in-out;
        }

        .gas:hover {
            transform: scale(1.01); /* 放大 */
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); /* 阴影效果 */
        }
    </style>
</head>
<body>
    <main class="container gas">
        <h1>Welcome to my website</h1>
        <p>This is a paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.
            <br>
            <br>
            Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.
            <br>
            <br>
            Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.
        </p>
        <a href="https://blog.csdn.net/weixin_46589442/article/details/157837683?spm=1011.2415.3001.5331">更多文章:https://blog.csdn.net/weixin_46589442/article/details/157837683?spm=1011.2415.3001.5331</p>
    </main>
</body>
</html>

三、 使用filter: blur()代码详解

1、先搭建没特效的卡片

(1)body放一个全局背景

(2)写三张小卡片

bash 复制代码
<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>毛玻璃卡片 · 修正版</title>
  <style>
    html {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }

    body {
      background: url(./image.png) 0 / cover fixed;
      width: 100%;
      padding-top: 30px;
      margin: 0;
    }

    main {
      width: 800px;
      height: 300px;
      padding: 20px;
      border-radius: 10px;
      position: relative;
      background: hsla(0, 0%, 0%, 0.3);
      overflow: hidden;
      color: #fff;
      margin: auto;
      margin-bottom: 30px;
      transition: all 0.2s ease-in-out;
    }

    main:hover {
      box-shadow: 0 0 0 2px rgba(255,255,255,0.5), 0 8px 16px rgba(0,0,0,0.2);
    }
  </style>
</head>
<body>
  <!-- 卡片 1 -->
  <main>
    <div class="card-content">
      <h1>Welcome to my website</h1>
      <p>
        This is a paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing
        elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet,
        adipiscing nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
      </p>
      <a href="https://blog.csdn.net/weixin_46589442/article/details/157837683">
        更多文章:https://blog.csdn.net/weixin_46589442/article/details/157837683
      </a>
    </div>
  </main>

  <!-- 卡片 2(内容与卡片1相同) -->
  <main>
    <div class="card-content">
      <h1>Welcome to my website</h1>
      <p>
        This is a paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing
        elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet,
        adipiscing nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
      </p>
      <a href="https://blog.csdn.net/weixin_46589442/article/details/157837683">
        更多文章:https://blog.csdn.net/weixin_46589442/article/details/157837683
      </a>
    </div>
  </main>

  <!-- 卡片 3(内容与卡片1相同) -->
  <main>
    <div class="card-content">
      <h1>Welcome to my website</h1>
      <p>
        This is a paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing
        elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet,
        adipiscing nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
        <br /><br />
        Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing
        nec, ultricies sed, dolor.
      </p>
      <a href="https://blog.csdn.net/weixin_46589442/article/details/157837683">
        更多文章:https://blog.csdn.net/weixin_46589442/article/details/157837683
      </a>
    </div>
  </main>
</body>
</html>

2、加一个有毛玻璃效果的元素

核心公式:固定背景 + 伪元素 + 模糊 + 负边距 + 溢出隐藏

(1)main::before:在main前加一个空元素,背景是

(2)设置这个空元素和main大小一样

(3)设置模糊效果filter: blur()

(4)优化=>模糊效果会向外扩散,如果刚好被容器裁掉,就会产生边缘硬线。解决方法:扩大伪元素范围,使模糊区域完整

bash 复制代码
 main::before {
      content: "";
      background: url(./image.png) 0 / cover fixed;
      position: absolute;
      top: -30px;   
      right: -30px;
      bottom: -30px;
      left: -30px;
      filter: blur(20px);
      z-index: -1;
    }

注:background: url(./image.png) 0 / cover fixed;等同于下面代码

bash 复制代码
	    background-image: url(./image.png);
        background-position: 0 50%;   
        background-size: cover;
        background-attachment: fixed;
        background-repeat: repeat;
        background-origin: padding-box;
        background-clip: border-box;

大白话通俗解释:

网页->海报

卡片->玻璃板

毛玻璃元素->半透明磨砂膜

把半透明磨砂膜贴在玻璃板的背面

✨ 为什么多块玻璃板同时看画报,背景还是连贯的?

因为所有玻璃板背面的贴膜,都是从墙上同一个固定位置"抓取"画报图案。

第一块玻璃放在墙的左上角,贴膜抓取左上角的画面。 第二块玻璃放在墙的中间,贴膜仍然抓取左上角的画面------等等,那不就错位了吗?

不会错位! 因为我们特意让贴膜抓取的不是玻璃板正下方的画面,而是墙上固定坐标的画面

但这样每块玻璃看到的模糊画面都是墙上固定位置的图案,而不是自己正下方的图案,背景不就乱了吗?

不,这正是精妙之处: 我们让每块玻璃板背面的贴膜抓取的画面位置 = 玻璃板自身在墙上的位置对应的画面。

怎么做到的?------贴膜的固定背景配合玻璃板的位置自动实现了这一点

更简单的说法:

1、每张贴膜都是一张半透明的、固定的"窗户" ,永远只能看到墙上某一个固定区域。

2、当你把玻璃板(带贴膜)移到墙上某个位置时,贴膜恰好透过玻璃板,让你看到墙上这个位置正后方的画报。

因为贴膜是固定在墙上的,不是固定在玻璃板上的!

这听起来矛盾:贴膜贴在玻璃板背面,怎么会固定在墙上?

代码的魔法就在这里:background-attachment: fixed 让贴膜上的背景图案相对于墙固定,而不是相对于玻璃板固定。

所以玻璃板移动时,贴膜虽然贴在玻璃板上,但它显示的图案却始终是墙上固定坐标的那一块

当玻璃板正好盖住那个坐标时,图案就完美重合;如果玻璃板盖住别的地方,贴膜还是会显示那个固定坐标的图案------那样就会错位。

但我们所有玻璃板都盖在墙的不同位置啊!那岂不是每块玻璃看到的模糊图案都是墙上同一块区域?

------是的,如果没有额外措施,就会这样。

解决方案:

让每块玻璃板的贴膜抓取的固定坐标,等于这块玻璃板自己所在的位置。

怎么做到?------不给贴膜写死固定坐标,而是让每个玻璃板的贴膜都相对于自身包含块定位。 在代码里,main::before 的
position: absolute 是相对于 main 定位的,所以每块玻璃板的贴膜位置是跟随玻璃板的。 但
background-attachment: fixed 又让贴膜上的背景图案相对于视口固定。 两者结合的效果:

贴膜的盒子随着玻璃板移动(因为绝对定位相对于父容器)。 但贴膜盒子里的背景图案不随盒子移动,固定在视口。
因此: 当玻璃板在墙上某个位置时,贴膜盒子正好覆盖玻璃板区域 ,它显示的固定背景恰好是视口中这个区域下方的画报内容。

这正是我们希望的效果:每块玻璃看到的模糊图案,就是它自己正后方那块画报

因为背景是固定的,所以无论页面怎么滚动,每块玻璃的贴膜盒子在屏幕上的位置变化时,它显示的背景也随之变化------始终显示自己背后的画面。

这样,多块玻璃板并排放置时,它们各自显示自己背后的模糊画面,背景自然就是连贯的。

四、使用backdrop-filter: blur()代码详解

直接用就可以,想让哪个元素背景变成毛玻璃特效就加到哪个元素上,非常简单

五、两者区别

backdrop-filter与我们熟悉的filter属性类似,都能应用模糊、色调等滤镜效果,但两者的作用对象截然不同:

filter:作用于元素自身及其所有子元素(对元素内部内容生效)。
backdrop-filter:仅作用于元素背后的内容(即元素下方的背景、其他元素等),元素自身内容不受影响。

这样看起来其实backdrop-filter更简单也更好用,但是他的兼容性没filter的好

相关推荐
何中应1 小时前
使用Jenkins部署前端项目(Vue)
前端·vue.js·jenkins
西门吹-禅1 小时前
node js 性能处理
开发语言·javascript·ecmascript
3秒一个大2 小时前
JWT 登录:原理剖析与实战应用
前端·http·代码规范
一只大侠的侠2 小时前
React Native for OpenHarmony:日期范围选择器实现
javascript·react native·react.js
NEXT062 小时前
2026 技术风向:为什么在 AI 时代,PostgreSQL 彻底成为了全栈工程师的首选数据库
前端·数据库·ai编程
NEXT062 小时前
拒绝“盲盒式”编程:规范驱动开发(SDD)如何重塑 AI 交付
前端·人工智能·markdown
@大迁世界2 小时前
仅用 CSS 实现元素圆形排列的方法
前端·css
一只大侠的侠3 小时前
React Native for OpenHarmony:DatePicker 日期选择器组件详解
javascript·react native·react.js
JosieBook3 小时前
【Vue】15 Vue技术——Vue计算属性简写:提升代码简洁性的高效实践
前端·javascript·vue.js