Wavy effect over an image background with css - html

I want to make that wave effect over a parallax background image.
So far I have the parallax effect and full-width (over parent container width).
section.parallax {
width: 100vw;
position: relative;
margin-left: -50vw;
left: 50%;
background-image: url(../images/parallax.jpg); // this image
height: 500px;
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
What can I do to have that wave effect on the image top and bottom with CSS? Is it possible?

Here is an idea using SVG and multiple background. Simply adjust the path of the SVG to fit your needs:
.container {
width: 500px;
height: 400px;
background:
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="500" ><path d="M0 48 C30 60 38 40 64 48 L64 64 L0 64 Z" fill="white" stroke="rgba(255,255,255,0.5)" stroke-width="5"/></svg>') bottom,
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="500" ><path d="M0 10 C30 20 38 2 64 10 L64 0 L0 0 Z" fill="white" stroke="rgba(255,255,255,0.5)" stroke-width="5"/></svg>') top,
url(https://picsum.photos/2000/1000?image=1069) center/cover;
}
<div class="container">
</div>

Related

linear-gradient rendering issue firefox

I'm trying to draw several grids of various sizes but I'm having an issue with Firefox - linear-gradient is breaking up for me in many places.
It's working all fine on Google Chrome with any units provided (px/mm/%/rounded/float) but it's doing some funny stuff on Firefox. I've tried using different units/rounding/prefixed/3d hacks but none of this is working.
div {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-image: linear-gradient(to right, black 1px, transparent 1px),
linear-gradient(to bottom, black 1px, transparent 1px);
background-size: 5mm 5mm;
}
<div></div>
A repeating gradient should give better result but it's always tricky when it comes to small values like 1px with gradients
div {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-image:
repeating-linear-gradient(to right, black 0 1px, transparent 0 5mm),
repeating-linear-gradient(to bottom, black 0 1px, transparent 0 5mm);
}
<div></div>
you can also consider an SVG here (adjust the viewBox, width and height or the rect until you get a good result)
div {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background:
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='black'> <rect x='0' y='0' width='1' height='100%' /> <rect x='0' y='0' width='100%' height='1'/></svg>")
0 0/5mm 5mm;
}
<div></div>
Also like below with only SVG:
svg {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
}
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
<rect x='0' y='0' width='1' height='100%' />
<rect x='0' y='0' width='100%' height='1'/>
</pattern>
</defs>
<rect width="3000" height="3000" fill="url(#grid)" />
</svg>

why do I need background-size 200% instead of cover

I'm trying to use an inline svg as a background-image (data url), but background-size:cover does not seems to work well, however with 200% its fits perfectly.
I'd like to understand the issue so that I can make sure I have a consistent render with different browsers. Ideally I'd like to keep using background-size:cover if possible
.card {
display: inline-flex; /* required in my context */
width: 45vmax;
background-color: lightblue;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 2 2"><g fill="red"><path d="M0,1v-1h1z" opacity=".4" /><path d="M1,0v1h-1z" opacity=".2"/></g></svg>');
background-size: cover;
}
._200percent {
background-size: 200%;
}
.video {
padding-top: 56.25%;
}
body {
margin: 0;
}
<a class="card">
<div class="video"></div>
</a>
<a class="card _200percent">
<div class="video"></div>
</a>
As commented you can adjust the viewbox to cover the path and avoid having extra spaces and the use of 200%
svg {
border:1px solid;
width:200px;
}
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 2 2"><g fill="red"><path d="M0,1v-1h1z" opacity=".4" /><path d="M1,0v1h-1z" opacity=".2"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 1 1"><g fill="red"><path d="M0,1v-1h1z" opacity=".4" /><path d="M1,0v1h-1z" opacity=".2"/></g></svg>
You can also do this using CSS and gradient without the need of SVG
.card {
display: inline-flex; /* required in my context */
width: 45vmax;
background:
linear-gradient(to bottom right,rgba(255,0,0,0.4) 49.5%,rgba(255,0,0,0.2) 50%),
lightblue;
}
.video {
padding-top: 56.25%;
}
body {
margin: 0;
}
<a class="card">
<div class="video"></div>
</a>

How to get an SVG to have a fluid width without changing its height?

I would like to accomplish two things:
The SVG width scales dynamically to take up 100% of the container's width.
SVG's is either stretched or smushed when the container's width changes (meaning the wave drawn with the svg's path)
SVG's height remains fixed to 760px. Currently if you resize the container, the SVG's height is reduced which is not desired.
.container {
width: 100%;
background: green;
height: 760px;
}
svg {
width: 100%;
}
svg path {
width: 100%;
}
<div class="container">
<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z"
fill="purple"
/>
</svg>
</div>
I would probably use the SVG as background of a div and you can make the height of the div fixed and adjust the background-position to be top
.container {
width: 100%;
background: green;
height: 760px;
}
.container>div {
height: 100%;
background:
url('data:image/svg+xml;utf8,<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z" fill="purple"/></svg>') top/100% no-repeat,
/*cover the bottom part with the same color*/
linear-gradient(purple, purple) bottom/ 100% calc(100% - 20vw) no-repeat;
}
<div class="container">
<div>
</div>
</div>
You can also reduce the code to keep only the container:
.container {
height: 760px;
background:
url('data:image/svg+xml;utf8,<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z" fill="purple"/></svg>') top/100% no-repeat,
/*cover the bottom part with the same color*/
linear-gradient(purple, purple) bottom/ 100% calc(100% - 20vw) no-repeat,
green;
}
<div class="container">
</div>
You can try adding preserveAspectRatio="none" to the svg tag. This does seem to mess with the position a bit but might be a good start.
.container {
width: 100%;
background: green;
height: 760px;
}
svg {
width: 100%;
}
svg path {
width: 100%;
}
<div class="container">
<svg width="1440" height="760" viewBox="0 0 1440 760" fill="none" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M677.112 54.1657C400.36 -43.9336 110.391 13.291 0 54.1657V760H1440V54.1657C1301.02 95.0404 953.865 152.265 677.112 54.1657Z"
fill="purple"
/>
</svg>
</div>

SVG + CSS; Clippath in flexbox environment

i think this might be very simple for some of you. i just want to mask an image with an SVG-graphic.
i created an SVG with the clipPath element in it:
<svg id="heart-path-container" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 50 50" xml:space="preserve">
<clipPath id="heart-path" clipPathUnits="objectBoundingBox">
<path d="M24.85,10.126c2.018-4.783,6.628-8.125,11.99-8.125c7.223,0,12.425,6.179,13.079,13.543
c0,0,0.353,1.828-0.424,5.119c-1.058,4.482-3.545,8.464-6.898,11.503L24.85,48L7.402,32.165c-3.353-3.038-5.84-7.021-6.898-11.503
c-0.777-3.291-0.424-5.119-0.424-5.119C0.734,8.179,5.936,2,13.159,2C18.522,2,22.832,5.343,24.85,10.126z">
</path>
</clipPath>
</svg>
and an SVG with the image in it:
<svg id="heart-image-container" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 50 50" xml:space="preserve">
<image class="clip-image" xlink:href="https://images.unsplash.com/photo-1490810277975-e64342ceecf0?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=88e69bf894f334456f8ae269752556e1&auto=format&fit=crop&w=2250&q=80"></image>
</svg>
i basically say in CSS that this image should be clipped with that SVG clipPath element.
.clip-image{
width: 100%;
height: 100%;
clip-path: url(#heart-path);
}
but it does not do it.
i created a fiddle to show that nothing is getting clipped.
what am i doing wrong?
https://codepen.io/Marvbuster/pen/MXvbXo
When you specify objectBoundingBox coordinates, the corrdinate have to be between 0 and 1. Your clip path coordinates go up to approx 50, so your clip path is 50x too big.
The simple fix is use a transform to scale your path back down to the correct size.
body, html{
height: 100%;
}
svg{
position: absolute;
width: 100%;
height: 100%;
}
.clip-image{
width: 100%;
height: 100%;
clip-path: url(#heart-path);
}
.wrapper{
position: relative;
margin: 0 auto;
height: 100%;
max-width: 500px;
display: flex;
flex-direction: column;
}
section{
position: relative;
background: red;
flex: 1;
width: 100%;
}
<div class="wrapper">
<section></section>
<section>
<svg x="0px" y="0px">
<clipPath id="heart-path" clipPathUnits="objectBoundingBox">
<path d="M24.85,10.126c2.018-4.783,6.628-8.125,11.99-8.125c7.223,0,12.425,6.179,13.079,13.543
c0,0,0.353,1.828-0.424,5.119c-1.058,4.482-3.545,8.464-6.898,11.503L24.85,48L7.402,32.165c-3.353-3.038-5.84-7.021-6.898-11.503
c-0.777-3.291-0.424-5.119-0.424-5.119C0.734,8.179,5.936,2,13.159,2C18.522,2,22.832,5.343,24.85,10.126z"
transform="scale(0.02,0.02)"></path>
</clipPath>
</svg>
<svg id="heart-image-container" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 50 50" xml:space="preserve">
<image class="clip-image" xlink:href="https://images.unsplash.com/photo-1490810277975-e64342ceecf0?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=88e69bf894f334456f8ae269752556e1&auto=format&fit=crop&w=2250&q=80"></image>
</svg>
</section>
<section></section>
</div>

How do you separate parallax elements from header?

I have moving parallax elements overlaying a large header image, however I can't seem to figure out how to separate the two so that the header image isn't affected by the parallax movement.
I'd like for only the circles to be moving upwards as you scroll, but it looks like the header image is attached to the same movement as the black circle.
Something I've tried was taking
<div class="background">...</div>
outside of
<div class="parallax">...</div>
but then the circles were no longer overlaying the header image.
Here is my JSFiddle: https://jsfiddle.net/uk0x33mj/3/
Thank you - I really appreciate the help!
As I understood you, you need something like that. Please let me know, if you need something else.
.parallax {
perspective: 1px;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
}
.parallax__layer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index:9999;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px) scale(2);
}
.circle {
position:absolute;
top:400px;
left:300px;
color:#ffffff;
}
.circle_2 {
position:absolute;
top:300px;
}
.background {
background:red;
background-image: url('http://i59.tinypic.com/2eofekz.jpg');
background-size: cover;
height: 350px;
width: 100%;
position: fixed;
}
.spacer {
height:1000px;
}
<div class="background">
</div>
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
<svg class="circle_2" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="576px" height="576px" viewBox="0 0 576 576" enable-background="new 0 0 576 576" xml:space="preserve">
<circle fill="#EC008C" cx="63.215" cy="61.778" r="41.83"/>
</svg>
</div>
<div class="parallax__layer parallax__layer--base">
<svg class="circle" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="576px" height="576px" viewBox="0 0 576 576" enable-background="new 0 0 576 576" xml:space="preserve">
<circle fill="#231F20" cx="63.215" cy="61.778" r="41.83"/>
</svg>
</div>
<div class="spacer"></div>
</div>