现代 CSS 高阶技巧:实现平滑内凹圆角的工程化实践
通过 数学计算 + CSS mask 复合遮罩 实现的真正几何内凹效果:
背景是一张图片,用来证明中间的凹陷是透明的。
完整代码:
app.js
import FormPage from "./pages/formPage";
import "./App.css";
const App = () => {return (<div className="box"><div className="block"></div></div>);
};export default App;
app.css
.box {background: url(../src/pages/img/10.jpg) 100%;height: 500px;
}.block {/* 增大圆角半径 */--r: 6px;/* 适当增加斜切长度 */--s: 69px;/* 微调角度使过渡更自然 */--a: 44deg;/* 更柔和的边缘过渡 */--_m: 0/calc(2*var(--r)) var(--r) no-repeat radial-gradient(50% 100% at bottom, #000 calc(100% - 0.8px), transparent);/* 自动计算的水平偏移 */--_d: (var(--s) + var(--r)) * cos(var(--a));width: 300px;height: 100px;background-color: antiquewhite;border-radius: 150px;mask:calc(50% + var(--_d)) var(--_m), calc(50% - var(--_d)) var(--_m),radial-gradient(var(--s) at 50% calc(-1*sin(var(--a))*var(--s)),transparent 100%, #000 calc(100% + 0.8px)) 0 calc(var(--r)*(1 - sin(var(--a)))),linear-gradient(90deg, #000 calc(50% - var(--_d)), transparent 0 calc(50% + var(--_d)), #000 0);mask-repeat: no-repeat;
}
🧠 整体思路
这段代码的核心思想是:
使用多个 mask 图层组合,通过 radial-gradient 和 linear-gradient 的叠加,形成一个“中间凹进去、边缘过渡柔和”的视觉效果。
它利用了 CSS 中的变量(--r
, --s
, --a
)、三角函数和 mask
属性,实现了动态可配置的内凹圆角效果。
📏 变量解析(CSS Custom Properties)
--r: 6px; /* 凹陷区域的半径(控制凹陷大小) */
--s: 69px; /* 圆弧的半径(控制凹陷的位置) */
--a: 44deg; /* 角度(用于三角函数计算) */
这些变量可以方便地调整最终的视觉效果。
🧮 计算变量(关键逻辑)
--_m
:定义一个遮罩图层(更柔和的边缘过渡)
--_m: 0 / calc(2*var(--r)) var(--r) no-repeatradial-gradient(50% 100% at bottom, #000 calc(100% - 0.8px), transparent);
- 创建一个宽度为
2 * --r
,高度为--r
的径向渐变。 - 渐变从底部开始,颜色从不透明到透明,形成一个边缘模糊的遮罩条带。
- 这个条带会在最终 mask 中作为“边缘柔化”层使用。
--_d
:水平偏移距离(基于三角函数自动计算)
--_d: (var(--s) + var(--r)) * cos(var(--a));
- 使用余弦函数计算出一个水平方向上的偏移值。
- 这个偏移值决定了凹陷区域在水平方向上的位置。
- 结合下面的 mask 设置,使凹陷区域对称分布在中心两侧。
🎭 Mask 图层详解(这是整个效果的关键)
mask:calc(50% + var(--_d)) var(--_m),calc(50% - var(--_d)) var(--_m),radial-gradient(var(--s) at 50% calc(-1*sin(var(--a))*var(--s)),transparent 100%, #000 calc(100% + 0.8px)) 0 calc(var(--r)*(1 - sin(var(--a)))),linear-gradient(90deg, #000 calc(50% - var(--_d)), transparent 0 calc(50% + var(--_d)), #000 0);
我们来逐行拆解这四个 mask 图层:
🔹 第一层 & 第二层(边缘柔化层)
calc(50% + var(--_d)) var(--_m),
calc(50% - var(--_d)) var(--_m)
- 这两个图层使用的是之前定义好的
--_m
遮罩条带。 - 分别放置在中心左右各偏移
--_d
的位置。 - 作用是柔和边缘,避免生硬的裁剪边界。
🔸 第三层(核心凹陷层)
radial-gradient(var(--s) at 50% calc(-1*sin(var(--a))*var(--s)),transparent 100%, #000 calc(100% + 0.8px))0 calc(var(--r)*(1 - sin(var(--a))));
- 创建一个以中心为圆心、向上偏移一定距离的径向渐变。
- 半径为
--s
,位于垂直方向上偏移sin(a) * s
。 - 渐变从透明到黑色,超出部分变为不透明。
- 最后定位在
0 calc(...)
,即垂直方向向下偏移一点,让凹陷区域更贴合整体形状。
✅ 这一层是形成“内凹”视觉的核心图层。
🔷 第四层(背景遮罩层)
linear-gradient(90deg, #000 calc(50% - var(--_d)), transparent 0 calc(50% + var(--_d)), #000 0)
-
水平方向的线性渐变:
- 左侧和右侧为黑色(显示区域)
- 中间一段为透明(隐藏区域)
-
作用是遮住中间的凹陷区域,只保留两边的内容。
🧪 最终效果总结
图层 | 作用 |
---|---|
第一、二层 | 边缘柔化处理(避免锯齿感) |
第三层 | 核心凹陷区域(模拟“内凹”形状) |
第四层 | 背景遮罩(只显示两边,中间隐藏) |
结合起来就形成了一个中间凹陷、边缘柔和、对称分布的视觉效果,非常适合用在按钮、卡片等需要轻微凹陷质感的 UI 元素中。
🖼️ 示例效果预览(文字描述)
想象一个椭圆形的盒子(border-radius: 150px
),原本是完整的圆形。但在它的正中央,有一个向上弯曲的凹陷区域,就像轻轻按下按钮时那种感觉,边缘还有轻微的阴影过渡。
这种效果常见于 macOS 的菜单栏按钮、iOS 控件等现代 UI 设计中。
🛠️ 如何调整?
你可以通过修改以下变量来实时调整视觉效果:
变量 | 默认值 | 调整建议 | 影响 |
---|---|---|---|
--r | 6px | 增大 → 凹陷更大 | 凹陷区域大小 |
--s | 69px | 增大 → 凹陷更深 | 凹陷位置与深度 |
--a | 44deg | 增大 → 凹陷更靠上 | 凹陷角度与位置 |
background-color | antiquewhite | 更浅/深色 | 整体对比度和质感 |
相关文章:

现代 CSS 高阶技巧:实现平滑内凹圆角的工程化实践
通过 数学计算 CSS mask 复合遮罩 实现的真正几何内凹效果: 背景是一张图片,用来证明中间的凹陷是透明的。 完整代码: app.js import FormPage from "./pages/formPage"; import "./App.css"; const App () > {re…...

【运维自动化-标准运维】如何实现在不同步骤间传递参数
当流程有多个步骤时,经常需要把前面某个个步骤处理的结果传递给下一个或后面的步骤使用(输出作为输入),这就是跨步骤传参的场景,标准运维通过特有的标记符号"<SOPS_VAR>key:value</SOPS_VAR> "来…...
STM32 UART通信实战指南:从原理到项目落地
STM32串口通信实战指南:从零开始手把手教你 前言:为什么串口这么重要? 在嵌入式开发中,串口就像设备的"嘴巴"和"耳朵"。无论是给单片机下达指令、读取传感器数据,还是让两个模块"对话"…...
基于stm32的 永磁同步电机二电平驱动控制系统设计
基于STM32的永磁同步电机(PMSM)二电平驱动控制系统设计方案: 系统架构 永磁同步电机二电平驱动控制系统主要由以下部分组成: STM32微控制器:作为控制核心,生成PWM信号并处理反馈数据。功率驱动电路:使用IGBT或MOSFET构成三相桥式逆变器,实现二电平驱动。电流采样电路:…...

[AI]主流大模型、ChatGPTDeepseek、国内免费大模型API服务推荐(支持LangChain.js集成)
主流大模型特色对比表 模型核心优势适用场景局限性DeepSeek- 数学/代码能力卓越(GSM8K准确率82.3%)1- 开源生态完善(支持医疗/金融领域)7- 成本极低(API价格仅为ChatGPT的2%-3%)5科研辅助、代码开发、数据…...

手机IP地址更换的影响与操作指南
在移动互联网时代,IP地址如同手机的“网络身份证”,其变更可能对上网体验、隐私安全及服务访问产生连锁反应。无论是为了绕过地域限制、保护隐私,还是解决网络冲突,了解IP更换的影响与正确操作方法都至关重要。本文将系统分析影响…...
iOS 响应者链详解
响应者链是 iOS 中处理用户事件(如触摸、摇动、按键)的核心机制,由一系列 UIResponder 对象构成,决定了事件传递的路径和优先级。以下是其核心机制与使用场景的详细解析: 一、响应者链的组成 1. 响应者对象࿰…...
Flink Table API 编程入门实践
Flink Table API 编程入门实践 前言 Apache Flink 是目前大数据实时计算领域的明星产品,Flink Table API 则为开发者提供了声明式、类似 SQL 的数据处理能力,兼具 SQL 的易用性与编程 API 的灵活性。本文将带你快速了解 Flink Table API 的基本用法&am…...

MongoDB 安全机制详解:全方位保障数据安全
在当今数据驱动的时代,数据库安全至关重要。MongoDB 作为一款流行的 NoSQL 数据库,广泛应用于 Web 应用、大数据分析和物联网等领域。然而,随着 MongoDB 的普及,其安全性也面临诸多挑战,如未授权访问、数据泄露和注入攻…...
Teensy LC 一款由 PJRC 公司开发的高性能 32 位微控制器开发板
Teensy LC 是一款由 PJRC 公司开发的高性能 32 位微控制器开发板,具有以下特点: 硬件配置 核心处理器 :采用 MKL26Z64VFT4 ARM Cortex-M0 处理器,运行频率为 48MHz,相较于传统的 8 位 AVR 处理器,速度更快…...
MicroPython 开发ESP32应用教程 之 线程介绍及实例分析
MicroPython ESP32 线程(Thread)基础 MicroPython 在 ESP32 上支持线程(Thread)功能,通过 _thread 模块实现。线程允许程序并发执行多个任务,适合处理需要同时运行的场景,例如传感器数据采集和…...
鸿蒙5开发宝藏案例分享---一多断点开发实践
🌟【鸿蒙开发实战进阶】六大核心案例深度拆解,带你玩转多端适配! 📐 案例4:动态网格布局(电商商品列表) 应用场景:手机/平板商品展示差异 痛点分析:手机单列→平板多列&…...

嵌入式学习之系统编程(六)线程
目录 一、线程 (一)线程概念 (二)特征 (三)优缺点 二、线程与进程的区别(面问) 三、多线程程序设计步骤 四、线程的创建(相关函数) 1、pthread_create…...
分布式常见概念
分布式常见概念 反向代理正向代理 vs 反向代理(对比理解名称)正向代理示意(“我去帮你拿数据”)反向代理示意(“你找我,我替你联系内部服务器”)为什么叫“反向”? API网关一、为什么…...
数据库的事务(Transaction)
在数据库中,事务(Transaction) 是保证数据操作一致性和完整性的核心机制。它通过一组原子性的操作单元,确保所有操作要么全部成功(提交),要么全部失败(回滚)。以下是数据…...

大语言模型 提示词的少样本案例的 演示选择与排序新突破
提示词中 演示示例的选择与排序 这篇论文《Rapid Selection and Ordering of In-Context Demonstrations via Prompt Embedding Clustering》聚焦于提升大语言模型(LLMs)在自适应上下文学习(ICL)场景中演示示例的选择与排序效率 一、论文要解决的问题 在上下文学习(ICL)…...

【算法篇】二分查找算法:基础篇
题目链接: 34.在排序数组中查找元素的第一个和最后一个位置 题目描述: 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target,返…...
Qtc++开发遇到的问题-按钮点击不管用?
我在设计自己的控件的时候,遇到了按钮点击不管用的问题,而且是有的自定义控件不管用,有的管用,有的一开始管用,多点几次就不管用了, 它是这样的,一个lineEdit和位于两侧的按钮,分别…...

重磅发布 | 复旦533页《大规模语言模型:从理论到实践(第2版)》(免费下载)
在人工智能浪潮席卷全球的今天,大语言模型正以前所未有的速度推动着科技进步和产业变革。从 ChatGPT 到各类行业应用,LLM 不仅重塑了人机交互的方式,更成为推动学术研究与产业创新的关键技术。 面对这一飞速演进的技术体系,如何系…...

智能体赋能效率,企业知识库沉淀价值:UMI企业智脑的双轮驱动!
智能体企业知识库:UMI企业智脑的核心功能与价值 在人工智能技术飞速发展的今天,企业智能化转型已经成为不可逆转的趋势。作为企业级AI智能体开发平台的佼佼者,优秘智能推出的UMI企业智脑,以其强大的智能体开发能力和全面的企业知…...
STM32CubeMX,arm-none-eabi-gcc简单试用
在windows下,为stm32系列单片机编程,keil有了免费的试用版,有很多开发板示例,给学习单片机编程带来很大的方便。 STM32CubeMX提供了stm32单片机的功能设置,在输出方式上给出了几种方式,有mdk(k…...
Spring AI(一)
Spring AI 官网 Spring AI 是一个用于 AI 工程的应用程序框架。其目标是将 Spring 生态系统设计原则(如可移植性和模块化设计)应用于 AI 领域,并将使用 POJO 作为应用程序的构建块推广到 AI 领域。 Spring AI 的核心是解决了 AI 集成的根本挑战:将您的企业数据和 API 与 A…...
Nacos适配GaussDB超详细部署流程
1部署openGauss 官方文档下载 https://support.huaweicloud.com/download_gaussdb/index.html 社区地址 安装包下载 本文主要是以部署轻量级为主要教程 1.1系统环境准备 操作系统选择 系统AARCH64X86-64openEuler√√CentOS7√Docker√√1.2软硬件安装环境 版本轻量版(单…...
vue-pure-admin动态路由无Layout实现解决方案
背景: 最近在使用vue-pure-admin开发后台项目的时候发现作者并没有动态路由的全屏无Layout实现方案。查询作者路由发现,作者只做了静态路由的无Layout方案,其它动态路由,作者在做整合的时候,都放进了 \ 下面的子路由&…...

vue项目 build时@vue-office/docx报错
我在打包vue项目时, 开始用的npm run build和cnpm run build,总是提示 vue-office/docx 错误,尝试过用cnpm重新安装node_modules几次都没用。类似下面的提示一直有。 Error: [commonjs--resolver] Failed to resolve entry for package "…...
卓力达蚀刻工艺:精密制造的跨行业赋能者
引言 蚀刻技术作为现代精密制造的核心工艺之一,通过化学或物理方法对金属材料进行选择性去除,实现微米级复杂结构的加工。南通卓力达凭借20余年技术积淀与全产业链布局,成为全球高端制造领域的重要支撑力量。本文将从蚀刻技术的多领域应用与…...
【大模型面试每日一题】Day 30:解释一下 FlashAttention 技术,并对比其与传统注意力在显存效率和计算性能上的差异。
【大模型面试每日一题】Day 30:解释一下 FlashAttention 技术,并对比其与传统注意力在显存效率和计算性能上的差异。 📌 题目重现 🌟🌟 面试官:解释一下 FlashAttention 技术,并对比其与传统注…...

#RabbitMQ# 消息队列入门
目录 一 MQ技术选型 1 运行rabbitmq 2 基本介绍 3 快速入门 1 交换机负责路由消息给队列 2 数据隔离 二 Java客户端 1 快速入门 2 WorkQueue 3 FanOut交换机 4 Direct交换机 5 Topic交换机 *6 声明队列交换机 1 在配置类当中声明 2 使用注解的方式指定 7 消息转…...
在promise中,多个then如何传值
在 JavaScript 中,Promise 的多个 .then() 是链式调用的,值可以通过返回值的方式,在多个 .then() 之间传递。这是 Promise 链式调用的核心机制。 基本原理:每个 then 接收上一个 then 的返回值 new Promise((resolve, reject) &g…...
TCP 三次握手过程详解
TCP 三次握手过程详解 一、TCP握手基础概念 1.1 什么是TCP握手 TCP三次握手是传输控制协议(Transmission Control Protocol)在建立连接时的标准过程,目的是确保通信双方具备可靠的双向通信能力。 关键结论:三次握手的本质是通过序列号同步和能力协商建立可靠的逻辑连接。 …...