前端必学:CSS实现精美渐变色票据组件(含完整源码)

CSS实现精美渐变色票据组件:六边缺角与虚线分割的完美结合

背景介绍

在现代Web开发中,优惠券和票据类组件是电商、金融等应用中不可或缺的UI元素。传统的实现方式往往依赖于图片背景或复杂的SVG路径,这不仅增加了资源加载时间,还降低了组件的可维护性和扩展性。

本文将介绍如何使用纯CSS实现一个具有六边缺角效果和虚线分割的精美票据组件,主要运用了以下高级CSS技术:

  • CSS Mask 属性:实现复杂的缺角效果
  • CSS Grid 布局:精确控制虚线分割的上下区域
  • CSS 自定义属性(变量):提高代码复用性和可维护性
  • CSS 渐变:创造丰富的视觉效果

效果展示

最终实现的票据组件具有以下特点:

六边缺角效果 :四个角落 + 左右两侧中部的圆形缺角 🎨 渐变背景 :优雅的蓝色渐变色彩 📏 虚线分割 :中间虚线将内容分为上下两部分,且严格平分容器高度 🔧 高度可配置 :通过CSS变量轻松调整缺角大小和平滑度 📱 响应式友好:支持灵活的布局和尺寸调整

核心实现原理

1. CSS Mask 属性实现缺角效果

mask 属性是CSS中一个强大但相对较新的功能,它允许我们通过遮罩来控制元素的可见部分。

css 复制代码
/* 使用径向渐变创建圆形缺角 */
--mask-value: 
  radial-gradient(circle at 0 0, transparent var(--corner-in), black var(--corner-out)),
  radial-gradient(circle at 100% 0, transparent var(--corner-in), black var(--corner-out)),
  radial-gradient(circle at 0 100%, transparent var(--corner-in), black var(--corner-out)),
  radial-gradient(circle at 100% 100%, transparent var(--corner-in), black var(--corner-out)),
  radial-gradient(circle at 0 50%, transparent var(--side-in), black var(--side-out)),
  radial-gradient(circle at 100% 50%, transparent var(--side-in), black var(--side-out));

mask: var(--mask-value);
mask-composite: intersect;

关键点解析:

  • radial-gradient(circle at x y, ...): 在指定位置创建径向渐变
  • transparent 区域会被"挖掉",形成缺角效果
  • black 区域保持可见
  • mask-composite: intersect 确保多个遮罩的交集效果

2. CSS Grid 实现精确的虚线分割

使用CSS Grid布局可以精确控制虚线上下区域的高度分配:

css 复制代码
.ticket-content {
  display: grid;
  grid-template-rows: 1fr auto 1fr;
}

布局解析:

  • 1fr auto 1fr:上部分占1份,虚线占自身高度,下部分占1份
  • 这确保了无论内容多少,虚线始终位于容器的垂直中心
  • 上下两部分永远平分剩余空间

3. CSS 变量提升可维护性

通过CSS自定义属性,我们可以轻松配置缺角效果:

css 复制代码
.ticket-four-corners-notch {
  --corner-notch: 12px;  /* 角落缺角尺寸 */
  --side-notch: 10px;    /* 侧边缺角尺寸 */
  --smooth: 0.3px;       /* 平滑度,消除锯齿 */
  
  /* 自动计算渐变位置 */
  --corner-in: calc(var(--corner-notch) - var(--smooth));
  --corner-out: calc(var(--corner-notch) + var(--smooth));
}

完整代码实现

Vue 模板部分

vue 复制代码
<template>
   <div class="ticket-container">
        <div style="display: flex; flex-direction: row; gap: 20px; justify-content: center; flex-wrap: wrap;">
            <div class="ticket-four-corners-notch">
                <div class="ticket-content">
                    <div class="ticket-section">
                        <span class="main-amount">¥300</span>
                    </div>
                    <div class="ticket-divider"></div>
                    <div class="ticket-section content-center">
                        <span class="bonus-amount">¥15 代金券</span>
                    </div>
                </div>
            </div>
            <div class="ticket-four-corners-notch">
                <div class="ticket-content">
                    <div class="ticket-section">
                        <span class="main-amount">¥300</span>
                    </div>
                    <div class="ticket-divider"></div>
                    <div class="ticket-section content-center">
                        <span class="bonus-amount">¥15 代金券</span>
                    </div>
                </div>
            </div>
        </div>
        <div class="ticket-four-corners-notch" style="margin-top: 20px;">
            <div class="ticket-content">
                <div class="ticket-section">
                    <span class="main-amount">¥300</span>
                </div>
                <div class="ticket-divider"></div>
                <div class="ticket-section content-center">
                    <span class="bonus-amount">¥15 代金券</span>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
  name: 'TicketComponent'
}
</script>

CSS 样式部分

vue 复制代码
<style scoped>
/* =================== 容器样式 =================== */
.ticket-container {
  padding: 20px;
  /* 页面背景:蓝紫色渐变 */
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  min-height: 100vh;
}

/* =================== 票据内容布局 =================== */
.ticket-content {
  position: relative;
  height: 100%;
  /* 关键:使用Grid布局实现精确的三等分 */
  display: grid;
  grid-template-rows: 1fr auto 1fr;  /* 上1份 + 虚线自适应 + 下1份 */
  color: #333;
  z-index: 2;
}

/* =================== 分割线样式 =================== */
.ticket-divider {
  width: 100%;
  margin: 0 auto;
  /* 虚线边框,模拟票据撕裂效果 */
  border-top: 1.5px dashed #d1d5db;
}

/* =================== 内容区域样式 =================== */
.ticket-section {
  text-align: center;
  padding: 8px;
  /* 使用Flexbox确保内容垂直居中 */
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 主要金额样式 */
.main-amount {
  font-size: 28px;
  font-weight: bold;
  color: #2563eb;  /* 蓝色主题 */
}

/* 优惠券金额样式 */
.bonus-amount {
  font-size: 18px;
  color: #4b5563;  /* 深灰色 */
}

/* =================== 六边缺角实现 =================== */
.ticket-four-corners-notch {
  /* CSS变量:可配置的缺角参数 */
  --corner-notch: 12px;    /* 四角缺角半径 */
  --side-notch: 10px;      /* 左右侧缺角半径 */
  --smooth: 0.3px;         /* 抗锯齿平滑度 */

  /* 自动计算渐变边界,实现平滑过渡 */
  --corner-in: calc(var(--corner-notch) - var(--smooth));
  --corner-out: calc(var(--corner-notch) + var(--smooth));
  --side-in: calc(var(--side-notch) - var(--smooth));
  --side-out: calc(var(--side-notch) + var(--smooth));

  /* 复杂的遮罩定义:六个径向渐变组合 */
  --mask-value: 
    radial-gradient(circle at 0 0, transparent var(--corner-in), black var(--corner-out)),        /* 左上角 */
    radial-gradient(circle at 100% 0, transparent var(--corner-in), black var(--corner-out)),     /* 右上角 */
    radial-gradient(circle at 0 100%, transparent var(--corner-in), black var(--corner-out)),     /* 左下角 */
    radial-gradient(circle at 100% 100%, transparent var(--corner-in), black var(--corner-out)),  /* 右下角 */
    radial-gradient(circle at 0 50%, transparent var(--side-in), black var(--side-out)),          /* 左侧中部 */
    radial-gradient(circle at 100% 50%, transparent var(--side-in), black var(--side-out));       /* 右侧中部 */

  /* =================== 票据基础样式 =================== */
  min-width: 320px;
  height: 120px;
  /* 票据背景:浅色渐变,营造纸质感 */
  background: linear-gradient(90deg, #EEF2FE 0%, #FAFBFD 51%, #E2F0FD 100%);
  overflow: hidden;
  /* 阴影效果,增加层次感 */
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
  
  /* =================== 性能优化 =================== */
  will-change: transform;           /* 提示浏览器进行硬件加速 */
  transform: translateZ(0);         /* 强制开启硬件加速 */
  backface-visibility: hidden;      /* 隐藏背面,优化渲染 */
  -webkit-font-smoothing: antialiased;      /* WebKit字体平滑 */
  -moz-osx-font-smoothing: grayscale;       /* Firefox字体平滑 */

  /* =================== 应用遮罩效果 =================== */
  mask: var(--mask-value);
  -webkit-mask: var(--mask-value);               /* WebKit兼容性 */
  mask-composite: intersect;                     /* 遮罩组合方式:交集 */
  -webkit-mask-composite: source-in;             /* WebKit遮罩组合 */
}
</style>

高级CSS属性详解

1. CSS Mask 属性

作用 :通过遮罩控制元素的可见区域 语法mask: <mask-layer># 兼容性:现代浏览器支持,需要WebKit前缀

css 复制代码
/* 基本语法 */
mask: radial-gradient(circle at x y, color-stop1, color-stop2);

/* 多重遮罩 */
mask: mask1, mask2, mask3;
mask-composite: intersect | add | subtract | exclude;

关键概念

  • transparent:完全透明,该区域被"挖掉"
  • black/white:完全不透明,该区域保留
  • mask-composite:控制多个遮罩的组合方式

2. CSS radial-gradient 径向渐变

作用 :创建从中心点向外辐射的圆形或椭圆形渐变效果 语法radial-gradient([shape size] [at position], color-stop1, color-stop2, ...)

基础语法详解
css 复制代码
/* 完整语法 */
radial-gradient(
  [shape] [size] [at position],
  color-stop1 [percentage],
  color-stop2 [percentage],
  ...
);
参数说明

Shape(形状)

  • circle:圆形渐变(默认)
  • ellipse:椭圆形渐变

Size(尺寸)

  • closest-side:渐变到最近边
  • closest-corner:渐变到最近角
  • farthest-side:渐变到最远边
  • farthest-corner:渐变到最远角(默认)
  • 具体值:如 50px50px 30px

Position(位置)

  • at x y:指定渐变中心位置
  • 支持像素值、百分比、关键字(top, bottom, left, right, center
在票据组件中的应用
css 复制代码
/* 左上角缺角 */
radial-gradient(circle at 0 0, transparent 11.5px, black 12.5px)

解析

  • circle:创建圆形渐变
  • at 0 0:渐变中心位于左上角(0,0)坐标
  • transparent 11.5px:从中心到11.5px半径范围内完全透明
  • black 12.5px:从12.5px半径开始完全不透明
  • 11.5px-12.5px:1px的过渡区域实现抗锯齿效果
实际渐变效果对比
css 复制代码
/* 硬边界(有锯齿) */
radial-gradient(circle at 0 0, transparent 12px, black 12px)

/* 软边界(平滑) */
radial-gradient(circle at 0 0, transparent 11.5px, black 12.5px)

/* 更软的边界 */
radial-gradient(circle at 0 0, transparent 11px, black 13px)
径向渐变的其他用法示例
css 复制代码
/* 基础圆形渐变 */
background: radial-gradient(circle, red, blue);

/* 椭圆渐变 */
background: radial-gradient(ellipse, red, blue);

/* 指定位置的渐变 */
background: radial-gradient(circle at top left, red, blue);

/* 指定大小的渐变 */
background: radial-gradient(circle 100px, red, blue);

/* 多个颜色停止点 */
background: radial-gradient(circle, red 0%, yellow 50%, blue 100%);

/* 重复径向渐变 */
background: repeating-radial-gradient(circle, red 0px, red 10px, blue 10px, blue 20px);
在票据组件中的创新应用

我们的票据组件巧妙地利用了径向渐变的特性:

  1. 精确定位 :使用 at x y 精确定位每个缺角的位置
  2. 透明度控制 :通过 transparentblack 创建遮罩效果
  3. 平滑过渡:利用渐变的过渡特性实现抗锯齿
  4. 多重组合 :通过 mask-composite: intersect 组合多个径向渐变
css 复制代码
/* 六个缺角的完整定义 */
--mask-value: 
  radial-gradient(circle at 0 0, transparent var(--corner-in), black var(--corner-out)),      /* 左上角 */
  radial-gradient(circle at 100% 0, transparent var(--corner-in), black var(--corner-out)),   /* 右上角 */
  radial-gradient(circle at 0 100%, transparent var(--corner-in), black var(--corner-out)),   /* 左下角 */
  radial-gradient(circle at 100% 100%, transparent var(--corner-in), black var(--corner-out)), /* 右下角 */
  radial-gradient(circle at 0 50%, transparent var(--side-in), black var(--side-out)),        /* 左侧中部 */
  radial-gradient(circle at 100% 50%, transparent var(--side-in), black var(--side-out));     /* 右侧中部 */

3. CSS Grid 布局

作用 :创建二维网格布局系统 优势:精确控制行列比例,适合复杂布局

css 复制代码
/* 关键属性 */
display: grid;
grid-template-rows: 1fr auto 1fr;    /* 行高定义 */
grid-template-columns: 1fr 1fr 1fr;  /* 列宽定义 */

/* fr单位:fraction,表示剩余空间的分数 */
/* auto:根据内容自适应 */

4. CSS 自定义属性(变量)

作用 :定义可重用的值,提高代码可维护性 语法--variable-name: value

css 复制代码
/* 定义变量 */
:root {
  --primary-color: #2563eb;
  --border-radius: 8px;
}

/* 使用变量 */
.element {
  color: var(--primary-color);
  border-radius: var(--border-radius);
}

/* 带默认值的变量 */
.element {
  color: var(--undefined-color, #000);  /* 如果变量未定义,使用黑色 */
}

5. CSS calc() 函数

作用:执行数学计算,支持不同单位混合运算

css 复制代码
/* 混合单位计算 */
width: calc(100% - 20px);
font-size: calc(1rem + 2vw);

/* 变量计算 */
--result: calc(var(--base-size) * 1.5);

浏览器兼容性

属性 Chrome Firefox Safari Edge
CSS Mask 120+ 53+ 15.4+ 79+
CSS Grid 57+ 52+ 10.1+ 16+
CSS Variables 49+ 31+ 9.1+ 15+
CSS calc() 26+ 16+ 7+ 12+

兼容性建议

  • mask属性添加-webkit-前缀
  • 考虑为旧版浏览器提供降级方案
  • 使用PostCSS等工具自动添加前缀

总结

本文介绍了如何使用纯CSS实现复杂的票据组件,主要涉及以下技术要点:

  1. CSS Mask属性:通过多重径向渐变实现六边缺角效果
  2. CSS Grid布局:精确控制虚线分割的上下区域比例
  3. CSS变量:提高代码的可维护性和复用性
  4. 性能优化:使用硬件加速和字体平滑技术

这种实现方式具有以下优势:

  • 纯CSS实现:无需图片资源,减少HTTP请求
  • 高度可定制:通过CSS变量轻松调整样式
  • 性能优秀:利用硬件加速,渲染流畅
  • 可维护性强:代码结构清晰,易于理解和修改
  • 响应式友好:支持灵活的布局适配

希望这篇文章能帮助你在项目中实现更加精美和高效的票据组件!


📝 技术交流:如果你在实现过程中遇到问题,欢迎在评论区交流讨论。

相关推荐
前端小趴菜057 分钟前
React - 组件通信
前端·react.js·前端框架
Amy_cx27 分钟前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing99941 分钟前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
后海 0_o1 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构
Scabbards_1 小时前
CPT304-2425-S2-Software Engineering II
前端
小满zs1 小时前
Zustand 第二章(状态处理)
前端·react.js
程序猿小D1 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim
萌萌哒草头将军1 小时前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js
狼性书生2 小时前
uniapp实现的简约美观的星级评分组件
前端·uni-app·vue·组件
书语时2 小时前
ES6 Promise 状态机
前端·javascript·es6