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)
Related
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%;
}
}
I'm trying to make a gradient animation in the background of a of a svg. Is this possible?
.ani_a {
background-color: #fff;
animation: anibg01 10s infinite linear;
background-image: linear-gradient(0deg,#0d4ba0,#00adee,#00aba5,#37b34a,#8dc63f,#ccdb29,#ffdd15,#fff100,#f6921e,#f05a28,#ec1c24,#ff008b,#90278e,#652d90,#0d4ba0,#00adee);
background-size: 1500% 100%;
}
#keyframes anibg01 {
0% { background-position: 0% 0%; }
100% { background-position: 0% 100%; }
}
<svg>
<polygon class="ani_a" points="35,70 70,70 105,0 70,0 "/>
</svg>
If you are looking to animate the linear gradient (by moving it) within that shape you could take an alternative approach using CSS/HTML rather than SVG to define the shape.
This snippet takes the linear-gradient and makes it the background of a div. The div is clipped to give a shape using clip-path with a polygon and the background is animated to move vertically downwards with repetition.
.ani_a {
background-color: #fff;
animation: anibg01 10s infinite linear;
background-image: linear-gradient(0deg, #0d4ba0, #00adee, #00aba5, #37b34a, #8dc63f, #ccdb29, #ffdd15, #fff100, #f6921e, #f05a28, #ec1c24, #ff008b, #90278e, #652d90, #0d4ba0, #00adee);
background-size: 100% 100%;
width: 20vmin;
height: 10vmin;
display: inline-block;
clip-path: polygon(50% 0, 100% 0, 50% 100%, 0 100%);
}
#keyframes anibg01 {
0% {
background-position: 0% 0%;
}
100% {
background-position: 0 10vmin;
}
}
<div class="ani_a">div</div>
The following HTML tag is rendering as expected statically.
style='background: linear-gradient(to right, rgba(255,255,255,0) 20%, rgba(255,255,255,1) 30%, rgba(255,255,255,1)), url(<%= image_path "/bg/#{#this_area.id}.svg" %>);'>
However, as this is being dynamically managed by a variable, and the goal is to add
#keyframes moveBg {
to {
background-position: 100% 0;
}
}
I was attempting to do the following
<div class='bg_x' style='background: url(<%= image_path "/bg/#{#this_area.id}.svg" %>);'>
and define the class
.bg_x {
background: linear-gradient(to right, rgba(255,255,255,0) 20%, rgba(255,255,255,1) 30%, rgba(255,255,255,1))
animation: moveBg 20s linear infinite;
}
However using a class plus an inline definition fails to integrate the gradient with the background image (even before adding the animation). So the inline is overriding the class, even though the instructions are complimentary.
As the CSS file cannot take variables, can this desired effect be achieved partially not inline?
Because of the Cascading in CSS the inline indeed overrules the class. Never the less. linear gradients are a part of the background-image property (shorthand background if you want to combine multiple styles, just like margin-left and margin). Normally you can separate the background-color and background-image or other elements, but with linear-gradient() that isn't possible because they both use background-image property too bad.
In the example below you can find two solution that I found. Hopefully this helps you progress this issue.
/* ClassBased */
.bg_classBased {
position: relative;
}
.bg_classBased:before {
content: "";
position: absolute;
top: 0;
left: 0;
z-index: 1;
background: linear-gradient(to right, rgba(255,255,255,0) 20%, rgba(255,255,255,1) 30%, rgba(255,255,255,1));
width: 100%;
height: 100%;
}
/* Animation */
.bg_x {
animation: moveBg 20s linear infinite;
}
#keyframes moveBg {
to {
background-position: 100% 0;
}
}
/* misc styling */
div {
padding: 40px;
}
<h1>Inline based</h1>
<div class="bg_x" style='background: linear-gradient(to right, rgba(255,255,255,0) 20%, rgba(255,255,255,1) 30%, rgba(255,255,255,1)), url("https://placehold.it/100x100");'></div>
<h1>Classbased</h1>
<div class="bg_x bg_classBased" style='background: url("https://placehold.it/100x100");'></div>
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
I am having an issue where I am unable to get the level of specificity I need to make some code work. I have a <ul> for which I want to make the backgrounds of the <li>'s change when hovered on with a fancy little slide-in animation.
I managed to get it working pretty well using a linear-gradient with a transition on :hover. I decided that I wanted to have the different list items have different background colors than each other, so I added three classes: .red, .blue, and .gold, and I figured I would just make everything with the .level1 class have the required properties other than the linear gradient itself—namely, background-size: 200% 100%, background-position:right bottom, and transition:all 1s ease, and then specify the linear gradient and color for each individual color class. I know this is all pretty intangible, but I will post my code below.
Here is what I was hoping to have (or something like it):
body .push [class^="level1"] {
background-size: 200% 100%;
background-position:right bottom;
transition:all 1s ease;
}
body .push [class^="level1"]:hover {
background-position:left bottom;
}
body .push .level1.blue {
background: linear-gradient(to right, #282e59 50%, rgba(0,0,0,0) 50%);
}
body .push .level1.red {
background: linear-gradient(to right, #94272a 50%, rgba(0,0,0,0) 50%);
}
body .push .level1.gold {
background: linear-gradient(to right, #e5d037 50%, rgba(0,0,0,0) 50%);
}
But that doesn't work. For the values in the first class to take effect, I have to get rid of the first one body .push [class^="level1"] { ... } and put that information in the three color-specific ones, like
body .push .level1.blue {
background: linear-gradient(to right, #282e59 50%, rgba(0,0,0,0) 50%);
background-size: 200% 100%;
background-position:right bottom;
transition:all 1s ease;
}
body .push .level1.red {
background: linear-gradient(to right, #94272a 50%, rgba(0,0,0,0) 50%);
background-size: 200% 100%;
background-position:right bottom;
transition:all 1s ease;
}
body .push .level1.gold {
background: linear-gradient(to right, #e5d037 50%, rgba(0,0,0,0) 50%);
background-size: 200% 100%;
background-position:right bottom;
transition:all 1s ease;
}
Is there any way to consolidate that information?
It seems the problem is not specificity, but that your shorthand background: declaration is overwriting the position & size values in your original declaration. Try changing background: to background-image: in your overwrites:
body .push .level1.blue {
background-image: linear-gradient(to right, #282e59 50%, rgba(0,0,0,0) 50%);
}
body .push .level1.red {
background-image: linear-gradient(to right, #94272a 50%, rgba(0,0,0,0) 50%);
}
body .push .level1.gold {
background-image: linear-gradient(to right, #e5d037 50%, rgba(0,0,0,0) 50%);
}
I am guessing you have html like:
...
<li class="level1">...</li>
<li class="level1 red">...</li>
<li class="level1 gold">...</li>
<li class="level1 blue">...</li>
In that case you can change your code to
.push .level1 {
background-size: 200% 100%;
background-position:right bottom;
transition:all 1s ease;
}
.push .level1:hover {
background-position:left bottom;
}
.push .blue {
background-image: linear-gradient(to right, #282e59 50%, rgba(0,0,0,0) 50%);
}
.push .red {
background-image: linear-gradient(to right, #94272a 50%, rgba(0,0,0,0) 50%);
}
.push .gold {
background-image: linear-gradient(to right, #e5d037 50%, rgba(0,0,0,0) 50%);
}