luqo33
luqo33

Reputation: 8361

Creating an irregular border with CSS overlapping colours

How would you go about creating an irregular border with variable colours like the one in the screenshot?

enter image description here

I considered creating a border image in a graphics editor and then using border-image property as described in the docs.

However, this technique would not allow me to achieve the effect of multiple background colours (grey and white in the screenshot) entering the border "waves".

Another solution would be to just produce the whole background white and grey in say Photoshop, and the just use it on the website. I really wanted to avoid this for performance reasons, and would prefer to just produce a grey, checked pattern fragment and repeat it.

Moreover, as you can see in the screenshot, the dark fragment is an image from a carousel - the images will all come in different colours so applying a border-image to the carousel container is not a solution either.

I would appreciate some advice. Thanks.

Upvotes: 2

Views: 1138

Answers (1)

Harry
Harry

Reputation: 89750

Using SVG:

You can do this using SVG. I would say it is pretty complex because the approach uses patterns for the repeating circles, a mask with the pattern as its fill to produce the transparent cuts. This mask is then applied to the image to produce the full effect. This in my opinion is the closest to what you want and also has good browser support. It works fine in IE10+, Edge, Firefox, Chrome, Opera and Safari.

There are a couple of points to note though - (1) You would have to somehow get your carousel work with SVG image because otherwise mask will have no effect (2) the radius of circles change as the width of the container change and so you'd either have to use a fixed size container (or) assign width of the container to the viewBox attribute using JS (or find some setting to prevent the radius change from happening, I don't know of any) .

.masked {
  position: relative;
  height: 175px;
  width: 100%;
  background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
  background-size: 51% 100%;
  background-repeat: no-repeat;
  background-position: 0% 0%, 100% 0%;
  padding-top: 100px;
}
.masked svg {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 100px;
  width: 100%;
}
path {
  fill: #fff;
}
image {
  mask: url("#mask");
}
<div class='masked'>
  <svg viewBox='0 0 1200 100' preserveAspectRatio='none'>
    <defs>
      <pattern id="circles" patternUnits="userSpaceOnUse" width="10" height="100">
        <path d="M0,0 L10,0 10,95 A5,5 0 0,0 0,95 L0,0" />
      </pattern>
      <mask id="mask">
        <rect height="100%" width="100%" fill="url(#circles)" />
      </mask>
    </defs>
    <image xlink:href='http://lorempixel.com/1200/100/nature/1' x="0" y="0" height="100%" width="100%" />
  </svg>
  Lorem Ipsum Dolor Sit Amet...
</div>

Using CSS:

This can be done using CSS masks but unfortunately the browser support for this feature is terrible. It is currently supported only in WebKit powered browsers. If other browsers need not be supported then this is a wonderful option. All that we need to do is create a radial gradient (that repeats in X axis) for the mask like in the below snippet, give it the required size and position it accordingly.

.masked {
  position: relative;
  height: 175px;
  width: 100%;
  background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
  background-size: 51% 100%;
  background-repeat: no-repeat;
  background-position: 0% 0%, 100% 0%;
  padding-top: 80px;
}
.masked:before {
  position: absolute;
  content: '';
  top: 0px;
  height: 80px;
  width: 100%;
  background: url(http://lorempixel.com/1000/100/nature/1);
  -webkit-mask-image: linear-gradient(to bottom, black, black), radial-gradient(circle at 50% 100%, transparent 50%, black 55%);
  -webkit-mask-size: 100% calc(100% - 12px), 12px 12px;
  -webkit-mask-position: 0% 0%, 0px 68px;
  -webkit-mask-repeat: repeat-x;
}
<div class="masked">Lorem Ipsum Dolor Sit Amet</div>

Upvotes: 9

Related Questions