How can I create a wavy shape CSS? - html

Please see the image below for what I am trying to create:
I have the following so far but it needs to be more ''frequent'' like increasing the frequency rate of a sin or cosine wave.
#wave {
position: relative;
height: 70px;
width: 600px;
background: #e0efe3;
}
#wave:before {
content: "";
display: block;
position: absolute;
border-radius: 100% 50%;
width: 340px;
height: 80px;
background-color: white;
right: -5px;
top: 40px;
}
#wave:after {
content: "";
display: block;
position: absolute;
border-radius: 100% 50%;
width: 300px;
height: 70px;
background-color: #e0efe3;
left: 0;
top: 27px;
}
<div id="wave"></div>

I have an online generator for the below code: https://css-generators.com/wavy-shapes/
Here is an idea with radial-gradient and CSS variables where you can easily control the shape:
.wave {
--c:red; /* Color */
--t:5px; /* Thickness */
--h:50px; /* Height (vertical distance between two curve) */
--w:120px; /* Width */
--p:13px; /* adjust this to correct the position when changing the other values*/
background:
radial-gradient(farthest-side at 50% calc(100% + var(--p)), #0000 47%, var(--c) 50% calc(50% + var(--t)),transparent calc(52% + var(--t))),
radial-gradient(farthest-side at 50% calc(0% - var(--p)), #0000 47%, var(--c) 50% calc(50% + var(--t)),transparent calc(52% + var(--t)));
background-size: var(--w) var(--h);
background-position: calc(var(--w)/2) calc(var(--h)/2),0px calc(var(--h)/2);
border:1px solid;
margin:5px 0;
display:inline-block;
width:300px;
height:150px;
}
<div class="wave"></div>
<div class="wave" style="--w:200px;--h:40px;--p:10px; --t:8px;--c:purple"></div>
<div class="wave" style="--w:80px ;--h:20px;--p:5px; --t:3px;--c:blue;"></div>
<div class="wave" style="--w:100px;--h:30px;--p:14px;--t:10px;--c:green;"></div>
Here is a Codepen to play with the code

Related

Add semi circle curve for a div at left and right using background color - CSS [duplicate]

This question already has answers here:
CSS Cut out circle from a rectangular shape
(3 answers)
Closed 1 year ago.
Can anyone help me with how to get the style like in the image attached below using background colour for a div? I tried adding using pseudo-classes before and after but doesn't seem to be coming through.
.card {
height: 190px;
background: #070B32;
width: 360px;
position: relative;
}
.card:before {
background: #070B32;
position: absolute;
content: "";
left: 0;
height: 50px;
border-radius: 50% 50% 0 0;
}
.card:after {
background: #070B32;
position: absolute;
content: "";
right: 0;
height: 50px;
border-radius: 50% 50% 0 0;
}
<div class="card">
</div>
Use width top values too to have semi-circles with a change in color
.card {
height: 190px;
background: #070B32;
width: 360px;
position: relative;
}
.card:before {
background: white;
position: absolute;
content: "";
left: 0;
top:35%;
width: 25px;
height: 50px;
border-radius: 0 150px 150px 0;
}
.card:after {
background: white;
position: absolute;
content: "";
right: 0;
top:35%;
width: 25px;
height: 50px;
border-radius: 150px 0 0 150px;
}
<div class="card">
</div>
Update:
div {
height: 150px;
margin: 5em 2em;
background: radial-gradient(circle at left center, transparent, transparent 30px, #070B32 30px, transparent), radial-gradient(circle at right center, transparent, transparent 30px, #070B32 30px, transparent);
border-radius: 8px;
position: relative;
width: 360px;
margin: auto;
}
body {
background-image: url(http://www.fillmurray.com/1000/1000);
background-size: cover;
}
<div>
</div>
you should use width: 50px, background-color: white;
and responsive vertical alignment:
top: 50%; transform: translateY(-50%);
.card {
height: 190px;
background: #070B32;
width: 360px;
position: relative;
}
.card:before {
background: #ffffff;
position: absolute;
content: "";
left: -25px;
top: 50%;
transform: translateY(-50%);
height: 50px;
width: 50px;
border-radius: 50%;
}
.card:after {
background: #ffffff;
position: absolute;
content: "";
right: -25px;
top: 50%;
transform: translateY(-50%);
height: 50px;
width: 50px;
border-radius: 50%;
}
<div class="card">
</div>
Or just use a background.
.card {
--circle-color: #fff;
--circle-size: 50px;
background: radial-gradient(farthest-side circle, var(--circle-color) 97%, transparent) calc(100% + (var(--circle-size) / 2)) 50% / var(--circle-size) var(--circle-size),
radial-gradient(farthest-side circle, var(--circle-color) 97%, transparent) calc(var(--circle-size) / -2) 50% / var(--circle-size) var(--circle-size),
#070B32;
background-repeat: no-repeat;
height: 190px;
width: 360px;
}
<div class="card">
</div>

Mixing two colors for a background in CSS

I want to stack two colors one on top of the other. I did it by creating and sovrapposing two divs, having the one on the top with an opacity of 60%.
I wonder if there's a simpler way requiring only one div with two colors or maybe just one color that is a mix of the two.
I post here my code, If you notice any bad practice let me know please. I am eager to improve my skills.
* {
padding: 0;
margin: 0;
border: 0;
box-sizing: border-box;
}
/* ~~~~~~~~~~SKY~~~~~~~~~~ */
#sky {
position: relative;
z-index: -100;
width: 100vw;
height: 100vh;
background-image: linear-gradient( to top, midnightblue, black);
}
/* ~~~~~~~~~~MOON~~~~~~~~~~ */
.moon {
position: absolute;
top: 3%;
right: 0%;
width: 200px;
height: 200px;
border-radius: 50%;
}
#dark-moon {
background-color: silver;
}
#light-moon {
background-color: goldenrod;
background-image: radial-gradient(dimgrey 20%, transparent 16%), radial-gradient(dimgrey 15%, transparent 16%);
background-size: 60px 60px;
background-position: 0 0, 30px 30px;
opacity: 60%;
}
/* ~~~~~~~~~~SEA~~~~~~~~~~ */
#sea {
position: absolute;
bottom: 0%;
width: 100vw;
height: 25vh;
background-color: #48B;
}
<div id="sky">
<div id="dark-moon" class="moon"></div>
<div id="light-moon" class="moon"></div>
</div>
<div id="sea"></div>
As you can see there's a golden moon over a silver one. How can I get the same result having only one moon?
You can do it with 0 elements using pseudo element and multiple backgrounds:
html {
min-height: 100%;
background: linear-gradient( to top, midnightblue, black);
}
html::before {
content:"";
position: absolute;
top: 3%;
right: 0;
width: 200px;
height: 200px;
border-radius: 50%;
background:
linear-gradient(rgba(192,192,192,0.4) 0 0),
radial-gradient(dimgrey 20%, transparent 16%),
radial-gradient(dimgrey 15%, transparent 16%) 30px 30px,
goldenrod;
background-size: 60px 60px;
}
html::after {
content:"";
position: absolute;
bottom: 0;
left:0;
right:0;
height: 25vh;
background: #48B;
}
Another fancy idea to optimize the code more:
html {
min-height: 100%;
background:
linear-gradient(#48B 0 0) bottom/100% 25vh no-repeat fixed,
linear-gradient(black,midnightblue);
}
html::before {
content:"";
position: absolute;
top: 3%;
right: 0;
width: 200px;
height: 200px;
border-radius: 50%;
background:
linear-gradient(#48B 0 0) bottom/100% 25vh no-repeat fixed,
linear-gradient(rgba(192,192,192,0.4) 0 0),
radial-gradient(dimgrey 20%, transparent 16%) 0 0 /60px 60px,
radial-gradient(dimgrey 15%, transparent 16%) 30px 30px/60px 60px,
goldenrod;
}
Another option that only involves setting one background property would be to "stretch and displace" a linear-gradient in such a way that the result is a single color.
--base-col and --blend-col defines the gradient, --blend-amount sets the color mix, and --stretch-factor determines how much stretch is applied to the gradient:
* {
padding: 0;
margin: 0;
border: 0;
box-sizing: border-box;
}
/* ~~~~~~~~~~SKY~~~~~~~~~~ */
#sky {
position: relative;
z-index: -100;
width: 100vw;
height: 100vh;
background-image: linear-gradient( to top, midnightblue, black);
}
/* ~~~~~~~~~~MOON~~~~~~~~~~ */
.moon {
position: absolute;
top: 3%;
right: 0%;
width: 200px;
height: 200px;
border-radius: 50%;
}
#dark-moon {
--blend-amount: 60%;
--base-col: silver;
--blend-col: goldenrod;
--stretch-factor: 100;
background: linear-gradient(
var(--base-col) calc(( 0% - var(--blend-amount)) * var(--stretch-factor)),
var(--blend-col) calc((100% - var(--blend-amount)) * var(--stretch-factor))
);
}
#light-moon {
background-image: radial-gradient(dimgrey 20%, transparent 16%), radial-gradient(dimgrey 15%, transparent 16%);
background-size: 60px 60px;
background-position: 0 0, 30px 30px;
}
/* ~~~~~~~~~~SEA~~~~~~~~~~ */
#sea {
position: absolute;
bottom: 0%;
width: 100vw;
height: 25vh;
background-color: #48B;
}
<div id="sky">
<div id="dark-moon" class="moon"></div>
<div id="light-moon" class="moon"></div>
</div>
<div id="sea"></div>
You can try to get the hex code for the mixed color first using online color mixer tool such as this one https://colordesigner.io/color-mixer. After that you can use the result color in one div.

CSS Shape with Gradient Next Adjacent to Container

I'm trying to put together a specific design for a website we are building. The header needs a parallelogram shape above it, and a trapezium to the right of the container, as shown below.
I've managed to add the parallelogram above the container, but i'm struggling to get the element to the right of the container. The following shows what i've done.
HTML
<div class="container">
<div class="row">
<div class="col">
Content Here
</div>
</div>
</div>
CSS
.container {
width: 700px;
}
.container:before {
content:'';
width: 100%;
height: 30px;
transform: skew(45deg);
background: #254896;
background: linear-gradient(90deg, #254896, #2c2b5b 100%);
display: block;
}
.row {
background: #f8f9fa;
}
.row:before {
content:'';
width: 100%;
height: 0;
border-image-source: linear-gradient(90deg, #FF0000, #940202);
border-image-slice: 1;
border-top: 30px solid red;
border-left: 30px solid transparent;
position: absolute;
left: 800px;
top: 30px;
}
.col {
background-color: #ddd;
padding: 10px;
}
https://jsfiddle.net/scarrott/vgtpna14/
The issues i'm having are:
Getting the red shape to sit neatly to the right of the container regardless of screen size.
Putting a gradient fill on the trapezium shape. If I use border-image-source it makes the shape a rectangle.
Any help would be greatly appreciated.
Here is an idea using multiple background. I used 400px instead of 700px to better see in the snippet
body {
overflow-x: hidden;
}
.container {
--w:400px;
max-width: var(--w);
position: relative;
margin: 40px auto;
}
.container:before {
content: '';
position: absolute;
top: -20px;
left: 0;
width: calc(50vw + var(--w)/2);
min-width: 100%;
height: 40px;
transform: skew(45deg);
transform-origin: top;
background:
linear-gradient(90deg, #254896, #2c2b5b 100%) top left/var(--w) 50%,
linear-gradient(90deg, #FF0000, #940202) bottom right /calc(100% - var(--w)) 50%;
background-repeat: no-repeat;
}
.row {
background: #f8f9fa;
}
.col {
padding: 10px;
}
<div class="container">
<div class="row">
<div class="col">
Content Here
</div>
</div>
</div>
Another idea with clip-path:
body {
overflow-x: hidden;
}
.container {
--w:400px;
max-width: var(--w);
position: relative;
margin: 40px auto;
}
.container:before {
content: '';
position: absolute;
top: -20px;
left: 0;
width: calc(50vw + var(--w)/2);
min-width: 100%;
height: 40px;
clip-path:polygon(0 0, calc(var(--w) - 20px) 0,var(--w) 50%,100% 50%,100% 100%,calc(var(--w) + 20px) 100%,var(--w) 50%, 20px 50%);
background:
linear-gradient(90deg, #254896, #2c2b5b 100%) top left/var(--w) 50%,
linear-gradient(90deg, #FF0000, #940202) bottom right /calc(100% - var(--w)) 50%;
background-repeat: no-repeat;
}
.row {
background: #f8f9fa;
}
.col {
padding: 10px;
}
<div class="container">
<div class="row">
<div class="col">
Content Here
</div>
</div>
</div>
Including bootstrap
body {
overflow-x: hidden;
}
.container {
--w: 540px;
position: relative;
margin-top: 40px;
}
#media (min-width: 768px) {
.container {
--w: 720px;
}
}
#media (min-width: 992px) {
.container {
--w: 960px;
}
}
#media (min-width: 1200px) {
.container {
--w: 1140px;
}
}
.container:before {
content: '';
position: absolute;
top: -20px;
left: 0;
width: calc(50vw + var(--w)/2);
min-width: 100%;
height: 40px;
clip-path: polygon(0 0, calc(var(--w) - 20px) 0, var(--w) 50%, 100% 50%, 100% 100%, calc(var(--w) + 20px) 100%, var(--w) 50%, 20px 50%);
background:
linear-gradient(90deg, #254896, #2c2b5b 100%) top left/var(--w) 50%,
linear-gradient(90deg, #FF0000, #940202) bottom right /calc(100% - var(--w)) 50%;
background-repeat: no-repeat;
}
.row {
background: #f8f9fa;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<div class="container">
<div class="row">
<div class="col">
Content Here
</div>
</div>
</div>
Another approach would be to to have the 2 parallelogram shapes inside the container div with specified percentages.
.row::before {
content: '';
width: calc(70% - 14px);
height: 30px;
transform: skew(45deg);
background: #254896;
background: linear-gradient(90deg, #254896, #2c2b5b 100%);
}
.row::after {
content: '';
width: calc(30% - 14px);
height: 30px;
position: absolute;
right: 0;
top: 30px;
transform: skew(45deg);
background: red;
background: linear-gradient(90deg, #FF0000, #940202);
}
jsFiddle

curved shape with curved line with blur effect CSS

the result I need to get:
what i have so far
header {
min-height: 300px;
background: #000;
}
main {
position: relative;
width: 100%;
overflow: hidden;
min-height: 300px;
}
main:before {
content: '';
position: absolute;
background: #000;
top: 0;
left: 0;
width: 100%;
height: 200px;
}
main:after {
content: '';
position: absolute;
top: 0rem;
background: #141f36;
width: 120%;
height: 300px;
margin-left: -10%;
margin-right: 10%;
border-radius: 200vh 200vh 0% 0% / 20vh 20vh 0% 0%;
}
<div class="page">
<header></header>
<main></main>
</div>
I have no idea how to make the line, can someone help me with this?
NOTE: the line needs to have blur/bright/light effect just like in the example image
Here is a single div idea with radial-gradients.
div {
min-height: 400px;
width: 100%;
/* you can change these variables to see what they do */
--top-distance: 3%;
--line-width: 0.3%;
--blur: 0.5%;
--gradient-top-distance: 100px;
--s: 350%; /* increase this to reduce the slope. */
background: radial-gradient(farthest-side at center bottom, transparent 0 calc(100% - (var(--top-distance) + var(--blur)*2 + var(--line-width))), #0c5dd3 calc(100% - (var(--top-distance) + var(--blur) + var(--line-width))) calc(100% - (var(--top-distance) + var(--blur))), transparent calc(100% - var(--top-distance)) 100%) 50% calc(100% + var(--gradient-top-distance))/var(--s) 100% no-repeat,
radial-gradient(farthest-side at center bottom, #141f36 99%, transparent 100%) 50% calc(100% + var(--gradient-top-distance))/var(--s) 100% no-repeat;
background-color: #000;
}
<div></div>
You can add another pseudo element where you apply a blur filter
main {
position: relative;
overflow: hidden;
min-height: 400px;
background: #000;
}
main:before,
main:after{
content: '';
position: absolute;
height:300px;
background: #141f36;
left:-10%;
right:-10%;
bottom:0;
border-radius: 200vh 200vh 0% 0% / 20vh 20vh 0% 0%;
}
main:after {
border:3px solid #0c5dd3;
filter:blur(1px);
bottom:-22px;
background:none;
}
<main></main>

Creating lines around a circle using ::before

I'm trying to create something similar to this with the use of pseudo:
But unsure on if the approach I currently have is the best way to go about this?
.divider{
display: flex;
flex-direction: column;
}
.line1::before{
content: '';
/*position: absolute;*/
display: block;
width: 4em;
height: .2em;
background: red;
transform: rotate(90deg);
}
.circle::before{
content: '';
display: inline-block;
width: 15px;
height: 15px;
-moz-border-radius: 7.5px;
-webkit-border-radius: 7.5px;
border-radius: 7.5px;
background-color: red;
}
<div class="divider">
<div class="line1"></div>
<div class="circle"></div>
<div class="line2"></div>
</div>
Would you create something like this using pseudo-elements? If so, how can I get it to appear like the one in the image?
It's fairly easy, just matter of elements placement in vertical and horizontal middle:
.wrapper {
width: 100px;
height: 200px;
background-color: rgba(30, 50, 80, .3);
position: relative;
}
.wrapper div {
border-radius: 50%;
background-color: blue;
position: absolute;
top: 50%;
margin-top: -25px;
left: 50%;
margin-left: -25px;
width: 50px;
height: 50px;
background: center center no-repeat url(https://static.thenounproject.com/png/19279-200.png) blue;
background-size: 30px;
}
.wrapper:before,
.wrapper:after {
content: '';
display: block;
width: 2px;
height: 60px;
background: blue;
position: absolute;
left: 49px;
}
.wrapper:before {
top: 0;
}
.wrapper:after {
bottom: 0;
}
<div class="wrapper"><div></div></div>
You can also do this with only one element:
.box {
width:40px;
height:40px;
border-top:40px solid transparent; /* The length of the top line */
border-bottom:40px solid transparent; /* The length of the bottom line */
padding:10px 0; /* Control distance between line and circle*/
/* The lines */
border-image:linear-gradient(to right,
transparent calc(50% - 2px),
red calc(50% - 2px) calc(50% + 2px),
transparent calc(50% + 2px)) 1;
/* The circle */
background:radial-gradient(farthest-side,red 95%,transparent 100%) content-box;
}
<div class="box"></div>
Where you can easily add another image
.box {
width:40px;
height:40px;
border-top:40px solid transparent; /* The length of the top line */
border-bottom:40px solid transparent; /* The length of the bottom line */
padding:10px 0; /* Control distance between line and circle*/
/* The lines */
border-image:linear-gradient(to right,
transparent calc(50% - 2px),
red calc(50% - 2px) calc(50% + 2px),
transparent calc(50% + 2px)) 1;
/* The circle */
background:
url(https://static.thenounproject.com/png/19279-200.png) center/30px no-repeat,
radial-gradient(farthest-side,red 95%,transparent 100%) content-box;
}
<div class="box"></div>