Search code examples
csscss-shapescss-mask

Creating a wavy border on all sides using CSS


Using this generator I can create the wavy border I'm after on either the top and bottom or left and right, but I'm having trouble combining these masks to create a wavy border all the way around.

Top and Bottom

.box {
background-color: aqua;
width: 500px;
height: 500px;
  --mask:
    radial-gradient(78.75px at 50% 111px,#000 99%,#0000 101%) calc(50% - 120px) 0/240px 51% repeat-x,
    radial-gradient(78.75px at 50% -51px,#0000 99%,#000 101%) 50% 60px/240px calc(51% - 60px) repeat-x,
    radial-gradient(78.75px at 50% calc(100% - 111px),#000 99%,#0000 101%) calc(50% - 120px) 100%/240px 51% repeat-x,
    radial-gradient(78.75px at 50% calc(100% + 51px),#0000 99%,#000 101%) 50% calc(100% - 60px)/240px calc(51% - 60px) repeat-x;
  -webkit-mask: var(--mask);
          mask: var(--mask);
}
<div class="box"></div>

Left and Right

.box {
background-color: aqua;
width: 500px;
height: 500px;
 --mask:
    radial-gradient(78.75px at 111px 50%,#000 99%,#0000 101%) 0 calc(50% - 120px)/51% 240px repeat-y,
    radial-gradient(78.75px at -51px 50%,#0000 99%,#000 101%) 60px 50%/calc(51% - 60px) 240px repeat-y,
        radial-gradient(78.75px at calc(100% - 111px) 50%,#000 99%,#0000 101%) 100% calc(50% - 120px)/51% 240px repeat-y,
    radial-gradient(78.75px at calc(100% + 51px) 50%,#0000 99%,#000 101%) calc(100% - 60px) 50%/calc(51% - 60px) 240px repeat-y;
  -webkit-mask: var(--mask);
          mask: var(--mask);
}
<div class="box"></div>


Solution

  • I have made it here: https://css-shape.com/wavy-box/

    .wavy-box {
      --s: 35px;  /* control the size of the wave */
      --w: 350px; /* preferred  width */
      --c:#CD8C52;
      
      width: round(var(--w),2*var(--s)); 
      aspect-ratio: 1;
      padding: var(--s);
      box-sizing: border-box;
      border-radius: calc(1.5*var(--s));
      --R:calc(var(--s)/sqrt(2)) at;
      --g:radial-gradient(var(--R) 50%,var(--c) calc(100% - 1px),#0000) 
         0 0/calc(2*var(--s)) calc(2*var(--s));
      --_c:#0000 100%,var(--c) calc(100% + 1px);
      --_b:calc(2*var(--s)) calc(51% - var(--s)/2) repeat-x;
      background: var(--g),
        radial-gradient(var(--R) 50% calc(100% + var(--s)/2),var(--_c)) 
         var(--s) calc(100% - var(--s)/2)/var(--_b),
        radial-gradient(var(--R) 50% calc(      var(--s)/-2),var(--_c)) 
         var(--s) calc(       var(--s)/2)/var(--_b);
      --_m:var(--s)/calc(51% - var(--s)/2) calc(2*var(--s)) repeat-y;
      mask: var(--g),
        radial-gradient(var(--R) calc(100% + var(--s)/2) 50%,var(--_c))
         calc(100% - var(--s)/2) var(--_m),
        radial-gradient(var(--R) calc(      var(--s)/-2) 50%,var(--_c)) 
         calc(       var(--s)/2) var(--_m);
    }
    /* if round() is not supported we work with an increment method */
    @supports not (opacity:round(1,1)) {
      .wavy-box {
        --n: 5;
        width: calc(var(--n)*2*var(--s));
      }
    }
    <div class="wavy-box"></div>

    If you want a version with gradient coloration check this link where I am using a more complex configuration: https://css-tip.com/image-wavy-borders-2/