I was asked with making such a background on a responsive site. I thought about preparing two divs using gradient, but it is highly problematic. Is it even possible to do it? Using this as a background-image is cumbersome for higher and lower resolutions.
Any ideas?
some clip-path and pseudo element can approximate this:
.box {
width: 300px;
aspect-ratio: .8;
position: relative;
z-index: 0;
}
.box:before,
.box:after {
content: "";
position: absolute;
z-index: -1;
inset: 0;
}
.box:before {
clip-path: polygon(0 0, 100% 50%, 10% 100%,0 100%);
background: linear-gradient(40deg, #3185c5, #0ea1b1);
}
.box:after {
clip-path: polygon(100% 30%, 100% 50%, 10% 100%,0% 100%, 0 80%);
background: linear-gradient(40deg, #3185c5, #f55778);
}
<div class="box"></div>
Related
I'm trying to create a repeated background existing out of two parts. Each part is a gradient and while the one moves up, the other moves down.
The best I got is this:
html {
background: black;
color: #4c4c4c;
}
body {
margin: 30vh auto;
max-width: 80vw;
}
.wave {
background: none;
height: 1rem;
width: 50%;
position: absolute;
z-index: 2;
animation: move 700ms 0ms steps(2) infinite both;
}
.color::after,
.color::before {
content: "";
position: absolute;
left: 0;
right: 0;
height: 100%;
top: 0;
}
.color {
background-image: linear-gradient(#fe0000 50%, #6531ff 0 100%);
}
.color::after {
background: linear-gradient(to bottom, #f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%), linear-gradient(to right, #042a2b 3rem, transparent 3rem, transparent 6rem);
}
.wave,
.color::after,
.color::before {
background-size: 5rem 1rem;
background-repeat: repeat-x;
}
#keyframes move {
0% {
margin-top: -3rem;
}
100% {
margin-top: -3.25rem;
}
}
<div class="color wave"></div>
I get why this doesn't work, but not sure how to proceed.
Since it is difficult to describe, here is an image of what I'm looking for:
At first (position 1), all odd blocks are higher than the even blocks. After the first animation, it's the other way around (position 2) and so on.
Maybe like below:
.box {
height:100px;
background:linear-gradient(red,blue,yellow,red) 0 0/100% 200%;
animation:y 2s linear infinite;
}
.box::after {
content:"";
display:block;
height:100%;
background:linear-gradient(green,lightblue,pink,green) 0 0/100% 200%;
animation:inherit;
animation-direction: reverse;
-webkit-mask:linear-gradient(90deg,#fff 50%,transparent 0) 0 0/20% 100%;
}
#keyframes y {
to {
background-position:0 -200%;
}
}
<div class="box"></div>
UPDATE: This is an interesting problem. I'm surprised to find that I don't have an obvious or particularly elegant solution to having a gradient running vertically while repeating with horizontal gaps.
Far more elusive than I initially expected.
Best I could come up with is to put one of the gradients in a pseudo element and apply a mask-image. This won't work in IE, but it appears to be supported everywhere else.
See updated demo below.
If I understand what you're trying to do, I think you could accomplish it by animating the background positions:
.demo {
height: 200px;
background-image:
linear-gradient(#f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%);
animation: move 0.7s infinite alternate;
background-size: 3rem;
position: relative;
}
.demo::before {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(#042a2b, transparent);
/* This is the magic part: using a horizontal repeating-linear-gradient
to mask out "columns", allowing the container's background gradient to
show through */
-webkit-mask-image: repeating-linear-gradient(to right, black 0 3rem, transparent 3rem 6rem);
background-size: 3rem;
/* run the same animation in reverse to animate up instead of down */
animation: move 0.7s infinite alternate-reverse;
}
#keyframes move {
from {
background-position: 0 0;
}
to {
background-position:
0 200px;
}
}
<div class="demo"></div>
It's difficult to infer exactly what you're trying to do, but here's another sample (very similar to #ray hatfield's answer) that will move the first background down while the second background moves up:
.sample {
width: 250px;
height: 50px;
position: relative;
background-image: linear-gradient(to bottom, #f4e04d, #3bceac 20%, rgba(22, 22, 22, 0) 100%), linear-gradient(to right, #042a2b 3rem, transparent 3rem, transparent 6rem);
animation: move 1s infinite linear;
}
#keyframes move {
0%, 100% {
background-position: 0 -75px, 0 0;
}
50% {
background-position: 0 0, 0 -75px;
}
}
<div class="sample"></div>
I want that the parts that are "whited" to get the image blurred.
I've tried using pseudo elements ::after and ::before to add the overlays but could only blurred the overlay.
tried with borders 2nd example codepen, but no sucess because with the transparent it creates a "square".
https://codepen.io/giventofly/pen/RQpqYZ
.hero-image {
width: 1280px;
height: 800px;
background-image: linear-gradient(rgba(46, 51, 82, 0.6) 100%, transparent 0), linear-gradient(125deg, rgba(255, 255, 255, 0.5) 35%, transparent 0), linear-gradient(-55deg, rgba(255, 255, 255, 0.5) 25%, transparent 0),
url('https://cdn.vox-cdn.com/thumbor/NU6lcSN3DGmjF7NhZp6ixY3HxgQ=/0x0:1620x1080/1200x800/filters:focal(0x0:1620x1080)/cdn.vox-cdn.com/uploads/chorus_image/image/46510678/Tarmogoyf_DGM_1920x1080_Wallpaper.0.0.jpg');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
z-index: 10;
}
<div class="hero-image"></div>
I only want to blur the part of the image that is "behind" the white linear-gradient
I'm sure someone can refine this approach a bit, but the main takeaways are:
Include the image twice in a container element.
Stack the two images.
Blur one and place it on the bottom.
Use clip-path on the top image to display the non-blurred region.
Insert a frost layer (transparent white) with a pseudo element of the container element between the two images.
Control layering with positioning and z-index.
.img-overlay {
display: inline-flex;
position: relative;
overflow: hidden;
}
.img-overlay::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba( 255, 255, 255, 0.5 );
z-index: 1;
}
.img-overlay img:first-child {
position: absolute;
top: 0;
left: 0;
filter: blur( 3px);
z-index: 0;
}
.img-overlay img:last-child {
position: relative;
z-index: 2;
-webkit-clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%);
clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%);
}
<div class="img-overlay">
<img src="http://unsplash.it/400/400?image=16">
<img src="http://unsplash.it/400/400?image=16">
</div>
You can use clip-path for this. The idea is to have two similar layer, the top with the clip-path to show only the needed part and keep the blur on the bottom layer visible. You can switch the blur between both element if you want to blur the middle part instead:
.hero-image {
width: 600px;
height: 250px;
position: relative;
overflow: hidden;
}
.hero-image:after,
.hero-image:before {
content: "";
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: center/cover no-repeat;
background-image:
linear-gradient(rgba(46, 51, 82, 0.6) 100%, transparent 0),
linear-gradient(125deg, rgba(255, 255, 255, 0.5) 35%, transparent 0),
linear-gradient(-55deg, rgba(255, 255, 255, 0.5) 25%, transparent 0),
url('https://picsum.photos/id/1024/800/800');
}
.hero-image:before {
filter: blur(4px);
}
.hero-image:after {
clip-path: polygon(45% 0, 97% 0, 68% 100%, 16% 100%);
}
<div class="hero-image"></div>
Currently working on a web design project for a client where I designed a multi-layered diagonal background. I solved a single diagonal with;
background-color: #dbebde;
background-image: -webkit-linear-gradient(120deg, #dbebde 50%, #f8f8f8 45%);
min-height: 400px;
However, as seen in the image below, I need to add a smaller diagonal on the left side.
Does anyone have an idea on how to solve this specific issue?
You can use a single HTML element, let's say a <div>, and use pseudo-elements, particularly ::before and ::after, to create those shapes, without writing additional HTML elements.
You would draw the red one first:
body {
margin: 0;
}
.fullBox {
position: relative;
height: 100vh;
}
.diagonalBox {
background: #FFF;
overflow: hidden;
}
.diagonalBox::before,
.diagonalBox::after {
content: '';
position: absolute;
width: 200%;
height: 200%;
left: 0;
}
.diagonalBox::before {
background: #D00;
top: 10%;
transform: rotate(30deg);
transform-origin: top left;
}
<div class="fullBox diagonalBox"></div>
And then add the light mint green one on top of that:
body {
margin: 0;
}
.fullBox {
position: relative;
height: 100vh;
}
.diagonalBox {
background: #FFF;
overflow: hidden;
}
.diagonalBox::before,
.diagonalBox::after {
content: '';
position: absolute;
width: 200%;
height: 200%;
left: 0;
}
.diagonalBox::before {
background: #D00;
top: 10%;
transform: rotate(30deg);
transform-origin: top left;
}
.diagonalBox::after {
background: #DFD;
top: 100%;
transform: rotate(-30deg);
transform-origin: bottom left;
}
<div class="fullBox diagonalBox"></div>
Keep in mind that your may need to adjust the dimensions and positions of the pseudo-elements.
I suggest you using 2 DIVs and give one of them a gradient with transparent color.
HTML :
<div class="outer">
<div class="inner"></div>
</div>
CSS:
.outer,.inner{
position:fixed;
top:0;
bottom:0;
left:0;
right:0;
}
.outer {
background-color: #dbebde;
background-image: -webkit-linear-gradient(50deg, red 70%, #f8f8f8 65%);
background-image: -moz-linear-gradient(50deg, red 70%, #f8f8f8 65%);
background-image: -o-linear-gradient(50deg, red 70%, #f8f8f8 65%);
background-image: -ms-linear-gradient(50deg, red 70%, #f8f8f8 65%);
}
.inner{
background-color: transparent;
background-image: -webkit-linear-gradient(120deg, #dbebde 60%, transparent 55%);
background-image: -moz-linear-gradient(120deg, #dbebde 60%, transparent 55%);
background-image: -o-linear-gradient(120deg, #dbebde 60%, transparent 55%);
background-image: -ms-linear-gradient(120deg, #dbebde 60%, transparent 55%);
}
You can see it in action:
https://codepen.io/FaridNaderi/pen/LLBVqw
Hope at least it helps you.
Let's say I have this clip path (a triangle generated here)
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
Is it possible to create a box-shadow from this clip path?
Something like this:
box-shadow: 20px 25px 50px -25px #000;
You can use a filter on the containing div, try:
.container {
filter: drop-shadow(0px 10px 5px rgba(0,0,0,0.1))
}
eg: https://plnkr.co/edit/kePuv7OLQwawPjiBLg3J?p=preview
I'm assuming you mean, is it possible to create the shadow along the polygon. If so, then no. box-shadow is unfortunately only a "box", so it can't follow the clip path. It'd still apply to the rectangle of the element itself.
You could however pair it with another element that has the same clipping, but is set below it and offset and create a pseudo-shadow:
#box {
position: relative;
width: 200px;
height: 200px;
}
#content {
width: 100%;
height: 100%;
background: #3CF;
-webkit-clip-path: polygon(0 100%, 0 0, 100% 0, 80% 100%);
}
#shadow {
position: absolute;
z-index: -1;
content: "";
background: rgba(0, 0, 0, .5);
width: 200px;
height: 200px;
left: 5px;
top: 5px;
-webkit-clip-path: polygon(0 100%, 0 0, 100% 0, 80% 100%);
}
<div id="box">
<div id="content"></div>
<div id="shadow"></div>
</div>
Depending on your use-case, with some clever use of a background image, multiple borders, and/or gradients, you could make the background look between with a fading shadow and what not.
It's not possible, I think. I would suggest you this work around.
.triangle {
font-size:100px;
color:blue;
text-shadow:0 0 10px black;
}
<span class="triangle">▲</span>
I have a shape with an edge like this in Photoshop:
Is it possible to make the repeated triangles as a border with CSS?
You can use gradients to create a zig-zag patterned background, use the ::after pseud-element to apply it like a border.
.header{
color: white;
background-color: #2B3A48;
text-align: center;
}
.header::after {
content: " ";
display: block;
position: relative;
top: 0px;
left: 0px;
width: 100%;
height: 36px;
background: linear-gradient(#2B3A48 0%, transparent 0%), linear-gradient(135deg, #272220 33.33%, transparent 33.33%) 0 0%, #272220 linear-gradient(45deg, #272220 33.33%, #2B3A48 33.33%) 0 0%;
background-repeat: repeat-x;
background-size: 0px 100%, 9px 27px, 9px 27px;
}
<div class="header"><h1>This is a header</h1></div>
Source: CSS Zigzag Border with a Textured Background
JSFiddle: http://jsfiddle.net/kA4zK/
For future viewers, I found this adaptation of #extramaster's answer to be a little simpler.
It's essentially the same, but it uses one fewer background gradients and allows the backing object (.navbar in my markup) to show through instead of hard-coding the second color into the zig-zag.
JsFiddle: http://jsfiddle.net/861gjx0b/2/
.header {
position: relative;
color: white;
background-color: #2B3A48;
text-align: center;
}
.navbar {
background: #272220;
height: 20px;
}
.header:after {
content: "";
position: absolute;
display: block;
height: 10px;
bottom: -10px;
/* -height */
left: 0;
right: 0;
/* TODO Add browser prefixes */
background: linear-gradient( 45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%), linear-gradient( -45deg, transparent 33.333%, #2B3A48 33.333%, #2B3A48 66.667%, transparent 66.667%);
background-size: 8px 20px;
/* toothSize doubleHeight */
background-position: 0 -10px;
/* horizontalOffset -height */
}
<div class="header">
<h1>This is a header</h1>
</div>
<nav class="navbar"></nav>
Personally, I think clip-path is easier to work with/understand than complex background gradients.
body {
font-family:Roboto,'Open Sans',Helvetica,sans-serif;
}
.container {
background:#ddd;
margin:0 auto;
max-width:800px;
padding:30px;
}
h1:first-child {margin:0;}
.jagged-bottom {
position:relative;
}
.jagged-bottom:after {
background:#ddd;
content:"";
height:2vw;
position:absolute;
top:100%;
left:0;
right:0;
clip-path:polygon(
0 0, 2.5% 100%, 5% 0, 7.5% 100%,
10% 0,12.5% 100%,15% 0, 17.5% 100%,
20% 0,22.5% 100%,25% 0, 27.5% 100%,
30% 0,32.5% 100%,35% 0, 37.5% 100%,
40% 0,42.5% 100%,45% 0, 47.5% 100%,
50% 0,52.5% 100%,55% 0, 57.5% 100%,
60% 0,62.5% 100%,65% 0, 67.5% 100%,
70% 0,72.5% 100%,75% 0, 77.5% 100%,
80% 0,82.5% 100%,85% 0, 87.5% 100%,
90% 0,92.5% 100%,95% 0, 97.5% 100%, 100% 0);
}
<div class="container jagged-bottom">
<h1>Looks Like A Receipt</h1>
<p>Simply adjust the clip path on the pseudo-element if you want more or fewer spikes, and the height if you want them to be taller or shorter.</p>
</div>
There is a border-image property in CSS3.
Maybe you can work it out in a way you want. More here:
https://developer.mozilla.org/en-US/docs/Web/CSS/border-image
Or here
https://www.w3schools.com/cssref/css3_pr_border-image.asp
You can create an individual triangle using CSS quite easily (just tweak border properties). In order for this to work you will need to generate quite a bit of markup yourself. I would recommend against this approach.
Instead you are likely better off using an individual image containing a single triangle (preferably a transparent .png) and then use background-image and background-repeat (repeat-x) properties to bind that to a div (your "border").
Unfortunately there is no yet a straight-forward way to achieve this using pure CSS.