更新记录

3.0.0(2026-05-29)

增加一个动图预览

2.0.0(2026-05-29)

初始化


平台兼容性

uni-app x(5.07)

Chrome Chrome插件版本 Safari Android Android插件版本 iOS iOS插件版本 鸿蒙 鸿蒙插件版本 微信小程序
3.0.0 - 12.0 3.0.0 18 3.0.0 Next 3.0.0 ×

其他

多语言 暗黑模式 宽屏模式
×

kelp-blur-view

跨平台原生毛玻璃组件,uni-app x 全端可用。

Android / 鸿蒙端通过原生组件实现实时高斯模糊,iOS / H5 通过 CSS backdrop-filter 走系统级 GPU 模糊。组件本身只在 Android / 鸿蒙生效,iOS / H5 直接用 CSS 即可——完整跨端写法见下方"跨端写法"章节。

一句话定位

平台 实现
Android ≥ 5 com.eightbitlab:blurview + RenderScriptBlur,逐帧抓取背景做模糊
HarmonyOS ArkUI BuilderNode + backdropBlur,系统级 GPU 模糊
iOS 直接用 CSS backdrop-filter,WebKit 调用底层 UIVisualEffectView
H5 直接用 CSS backdrop-filter,主流浏览器原生支持

快速上手

<template>
    <view class="container">
        <!-- 你的页面内容 -->
        <image class="bg" src="/static/bg.png" />

        <!-- 贴底毛玻璃栏 -->
        <view class="bottom-bar">
            <kelp-blur-view class="blur-bg" :blurRadius="20" overlayColor="#80FFFFFF" />
            <text class="title">毛玻璃效果</text>
        </view>
    </view>
</template>

<style>
.bottom-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 80px;
}

.blur-bg {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
}

.title {
    position: relative;
    z-index: 2;
    color: #111;
}
</style>

属性

属性 类型 默认值 说明
blurRadius number 20 模糊半径,数值越大模糊越强。Android 建议 10-25,鸿蒙建议 8-20。
overlayColor string #80FFFFFF 模糊层之上叠加的颜色蒙版,8 位十六进制(前两位是 alpha)。一般用半透明白色让模糊看起来更"奶白"。透明传 #00000000

属性可响应式更新,改 blurRadiusoverlayColor 会立即生效。

平台支持矩阵

平台 用本组件 备注
App-Android minSdkVersion ≥ 21(Android 5.0)。低于此版本会降级为半透明色块,不报错。
App-HarmonyOS HarmonyOS Next 5.0+。
App-iOS 否(用 CSS) iOS WebKit 原生支持 backdrop-filter,无须组件,见"iOS / H5 写法"章节。
H5 否(用 CSS) 主流移动浏览器(Safari / Chrome 76+)支持 backdrop-filter,见"iOS / H5 写法"。
小程序 uni-app x 当前未覆盖小程序端。
Vue 2 仅 uni-app x(Vue 3 + UTS)。

iOS / H5 写法

iOS 和 H5 上不需要本组件,CSS 一句话就够,且性能比原生组件更好。任意位置都能用——贴底栏、悬浮卡、对话框、模态背景都是同一套写法:

<template>
    <view class="glass-bar">
        <text class="title">毛玻璃顶栏</text>
    </view>
</template>

<style>
.glass-bar {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 88px;
    background-color: rgba(255, 255, 255, 0.55);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
}
</style>

调参建议:

  • blur(N) 数值越大模糊越强,iOS 一般 15-25 看着舒服。
  • background-color 的 alpha 控制蒙版浓度,0.4-0.6 是常用区间;数值越高越接近"奶白",越低越透。
  • -webkit-backdrop-filter 不能省,部分旧版 WebKit 只认带前缀的写法。

跨端统一写法(推荐)

如果项目要同时跑 iOS / H5 / Android / 鸿蒙,用条件编译让 CSS 和 <kelp-blur-view> 各管一端:

<template>
    <view class="bar">
        <!-- iOS / H5: CSS backdrop-filter -->
        <!-- #ifdef APP-IOS || H5 -->
        <view class="glass-css"></view>
        <!-- #endif -->

        <!-- Android / 鸿蒙: 原生 blur-view -->
        <!-- #ifdef APP-ANDROID || APP-HARMONY -->
        <kelp-blur-view class="glass-native" :blurRadius="20" overlayColor="#80FFFFFF" />
        <!-- #endif -->

        <!-- 你的内容 -->
    </view>
</template>

<style>
/* #ifdef APP-IOS || H5 */
.glass-css {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background-color: rgba(255, 255, 255, 0.55);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    z-index: 1;
}
/* #endif */

/* #ifdef APP-ANDROID || APP-HARMONY */
.glass-native {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    z-index: 1;
}
/* #endif */
</style>

最佳实践

场景 1:悬浮卡片

<view class="card">
    <kelp-blur-view class="card-bg" :blurRadius="15" overlayColor="#A0FFFFFF" />
    <view class="card-content">
        <text>卡片内容</text>
    </view>
</view>

<style>
.card {
    position: relative;
    width: 300px;
    height: 200px;
    border-radius: 16px;
    overflow: hidden;
}
.card-bg {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
}
.card-content {
    position: relative;
    z-index: 2;
    padding: 20px;
}
</style>

场景 2:贴底 TabBar(进阶)

这种场景要同时处理"手势小白条安全区"和"模糊覆盖完整高度",有踩坑,详见下面的踩坑指南。

踩坑指南

坑 1: 设备有手势小白条,导致小白条区域高斯模糊失效?(仅oppo和vivo中出现)

现象:<kelp-blur-view>position: absolute; top/left/right/bottom: 0 撑满父容器,父容器有 padding 或包含其它非 absolute 子元素时,模糊只覆盖到非 absolute 子元素的总和高度,padding 区域和兄弟 view 区域透出底部页面背景。

根因:<kelp-blur-view> 在 Android/鸿蒙 是原生 View,uni-app x 把 absolute 撑满翻译成原生布局时,实际测量参考的是非 absolute 子元素的内容总和(content-box),不包含 padding,也不会跟着兄弟 view 增高。

解法:<kelp-blur-view> 显式 style="height: ...",绕开 absolute 撑满的测量逻辑。

<template>
    <view class="bar">
        <kelp-blur-view class="bg" :style="blurStyle" :blurRadius="20" overlayColor="#80FFFFFF" />
        <view class="content"><!-- 50px 高 --></view>
        <view class="placeholder" :style="placeholderStyle"><!-- 安全区,16px 高 --></view>
    </view>
</template>

<script setup lang="uts">
    const safeBottom = ref<number>(16)

    const blurStyle = computed<UTSJSONObject>(() : UTSJSONObject => {
        return { height: (50 + safeBottom.value) + 'px' } as UTSJSONObject
    })

    const placeholderStyle = computed<UTSJSONObject>(() : UTSJSONObject => {
        return { height: safeBottom.value + 'px' } as UTSJSONObject
    })
</script>

<style>
.bg {
    position: absolute;
    top: 0; left: 0; right: 0;
    /* 不要写 bottom: 0 或 height: 100%,改用上面 :style 显式高度 */
    z-index: 1;
}
</style>

坑 2:贴底毛玻璃栏与手势小白条适配

现象:Android 全面屏开手势导航后,小白条会盖住 TabBar 一部分;不处理就显得"按钮被切了一半"。

解法要点:

  1. uni.getWindowInfo().safeAreaInsets.bottom 拿手势条高度,加到容器高度里(参考坑 1 的写法)
  2. 冷启动时 safeAreaInsets.bottom 可能为 0,需要 fallback 算法。三个候选值,有哪个用哪个:
    • safeAreaInsets.bottom(优先)
    • screenHeight - safeArea.bottom
    • screenHeight - windowHeight(注意:不要再减 statusBarHeight,部分机型 windowHeight 已扣过)
function resolveBottomInset() : number {
    const info = uni.getWindowInfo()
    if (info.safeAreaInsets.bottom > 0) return info.safeAreaInsets.bottom
    if (info.screenHeight > info.safeArea.bottom && info.safeArea.bottom > 0) {
        return info.screenHeight - info.safeArea.bottom
    }
    if (info.screenHeight > info.windowHeight) {
        return info.screenHeight - info.windowHeight
    }
    return 0
}

坑 3:鸿蒙 ArkUI 自动避让,手动加会变双倍

现象:鸿蒙端按"坑 2"的算法直接给容器加全量手势条高度,实际看到的留白是双倍。

根因:HarmonyOS ArkUI 对 fixed 容器有默认的底部安全区避让机制,会自动顶起一半,我们再加全量就重了。

解法:鸿蒙端用 Math.round(raw / 2),Android 用全量。

let raw = resolveBottomInset()

// #ifdef APP-HARMONY
return Math.round(raw / 2)
// #endif

// #ifdef APP-ANDROID
return raw
// #endif

FAQ

Q: Android 上模糊看起来颗粒粗,iOS 细腻很多?

A: RenderScriptBlur 是采样降级 + 高斯模糊,半径越大颗粒越明显。把 blurRadius 调到 12-18 一般能平衡性能和效果;如果项目允许,可以把 overlayColor 透明度调高(如 #B0FFFFFF),靠蒙版掩盖颗粒感。

Q: 鸿蒙端最低系统要求?

A: HarmonyOS Next 5.0+。HarmonyOS 4.x 的旧版 ArkUI 不支持 backdropBlur,组件不会报错但模糊不生效。

Q: iOS 为什么不用这个组件?

A: iOS WebKit 原生支持 backdrop-filter,底层调用的是 UIVisualEffectView,本身就是系统级 GPU 模糊,效果和性能都比再封一层原生组件好。组件层不强行抽象 iOS,各端用最优解。具体写法见 "iOS / H5 写法" 章节。

Q: 在 slot 内放内容会怎样?

A: slot 内容会渲染在 blur-view 的 native-view 内部,但不推荐——native-view 内的子元素布局/事件会受平台原生差异影响,排查问题困难。建议把 blur-view 作为 absolute 背景层,内容放外层兄弟节点,通过 z-index 叠加。

更新日志

2.0.0

  • 鸿蒙端原生支持(BuilderNode + backdropBlur)
  • Android 端切换到 com.eightbitlab:blurview Maven 库,渲染稳定性提升
  • 标准模式重写为 native-view + UTS,API 简化

1.x

  • 仅 Android,基于自研 RenderScript 实现

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。