preface

A few days ago, I happened to see the function of missing Angle rectangle, and the first idea in my head was to make an absolute positioning pseudo element, where I need to block where, or chat with UI little brother. Suddenly, I had a flash of inspiration, and REMEMBERED the book “CSS Revealed” that I had turned over before. I remembered that there was this chapter, so I had this article.

Without further ado, let’s put a sketch first

Lack of Angle


1. Pseudo-element implementation

<div class="bg cover"></div>
Copy the code
.bg{ width: 120px; height: 80px; background: #58a; } /* The following elements use this style */Copy the code

.cover{ position: relative; } .cover::before { content: ''; width: 0; height: 0; position: absolute; right: 0; bottom: 0; border: 5px solid #fff; border-top-color: transparent; border-left-color: transparent; } .cover::after{ content: ''; width: 0; height: 0; position: absolute; left: 0; top: 0; border: 5px solid #fff; border-bottom-color: transparent; border-right-color: transparent; }

Use the pseudo-element to draw a triangle with the same color as the background, and then absolutely locate the area to be covered, as shown below, but this can only make two missing angles at most


2. Gradual implementation

The CSS syntax

background-image: linear-gradient(direction, color-stop1, color-stop2, ...) ;Copy the code
value describe
direction Specify the direction (or Angle) of the gradient with an Angle value.
color-stop1, color-stop2,… Used to specify the start and end colors of the gradient.

The gradient can accept an Angle (such as 45deg) as the direction, and the color position information can also be an absolute length value.


The picture is from the official website. P is a bit more complete

45deg: indicates the direction from the lower left to the upper right. -45deg: indicates the direction from the lower right to the upper left……

<div class="bg missAngle"></div>
Copy the code
.missAngle{
    background: linear-gradient(-45deg, transparent 10px, #58a 0);
}
Copy the code

Implement multiple angles

<div class="bg rect"></div>
Copy the code
.rect{ background: linear-gradient(135deg, transparent 10px, #58a 0) top left, linear-gradient(-135deg, transparent 10px, #58a 0) top right, linear-gradient(-45deg, transparent 10px, #58a 0) bottom right, linear-gradient(45deg, transparent 10px, #58a 0) bottom left; background-size: 50% 50%; background-repeat: no-repeat; /* Internet Explorer 9 and earlier versions do not support gradients. * /}Copy the code

This is actually a Mosaic of four shapes, as shown below

background-size: 50% 50%; Indicates that each small graph is 50% wide and 50% high

Arc corner cut

<div class="bg cricle"></div>
Copy the code
.cricle{
  background: radial-gradient(circle at top left, transparent 10px, #58a 0) top left,
          radial-gradient(circle at top right, transparent 10px, #58a 0) top right,
          radial-gradient(circle at bottom right, transparent 10px, #58a 0) bottom right,
          radial-gradient(circle at bottom left, transparent 10px, #58a 0) bottom left;
  background-size: 50% 50%;
  background-repeat: no-repeat;
}
Copy the code

Finally, Gradients are not supported in Internet Explorer 9 and earlier versions.

There is a problem here. When you pull the browser, when the width is squeezed less than the defined width, there may be white gaps






Clip – the path to achieve

The clip-path CSS property creates a clipping area where only parts of the element can be displayed. The part inside the region is displayed, and the part outside the region is hidden.

clip-path: polygon(x y, x1 y1, x2 y2, x3 y3, ...)
Copy the code

x y, x1 y1, x2 y2, x3 y3, … These represent the points in the coordinate axis, and draw a closed graph from all the points

<div class="bg rect-clip"></div>
Copy the code
.rect-clip{
  background-image: url(./im.jpg);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  clip-path: polygon(15px 0, calc(100% - 15px) 0, 100% 15px, 
    100% calc(100% - 15px), calc(100% - 15px) 100%,
    15px 100%, 0 calc(100% - 15px), 0 15px)
}
Copy the code

Effect:

Total width 120px calc(100%-15px) => 105px 100% => 120pxCopy the code

The corresponding points are joined together to form a missing rectangle


Clip-path can be used to draw various shapes such as diamonds and pentagons, as shown in the picture below

<div class="bg clip5"></div>
Copy the code
.clip5{ margin-left: 30px; /*clip-path: inset(25% 0 25% 0 round 0 25% 0 25%); */ clip-path: inset(0 round 0 25%); / /* inset(<top> <right> <bottom> <left> round <top-radius> <right-radius> <bottom-radius> <left-radius>) */ /* Inset uses four values (in the order of "top, right, bottom, left") to set the radius of the corner. * /}Copy the code

For animation

<div class="line-box">
	<div class="line line1"></div>
	<div class="line line2"></div>
	<div class="line line3"></div>
</div>
Copy the code
.line-box{ width: 100px; height: 60px; } .line{ width: 100%; height: 100%; background: #26b91a; } .line1{ -webkit-clip-path: polygon(80% 0, 40% 40%, 80% 80%); clip-path: polygon(80% 0, 40% 40%, 80% 80%); animation: a 2s 1s infinite; } .line2{ clip-path: polygon(10% 10%, 60% 40%, 50% 90%); animation: b 2s 1s infinite; } .line3{ clip-path: polygon(20% 20%, 30% 20%, 30% 50%, 20% 50%); animation: c 2s 1s infinite; } @keyframes a{ 90% { background: #1f351f; } 100% { clip-path: polygon(50% 40%, 25% 100%, 75% 100%); } } @keyframes b{ 90% { background: #1f351f; } 100% { clip-path: polygon(50% 0, 0% 100%, 100% 100%); } } @keyframes c{ 90% { background: #1f351f; } 100% { clip-path: polygon(40% 0, 60% 0, 60% 100%, 40% 100%); }}Copy the code

Clip-path is a website that generates shapes (including dragging custom shapes) and generates code directly.

Although this can draw various shapes, but compatibility is not very good, Google version 79, Firefox 71 test is normal, IE is not compatible, please see here


Missing Angle frame

<div class="out-rect">
	<div class="in-rect"></div>
</div>
Copy the code
.out-rect {
    margin-top: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 200px;
    height: 80px;
    padding: 5px;
    background: linear-gradient(-45deg, transparent 10px, #58a 0) top right;
    background-size: 100% 100%;
    background-repeat: no-repeat;
}
.in-rect{
    width: 100%;
    height: 100%;
    background: linear-gradient(-45deg, transparent 8px, #fff 0) top right;
    background-size: 100% 100%;
    background-repeat: no-repeat;
}
Copy the code

The effect is as follows:The width and height of the inner rectangle follow the size of the parent div, as long as it is vertically centered. The padding value is the width of the final rendered border

Angle

Linear-gradient is also used to achieve this, adding a fold Angle on the basis of the missing rectangle

The renderings are as follows:

Implement the first one first

<div class="bg foldingAngle"></div>
Copy the code
.bg{ width: 120px; height: 80px; background: #58a; } .foldingAngle{ background: Linear-gradient (to left bottom, transparent 50%, rgba(0, 0, 0, 0.4) 0) no-repeat 100/1.4em 1.4em, linear-gradient(-135deg, transparent 1em, #58a 0); }Copy the code

rendering

Linear-gradient (to left bottom, transparent 50%, Rgba (0, 0, 0, 0.4) 0) no-repeat 100% 0/1.4em 1.4em in the lower left direction, 0 size: 1.4EM 1.4EMCopy the code

As follows:The triangle is a 45° right triangle with sides 1.4em and hypotenuse 1.4/√2 ≈ 1

So draw a rectangle with a missing Angle of 1em

Linear-gradient (-135DEg, Transparent 1em, #58a 0) -135DEg draws a missing rectangle in the lower left directionCopy the code

The two gradients overlap, so the picture looks like:

Be sure to draw the smaller triangle first and then the missing rectangle, otherwise the rectangle will cover the smaller triangle

Fold the lower right corner

<div class="bg foldingAngle2"></div>
Copy the code
.foldingAngle2{ background: Linear-gradient (to left Top, transparent 50%, Rgba (0, 0, 0, 0.4) 0) no-repeat linear-gradient(-45deg, transparent 1em, #58a 0); }Copy the code

This looks a little unreal, and in reality the Angle is not always 45 degrees

Now let’s draw a 30 degree Angle. Let’s draw a missing rectangle

<div class="bg foldingAngle2"></div>
Copy the code
.foldingAngle2{
	margin-top: 30px;
    position: relative;
    border-radius: .3em;
	background: linear-gradient(-150deg, transparent 1em, #58a 0);
}
Copy the code

Now let’s fold the Angle

According to the red numbers above, fold Angle width 2/√3 ≈ 1.15em Length: 2em Draw the fold Angle

.foldingAngle2::before{ content: ''; position: absolute; right: 0; top: 0; Width: 1.15 em. height: 2em; background: Linear-gradient (to left bottom, transparent 50%, Rgba (0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.3)) border-bottom-left-radius: inherit; }Copy the code

A rotating

.foldingAngle2::before{ content: ''; position: absolute; right: 0; top: 0; Width: 1.15 em. height: 2em; background: Linear-gradient (to left bottom, transparent 50%, Rgba (0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.3)) transform: rotate(-30deg); transform-origin: bottom right; /* Make the bottom right corner of the triangle the center of the rotation */}Copy the code

Move it up to offset 2-1.15=0.85em and add some shadows

.foldingAngle2::before{ content: ''; position: absolute; right: 0; top: 0; Width: 1.15 em. height: 2em; background: Linear-gradient (to left bottom, transparent 50%, Rgba (0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0.3)) The transform: translateY (0.85 em) rotate 30 deg (-); transform-origin: bottom right; box-shadow: -.2em .2em .3em -.1em rgba(0, 0, 0, .15); border-bottom-left-radius: inherit; /* border-radius */}Copy the code

This is the final result

Changing the Angle and width calculations is a bit tricky, so you can use the preprocessor @mixin

Ok, end 👏

This article is formatted using MDNICE