Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wave (or shape?) with border on CSS3

I need to implement a wave shape with CSS3, I tried to implement with CSS3 Shapes, but I has not reached the desired result.

* {
  margin: 0;
  padding: 0;
}
body {
  background: #007FC1;
}
.container,
.panel {
  border-bottom: 4px solid #B4CAD8;
}
.container {
  background-color: #fff;
}
.container > .text {
  padding: 0.5em;
}
.panel {
  position: relative;
  float: right;
  width: 200px;
  height: 40px;
  margin-top: -4px;
  background-color: #fff;
  line-height: 42px;
  text-align: center;
}
.panel:before {
  content: '';
  position: absolute;
  left: -44px;
  width: 0;
  height: 0;
  border-top: 44px solid #B4CAD8;
  border-left: 44px solid transparent;
}
<div class="container">
  <div class="text">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis.</p>
  </div>
</div>
<div class="panel">this is a panel</div>

It is impossible to implement border and set background color on the wave shape. I need to achieve this result:

wave shape with border

like image 335
Artem Avatar asked Jan 05 '15 10:01

Artem


People also ask

How do you make a wave shape in CSS?

One of the easiest ways to add waves to an element is the ShapeDriver tool. It allows you to create a wave effect generating an SVG path and required CSS code to style it. To add more complex layered waves, you can use the Haikei app to randomly generate a variety of beautiful waves, blobs, and other shapes.

What is CSS shape?

CSS is capable of making all sorts of shapes. Squares and rectangles are easy, as they are the natural shapes of the web. Add a width and height and you have the exact size rectangle you need. Add border-radius and you can round that shape, and enough of it you can turn those rectangles into circles and ovals.


2 Answers

You could use svg instead of .panel(div) and float it to the right.

enter image description here

body {
  background: #007FC1;
}
.container {
  border-bottom: 4px solid #B4CAD8;
}
.container {
  background-color: #fff;
  z-index: -1;
}
.container > .text {
  padding: 0.5em;
}
.panel {
  position: relative;
  float: right;
  margin-top: -4px;
}
<div class="container">
  <div class="text">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis.</p>
  </div>
</div>
<svg class="panel" width="200" height="54">
  <path d="M0,0 h7 q9,3 12.5,10 l13,30 q3.2,10 13,10 h157 v-50z" fill="white" />
  <path transform="translate(0, -0.5)" d="M0,2 h7 q10,2 13,10 l13,30 q3,9 13,10 h157" fill="none" stroke="#B4CAD8" stroke-width="4" />
  <text x="110.5" y="25" text-anchor="middle">This is a panel</text>
</svg>

You could also get a shape other way around.

enter image description here

body {
  background: #007FC1;
}
.container {
  border-bottom: 4px solid #B4CAD8;
}
.container {
  background-color: #fff;
  z-index: -1;
}
.container > .text {
  padding: 0.5em;
}
.panel {
  position: relative;
  float: right;
  margin-top: -4px;
}
<div class="container">
  <div class="text">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis.</p>
  </div>
</div>
<svg class="panel" width="200" height="59">
  <path d="M0,0 h30 q15,0 5,15 l-17,20 q-13,16 5,15 h200 v-58" fill="white" />
  <path transform="translate(0, -0.5)" d="M0,2 h30 q15,0 5,15 l-17,20 q-13,16 5,15 h200" fill="none" stroke="#B4CAD8" stroke-width="4" />
  <text x="115" y="30" text-anchor="middle">This is a panel</text>
</svg>

A bit more curvy.

enter image description here

body {
  background: #007FC1;
}
.container {
  border-bottom: 4px solid #B4CAD8;
}
.container {
  background-color: #fff;
  z-index: -1;
}
.container > .text {
  padding: 0.5em;
}
.panel {
  position: relative;
  float: right;
  margin-top: -4px;
}
<div class="container">
  <div class="text">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis.</p>
  </div>
</div>
<svg class="panel" width="200" height="54">
  <path d="M0,0 h7 q55,-5 15,35 q-13,16 15,15 h200 v-54" fill="white" />
  <path transform="translate(0, -0.5)" d="M0,2 h7 q55,-5 15,35 q-13,16 15,15 h200" fill="none" stroke="#B4CAD8" stroke-width="4" />
  <text x="115" y="30" text-anchor="middle">This is a panel</text>
</svg>

How about a real wave shape?

enter image description here

body {
  background: #007FC1;
}
.container {
  border-bottom: 4px solid #B4CAD8;
}
.container {
  background-color: #fff;
  z-index: -1;
}
.container > .text {
  padding: 0.5em;
}
.panel {
  position: relative;
  float: right;
  margin-top: -24px;
}
<div class="container">
  <div class="text">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis.</p>
  </div>
</div>
<svg class="panel" width="200" height="85">
  <path d="M0,24 a10,7.5 1 1,0 0,-15 q20,-11 40,26" fill="#007FC1" />
  <path d="M0,22 m0,-15 q40,-10 40,60 q0,15 15,15 h146 v-65" fill="white" />
  <path d="M0,22 a10,7.5 1 1,0 0,-15 q40,-10 40,60 q0,15 15,15 h146" fill="none" stroke="#B4CAD8" stroke-width="4" />
  <text x="110.5" y="55" text-anchor="middle">This is a panel</text>
</svg>
like image 69
Weafs.py Avatar answered Sep 20 '22 15:09

Weafs.py


Here is a method to achieve the wave shape using CSS. (This is only an illustration on how to achieve it with CSS but SVG is still the recommended tool to use.)

  1. The base is a div which is the white rectangular box. In the box, the bottom 50px has transparent color, the 3px after that has lightblue color and the rest has white color. This makes it look like the top half is a white rectangle with a lightblue border. The transparent 50px part at the bottom helps to make the cut out area look as though it is not a part of the container.
  2. Pseudo-elements are skewed and positioned at the bottom right of the parent container to produce the curved effect. They also have some box-shadows added to produce the border.
  3. The content is added using a separate div and is again positioned at the bottom right corner of the parent.

.content {
  position: relative;
  height: 150px;
  padding: 10px;
  background: linear-gradient(270deg, transparent 200px, lightblue 200px) no-repeat, linear-gradient(0deg, transparent 50px, white 50px);
  background-position: 100% 117px, 100% 100%;
  background-size: 100% 3px, 100% 100%;
  overflow: hidden;
}
.content:before {
  position: absolute;
  content: '';
  height: 25px;
  width: 50px;
  bottom: 25px;
  right: 170px;
  background: transparent;
  border-top-right-radius: 18px;
  box-shadow: 4px -3px 0px lightblue, 4px 0px 0px lightblue, 20px 0px 0px white;
  transform: skew(30deg);
  z-index: 2;
}
.content:after {
  position: absolute;
  content: '';
  right: 0px;
  bottom: 0px;
  height: 50px;
  width: 177px;
  background: white;
  border-bottom-left-radius: 18px;
  box-shadow: inset 4px -3px 0px lightblue;
  transform-origin: right top;
  transform: skew(30deg);
}
.panel {
  position: absolute;
  bottom: 3px;
  right: 0px;
  height: 50px;
  width: 135px;
  line-height: 50px;
  z-index: 3;
}


/* just for demo */
body {
  background: linear-gradient(90deg, crimson, indianred, purple);
  font-family: Calibri;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='content'>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis
  <div class='panel'>This is a panel</div>
</div>

enter image description here

Here is a version with a transparent background for the container (instead of white).

enter image description here


Older version using Rotate Transform:

  1. The base is a div which is the white rectangular box with a white background and an inset light blue color shadow .
  2. A small portion is created for the right side (which has the "This is Panel" text) using a pseudo-element and is positioned absolutely towards the right corner of the parent div. The content of this pseudo-element is set using the data-content attribute. The curved corner on the bottom-left of this box is achieved using border-radius.
  3. The curved area flowing from the bottom of the parent div to the bottom of the panel pseudo-element is another pseudo-element which is created and positioned absolutely as required. It also uses a box-shadow to produce the light blue line while its background merges with the background of the body. This pseudo-element is rotated using transforms to achieve a slanted effect.

body {
  background: #007FC1;
  font-family: Calibri;
}
div {
  position: relative;
  height: 100px;
  width: auto;
  padding-top: 10px;
  padding-left: 10px;
  background: white;
  box-shadow: inset 0px -3px 0px lightblue;
}
div:after {
  position: absolute;
  content: attr(data-content);
  right: 0px;
  padding-left: 20px;
  bottom: -47px;
  height: 50px;
  width: 145px;
  line-height: 40px;
  background: white;
  border-bottom-left-radius: 7px;
  box-shadow: inset 1px -3px 0px lightblue;
}
div:before {
  content: '';
  position: absolute;
  right: 179.5px;
  bottom: -48px;
  height: 57px;
  width: 7px;
  background: transparent;
  border-top-right-radius: 6px;
  box-shadow: inset -3px 2px 1px lightblue, 16px -10px 0px 11px white;
  transform: rotateZ(-36deg);
  z-index: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div data-content="This is a panel">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis</div>

Sample using Skew Transform:

Credit to web-tiki for this idea. The same as above can be done using skew transformation also instead of rotate like in the below sample.

body {
  background: #007FC1;
  font-family: Calibri;
}
div {
  position: relative;
  height: 100px;
  width: auto;
  padding-top: 10px;
  padding-left: 10px;
  background: white;
  box-shadow: inset 0px -3px 0px lightblue;
}
div:after {
  position: absolute;
  content: attr(data-content);
  right: 0px;
  padding-left: 15px;
  bottom: -47px;
  height: 50px;
  width: 150px;
  line-height: 40px;
  background: white;
  border-bottom-left-radius: 10px;
  box-shadow: inset 2px -3px 1px lightblue, 2px 1px 2px #007FC1;
}
div:before {
  position: absolute;
  content: '';
  right: 174px;
  bottom: -44px;
  height: 47px;
  width: 15px;
  background: transparent;
  border-top-right-radius: 4px;
  box-shadow: inset -4px 3px 1px lightblue, 20px -10px 0px 6px white;
  z-index: 2;
  transform: skew(33deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div data-content="This is a panel">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates nam fuga eligendi ipsum sed ducimus quia adipisci unde atque enim quasi quidem perspiciatis totam soluta tempora hic voluptatem optio perferendis</div>
like image 25
Harry Avatar answered Sep 19 '22 15:09

Harry