I'm looking to make a website splash page. The page will have one background that will be cut off on the left side with a slanted div, say at a constant 110 degrees from the horizontal (or equivalent, keep reading). This div will blur the background behind it and will allow for content to be put on it, like text. See the YouTube Brand Resources page: instead of having a plain white background on the left, I would like that to blur the background picture that sits underneath it.
I've not yet found a way to put all of the information I've found together in a way that works and is supported by most browsers. For example, I recently tried a skewed div that shared a background with the parent container, like this post asked about, but CSS clip paths aren't commonly supported yet, and a white div won't cut it for my use case (to be clear, this solution ends with a skewed background image).
Using SVG clip paths and filters (see below) gets me close, but as you can see, I don't know how to make sure the image and the SVG fills the screen and lines up with the background behind it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Page</title>
</head>
<body>
<div class="splash">
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
<filter id="blur" x="0" y="0">
<feGaussianBlur stdDeviation="1"></feGaussianBlur>
</filter>
<clipPath id="clip">
<polygon points="0,0 100,100 0,100"></polygon>
</clipPath>
<image clip-path="url('#clip')" filter="url('#blur')" x="0" y="0" width="100" height="100" xlink:href="https://cdn.pixabay.com/photo/2018/11/17/22/15/tree-3822149_960_720.jpg"></image>
</svg>
</div>
</body>
</html>
Sass:
html, body
position: relative
margin: 0
overflow-x: hidden
height: 100%
.splash
position: absolute
width: 100%
height: 100%
overflow: hidden
background-image: url("https://cdn.pixabay.com/photo/2018/11/17/22/15/tree-3822149_960_720.jpg")
background-size: cover
background-repeat: no-repeat
background-color: lightgrey
background-attachment: fixed
svg
position: absolute
width: inherit
height: inherit
Any ideas?
You can consider skew transform without the need of clip-path
. here is a basic example where the trick is to specify the correct value of background-position
to create the illusion of one image.
.box {
height:300px;
background-image:url(https://picsum.photos/600/800?image=1069);
background-position:left center;
background-size:cover;
position:relative;
overflow:hidden;
}
.skew,
.skew::before{
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
transform-origin:top left;
transform:skewY(30deg);
overflow:hidden;
background-image:inherit;
background-position:inherit;
background-size:0 0;
}
.skew::before {
content:"";
transform:skewY(-30deg);
filter:blur(10px);
background-size:cover;
}
/*to illustrate the separation*/
.skew {
border-top:1px solid;
}
/**/
.container {
position:relative;
z-index:1;
margin-top:150px;
padding-left:50px;
}
body {
margin:0;
}
<div class="box">
<div class="skew"></div>
<div class="container">
<h1>some text</h1>
<p>Lorem ipsum</p>
</div>
</div>
<div class="box" style="background-image:url(https://picsum.photos/600/800?image=3)">
<div class="skew"></div>
<div class="container">
<h1>some text</h1>
<p>Lorem ipsum</p>
</div>
</div>
In case you want the skew to be responsive you can add a small JS code to adjust the angle and always cover half the iamge:
var w = window.innerWidth;
var h = 300; /*the height of the box*/
document.querySelector('.box .skew').style.transform="skewY("+(Math.atan(h/w)*180/Math.PI )+"deg)";
document.querySelector('.box .skew span').style.transform="skewY(-"+(Math.atan(h/w)*180/Math.PI )+"deg)";
window.onresize = function(event) {
w = window.innerWidth;
document.querySelector('.box .skew').style.transform="skewY("+(Math.atan(h/w)*180/Math.PI )+"deg)";
document.querySelector('.box .skew span').style.transform="skewY(-"+(Math.atan(h/w)*180/Math.PI )+"deg)";
};
.box {
height:300px;
background-image:url(https://picsum.photos/600/800?image=1069);
background-position:left center;
background-size:cover;
position:relative;
overflow:hidden;
}
.skew,
.skew span{
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
transform-origin:top left;
transform:skewY(30deg);
overflow:hidden;
background-image:inherit;
background-position:inherit;
background-size:0 0;
}
.skew span{
transform:skewY(-30deg);
filter:blur(10px);
background-size:cover;
}
/*to illustrate the separation*/
.skew {
border-top:1px solid;
}
/**/
.container {
position:relative;
z-index:1;
margin-top:150px;
padding-left:50px;
}
body {
margin:0;
}
<div class="box">
<div class="skew"><span></span></div>
<div class="container">
<h1>some text</h1>
<p>Lorem ipsum</p>
</div>
</div>
You can also make it all in a single <svg> image, using a <pattern> element to fill half a triangle with the image, and apply your filter on it.
svg {
width: 100vw;
height: 200px;
position: absolute;
top: 0;
}
.container {
position: relative;
z-index: 1;
margin-top: 100px;
padding-left: 50px;
}
<svg width="1024" height="200" viewBox="0 0 1024 200" preserveAspectRatio="none">
<defs>
<pattern id="pat" viewBox="0 0 1024 200" width="100%" height="100%">
<image xlink:href="https://picsum.photos/1024/200?image=1029" width="1024" height="200"/>
</pattern>
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" />
</filter>
</defs>
<!-- background no filter -->
<rect width="1024" height="200" fill="url(#pat)"/>
<!-- foreground triangle, blurred -->
<path d="M0,0L1024,200H0Z" fill="url(#pat)" filter="url(#blur)"/>
</svg>
<div class="container">
<h1>some text</h1>
<p>Lorem ipsum</p>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With