您现在的位置:首页 >> 前端 >> 内容

两种纯CSS的方式实现优惠券上的锯齿效果

时间:2018/3/22 14:35:03 点击:

  核心提示:昨天公司做前端的好像对CSS都不是很熟(其实就是一群Javaer兼职干前端),估计是用多了React、Bootstrap这种现成的框架(就只知道写组件了),没写过啥基础的CSS。然后有个优惠券的模块分...

昨天公司做前端的好像对CSS都不是很熟(其实就是一群Javaer兼职干前端),估计是用多了React、Bootstrap这种现成的框架(就只知道写组件了),没写过啥基础的CSS。然后有个优惠券的模块分到了我的头上,正好总结总结。

优惠券最主要就是这个锯齿的问题。其实用图片做也完全可以,反正最后那些小图片都会被webpack编码成Base64的DataURL

关于DataURL的内容可以参考RFC2397

不过用图片方式就没有啥挑战性了,那我也没必要写这篇文章记录这个过程。

我们的目的是用纯CSS实现锯齿

一、使用before和after伪元素的border实现

先看一张效果图

两种纯CSS的方式实现优惠券上的锯齿效果

先定义一下最基本的html:

这里我们主要关注怎么实现锯齿,内容什么的我就没写,背景颜色也直接放在html里面了。

1. 用dotted圆点边框覆盖p

我们的主要思路就是用两排圆点覆盖在p上:

.sawtooth {
    /* 相对定位,方便让before和after伪元素绝对定位偏移 */
    position: relative;
}

.sawtooth:before, .sawtooth:after {
    content: ' ';
    width: 0;
    height: 100%;
    /* 绝对定位进行偏移 */
    position: absolute;
    top: 0;
}

.sawtooth:before {
    /* 圆点型的border */
    border-right: 10px dotted white;
    /* 偏移一个半径,让圆点的一半覆盖p */
    left: -5px;
}

.sawtooth:after {
    /* 圆点型的border */
    border-left: 10px dotted white;
    /* 偏移一个半径,让圆点的一半覆盖p */
    right: -5px;
}

得到下面这样的效果:

两种纯CSS的方式实现优惠券上的锯齿效果

2. 微调边框位置

但是由于圆点是顶着p开始的,总感觉不怎么好看,我们把before和after两个伪元素往下移动一点:

.sawtooth:before, .sawtooth:after {
    ...
    /* 下移一个圆点直径的距离,让最后一个圆点超出p */
    top: 10px;
}

两种纯CSS的方式实现优惠券上的锯齿效果

这样虽然已经出效果了,但是在实际应用中,由于背景色的不同导致,我们border圆点露馅了。

3. 隐藏多余的部分

为了解决这个问题,我们把需要把超出p的部分剪切掉:

.sawtooth {
    /* 相对定位,方便让before和after伪元素绝对定位偏移 */
    position: relative;
    /* 把超出p的部分隐藏起来 */
    overflow: hidden;
}

两种纯CSS的方式实现优惠券上的锯齿效果

因为border的颜色(白色)和背景色(青绿色)不同,导致优惠券看上去很突兀。

对于这个问题,最开始相到的解决办法是让把border设置为transparent(透明),可惜透明的结果是显示后面p的红色。所以暂时只能用最笨的方法:把border的颜色设置成背景色。

两种纯CSS的方式实现优惠券上的锯齿效果

整理以下CSS

.sawtooth {
    /* 相对定位,方便让before和after伪元素绝对定位偏移 */
    position: relative;
    /* 把超出p的部分隐藏起来 */
    overflow: hidden;
}

.sawtooth:before, .sawtooth:after {
    content: ' ';
    width: 0;
    height: 100%;
    /* 绝对定位进行偏移 */
    position: absolute;
    top: 10px;
}

.sawtooth:before {
    /* 圆点型的border */
    border-right: 10px dotted white;
    /* 偏移一个半径,让圆点的一半覆盖p */
    left: -5px;
}

.sawtooth:after {
    /* 圆点型的border */
    border-left: 10px dotted white;
    /* 偏移一个半径,让圆点的一半覆盖p */
    right: -5px;
}

二、使用透明背景实现

上面的方法的缺点是,我们需要让border的颜色和背景色一致,才能让我们的优惠券不“露馅”。

所以这次我们就直接用透明的背景。透明的背景当然不是指全透明,全透明那就是没背景了。看一下下面这张图你就知道我们要怎么干了。

两种纯CSS的方式实现优惠券上的锯齿效果

哇塞,这么多洞!密集恐惧症患者,看了估计有点闹心。

我们的主要思路是:在这张有这么多洞的网上面盖一张p,把多余的洞遮住,只保留两边有锯齿的洞。

不过使用这种方式我们先要把html中的背景色干掉,只保留宽高:

 

1. 用css画出这张网

为了画出这么多的洞,我们要用到radial-gradient这个渐变函数,不过我们并不需要用到它的渐变功能,只要用它来画透明的圆点就行。

radial-gradient要求IE10及以上的版本的浏览器

关于radial-gradient的更多详细内容,请参考MDN的文档

.sawtooth{
    /* 画出一个半径为5px的透明的圆,透明圆以外都是#e24141颜色 */
    background-image: radial-gradient(transparent 0, transparent 5px, #e24141 5px);
    /* 截取上面生成的渐变图的一部分,相当于截取15px的正方形中有一个直径10px的透明圆点 */
    background-size: 15px 15px;
    /* 根据优惠券p大小进行微调 */
    background-position: 8px 3px;
}

上面简单的三句话就生成了这张网:

两种纯CSS的方式实现优惠券上的锯齿效果

也许你看到样式上面的注释会很纳闷,这样就生成了一张网?你把sawtooth类改成下面的样式看一下,估计你就会明白了:

.sawtooth{
    background-image: radial-gradient(transparent 0, transparent 5px, #e24141 5px);
    background-size: 100px 100px;
    background-repeat: no-repeat;
}

两种纯CSS的方式实现优惠券上的锯齿效果

2. 找一个元素把多余的洞覆盖掉

为了不影响html的整洁性,我们就使用before或after这两个伪元素中的一个来覆盖多余的洞吧。

.sawtooth {
    background-image: radial-gradient(transparent 0, transparent 5px, #e24141 5px);
    background-size: 15px 15px;
    background-position: 8px 3px;
    /* 相对定位,让before伪元素方便定位 */
    position: relative;
}

.sawtooth:before {
    content: ' ';
    display: block;
    /* 用相同的颜色覆盖 */
    background-color: #e24141;
    /* 绝对定位,遮住中间所有的洞,只保留边角的锯齿 */
    position: absolute;
    top: 0;
    bottom: 0;
    /* 为锯齿保留的距离 */
    left: 10px;
    right: 10px;
}

完成的效果图如下:

两种纯CSS的方式实现优惠券上的锯齿效果

3. 让遮罩层下移,让它成为背景

上面的样式还有一点点问题。

当我们网p中加内容的时候:

内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容 内容内容内容内容内容内容内容内容内容内容

发现它不仅把洞给遮住了,还把我们的内容给遮住了:

两种纯CSS的方式实现优惠券上的锯齿效果

出现上面这种现象的原因就是:绝对定位脱离文档流后,会浮在文档的上面。

“我们的内容在地表上,遮罩层却在一楼”

为了解决这个问题,我们还需要加一个样式,让这个遮罩层不再是“遮罩层”,而是在文档下面当做背景。

.sawtooth:before {
    ...
    z-index: -1;
}

让“遮罩层”到负一楼去。

两种纯CSS的方式实现优惠券上的锯齿效果

OK,我们想要的效果有了。

而且不管背景换成什么颜色,我们的“优惠券”都不会“露馅”。

两种纯CSS的方式实现优惠券上的锯齿效果

附加:改变形状,生成别样的锯齿

我们可以通过适当修改background的几个参数,将圆形压扁,生成其他形状的锯齿:

.sawtooth {
    background-image: radial-gradient(transparent 0, transparent 4px, #e24141 4px);
    background-size: 12px 8px;
    background-position: -5px 10px;
    position: relative;
}

.sawtooth:before {
    content: ' ';
    display: block;
    background-color: #e24141;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 6px;
    right: 6px;
    z-index: -1;
}

两种纯CSS的方式实现优惠券上的锯齿效果

Tags:两种 种纯 纯C CS 
作者:网络 来源:胡飞飞的个人博客