Background-position not working with CSS animation and linear gradient - css

I'm attempting to use CSS3 (gradients and animations) to make an animation similar to the iphone slide to unlock gradient. However, for some reason, the background-position only works when I use static pixel numbers and not when I use percentages. Ideally, I'd be able to apply this class to any element, and have the animation work, without needing to code for specific widths. Can somebody point me in the right direction?
JSFiddle:
https://jsfiddle.net/ekLamtbL/
.slideToUnlock {
background: linear-gradient(-90deg, black 0%, gray 40%, white 45%, gray 55%, black 60%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;
-webkit-animation: slidetounlock 5s infinite;
animation: slidetounlock 5s infinite;
-webkit-animation-direction: normal;
animation-direction: normal;
}
#-webkit-keyframes slidetounlock {
0% {
background-position: -100% 0;
}
100% {
background-position: 100% 0;
}
}

Added your code
background-size: 250% 250%;
Example
.slideToUnlock {
background: linear-gradient(-90deg, black 0%, gray 40%, white 45%, gray 55%, black 60%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;
-webkit-animation: slidetounlock 5s infinite;
animation: slidetounlock 5s infinite;
-webkit-animation-direction: normal;
animation-direction: normal;
background-size: 250% 250%;
}
https://jsfiddle.net/ekLamtbL/2/

Article on MDN explains it well
tldr:
To make a use of percentage background-position your background's size should not equal to 100% of the dimension you want to position. N% position means N% of the background is mapped to N% of the element. Since gradient is automatically has size of 100%x100% setting background-position seem to have no effect unless you set background-size to some value like 200% for example

Related

How to set interval in animated gradient text?

I'm trying to set a interval while my animated gradient text is running but I don't know how to do it with CSS only.
I have 3 different colors and I'd like to initiate it in black, turn to colored and back to black again, like a loop.
HTML
<h2 className="gradient-text">
Text Exemple
</h2>
CSS
.gradient-text {
background: linear-gradient(45deg, #000, #2FEBDC, #EB413B, #FFA300, #E422EB);
background-size:400%;
animation: text-gradient 8s linear infinite;
padding:5px 0;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
}
#keyframes text-gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 50% 100%;
}
}
Is it possible using only CSS instead javascript?
Your animation-direction is by default set to normal. In order to get back to black in reverse order (i.e, black -> coloured -> black), set it to alternate. This will cycle between playing the animation forwards and backwards.
In order to set a play interval, (i.e, wait at black for a particular amount of time before resuming the animation), you can set two keyframes with no changes between the two. This will make your animation stay put for a set duration before resuming. You will have to increase the animation-duration if you want to retain the speed at which your animation plays.
Your CSS may look something like so:
.gradient-text {
background-image: linear-gradient(45deg, #000, #2FEBDC, #EB413B, #FFA300, #E422EB);
animation: text-gradient 10s linear alternate infinite;
padding: 5px 0;
background-clip: text;
background-size: 400%;
}
#keyframes text-gradient {
0% {
background-position: 0% 50%;
}
33% {
background-position: 0% 50%;
}
66% {
background-position: 50% 100%;
} /* In my example here, this keyframe at 66% is not needed as the animation is progressing linearly from 33% to 100% anyways... it can be omitted */
100% {
background-position: 100% 100%;
}
}

Pure CSS fade-in fade-out each from left to right

Is it possible to create a fade-in fade-out effect in pure css, each running from left to right (cf. gif)?
I implemented the fade-in hover effect with the following code:
input[type='submit'] {
background: linear-gradient(to left, var(--btn-prim-bg-color) 50%, var(--color-primary) 50%) right;
background-size: 200%;
transition: .5s;
color: white;
text-transform: uppercase;
border: none;
}
input[type="submit"]:hover {
background-position: left;
color: var(--color-text);
}
But I have problems with the fade-out on mouse leave, it runs from right to left afterwards. but it should run from left to right again (cf. gif)
We can take advantage of the fact that some properties can be transitioned and others can happen instantly.
In this snippet the background-color of the input is changed instantly on hover, its background image which consists of a blue part and a yellow part initially is changed to a transparent part and a yellow part on hover.
The only property that is transitioned is the background sizes of the two linear gradients.
input {
background-color: yellow;
background-image: linear-gradient(cornflowerblue, cornflowerblue), linear-gradient(yellow, yellow);
background-size: 100% 100%, 0% 100%;
background-position: left top, left top;
background-repeat: no-repeat;
transition: background-size 5s linear;
border: none;
}
input:hover {
background-color: cornflowerblue;
background-image: linear-gradient(transparent, transparent), linear-gradient(yellow, yellow);
background-size: 0% 100%, 100% 100%;
}
<input>

How can I animate my text to highlight from left to right?

I've been looking for a way to make this work and I can't quite find what I want at this point.
I have this text that I want to highlight, and I would like to animate that to go from left to right. As of now, I've managed to make the highlight appear after a set amount of time, but without the left-to-right effect.
Here's what it looks like right now for reference :
And this is the css I used to make this happen :
#keyframes highlight {
0% {
background: none;
}
100% {
background: linear-gradient(to top, $light-purple 50%, transparent 50%);
}
}
h2 {
display: inline;
animation-name: highlight;
animation-duration: 0.75s;
animation-fill-mode: forwards;
}
I know this is a very rookie question, but I honestly can't find a way to do it properly, considering what I already have... I would appreciate it if someone could help!
Thanks in advance
I found a solution inspired by this article :
#keyframes highlight {
from {
background-position: 0;
}
to {
background-position: -100%;
}
}
h2 {
animation-name: highlight;
animation-duration: 0.75s;
animation-fill-mode: forwards;
background-size: 200%;
background-image: linear-gradient(to right, white 50%, transparent 50%),
linear-gradient(transparent 50%, purple 50%);
}
<h2>Here is an example text that will have the highlight</h2>

CSS text background hover effect behaving strangely on mouseout

I've implemented a hover effect on a h1 element (see code and pen below), but the effect is behaving strangely on mouse out and sort of flickering before going back to it's original state.
Any ideas how to make it transition back to it's original color as smoothly as it fades in on hover?
Thanks in advance.
https://codepen.io/lobodemon/pen/YOXKNJ
h1 {
transition: 0.5s;
}
h1:hover {
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
color:transparent;
-webkit-background-clip: text;
background-clip: text;
-webkit-animation: Gradient 15s ease infinite;
-moz-animation: Gradient 15s ease infinite;
animation: Gradient 15s ease infinite;
}
#-webkit-keyframes Gradient {
0%, 100% {
background-position: 0 50%
}
50% {
background-position: 100% 50%
}
}
#-moz-keyframes Gradient {
0%, 100% {
background-position: 0 50%
}
50% {
background-position: 100% 50%
}
}
#keyframes Gradient {
0%, 100% {
background-position: 0 50%
}
50% {
background-position: 100% 50%
}
}
<h1>The Title</h1>
The issue is that you are trying to combine an animation with transtion which will not work like you expect. By adding a transtion you will not make the animation go smooth. In other words, you cannot add transtion to animation.
Since you made the duration of the animation to be 15s on hover, I don't think the infinite is needed in this case because no one will keep hovering more than 15s, so you can change this into a transition and it will be smooth.
I have added the black color to the gradient to have our initial state then with a transition we can do half the initial animation and at the end you will have a 7s duration which is somehow enough for a hover effect:
h1 {
transition: 7s;
background:
linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB,#000);
background-size: 400% 400%;
color:transparent;
-webkit-background-clip: text;
background-clip: text;
background-position: 0 0;
}
h1:hover {
background-position: 100% 50%;
}
<h1>The Title</h1>
When you are working with transition, you need to set initial state of element properties that you are going to change.
h1 {
background: black;
-webkit-background-clip: text;
background-clip: text;
}
I also found intresting example with same effect as yours.
https://codepen.io/anthony-liddle/pen/uFoxA

Changing gradient colors of an animated background

I have an animated gradient background, and I want to override the original color by applying an other class. When I apply this new class, the animation stops.
See the code below and try to add the oc class to the div to reproduce.
.background {
background: linear-gradient(
to right,
#eee9e5 20%,
red 50%,
#eee9e5 80%
);
background-size: 400% 400%;
height: 16px;
margin: 16px 0;
}
.oc {
background: linear-gradient(
to right,
#eee9e5 20%,
blue 50%,
#eee9e5 80%
) !important;
}
.animated {
animation: move 4s ease-in infinite;
}
#keyframes move {
0%{background-position:0% 50%}
50%{background-position:100% 50%}
100%{background-position:0% 50%}
}
<div class="background animated" />
You can also see the code at https://codepen.io/Taskim/pen/KegLmJ.
Do you know any workaround to achieve that?
The problem is with the use of the !important on the background rule.
The background is a short-hand property that alters all the background-* properties.
So when you set background: linear-gradient(...)!important you override the background-position as well and setting it to default values that cannot be animated since they are more important.
Use background-image: linear-gradient(...) and it should work.
document.querySelector('button').addEventListener('click', function() {
document.querySelector('.animated').classList.toggle('oc');
})
.background {
background: linear-gradient( to right, #eee9e5 20%, red 50%, #eee9e5 80%);
background-size: 400% 400%;
height: 16px;
margin: 16px 0;
}
.oc {
background-image: linear-gradient( to right, #eee9e5 20%, blue 50%, #eee9e5 80%);
}
.animated {
animation: move 4s ease-in infinite;
}
#keyframes move {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
<div class="background animated"></div>
<button>toggle gradient</button>
Also keep in mind that you cannot self-close a div (unless that is not real html but some template from a framework)

Resources