1

I want to create a effect as below with CSS, initially, I was thinking to merge two rectangle with rounded corner, but I can't use that way since it is a sharp angle, not rounded, look at the area in cirle, this is most hard part.

enter image description here

So I do it this way:
1. Create a rounded rectangle as the outline. with border color gray.
2. Create a tringle with gray color at the center of the left side of the rect.
3. Create another triangle with white color to cover the gray triangle in step 2, with a little offset, to make it appears as the border of the rect.

Here is the effect:

enter image description here

My question is:
1. How can I add the right part? it seems I can only draw one shap at the same time in CSS selector :before or :after.
2. What if i want to add border shadow effect? the white triangle will appear if I add shadow of the rect, it's ugly.
3. Or any other way to make this effect?

Here is the code:

.triangle_left {
  width: 600px;
  height: 600px;
  position: relative;
  margin: 20px auto;
  border: 2px solid #cccccc;
  /* box-shadow: 0px 0px 8px 1px darkgrey; */
  border-radius: 20px;
}

.triangle_left:before {
  content: '';
  width: 0;
  height: 0;
  border: 20px solid transparent;
  border-left-color: #cccccc;
  position: absolute;
  left: 0;
  top: 50%;
  margin-top: -20px;
}

.triangle_left:after {
  content: '';
  width: 0;
  height: 0;
  border: 18px solid transparent;
  border-left-color: white;
  position: absolute;
  left: -2px;
  top: 50%;
  margin-top: -18px;
}
<div class="triangle_left">

</div>

Try it here in JSFiddle

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
zdd
  • 8,258
  • 8
  • 46
  • 75
  • 1
    I have used this website quite often to find the shapes I need to create: https://css-tricks.com/examples/ShapesOfCSS/ – Luay Jul 16 '18 at 14:50
  • Thanks, I know that link, but that's not all. – zdd Jul 16 '18 at 14:54
  • 2
    1. True, the pseudo-_elements_ can mostly be treated as an actual element, but they are _one_ element, and therefore basically one shape. But with lots of effort some people can build quite awesome effects. If you could manage to do the left side with just `::before`, you could do the right side with `::after`. 2.True as well. You're hiding part of the border with the overlay. Maybe you could give it an inner shadow. 3. SVG. A scalable vector graphic that gives you way more possibilities. – GolezTrol Jul 16 '18 at 14:55
  • 1
    So for 1. This is not perfect, but maybe you can finetune it until you're happy. I'm using a rotated pseudo-element and gave it an inset shadow that shows up on 2 sides (and unfortunately a bit on other sides as well). The pseudo-element itself has a white background that makes it hide a bit of the existing shadow. If you can fine-tune this to your need, you can then mirror the effect for the `::after` pseudo-element and use that for the right side. https://jsfiddle.net/v21xek78/1/ – GolezTrol Jul 16 '18 at 15:13
  • You could do it with a containing element https://jsfiddle.net/7tun48es/65/ which is in one of the answers in the marked duplicate – Huangism Jul 16 '18 at 15:27
  • Thanks @GolezTrol, this is really help! – zdd Jul 17 '18 at 11:26

2 Answers2

5

An idea is to build the shape using gradient and rely on drop-shadow filter

.box {
  margin-top:50px;
  border-radius:10px;
  width:200px;
  height:200px;
  background:
  /*the middle line */
    repeating-linear-gradient(to right,gold 0px,gold 5px,transparent 5px,transparent 10px) center/calc(100% - 40px) 2px,
    /*The background*/
    linear-gradient(to bottom right,#fff 49%,transparent 50%) 100% calc(50% - 10px) / 20px 20px,
    linear-gradient(to top    right,#fff 49%,transparent 50%) 100% calc(50% + 10px) / 20px 20px,
    linear-gradient(to bottom left ,#fff 49%,transparent 50%) 0    calc(50% - 10px) / 20px 20px,
    linear-gradient(to top    left ,#fff 49%,transparent 50%) 0    calc(50% + 10px) / 20px 20px,
    
    linear-gradient(#fff,#fff) top    right / 20px calc(50% - 20px),
    linear-gradient(#fff,#fff) bottom right / 20px calc(50% - 20px),
    
    linear-gradient(#fff,#fff) top    left / 20px calc(50% - 20px),
    linear-gradient(#fff,#fff) bottom left / 20px calc(50% - 20px),
    
    linear-gradient(#fff,#fff) center/calc(100% - 40px) 100%;
   background-repeat:no-repeat;
   filter:drop-shadow(0 0 5px #000); 
}

body {
  background:pink;
}
<div class="box">
</div>

CSS transparent triangle with shadow

You can also do it with clip-path but you need an extra wrapper where you apply the drop-shadow filter

.box {
  margin-top: 50px;
  border-radius: 10px;
  width: 200px;
  height: 200px;
  background: 
   repeating-linear-gradient(to right, gold 0px, gold 5px, transparent 5px, transparent 10px) center/100% 2px no-repeat,
   #fff;
  clip-path:polygon(
  0 0,100% 0,
  100% calc(50% - 20px),calc(100% - 20px) 50%,100% calc(50% + 20px),
  100% 100%, 0 100%,
  0 calc(50% + 20px),20px 50%,0 calc(50% - 20px)
  );
}

.drop {
  filter: drop-shadow(0 0 5px #000);
}

body {
  background: pink;
}
<div class="drop">
  <div class="box">
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
0

In my opinion you would either have to work with borders (as you did) or SVGs. For the shadow it does not work with borders and regular css-shadows, so you want to apply drop-shadow as a filter (or you can use a SVG for the shadow).

This is what I came up with

.triangle_left {
  width: 600px;
  height: 600px;
  position: relative;
  margin: 20px auto;
  border: 2px solid #cccccc;
  /* box-shadow: 0px 0px 8px 1px darkgrey; */
  border-radius: 20px;
}

.triangle_left:before {
  content: '';
  width: 0;
  height: 0;
  border-top: 30px solid transparent;
  border-left: 30px solid white;
  border-bottom: 30px solid transparent;
  filter: drop-shadow(4px 0px 0px #ccc);
  position: absolute;
  left: -6px;
  top: 50%;
}

.triangle_left:after {
  content: '';
  width: 0;
  height: 0;
  border-top: 30px solid transparent;
  border-right: 30px solid white;
  border-bottom: 30px solid transparent;
  filter: drop-shadow(-4px 0px 0px #ccc);
  position: absolute;
  right: -6px;
  top: 50%;
}
<div class="triangle_left">

</div>
Carle B. Navy
  • 1,156
  • 10
  • 28