The implementation of this article is not perfect, only for reference, it is recommended to view the advanced version directly

This article will introduce how to use the radial-gradient in CSS to achieve the effect of coupon style as shown in the figure below:

Draw basic Styles

First, we draw the basic pattern of the coupon, which is very simple, but I won’t go into that.

<div class="voucher">
  <div class="left"></div>
  <div class="right">The full 100 minus 30</div>
</div>/* scss */ .voucher { width: 600px; height: 200px; display: flex; .left { width: 30%; height: 100%; background-color: #f76260; } .right { height: 100%; border: 1px solid #ddd; flex: 1; display: flex; align-items: center; justify-content: center; font-size: 40px; }}Copy the code

Sawtooth implementation anatomy

The jagged portion can actually be viewed as a Mosaic of ten image fragments as shown below. Each segment is 6px wide with a sawtooth radius and 20px high. So all we need to do is draw the segment and repeat the rest.

We add the zigzag style to the pseudo element of voucher and we are done:

&::before {
  content: ' ';
  position: absolute;
  height: 100%;
  width: 6px;
  left: 0;
  top: 0;
  background-image: radial-gradient(circle at 0px 10px, white 6px, #f76260 6px);
  background-size: 6px 20px;
}
Copy the code

The core code here is background-image: radial (circle at 0px 10px, white 6px, #f76260 6px); . Background-image: radial (circle at 0px 10px, white 0, white 6px, #f76260 6px, #676260 100%); , indicates that the radial gradient starts at (0px, 10px) and the shape of the gradient is circular. From 0 to 6px, the gradient gradually changes from white to white, which is a solid color. At 6px, the edge of the image gradually changes from # F76260 to # F76260, also a solid color.

To reuse our sawtooth style code, we can define an SCSS mixin:

$radius < $height / $num */
@mixin leftSawtooth($height.$num.$radius.$color.$bgColor) {
  $segmentHeight: $height / $num;
  height: $height;
  &::before {
    content: ' ';
    position: absolute;
    height: 100%;
    width: $radius;
    left: 0;
    top: 0;
    background-image:
      radial-gradient(circle at 0px $segmentHeight / 2.$bgColor $radius.$color $radius);
    background-size: $radius $segmentHeight; }}Copy the code

In this way, it is very convenient to use:

@include leftSawtooth(600px.10.6px, #f76260, white);
Copy the code

Updated version

The updated version of the sawtooth color and the left part of the background color is not consistent, there will be some implementation differences, but the idea is the same.

First, draw the basic styles:

.voucher {
  width: 600px;
  height: 200px;
  margin: 20px auto;
  display: flex;
  position: relative;
  border: 1px solid #ddd;
  .left {
    width: 30%;
    height: 100%;
    border-right: 1px dashed #ddd;
  }

  .right {
    height: 100%;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 40px; }}Copy the code

Next, draw the sawtooth part. Note that the radius of the circle is 5px blank with a 1px border, so the background fragment needs to be drawn with an extra gradient:

background-image: radial-gradient(circle at 0px 10px.white 5px./* The color inside the circle is the background color */
  #ddd 5px.#ddd 6px.transparent 6px /* The color outside the circle is transparent */
);
Copy the code

Note that we set the color inside the circle to the background color and the color outside the circle to the transparent color. We’ll explain why we did this later. Now it’s getting closer to the goal, but it’s still a bit off:

The solution is to move the pseudo-element one border size to the left. The lines on the left side of the semicircle will be covered by the color inside the circle, while the rest of the semicircle will remain because it is transparent (this is why the color inside the circle is set to background and the color outside the circle is set to transparent).

The complete mixin looks like this:

@mixin leftSawtoothBorder($height.$num.$radius.$bgColor.$borderColor.$borderWidth) {
  $segmentHeight: $height / $num;
  $extendedRadius: $radius + $borderWidth;
  height: $height;
  &::before {
    content: ' ';
    position: absolute;
    height: 100%;
    width: $extendedRadius;
    left: -$borderWidth;
    top: 0;
    background-image: radial-gradient(circle at 0px $segmentHeight / 2.$bgColor $radius.$borderColor $radius.$borderColor $extendedRadius,
      transparent $extendedRadius
    );
    background-size: $extendedRadius $segmentHeight; }}Copy the code