一个复杂按钮的实现(类点九+遮罩+背景融合)

470 阅读5分钟

最近跟进的需求中,页面有一系列复杂视觉效果的按钮(大致效果如下所示)。

image.png

对于单一复杂的视觉效果按钮,完全可以切图来完成(雪碧图等等,放过自己为好,阿门~)。

但是鉴于这个页面这类按钮较多(宽高有细微差距)且追求较少的性能消耗,此处使用了css的方案进行实现。

主要是通过点九图的思维、叠加了遮罩背景融合进行实现~

具体的实现思路,可以详细查看下方的描述过程:

实现带有特殊形状的轮廓

主要是通过-webkit-mask-box-image实现带有拉伸的特殊形状。 image.png

代码及效果图如下所示。

<div class="demo"></div>
.demo {
    height: 104px;
    background-color: #61A1AD;
    webkit-mask-box-image: url("形状.svg") 30   40 fill  / 30px   40px;
}

image.png PS:此处的素材建议使用svg,图片边缘容易有锯齿形状。

实现带噪点及渐变色效果的背景填充

主要是通过background的叠加,再添加背景的混合(background-blend-mode)

/* 燥点渐变背景 */ 
background: url("噪点素材图.png") repeat, linear-gradient(278deg, rgba(209, 174, 113, 0.00) 16.44%, rgba(209, 174, 113, 0.25) 102.55%), linear-gradient(142deg, rgba(0, 0, 0, 0) 22%, rgba(0, 0, 0, 0.60) 77%), #61A1AD;
/* 背景混合 */
background-blend-mode: soft-light, overlay, soft-light, normal;

image.png

纹理实现

一个祥云纹理(png素材)直接用background即可;一个边框方形纹理(svg素材,避免边缘锯齿),需要做延伸用mask-box-image做。
关键代码如下:

<div class="demo">
    <i class="demo-icon"></i>
</div>
    .demo-icon::before { 
        content: "";
        position: absolute;
        position: absolute;
        top: 0; left: -4px; bottom: 0; right: -4px;
        background-color: #61A1AD;
        -webkit-mask-box-image: url("形状.svg") 30 40 fill / 30px 40px;
        background: linear-gradient(278deg, rgba(209, 174, 113, 0.00) 16.44%, rgba(209, 174, 113, 0.25) 102.55%), linear-gradient(142deg, rgba(0, 0, 0, 1) 22%, rgba(0, 0, 0, 1) 77%), #61A1AD;
        background-blend-mode: overlay, soft-light, normal; 
        z-index: -1;
    } 
    .demo-icon::after {
        content: "";
        position: absolute;
        top: 0; left: 0; bottom: 0; right: 0;
        background-image: url('祥云.png');
        background-size: auto 100%;
        background-position: center right;
        /* 层级需要低一些 */ z-index: -2;
}

image.png

完整代码示意

1️⃣支持通过mainColor变色;
2️⃣支持通过-webkit-mask-box-image-slice调整适配不同的高度
3️⃣注意z-index

<!-- html -->
<div class="demo">
    <i class="demo-icon"></i>
    <p>其他按钮内容</p>
</div>

<!-- css -->
.demo {
    position: relative;
    height: 104px;
    z-index: 4;
    display: flex;
    justify-content: center;
    align-items: center;
}
.demo::before {
    content: "";
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
    margin: auto;
    background-color: var(--mainColor, #61A1AD);
    -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='120' height='120' viewBox='0 0 120 120' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_43_17435)' fill-rule='evenodd' clip-rule='evenodd'%3E%3Cpath d='M11.505 108.495C4.605 104.279 0 96.677 0 88V32c0-8.677 4.605-16.28 11.505-20.495C15.721 4.605 23.323 0 32 0h56c8.677 0 16.279 4.605 20.495 11.505C115.395 15.721 120 23.323 120 32v56c0 8.677-4.605 16.279-11.505 20.495C104.279 115.395 96.677 120 88 120H32c-8.677 0-16.28-4.605-20.495-11.505z' fill='%23E1E7EB'/%3E%3Cpath d='M11.505 108.495C4.605 104.279 0 96.677 0 88V32c0-8.677 4.605-16.28 11.505-20.495C15.721 4.605 23.323 0 32 0h56c8.677 0 16.279 4.605 20.495 11.505C115.395 15.721 120 23.323 120 32v56c0 8.677-4.605 16.279-11.505 20.495C104.279 115.395 96.677 120 88 120H32c-8.677 0-16.28-4.605-20.495-11.505z' fill='%23E5353E'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_43_17435'%3E%3Cpath fill='%23fff' d='M0 0h120v120H0z'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E") 30   40 fill  / 30px   40px;
    z-index: -4;
}
.demo::after {
    content: "";
    position: absolute;
    top: 2px; left: 2px; bottom: 2px; right: 2px; 
    background: url("噪点素材图.png") repeat, linear-gradient(278deg, rgba(209, 174, 113, 0.00) 16.44%, rgba(209, 174, 113, 0.25) 102.55%), linear-gradient(142deg, rgba(0, 0, 0, 0) 22%, rgba(0, 0, 0, 0.60) 77%), var(--mainColor, #61A1AD);
    background-blend-mode: soft-light, overlay, soft-light, normal;
    -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='120' height='120' viewBox='0 0 120 120' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_43_17435)' fill-rule='evenodd' clip-rule='evenodd'%3E%3Cpath d='M11.505 108.495C4.605 104.279 0 96.677 0 88V32c0-8.677 4.605-16.28 11.505-20.495C15.721 4.605 23.323 0 32 0h56c8.677 0 16.279 4.605 20.495 11.505C115.395 15.721 120 23.323 120 32v56c0 8.677-4.605 16.279-11.505 20.495C104.279 115.395 96.677 120 88 120H32c-8.677 0-16.28-4.605-20.495-11.505z' fill='%23E1E7EB'/%3E%3Cpath d='M11.505 108.495C4.605 104.279 0 96.677 0 88V32c0-8.677 4.605-16.28 11.505-20.495C15.721 4.605 23.323 0 32 0h56c8.677 0 16.279 4.605 20.495 11.505C115.395 15.721 120 23.323 120 32v56c0 8.677-4.605 16.279-11.505 20.495C104.279 115.395 96.677 120 88 120H32c-8.677 0-16.28-4.605-20.495-11.505z' fill='%23E5353E'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_43_17435'%3E%3Cpath fill='%23fff' d='M0 0h120v120H0z'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E") 30   40 fill  / 30px   40px;
    z-index: -3;
}
.demo-icon::before {
    content: "";
    position: absolute;
    position: absolute;
    top: 0; left: -4px; bottom: 0; right: -4px;
    background-color: var(--mainColor, #61A1AD);
    -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='216' height='104' viewBox='0 0 216 104' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M197.414 50.586l5.969-5.97C199.871 23.832 181.784 8 160 8H56C34.215 8 16.128 23.831 12.617 44.617l5.968 5.969L20 52l-1.415 1.414-5.968 5.97C16.128 80.167 34.215 96 56 96h104c21.784 0 39.871-15.832 43.383-36.617l-5.969-5.969L196 52l1.414-1.414zm3.814 9.47l-6.642-6.642L193.172 52l1.414-1.414 6.642-6.643C197.472 24.602 180.439 10 160 10H56c-20.44 0-37.472 14.602-41.228 33.943l6.642 6.643L22.828 52l-1.414 1.414-6.643 6.643C18.529 79.398 35.561 94 56 94h104c20.439 0 37.472-14.602 41.228-33.943zM208 44l-8 8 8 8 8-8-8-8zM0 52l8-8 8 8-8 8-8-8z' fill='%23000' style='mix-blend-mode:soft-light'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M197.414 50.586l5.969-5.97C199.871 23.832 181.784 8 160 8H56C34.215 8 16.128 23.831 12.617 44.617l5.968 5.969L20 52l-1.415 1.414-5.968 5.97C16.128 80.167 34.215 96 56 96h104c21.784 0 39.871-15.832 43.383-36.617l-5.969-5.969L196 52l1.414-1.414zm3.814 9.47l-6.642-6.642L193.172 52l1.414-1.414 6.642-6.643C197.472 24.602 180.439 10 160 10H56c-20.44 0-37.472 14.602-41.228 33.943l6.642 6.643L22.828 52l-1.414 1.414-6.643 6.643C18.529 79.398 35.561 94 56 94h104c20.439 0 37.472-14.602 41.228-33.943zM208 44l-8 8 8 8 8-8-8-8zM0 52l8-8 8 8-8 8-8-8z' fill='url(%23paint0_linear_69_17948)' fill-opacity='.25' style='mix-blend-mode:overlay'/%3E%3Cdefs%3E%3ClinearGradient id='paint0_linear_69_17948' x1='177.983' y1='96.523' x2='-19.148' y2='29.128' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23D1AE71' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='%23D1AE71'/%3E%3C/linearGradient%3E%3C/defs%3E%3C/svg%3E") 30   40 fill  / 30px   40px;

    background: linear-gradient(278deg, rgba(209, 174, 113, 0.00) 16.44%, rgba(209, 174, 113, 0.25) 102.55%), linear-gradient(142deg, rgba(0, 0, 0, 1) 22%, rgba(0, 0, 0, 1) 77%), var(--mainColor, #61A1AD);
    background-blend-mode: overlay, soft-light, normal;
    z-index: -1;
}
.demo-icon::after {
    content: "";
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
    background-image: url('祥云素材图.png');
    background-size: auto 100%;
    background-position: center right;
    z-index: -2;
}