Search code examples
htmlcsssvg

How to create a rounded hexagon with border using CSS?


I'm sharing the design below.

enter image description here

And my code:

https://jsfiddle.net/09h5coq8/

.hex {
        position: relative;
        margin: 1em auto;
        width: 200px; 
        height: 346.4px;
        border-radius: 20px/10px;
        background: rgb(139,21,186);
        background: linear-gradient(70deg, rgba(139,21,186,1) 0%, rgba(64,13,104,1) 100%);
        background-size:cover;
        transition: opacity .5s;
        transform: rotate(20deg);
        margin-top:125px;
        }
        .hex:before, .hex:after {
        position: absolute;
        width: inherit; height: inherit;
        border-radius: inherit;
        background: inherit;
        content: '';
        }
        .hex:before {
            -webkit-transform: rotate(60deg);
            transform: rotate(60deg);
            background: linear-gradient(180deg, rgba(139,21,186,1) 0%, rgba(64,13,104,1) 100%);
        }
        .hex:after {
            -webkit-transform: rotate(-60deg);
            transform: rotate(-60deg);
            background: linear-gradient(-50deg, rgba(139,21,186,1) 0%, rgba(64,13,104,1) 100%);
        }
       .hex-inside {
        position: absolute;
        width: 150px; 
        height: 259.8px;
        border-radius: 15px/7.5px;
        background: grey;
        transition: opacity .5s;
        z-index:99;
        left:25px;
        top:43.3px;
        }
        .hex-inside:before, .hex-inside:after {
        position: absolute;
        width: inherit; height: inherit;
        border-radius: inherit;
        background: inherit;
        content: '';
        }
        .hex-inside:before {
            -webkit-transform: rotate(60deg);
            transform: rotate(60deg);
        }
        .hex-inside:after {
            -webkit-transform: rotate(-60deg);
        transform: rotate(-60deg);
        }



<div class="hex">
        <div class="hex-inside">
            
        </div>  
    </div>

As you can see; my code has more "sharpen corners" broken "gradient" and not enough feelings. Whats wrong?

How can this be possible to make with "pure css and javascript".

Do I have to make it with SVG?


Solution

  • Here is my idea using clip-path and gooey filter:

    .box {
      width: 300px; /* adjust this to control the size of the shape */
      margin: 20px;
      transform:rotate(-20deg);
    }
    
    .box,
    .box > div > div{
      filter: url('#goo'); /* the SVG filter (adjust the "stDeviation" value to control the radius) */
    }
    
    .box > div {
      padding: 20px; /* thickness of the gradient */
      /* your gradient here */
      background: linear-gradient(70deg, rgba(139,21,186,1), rgba(64,13,104,1), rgba(139,21,186,1));
    }
    
    .box > div,
    .box > div > div > div {
      /* hexagon shape (https://bennettfeely.com/clippy/) */
      clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
    }
    
    .box > div > div > div  {
      padding-top: 91%; /* keep the ratio of the shape */
    }
    
    .box > div > div > div::before {
      content:"";
      position:absolute;
      top:-10%;
      left:-10%;
      right:-10%;
      bottom:-10%;
      background:url(https://picsum.photos/id/1069/800/800) center/cover;
      transform:rotate(20deg); /* rotate the image back */
    }
    
    * {
      box-sizing: border-box;
    }
    <div class="box">
      <div>
        <div>
          <div></div>
        </div>
      </div>
    </div>
    
    <svg style="visibility: hidden; position: absolute;" width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1">
        <defs>                                  
            <filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />    
                <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9" result="goo" />
                <feComposite in="SourceGraphic" in2="goo" operator="atop"/>
            </filter>
        </defs>
    </svg>