1. The train of thought
How do I draw a shaded triangle with CSS? There are many solutions on the Internet, but in fact, most of them are not perfectly implemented, there are some problems
Let’s say we make a downward triangular arrow and there are two common ways to do it
- With border control, set border-left and border-right to transparent, and border-top to a predetermined color
- Rotate the box by transform
Design of 2.
So let me draw the triangle
<body>
<div class="box"></div>
</body>
Copy the code
CSS styles
.box {
position: relative;
width: 200px;
height: 100px;
background: #ff8605;
box-shadow: 2px 2px 2px rgba(0, 0, 0, 2); }.box::after {
content: ' ';
position: absolute;
bottom: -9px;
left: 45px;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #ff8605;
}
Copy the code
The disadvantage is obvious, we can’t set the shadow by box-shadow, the shadow will be a box
2.1 frame method
If the shadow requirement is not so high, we can define another pseudo-element triangle, but it is similar to the shadow color, this shadow triangle is covered under our original triangle
.box::before {
position: absolute;
bottom: -10px;
left: 45px;
content: ' ';
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid rgba(0, 0, 0, 1); }Copy the code
As is shown in
The advantage is that compatibility is better, the requirements are not strict seems to be enough
But being a strict front end engineer! We still can’t tolerate this implementation
2.2 filter method
The correct posture is the drop shadow() in filter.
The drop-shadow attribute in filter is a real projection, which only projects the shadow of the real graph
Box-shadow only casts shadows on box models
.box::after {
position: absolute;
bottom: -9px;
left: 45px;
content: ' ';
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #ff8605;
filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, .2));
}
Copy the code
Very perfect implementation of the effect, the disadvantage is that compatibility may be poor
Filter Compatibility
(The filter method was suggested by the kids in the comments section, thanks ~~)
2.3 the transform method
The idea of this method is to use the box model shadow for the triangle. Instead of drawing a triangle, we can directly draw a square box and rotate it 45 degrees by the Transform attribute
.box::before {
position: absolute;
bottom: -5px;
left: 45px;
content: ' ';
width: 10px;
height: 10px;
background: #ff8605;
transform: rotate(135deg);
box-shadow: 1px -2px 2px rgba(0, 0, 0, 2); }Copy the code
We seem to have achieved what we wanted, however, there is a problem, but because our shadow area is not large enough, it doesn’t look obvious on the image
When we enlarge the area of the box-shadow, we see the problem
The box is sticking out. How do you fix it
Let’s make another box with the same color as the container and cover the top half.
/* transform method */
.box::before {
position: absolute;
bottom: -5px;
left: 45px;
content: ' ';
width: 10px;
height: 10px;
background: #ff8605;
transform: rotate(135deg);
box-shadow: 1px -2px 5px rgba(0, 0, 0, 2); }.box::after {
position: absolute;
bottom: 0px;
left: 40px;
content: ' ';
width: 20px;
height: 20px;
background: #ff8605;
}
Copy the code
Note that the triangle should be defined before and the overlying box should be defined after so that the box covers the triangle
Effect:
Of course, this approach could affect the contents of the box
3. Final solution code
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>CSS implements Shadowed triangles</title>
<style>
.box {
position: relative;
width: 200px;
height: 100px;
background: #ff8605;
box-shadow: 2px 2px 2px rgba(0, 0, 0, 2); }/ * * / border method
.box::before {
position: absolute;
bottom: -10px;
left: 45px;
content: ' ';
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid rgba(0, 0, 0, 1); }/* drop-shadow */
.box::after {
position: absolute;
bottom: -9px;
left: 45px;
content: ' ';
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-top: 10px solid #ff8605;
filter: drop-shadow(1px 3px 1px rgba(0, 0, 0, .2));
}
/* tranform */
.box::before {
position: absolute;
bottom: -5px;
left: 45px;
content: ' ';
width: 10px;
height: 10px;
background: #ff8605;
transform: rotate(135deg);
box-shadow: 1px -2px 5px rgba(0, 0, 0, 2); }.box::after {
position: absolute;
bottom: 0px;
left: 40px;
content: ' ';
width: 20px;
height: 20px;
background: #ff8605;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
Copy the code
If you have a better way to achieve, feel free to leave a message to me