This question already has answers here:
How to Animate Gradients using CSS
(5 answers)
Closed 1 year ago.
I have a div where the background is divided as follows:
div {
width: 200px;
height: 50px;
background: linear-gradient(135deg, gray 0%, gray 70%, blue 70%, blue 85%, red 85%);
}
div:hover {
animation: animate .5s ease forwards;
}
#keyframes animate {
0% {
background: linear-gradient(135deg, gray 0%, gray 70%, blue 70%, blue 85%, red 85%);
}
100% {
background: linear-gradient(135deg, gray 0%, gray 50%, blue 50%, blue 75%, red 75%);
}
}
<div></div>
As you can see, I would like the stripes in the background to shift on hover (and, indeed, shift back on leave).
I saw all the tutorials suggesting to use background-size and background-position but as I need the proportions to actually change, I don't know that that is the solution here.
I'd like the gradient proportion to animate smoothly, instead of just clipping like they do in the above snippet.
As you have disovered, linear gradients as you have them don't animate.
One simple way of getting a similar but smooth effect is to use scale, which is animatable.
This snippet draws the linear-gradient on a pseudo element and transitions the scale on that, having put the transform origin to the bottom right hand corner. The div has overflow set to hidden.
div {
width: 200px;
height: 50px;
overflow: hidden;
position: relative;
}
div::before {
content: '';
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 100%;
height: 100%;
transform: scale(1);
transform-origin: right bottom;
transition: transform .5s ease;
background: linear-gradient(135deg, gray 0%, gray 70%, blue 70%, blue 85%, red 85%);
z-index: -1;
}
div:hover::before {
transform: scale(1.5);
}
<div>SOME CONTENT</div>
Take a look at the second and third answers from this post. By animating the opacity of two different gradients or using css variables alongside a transition, you should be able to get the desired result.
I've set up an example of the second method using your code:
#property --gb { /* grey/blue */
syntax: '<percentage>';
inherits: false;
initial-value: 70%;
}
#property --br { /* blue/red */
syntax: '<percentage>';
inherits: false;
initial-value: 85%;
}
div {
--gb: 70%;
--br: 85%;
width: 200px;
height: 50px;
transition: --gb 2s, --br 2s;
background: linear-gradient(135deg, gray 0%, gray var(--gb), blue var(--gb), blue var(--br), red var(--br));
}
div:hover {
--gb: 50%;
--br: 75%;
}
<div></div>
Related
This question already has an answer here:
How can I apply css transitions to a background image change?
(1 answer)
Closed 3 months ago.
I created a CSS keyframes animation with 5 frames where the background image would fade and change to the next image. The animation works like its supposed to in all cycles except during the first cycle where it glitches before each transition. How to fix this?
HTML:
<div class="container"></div>
CSS:
#keyframes animation1 {
0%, 15%{background-image: url("https://i.imgur.com/IzY1cRC.jpeg");}
20%, 35%{background-image: url("https://i.imgur.com/Bq4PJjC.jpeg");}
40%, 55%{background-image: url("https://i.imgur.com/43idGF1.jpg");}
60%, 75%{background-image: url("https://i.imgur.com/OMa9YYH.jpg");}
80%, 95%{background-image: url("https://i.imgur.com/CTLFd8t.jpg");}
100%{background-image: url("https://i.imgur.com/IzY1cRC.jpeg");}
}
.container{
height: 300px;
width: 550px;
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
animation-name: animation1;
animation-duration: 25s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
Extremely grateful for any help this has been hindering a couple of projects for a good time.
The first time the animation plays, images will not be loaded yet, the browser will fetch only when they're actually needed.
While the image is loading, the default background will be displayed (in this case, transparent, which will ultimately show the white background of the body)
You can 'pre-load' the images. So the browser already had the image data in cache when it's needed for the animation. There's different techniques for pre-loading. A straightforward way is to add an invisible element that requires all the images used in the animation.
In the example below, we add an 'invisible' :after element that loads all images.
.container::after {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
z-index: -1;
content: url(https://i.imgur.com/IzY1cRC.jpeg) url(https://i.imgur.com/Bq4PJjC.jpeg) url(https://i.imgur.com/43idGF1.jpg) url(https://i.imgur.com/OMa9YYH.jpg) url(https://i.imgur.com/CTLFd8t.jpg) url(https://i.imgur.com/IzY1cRC.jpeg);
}
#keyframes animation1 {
0%,
15% {
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
}
20%,
35% {
background-image: url("https://i.imgur.com/Bq4PJjC.jpeg");
}
40%,
55% {
background-image: url("https://i.imgur.com/43idGF1.jpg");
}
60%,
75% {
background-image: url("https://i.imgur.com/OMa9YYH.jpg");
}
80%,
95% {
background-image: url("https://i.imgur.com/CTLFd8t.jpg");
}
100% {
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
}
}
.container {
height: 300px;
width: 550px;
background-image: url("https://i.imgur.com/IzY1cRC.jpeg");
background-position: center center;
background-repeat: no-repeat;
background-size: 100% 100%;
animation-name: animation1;
animation-duration: 25s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
<div class="container"></div>
This question already has answers here:
Using percentage values with background-position on a linear-gradient
(2 answers)
How to animate background-position using percentages when background-size is 100%?
(1 answer)
Closed 4 months ago.
I'm trying to have an animated linear-gradient work vertically, but for some reason it only works when I use a value in px instead of % for the background-position in the keyframes. A percentage would be way better since the width/height of the element is going to change, therefore the background-position should follow.
If the gradient is oriented 90deg, it works but obviously it renders horizontally instead of vertically.
Here is the code :
div {
width: 50px;
height: 150px;
background: linear-gradient(0deg, yellow, orange, red, violet, purple, blue, yellow);
animation: color 5s linear infinite;
margin: 50px auto;
}
#keyframes color {
0% {
background-position: 0%;
}
100% {
background-position: 200%; /* doesn't work */
/*background-position: 0 -150px; -> works fine but not ideal */
}
}
<div></div>
I tried negative value and other background-position variations, without success.
Here is a pen with the code : https://codepen.io/petruhaand1/pen/jOKMrWB
Using aspects from this answer to a similar question, got it working somewhat:
div {
width: 50px;
height: 150px;
margin: 50px auto;
overflow: hidden;
position: relative;
z-index: 0;
}
div:before {
content: "";
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
background: linear-gradient( 0deg, yellow, orange, red, violet, purple, blue, yellow) top/100% 50%;
bottom: 0;
animation: color 5s linear infinite;
}
#keyframes color {
0% {
background-position: top;
}
100% {
background-position: bottom;
}
}
<div></div>
I need a help with writing css class. I want to create button as it is shown on image below. There is screenshot with dimensions.
First parallelogram is:
height: 52px;
width: 235px;
background: linear-gradient(180deg, #FEE195 0%, #FFD361 100%);
Second one:
height: 52px;
width: 26px;
left: 222px;
background: #FFFFFF;
Text is in the middle of the first one.
If you want to create a button with the "double parallelogram" background, your on the right track using linear-gradient. You can style a <button> element using linear-gradient with color stops to create the parallelogram background you shared. I used an arbitrary width: 180px but you can adjust your color stops in the linear gradient to whichever width you end up choosing.
body {
background-color: #252525;
}
button {
text-align: center;
display: block;
width: 180px;
height: 50px;
border: none;
background: linear-gradient(68deg, #000 0% 10%, #FEE195 10% 30%, #FEE195 30% 83%, #000 83% 86%, #fff 86% 90%, #000 90%);
}
<button class="custom-bg">Some Text</button>
I am using CSS animation to show an indeterminate progress bar. Refer code below. If you'll notice there are 2 moving gradient at any point of time, i.e. when the 1st one reaches 50% of the width, 2nd one starts. I know that I have defined the css that way using webkit-background-size(50% and 100%). However what I am not able to do is make sure that there should be only 1 moving part at any point of time - i.e. once the animation reaches the right end of the div only then it should start it from the left end. Any pointers on this?
Refer https://jsfiddle.net/AnuragSinha/nuokygpe/1/ and corresponding code below.
#-webkit-keyframes moving-gradient {
0% { background-position: left bottom; }
100% { background-position: right bottom; }
}
.loading-gradient {
width: 200px;
height: 30px;
background: -webkit-linear-gradient(
left,
#e9e9e9 50%,
#eeefef 100%
) repeat;
-webkit-background-size: 50% 100%;
-webkit-animation-name: moving-gradient;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
<div class="loading-gradient" style="width: 200px; height: 30px"> </div>
Instead of making the gradient 50% make it 200% and define 2 gradient coloration inside it. Doing so each part of the gradient will cover exactly 100% of the element width then you can animation it from left to right.
.loading-gradient {
width: 200px;
height: 30px;
background: linear-gradient(to left,
#e9e9e9 0% 25%, #eeefef 50%, /* first one take the half*/
#e9e9e9 50% 75%, #eeefef 100%); /* second one take the other half*/
background-size: 200% 100%;
animation: moving-gradient 1s linear infinite;
}
#keyframes moving-gradient {
0% {
background-position: right;
}
/*100% {
background-position: left; /* No need to define this since it's the default value*/
}*/
}
<div class="loading-gradient" style="width: 200px; height: 30px"> </div>
Since the gradient is now having a size bigger than the container, you need to do the opposite animation (from right to left).
More details: Using percentage values with background-position on a linear gradient
Here is another idea where you can consider pseudo element and translate animation:
.loading-gradient {
width: 200px;
height: 30px;
position:relative;
z-index:0;
overflow:hidden;
}
.loading-gradient:before {
content:"";
position:absolute;
z-index:-1;
top:0;
right:0;
width:200%;
bottom:0;
background: linear-gradient(to left, #e9e9e9 50%, #eeefef 100%);
background-size: 50% 100%;
animation: moving-gradient 1s linear infinite;
}
#keyframes moving-gradient {
100% {
transform: translate(50%);
}
}
<div class="loading-gradient" style="width: 200px; height: 30px"> </div>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I want to create a diagonal background image as seen in the attached image. I can create a diagonal line using linear-gradient however as I have two different angles this didn't work.
Using Linear Gradients:
This can be done using multiple background images and positioning them accordingly. In the snippet below I've used 3 different layers - one for the top angle (a triangle which is transparent for 50% and is colored for the rest), one for the middle which is essentially nothing but a solid colored rectangle, this is created using linear gradients as it is easier to control the dimensions of an image and finally one for the bottom angle (same approach as the top one but this has a different height and so different angle.)
The output is also responsive as you can see by hovering the element in the below snippet. In the 2nd div, I've set different colors for each image so that you can see how it is formed.
div {
height: 300px;
width: 100%;
background: linear-gradient(to bottom right, transparent 50%, lightblue 51%), linear-gradient(lightblue, lightblue), linear-gradient(to top right, transparent 50%, lightblue 51%);
background-size: 100% 30px, 100% calc(100% - 130px), 100% 100px;
background-position: top left, left 30px, bottom left;
background-repeat: no-repeat;
transition: all 1s ease; /* just for demo */
}
/* just for demo */
div {
margin-bottom: 10px;
}
div:hover {
height: 400px;
}
div:nth-of-type(2) {
background: linear-gradient(to bottom right, transparent 50%, lightblue 51%), linear-gradient(lightpink, lightpink), linear-gradient(to top right, transparent 50%, lightgreen 51%);
background-size: 100% 30px, 100% calc(100% - 130px), 100% 100px;
background-position: top left, left 30px, bottom left;
background-repeat: no-repeat;
}
<div></div>
<div></div>
Using SVG: recommended
This is the approach that I generally recommend and is the best. It involves creating the shape using SVG and then placing it absolutely behind the div element.
div {
position: relative;
height: 300px;
width: 100%;
}
svg {
position: absolute;
height: 100%;
width: 100%;
}
polygon {
fill: lightblue;
}
<div>
<svg viewBox='0 0 300 100' preserveAspectRatio='none'>
<polygon points='0,10 300,0 300,100 0,75z' />
</svg>
</div>
Using Clip-path:
Another approach that can be used is to position a pseudo-element behind the main div and then set a clip-path in the required shape to this pseudo-element.
Note: This snippet will currently work only in WebKit powered browsers. Firefox would need the clip-path to be created via SVG element whereas IE doesn't support it all.
div {
position: relative;
height: 300px;
width: 100%;
}
div:before {
position: absolute;
content: '';
height: 100%;
width: 100%;
background: lightblue;
-webkit-clip-path: polygon(0% 5%, 100% 0%, 100% 100%, 0% 75%);
clip-path: polygon(0% 5%, 100% 0%, 100% 100%, 0% 75%);
}
<div></div>
CSS Perspective
You can use a CSS Perspective Transform to create the shape you want.
div {
margin-top: 25px;
width: 500px;
height: 150px;
transform: perspective( 800px ) rotateY( -25deg );
background: blue;
}
<div></div>
CSS Tricks Docs
Perspective - CSS | MDN
You can apply perspective to the parent container of the rotated div to give it 3-dimensional depth from the front of the viewport.
N.B. For the difference between transform: perspective(value) and perspective: value, see the CSS Tricks Almanac entry on perspective:
Important: Please note the perspective property doesn't affect how the element is rendered; it simply enables a 3D-space for children
elements. This is the main difference between the transform: perspective() function and the perspective property. The first
gives element depth while the latter creates a 3D-space shared by all
its transformed children.
After applying a 3-dimensional depth to the parent container using perspective, you can then apply rotateY to the div you want to rotate.
Working Example:
section {
position: relative;
width: 600px;
perspective: 800px;
transform: translateX(-60px);
}
div:nth-of-type(1) {
position: absolute;
top:30px;
left: 0;
width: 100%;
height: 100px;
background-color: rgb(235,250,255);
transform: rotateY(320deg);
}
div:nth-of-type(2) {
position: absolute;
top: 0;
left: 220px;
width: 120px;
height: 140px;
background-color: rgb(103,201,236);
box-shadow: 6px 6px 6px rgba(127,127,127,0.5);
}
div:nth-of-type(3) {
position: absolute;
top: 24px;
left: 340px;
width: 120px;
height: 140px;
background-color: rgb(255,255,255);
box-shadow: 6px 6px 6px rgba(127,127,127,0.5);
}
<section>
<div></div>
<div></div>
<div></div>
</section>