Golak Chandra Satiar
Golak Chandra Satiar

Reputation: 153

How to create reuleaux triangle shape using CSS3

I need a help to make reuleaux triangle shape using CSS3 like below the image. The shape has a white border around. How is it possible?

enter image description here

Upvotes: 6

Views: 1791

Answers (3)

Persijn
Persijn

Reputation: 14990

SVG solution

svg {
  border: 1px solid black;
}
<svg width="400px" viewBox="0 0 100 100">
  <path stroke="black" d="m50 90, 
                          q -40 -20, -40 -80, 
                          q 40 -10, 80 0, 
                          q 0 60, -40 80z" />
</svg>

Upvotes: 3

Stewartside
Stewartside

Reputation: 20905

This shape is possible with pure CSS in a single element with a little bit of creativity.

It is not exactly the shape as above as it has rounded corners but its still pretty darn close.

div {
  width: 200px;
  height: 200px;
  background: blue;
  border-radius: 75% 75% 80% 80% / 15% 15% 150% 150%;
}
<div></div>

Here is another possible way to do it

div {
  width: 200px;
  height: 200px;
  background: blue;
  border-radius: 10% 100% 100% 0 / 100% 100% 10% 0;
  transform: rotate(-45deg);
  margin-left: 50px;
}
<div></div>

Upvotes: 2

Harry
Harry

Reputation: 89750

CSS is not the right tool for creating such shapes even though they can be created using it. They will require multiple real/pseudo-elements, transforms etc and even then maintenance of the curves, their radii etc are very tricky. It gets even more complex when you require borders around them or have to place images or gradients inside them.

The best and recommended tool for creating such shapes is SVG as they have the following pros:

  • SVGs are scalable by nature and so are very good for responsive designs
  • SVG shapes can take images or gradients as fills
  • Curve and radii control is very optimum

Below is a sample snippet for creating the reuleaux triangle shape using SVG. All it needs is a single path element with 3 Quadratic Curveto commands.

svg {
  height: 200px;
  width: 200px;
}
path {
  fill: steelblue;
  stroke: white;
  stroke-width: 2;
}
path.image {
  fill: url(#g-image);
}
body {
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}
<svg viewBox="0 0 105 105" preserveAspectRatio="none">
  <path d="M2,15 q50,-25 100,0 q0,50 -50,85 q-50,-30 -50,-85z" />
</svg>
<svg viewBox="0 0 105 105" preserveAspectRatio="none">
  <defs>
    <pattern id="g-image" width="1" height="1" patternUnits="objectBoundingBox">
      <image xlink:href="http://lorempixel.com/200/200/nature/4" width="200" height="200" />
    </pattern>
  </defs>
  <path d="M2,15 q50,-25 100,0 q0,50 -50,85 q-50,-30 -50,-85z" class="image" />
</svg>


The same can be achieved by using CSS Clip-path with inline SVG for the path also but the support is non-existent in IE for this and hence it is not recommended.

div {
  position: relative;
  background: white;
  height: 200px;
  width: 200px;
  -webkit-clip-path: url(#clipper);
  clip-path: url(#clipper);
}
div:after {
  position: absolute;
  content: '';
  height: calc(100% - 4px);
  width: calc(100% - 4px);
  top: 2px;
  left: 2px;
  background: steelblue;
  -webkit-clip-path: url(#clipper);
  clip-path: url(#clipper);
}
div.image:after{
  background: url(http://lorempixel.com/200/200);
}
body {
  background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
}

/* Just for demo */

div{
  display: inline-block;
}
<svg width="0" height="0">
  <defs>
    <clipPath id="clipper" clipPathUnits="objectBoundingBox">
      <path d="M0,0.15 q0.5,-0.25 1,0 q0,0.5 -0.5,0.85 q-0.5,-0.3 -0.5,-0.85z" />
    </clipPath>
  </defs>
</svg>
<div></div>
<div class='image'></div>

Upvotes: 5

Related Questions