👏 前几周有小伙伴问我如何用css实现一些优惠券/卡券,今天就来分享一波吧!速速来Get吧~
🥇文末分享源代码。记得点赞+关注+收藏!

假设我们要实现这样的一个效果,两侧透明内圆角+外侧投影,有几种实现方式呢?




.card{
width: 700rpx;
height: 250rpx;
margin: 0 auto 20rpx;
border-radius: 20rpx;
position: relative;
background: #ff6810;
position: relative;
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
}
.card::before,
.card::after {
content: '';
position: absolute;
width: 20rpx;
height: 40rpx;
background: var(--bg);
top: calc(50% - 20rpx);
}
.card::before {
border-radius: 0 20rpx 20rpx 0;
left: 0;
}
.card::after {
border-radius: 20rpx 0 0 20rpx;
right: 0;
}
1.当页面背景是图片或者非纯色的时候,无法正确的显示
2.无法正确的显示投影
radial-gradient:
radial-gradient() CSS 函数创建一个图像,该图像由从原点辐射的两种或多种颜色之间的渐进过渡组成。它的形状可以是圆形或椭圆形。函数的结果是 gradient数据类型的对象。这是一种特别的 image。
语法:
background-image: radial-gradient(shape size at position, start-color, ..., last-color);
径向渐变通过指定渐变的中心(0% 椭圆所在的位置)和结束形状(100% 椭圆)的大小和形状来指定。
渐变颜色默认第一个颜色位置是0%,最后一个颜色位置是100%.
background: radial-gradient(circle at 0rpx, orange , pink, skyblue ) ;
//等价于background: radial-gradient(circle at 0rpx, orange 0, pink 50%, skyblue 100%) ;

background: radial-gradient(circle at left center, transparent 20rpx, pink 20rpx, skyblue);

background: radial-gradient( circle ,transparent 20%, pink 20% 45%, skyblue 45% 70%, rgb(211, 128, 50) 70% 100%);

background: radial-gradient(circle at left center, transparent 0rpx 20rpx, pink 20rpx 30%, skyblue 30%);

background: radial-gradient(circle at left center, transparent 20rpx, pink 20rpx);


background: radial-gradient(circle at left, transparent 20rpx, pink 20rpx), radial-gradient(circle at right, transparent 20rpx, pink 20rpx);

XboxYan-CSS 实现优惠券的技巧这篇文章在讲mask遮罩时,有说到是因为两层背景相互叠加,导致整块背景都成了不透明的,那么是不是同样适用到这个渐变上呢?试试看
修改background-position为对应位置,background-size宽度为50%,高度不变,background-repeat不重叠,先将颜色分开试试,看看效果如何
background-position:
background-position CSS 属性为每一个背景图片设置初始位置。这个位置是相对于由 background-origin 定义的位置图层的。
对于两个值的语法: 一个定义 x 坐标,另一个定义 y 坐标,其他的请看相关文档,这里就不赘述了。
background: radial-gradient(circle at left, transparent 20rpx, skyblue 20rpx) 0 100% /51% no-repeat, radial-gradient(circle at right, transparent 20rpx, pink 20rpx) 100% 0 /51% no-repeat;
//或者
background: radial-gradient(circle at left, transparent 20rpx, skyblue 20rpx) ,radial-gradient(circle at right, transparent 20rpx, pink 20rpx) ;
background-size: 51%;
background-repeat: no-repeat;
background-position: 0, 100%;


background: radial-gradient(circle at 20rpx center, transparent 20rpx, #ff6810 20rpx) ;

filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
background: radial-gradient(circle at 20rpx center, transparent 20rpx, #ff6810 20rpx) -20rpx;
//或者
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
background: radial-gradient(circle at 20rpx center, transparent 20rpx, #ff6810 20rpx);
background-position: -20rpx ;

1.当优惠券背景是渐变色的时候,处理起来不方便
mask:
CSS 属性 mask 允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。可以理解为透明的部分不显示,展示非透明区域。
mask语法与background类似,使用mask可以实现一些amazing的效果,可以参考文章ChokCoco-奇妙的 CSS MASK
background: pink;
-webkit-mask: radial-gradient(circle at left center, transparent 20rpx, skyblue 21rpx);


.card-002 {
background: #ff6810;
-webkit-mask: radial-gradient(circle at left, transparent 20rpx, pink 20rpx) 0 100% /51% no-repeat, radial-gradient(circle at right, transparent 20rpx, pink 20rpx) 100% 0 /51% no-repeat;
}
.card-002 {
background: #ff6810;
-webkit-mask: radial-gradient(circle at 20rpx center, transparent 20rpx, red 0) -20rpx;
}

-参考 XboxYan-CSS 实现优惠券的技巧这篇文章, 利用-webkit-mask-composite设置重叠区域的展示,设置source-in,只显示重合的地方,也可以实现两个内圆角
.card-002 {
background: #ff6810;
-webkit-mask: radial-gradient(circle at left, transparent 20rpx, pink 20rpx),
radial-gradient(circle at right, transparent 20rpx, pink 20rpx);
-webkit-mask-composite: source-in;
}

.card-002{
width: 700rpx;
height: 250rpx;
position: relative;
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
}
.card-002::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: -1;
background: #ff6810;
border-radius: 20rpx;
-webkit-mask: radial-gradient(circle at 20rpx center, transparent 20rpx, red 0) -20rpx;
mask: radial-gradient(circle at 20rpx center, transparent 20rpx, red 0) -20rpx;
}
--c1: orange;
--c2: #ff2e63;
background: linear-gradient(35deg, var(--c1), var(--c2));

假设我们要实现这样的一个效果,矩形四边分别有1/4的圆角,有几种实现方式呢?


background: radial-gradient(circle at 0 0, transparent 20rpx, #ff6810 0) ;

background: radial-gradient(circle at left 0, transparent 20rpx, pink 0) left 0 /50% 50% no-repeat,
radial-gradient(circle at right 0, transparent 20rpx, skyblue 0) right 0 /50% 50% no-repeat,
radial-gradient(circle at left 100%, transparent 20rpx, orange 0) left 100% /50% 50% no-repeat,
radial-gradient(circle at right 100%, transparent 20rpx, #a6d1a9 0) right 100% /50% 50% no-repeat;

或者将起始点设置到左边20rpx,上边20rpx,并调整background-position位置
.card-003 {
background: radial-gradient(circle at 20rpx 20rpx, transparent 20rpx, #ff6810 0) -20rpx -20rpx;
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
}

background:slateblue;
-webkit-mask: radial-gradient(circle at left 0, transparent 20rpx, pink 0) left 0 /50% 50% no-repeat,
radial-gradient(circle at right 0, transparent 20rpx, skyblue 0) right 0 /50% 50% no-repeat,
radial-gradient(circle at left 100%, transparent 20rpx, orange 0) left 100% /50% 50% no-repeat,
radial-gradient(circle at right 100%, transparent 20rpx, #a6d1a9 0) right 100% /50% 50% no-repeat;
.card-004{
position: relative;
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
}
.card-004::after {
-webkit-mask: radial-gradient(circle at 20rpx 20rpx, transparent 20rpx, red 0) -20rpx -20rpx;
background: slateblue;
}

background: linear-gradient(to right, var(--c1) 0%, var(--c2) 100%);

假设我们要实现这样的一个效果,内凹圆角边框,有几种实现方式呢?

参考 XboxYan-CSS filter生成不规则边框这篇文章,利用多重投影drop-shadow
因为mask会裁剪掉drop-shadow,所以要把mask渐变写到器伪元素上
由于mask是显示非透明部分,所以要为元素设置背景色,不能为transparent,即与页面的背景色一致
.card-005 {
filter: drop-shadow(0 0 2rpx) drop-shadow(0 0 0) drop-shadow(0 0 0) drop-shadow(0 0 0) drop-shadow(0 0 0);
//投影的颜色默认是跟随当前文字颜色的
color: #eb4f8b;
}
.card-005::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: -1;
border-radius: 20rpx;
-webkit-mask: radial-gradient(circle at 20rpx center, transparent 20rpx, red 0) -20rpx;
//页面的背景色
background: var(--bg);
}

-webkit-mask: radial-gradient(circle at 20rpx center, transparent 18rpx, #000 0) -20rpx;
color: #ff6810;
border: 3rpx solid #ff6810;

添加两个半圆伪元素,背景色与border颜色一致,调整好相应位置
.card-006::before,
.card-006::after {
content: '';
position: absolute;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background-color: #ff6810;
top: calc(50% - 21rpx);
}
.card-006::before {
left: -3%;
}
.card-006::after {
right: -3%;
}

内容较多,这里展示前两个demo,完整代码请戳这里🍡苏苏的github,🍪苏苏的码云
<!-- 样式1 -->
<view class="card-box">
<view class="card-name">苏苏就是小苏苏哇</view>
<view class="card-banner">VIP</view>
<view class="card-content">
<text>剩余</text>
<text>88888</text>
<text>元</text>
</view>
<view class="flex-row j_c card-btm">
<view class="flex-column j_c card-btm-item">
<text>已获得奖项</text>
<text>888个</text>
</view>
<view class="flex-column j_c card-btm-item">
<text>已出售</text>
<text>1008个</text>
</view>
<view class="flex-column j_c card-btm-item">
<text>已买入</text>
<text>999个</text>
</view>
</view>
</view>
<!-- 样式2 -->
<view class="coupon-box flex">
<view class="cou-banner">即将过期</view>
<view class="cou-left flex-row j_c">
<view>
<text>888</text>
<text>元</text>
</view>
</view>
<view class="cou-right flex-row ">
<view>
<view>苏苏就是小苏苏哇--苏苏</view>
<view class="cou-right-time">剩余 23:59:59</view>
</view>
</view>
</view>
/* 样式1 */
.card-box {
width: 700rpx;
height: 360rpx;
margin: 0 auto 20px;
border-radius: 30rpx;
overflow: hidden;
box-sizing: border-box;
padding: 20rpx;
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
position: relative;
color: #fff;
}
.card-box::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
background: linear-gradient(35deg, var(--c1), var(--c2));
-webkit-mask: radial-gradient(circle at 20rpx 65%, transparent 20rpx, red 0) -20rpx;
mask: radial-gradient(circle at 20rpx 65%, transparent 20rpx, red 0) -20rpx;
z-index: -1;
animation: bgchange 3s infinite ease-in-out alternate-reverse;
}
@keyframes bgchange {
0% {
filter: hue-rotate(0deg);
}
100% {
filter: hue-rotate(-50deg);
}
}
.card-name {
font-size: 40rpx;
font-weight: bold;
letter-spacing: 2rpx;
margin-bottom: 45rpx;
}
.card-banner {
position: absolute;
display: inline-block;
min-width: 100rpx;
padding: 10rpx 0;
text-align: center;
height: 30rpx;
line-height: 30rpx;
border-radius: 30rpx;
background: rgba(255, 255, 255, .26);
top: 20rpx;
right: 20rpx;
}
.card-content {
font-size: 28rpx;
display: flex;
align-items: baseline;
justify-content: center;
position: relative;
margin-bottom: 40rpx;
}
.card-content::before {
content: '';
width: 600rpx;
height: 3rpx;
position: absolute;
background-image: linear-gradient(90deg, var(--c3) 50%, transparent 50%);
background-size: 30rpx 30rpx;
left: calc(50% - 300rpx);
bottom: -30rpx;
}
.card-content text:nth-child(2) {
font-size: 80rpx;
line-height: 90rpx;
letter-spacing: 2rpx;
margin: 0px 20rpx;
}
.card-btm {
font-size: 28rpx;
}
.card-btm-item {
width: 30%;
line-height: 48rpx;
}
/* 样式2 */
.coupon-box {
width: 700rpx;
height: 220rpx;
overflow: hidden;
border-radius: 20rpx;
position: relative;
background: radial-gradient(circle at right top, transparent 18rpx, var(--c4) 0) top left / 215rpx 51% no-repeat,
radial-gradient(circle at right bottom, transparent 18rpx, var(--c4) 0) bottom left /215rpx 51% no-repeat,
radial-gradient(circle at left top, transparent 18rpx, var(--c5) 0) top right /487rpx 51% no-repeat,
radial-gradient(circle at left bottom, transparent 18rpx, var(--c5) 0) bottom right /487rpx 51% no-repeat;
filter: drop-shadow(2px 2px 1px rgba(0, 0, 0, .3));
margin: 20px auto;
/* 解决filter-导致border-radius生效 */
transform: translate3d(0, 0, 0);
}
.coupon-box::after {
content: '';
height: 184rpx;
width: 3rpx;
background-image: linear-gradient(0deg, #fff 50%, transparent 50%);
background-size: 20rpx 20rpx;
position: absolute;
left: 212rpx;
top: 0;
bottom: 0;
margin: auto;
}
.cou-banner {
position: absolute;
left: 0;
top: 0;
min-width: 130rpx;
text-align: center;
padding: 0 10rpx;
line-height: 45rpx;
height: 45rpx;
font-size: 25rpx;
color: red;
background: rgba(255, 165, 0, .2);
border-radius: 20rpx 0 20rpx 0;
}
.cou-left {
width: 214rpx;
height: 100%;
font-size: 25rpx;
color: red;
}
.cou-left text:nth-child(1) {
font-size: 35px;
}
.cou-right {
width: 484rpx;
height: 100%;
box-sizing: border-box;
padding: 20rpx 20rpx 20rpx 35rpx;
color: #333;
font-size: 30rpx;
font-weight: bold;
line-height: 48rpx;
}
.cou-right-time {
color: red;
}
XboxYan-CSS 实现优惠券的技巧
XboxYan-用纯css来实现一个优惠券
XboxYan-CSS filter 生成不规则边框