Does CSS have any predefined animations? - html

So I just saw this question where op defined an animation called flash. It causes weird behaviour in all browsers I tested (Chrome and Firefox - both recently updated):
The animation values I enter get ignored and instead the block fades in and out with a yellow color - kind of like a flash.
Here's a screenshot of what I'm seeing:
I couldn't find anything about predefined CSS animations and I can't seem to override them either.
Here's the code snippet:
.block {
height: 100px;
width: 100px;
background-color: red;
}
.flash {
animation: flash 2s infinite;
}
#keyframes flash {
0% {
background-color: blue;
}
50% {
background-color: red;
}
100% {
background-color: blue;
}
}
.notFlash {
animation: notFlash 2s infinite;
}
#keyframes notFlash {
0% {
background-color: blue;
}
50% {
background-color: red;
}
100% {
background-color: blue;
}
}
<div class='block flash'>Flash Animation Name</div>
<div class='block notFlash'>A Different Animation Name</div>
What is happening here? Does such a thing as preset animations exist?
I couldn't find anything googling.

StackOverflow uses an animation with that name in its own styles. As the StackSnipppet is not sandboxed, this style overrides the one you define in the snippet.
The following snippet shows the animation in use in the console output to indicate a new item has been logged to the console:
let i = 0
setInterval(() => {
console.log(++i)
}, 1000)
You can see that this is not the case if you try a different snippet tool or run your code locally.
See the post on meta for more information (linked by esqew in the comments).

Related

CSS Variables in keyframes [duplicate]

I have been trying to get this to work for a while.
The point is that the inner div will have some shape and there will probably more than one (That's why I used the nth-child selector).
This inner div is supposed to be shown and then be hidden again both for some set amount of time.
the problem is, that I would like to animate all the (later) multiple inner divs in one animation. For this I thought I could use CSS variables, but this does not seem to work.
What I am trying to archieve in this example is the inner div basically just blinking by using the variable. But my result in Firefox is just a black box.
Am I missing anything? I already looked up if one could even use CSS variables in #keyframes and sure enough you can.
The only problem with them in animations seems to be that they are not interpolated in between but that they suddenly switch which is not a problem in this case.
#keyframes test{
from{
--one: 0;
}
to{
--one: 1;
}
}
#test{
width: 100px;
height: 200px;
background-color: black;
animation: test 1s infinite;
}
#test :nth-child(1){
width: 20px;
height: 20px;
margin: auto;
background-color: white;
opacity: var(--one,0);
}
<div id="test">
<div></div>
</div>
This can be achieved by defining variables using (as of writing this, not well-supported) #property, which allows declaring types and that allows the browser to "understand", for example, that a certain property (variable) is a Number and then it can gradually animate/transition that variable.
Example Code:
#property --opacity {
syntax: '<number>'; /* <- defined as type number for the transition to work */
initial-value: 0;
inherits: false;
}
#keyframes fadeIn {
50% {--opacity: 1}
}
html {
animation: 2s fadeIn infinite;
background: rgba(0 0 0 / var(--opacity));
}
The current types that are allowed include:
length, number, percentage, length-percentage, color, image, url, integer, angle, time, resolution, transform-list, transform-function, custom-ident (an identifier string)
Helpful articles:
https://web.dev/at-property/#writing-houdini-custom-properties
https://css-tricks.com/using-property-for-css-custom-properties
Cool Houdini demos
As stated in the specification:
Animatable: no
and also
Notably, they can even be transitioned or animated, but since the UA
has no way to interpret their contents, they always use the "flips at
50%" behavior that is used for any other pair of values that can’t be
intelligently interpolated. However, any custom property used in a
#keyframes rule becomes animation-tainted, which affects how it is
treated when referred to via the var() function in an animation
property.
So even if you use opacity with var() in the keyframes it won't animate:
#keyframes test {
from {
--one:0;
opacity: var(--one);
}
to {
opacity: var(--one);
--one: 1;
}
}
#test {
width: 100px;
height: 200px;
background-color: black;
}
#test :nth-child(1) {
width: 20px;
height: 20px;
margin: auto;
background-color: white;
animation: test 1s infinite;
}
<div id="test">
<div></div>
</div>
By the way you can make it working if you use it as a transition because in this case you will apply a transtion to the opacity and not the custom property:
#test {
width: 100px;
height: 200px;
background-color: black;
}
#test:hover {
--one:1;
}
#test :nth-child(1) {
width: 20px;
height: 20px;
margin: auto;
background-color: white;
opacity: var(--one,0);
transition:1s all;
}
<div id="test">
<div></div>
</div>

Container expanding animation based on the height/width of the container

I have a container that displays input fields based on list. The user changes data in the displayed fields and more or less input will appear. The issue is that the container instantly changes to the size required and it is jarring. I would like an animation to ease the change in size.
body{
background: lightblue;
}
.my-card{
align-self: center;
padding: 20px;
margin: 0 auto;
width: auto;
border-radius: 4px;
display: inline-block;
background-color: #F2F2F2;
color: black;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
border: 1px solid rgba(0,0,0,0);
bottom: 1px;
-webkit-transform-origin:top;
-moz-animation: fadein 2000ms; /* Firefox */
-webkit-animation: fadein 2000ms; /* Safari and Chrome */
-o-animation: fadein 2000ms; /* Opera */
}
.user-data{
text-align: left;
font-size: 18px;
margin: 1px 5px 5px;
-webkit-transform-origin:top;
-moz-animation: fadein 2000ms; /* Firefox */
-webkit-animation: fadein 2000ms; /* Safari and Chrome */
-o-animation: fadein 2000ms; /* Opera */
}
#keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}
#-moz-keyframes fadein { /* Firefox */
from {
opacity:0;
}
to {
opacity:1;
}
}
#-webkit-keyframes fadein { /* Safari and Chrome */
from {
opacity:0;
}
to {
opacity:1;
}
}
#-o-keyframes fadein { /* Opera */
from {
opacity:0;
}
to {
opacity: 1;
}
}
<div class="my-card">
<div class="user-data">
<div>header text</div>
<input type="text" />
</div>
</div>
The new user-data fades in nicely but the my-card makes the change with no animation. The my-card does animate on the first load.
Is there some event on the for my-card like hover for the change in size?
Note: The HTML of the snippet is not exact, as this is Blazor. The data is populated with a foreach and in the foreach there is logic to determine what gets displayed. A better idea of what the actual HTLM is is something like this:
<div class="my-card">
#foreach (var x in MyList)
{
#if (x.Show == 1)
{
<div class="user-data">
<div>#x.HeaderText</div>
<input type="text" #bind="#x.StringValue" />
</div>
}
}
</div>
CSS transitions need a property to animate, and you need to change that property. Since there isn't a height or opacity change in the rules, it can't animate. The nested components that actually change in response to the data collection changing come in and out of the DOM which is a change.
So, you have a couple of options:
Set a height to your container and change that with C# so that it travels to the DOM and do a CSS animation on it. This is going to be tough - you need to somehow calculate how tall you want your container.
Hide all the content for a bit, then await Task.Delay(20); to let it render, then show it again (a simple if-block) - that can let initial css animation do its work. The caveat is that you will do a lot of DOM changes, maybe lose data (so you maybe need to do some state management) and the screen will flicker badly.
Do animations with JS - when you alter the collection, get the current content height (the parent must have some height set and maybe hidden overflow, there are a few ways to setup the container so you can get the actual content size), and use JS to animate to the new height. That's the general way animations are done - with JS, when you need particular dimensions and settings.
Try toggling a class on the main wrapping element that will contain the desired animation (such as fade), something like the pseudocode below
<div class="my-card #AnimationClass">
. . .
</div>
#code{
string AnimationClass {get;set;} = string.Empty;
ObservableCollection<TItem> MyList {get;set;} = new ObservableCollection<TItem>();
void OnInitialized()
{
MyList.CollectionChanged += MyCollectionChangedHandler;
}
//I don't remember the exact syntax here, if it can't take a Task, use Task.Run in the body to do the async work
async Task MyCollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
{
AnimationClass = "my-anination-class";
await InvokeAsync(StateHasChanged);
await Task.Delay(500); // about the time of your animation
AnimationClass = "";
}
void Dispose()
{
MyList.CollectionChanged -= MyCollectionChangedHandler;
}
}

SVG vector image animation

I have 3 vector images created in Adobe Illustrator.
I want animate this vector quality images same way as gif does, fast endless loop sequence of 3 images in .svg format in browser mypage.php <img src="assets/img/logo.svg" alt="" alt="" width="65" height="45"/>.
What would be most correct way to get such animation for .svg, do I have to use all given methods to create vector animation, or in my scenario case I can do it some different way
There are a few ways you can do it. Given the information you have provided, here is one way.
We stack the frames on top of one another. Then make them visible one at a time.
.sequence {
position: relative;
}
.sequence img {
position: absolute;
top: 0;
opacity: 0; /* start all frames invisible */
animation: cycle 3s steps(1) infinite;
}
/* three images, so each gets made visible for 1/3 of the time */
#keyframes cycle {
0% { opacity: 1; }
33% { opacity: 0; }
}
/* start (ie. show) the second frame 1 sec after the first */
.sequence img:nth-child(2) {
animation-delay: 1s;
}
/* start (ie. show) the third frame 2 sec after the first */
.sequence img:nth-child(3) {
animation-delay: 2s;
}
<div class="sequence">
<img src="https://placeimg.com/300/200/animals"/>
<img src="https://placeimg.com/300/200/nature"/>
<img src="https://placeimg.com/300/200/people"/>
</div>
These images happen to be JPEGs, but it doesn't matter what type they are. Your SVGs should work.
Given you have SVGs, you might find it better to combine them in a single SVG. Put the contents for each frame in it's own group (<g> element). Then use a similar approach as above, but instead show the groups one at a time.
For what you want, the fact that it are svg images is not relevant.
You can create an element and animate trough the different files as background.
div{
width: 102px;
height: 102px;
border: 1px solid black;
animation: rotateImages 1s infinite;
}
#keyframes rotateImages {
0% { background: url("https://www.placecage.com/g/100/100"); }
32% { background: url("https://www.placecage.com/g/100/100"); }
33% { background: url("https://www.placecage.com/100/100"); }
65% { background: url("https://www.placecage.com/100/100"); }
66% { background: url("https://www.placecage.com/c/100/100"); }
100% { background: url("https://www.placecage.com/c/100/100"); }
}
<div></div>

CSS animate custom properties/variables

I have been trying to get this to work for a while.
The point is that the inner div will have some shape and there will probably more than one (That's why I used the nth-child selector).
This inner div is supposed to be shown and then be hidden again both for some set amount of time.
the problem is, that I would like to animate all the (later) multiple inner divs in one animation. For this I thought I could use CSS variables, but this does not seem to work.
What I am trying to archieve in this example is the inner div basically just blinking by using the variable. But my result in Firefox is just a black box.
Am I missing anything? I already looked up if one could even use CSS variables in #keyframes and sure enough you can.
The only problem with them in animations seems to be that they are not interpolated in between but that they suddenly switch which is not a problem in this case.
#keyframes test{
from{
--one: 0;
}
to{
--one: 1;
}
}
#test{
width: 100px;
height: 200px;
background-color: black;
animation: test 1s infinite;
}
#test :nth-child(1){
width: 20px;
height: 20px;
margin: auto;
background-color: white;
opacity: var(--one,0);
}
<div id="test">
<div></div>
</div>
This can be achieved by defining variables using (as of writing this, not well-supported) #property, which allows declaring types and that allows the browser to "understand", for example, that a certain property (variable) is a Number and then it can gradually animate/transition that variable.
Example Code:
#property --opacity {
syntax: '<number>'; /* <- defined as type number for the transition to work */
initial-value: 0;
inherits: false;
}
#keyframes fadeIn {
50% {--opacity: 1}
}
html {
animation: 2s fadeIn infinite;
background: rgba(0 0 0 / var(--opacity));
}
The current types that are allowed include:
length, number, percentage, length-percentage, color, image, url, integer, angle, time, resolution, transform-list, transform-function, custom-ident (an identifier string)
Helpful articles:
https://web.dev/at-property/#writing-houdini-custom-properties
https://css-tricks.com/using-property-for-css-custom-properties
Cool Houdini demos
As stated in the specification:
Animatable: no
and also
Notably, they can even be transitioned or animated, but since the UA
has no way to interpret their contents, they always use the "flips at
50%" behavior that is used for any other pair of values that can’t be
intelligently interpolated. However, any custom property used in a
#keyframes rule becomes animation-tainted, which affects how it is
treated when referred to via the var() function in an animation
property.
So even if you use opacity with var() in the keyframes it won't animate:
#keyframes test {
from {
--one:0;
opacity: var(--one);
}
to {
opacity: var(--one);
--one: 1;
}
}
#test {
width: 100px;
height: 200px;
background-color: black;
}
#test :nth-child(1) {
width: 20px;
height: 20px;
margin: auto;
background-color: white;
animation: test 1s infinite;
}
<div id="test">
<div></div>
</div>
By the way you can make it working if you use it as a transition because in this case you will apply a transtion to the opacity and not the custom property:
#test {
width: 100px;
height: 200px;
background-color: black;
}
#test:hover {
--one:1;
}
#test :nth-child(1) {
width: 20px;
height: 20px;
margin: auto;
background-color: white;
opacity: var(--one,0);
transition:1s all;
}
<div id="test">
<div></div>
</div>

Creating a Web Page background fade with CSS

I want to make a website that when you open it, the background fades into a different color.
Example:
/* Chrome, Safari, Opera */
#-webkit-keyframes {
from {
background: white;
}
to {
background: #F7F2E0;
}
}
/* Firefox */
#-moz-keyframes {
from {
background: white;
}
to {
background: #F7F2E0;
}
}
#keyframes {
from {
background: white;
}
to {
background: #F7F2E0;
}
}
But when I run the script, nothing happens.
You need to add a name to the animation and then add the animation properties to the desired element(s).
Example Here
#keyframes background {
from {
background:white;
}
to {
background:#000;
}
}
In the animation shorthand below, the value forwards is added for the animation-fill-mode property in order to end the animation at the last color.
body {
animation: background 4s forwards;
}
Vendor prefixes omitted for simplicity - see the example for the full CSS.
I'd suggest reading more about CSS animations at MDN.
You have to give a name to your keyframe and and then apply it to the body. See this example. For animations and browser support see here.
#keyframes fadeBackgroud{
from {
background:white;
} to {
background:#F7F2E0;
}
}
body {
animation:fadeBackgroud 5s infinite;
}