当前位置: 首页 > news >正文

移动端卡片边框怎么做高级?我用 CSS 实现了设计师的刁钻要求

一个让产品经理和设计师都满意的卡片边框方案

📖 前言

上周设计突然甩过来一张图,问我能不能不切图做出这种效果?

我蒙了一下第一反应感觉可以,无非就是常规的伪类+渐变。但尝试了一下发现两个致命问题:

1、border-image支持渐变但不支持每条边自定义设置;8

2、使用伪类可以解决线的问题但是不能解决圆角问题;

忙乎半天又问了问ai感觉还是实现起来不容易,但随后产品过来又是那老一套。拿着别人家的产品看人家这个如何好看,如何优雅,巴拉巴拉。大有一种:

别人能做,你做不了。

这是不能接受的,于是又潜心研究了下,有了最后的效果。

🎯 需求拆解

先梳理一下具体需求:

需求描述
位置卡片左下角 L 形(左边 + 底边)
渐变左下角颜色最深,向两端渐淡
粗细视觉上 1px
长度左边和底边长度大致相等
圆角适配卡片 20px 圆角
性能纯 CSS,无图片,无 SVG

看起来简单,做起来全是坑。

🧪 方案探索

方案一:两个伪元素分别画线

最直观的想法:用::before画底部线,::after画左边线。

scss

.card { &::before { // 底部线 background: linear-gradient(90deg, gold, transparent); } &::after { // 左边线 background: linear-gradient(0deg, gold, transparent); } }

问题:两条线在圆角处有接缝,怎么都对不齐。调整了半天,还是能看到明显的拼接痕迹。

结论:放弃,圆角处无法完美衔接。

方案二:SVG 路径描边

SVG 可以精确控制路径和圆角,效果确实完美。

问题

  • 需要额外 HTML 结构
  • 移动端多一个网络请求或内联代码
  • 响应式适配需要额外处理

结论:能用,但不够优雅,性能也不够极致。

方案三:border-image + 渐变

scss

border-image: radial-gradient(circle at bottom left, gold, transparent) 1;

问题border-image会覆盖四边,无法只控制左下角。

结论:放弃。

方案四:radial-gradient + mask(最终方案)

经过多次尝试,我发现径向渐变的圆心在左下角时,渐变会自然地向左和向上扩散,形成完美的 L 形。

配合mask组合,可以精确控制只显示边框区域,而不是整个渐变圆。

完美解决所有问题!

💻 最终代码

以下是基于vue2的一个组件CornerGradientCard,开箱即用。

但注意基于他的点击事件要使用click.native!!!

<template> <div :class="`gradient-wrapper ${type} `" :style="wrapperStyle" > <div class="gradient-wrapper__content" :style="{ borderRadius: radiusRem }" > <slot></slot> </div> </div> </template> <script> /** 与 postcss.config.js 中非 vant 资源的 rootValue(75) 一致,设计稿 px → rem */ const POSTCSS_ROOT_VALUE = 75 function pxToRem(px) { const n = Number(px) if (Number.isNaN(n)) return '0rem' return `${parseFloat((n / POSTCSS_ROOT_VALUE).toFixed(10))}rem` } export default { props: { type: { default: '', type: String }, radius: { default: 12, type: Number }, marginBottom: { default: 14, type: Number } }, computed: { radiusRem() { return pxToRem(this.radius) }, wrapperStyle() { const r = this.radiusRem return { borderRadius: r, marginBottom: pxToRem(this.marginBottom), '--corner-radius': r } } } } </script> <style lang="scss" scoped> $gradient-first-percent: 4%; // 第一个实色节点百分比 $gradient-second-percent: 10%; // 第二个半透明节点百分比 $gradient-transparent-percent: 30%; // 透明节点百分比 .gradient-wrapper { width: 100%; position: relative; padding: 0 0 1px 1px; box-sizing: border-box; background-color: #fff; overflow: hidden; -webkit-backface-visibility: hidden; backface-visibility: hidden; &__content { width: 100%; position: relative; z-index: 3; margin: 0 0 1px 1px; box-sizing: border-box; overflow: hidden; background-color: transparent; } // 渐变边框线(核心) &::after { content: ''; position: absolute; z-index: 2; bottom: 0; left: 0; width: 100%; height: 100%; border-radius: var(--corner-radius); pointer-events: none; mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask-composite: exclude; -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; padding: 1px; } // 渐变底色(光晕效果) &::before { content: ''; position: absolute; z-index: 1; bottom: 1px; left: 1px; width: 143px; height: 73px; border-radius: var(--corner-radius); filter: blur(10px); pointer-events: none; } &.WX { &::after { background: radial-gradient( circle at bottom left, #B6E2C8 $gradient-first-percent, #DFF7EA $gradient-second-percent, transparent $gradient-transparent-percent ); } &::before { background: radial-gradient( 83% 83% at 31% 52%, #F0FBF5 0%, rgba(239,255,246,0) 100%); } } } </style>

<CornerGradientCard v-for="(item, index) in infoData" :key="item.id" :id="item.id" :type="item.type" @click.native="clickItem(item)" > <!-- 卡片内容 --> </CornerGradientCard>

🎨 参数调节指南

参数位置作用移动端建议
padding: 1px.wrapper边框粗细保持 1px
4% / 10% / 30%径向渐变边框长度根据卡片大小调整
blur(10px)光晕柔和度移动端 8-12px 较佳
border-radius全局圆角与设计稿保持一致

当然,基于此样式还可以可发出各种变种,例如将渐变等放到常规的右上角,替代常规的卡片标签展示样式。

http://www.jsqmd.com/news/604738/

相关文章:

  • 实战应用:基于快马平台快速开发集成快速排序算法的学生成绩排名系统
  • 提升安全测试效率,用快马生成kali自动化助手实现批量扫描与智能报告
  • 前瞻2026:贵州橡塑管市场专业厂商甄选与廊坊驰平实力测评 - 2026年企业推荐榜
  • MySQL InnoDB核心参数深度优化/性能调优
  • 保姆级教程:在Windows/Mac上,用ModelScope和FastAPI给Qwen3-0.6B模型做个本地聊天接口
  • 20254112邓新锐 2025-2026-2 《Python程序设计》实验2报告
  • FXOS8700CQ_ISP:面向工业嵌入式的六轴传感ISP驱动框架
  • 别再死记硬背!用孙楠老师的《现代模拟集成电路设计》轻松搞定CMOS差分放大器设计
  • 别再手动抠图了!用HRNet+Mask Guidance实现交互式分割,5分钟搞定复杂背景
  • 利用快马平台快速原型:模拟Windows驱动ahflt.sys的运行机制
  • 2026届毕业生推荐的AI写作方案横评
  • 从线性到对数:用Python透视数据缩放的艺术
  • CloudCompare点云处理实战指南(一):从基础操作到高程赋色
  • 读懂公司第三篇-资产负债表解读 - 智慧园区
  • 深入解析c10::Half与float类型不匹配问题及高效解决方案
  • 嵌入式C程序高效编写与优化实践
  • Qwen3-8B入门首选:Ollama部署全流程,高性价比AI模型亲测好用
  • 2026箱梁切割技术全解析:高速防撞墙切割/剪力墙切割/地面切割/墙体切割开门洞/护栏切割/支撑梁切割/选择指南 - 优质品牌商家
  • OpenSSH安全升级指南:如何快速禁用CBC模式并切换到CTR加密(附最新配置命令)
  • AI辅助排错:让快马智能分析并解决你的openclaw安装难题
  • 台达AS系列PLC modbus TCP网口上位机通信实现,C#源代码监控设备生产数据并生成E...
  • 牛屎芯片(COB封装)技术解析与维修实践
  • NAYAX VPOS刷卡器MDB协议实战:3条关键指令搞定RS232通信(附完整测试流程)
  • 【仅限首批200名开发者】获取2024边缘C++轻量编译Checklist v3.2:覆盖Zephyr、FreeRTOS、Linux Yocto三平台
  • eMPL_MPU库:MPU6050/MPU9250嵌入式姿态解算驱动框架
  • 西工大NOJ刷题避坑指南:从T001到T056,一个C语言小白的踩坑实录与心得
  • Matlab R2024a 一站式部署指南:从网盘获取到科研环境就绪
  • SQL注入基础(文本型和数字型)
  • 3分钟解决百度网盘提取码难题:这款开源工具如何改变你的资源获取方式?
  • 利用快马AI平台快速生成STM32温湿度监测系统原型代码