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

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;
}
}

Related

Outlook not rendering my CSS in Signature

I have put a css in my outlook signature, however when I send an email it doesn't work.
<head>
<style>
.typewriter h4 {
overflow: hidden; /* Ensures the content is not revealed until the animation */
border-right: .15em solid orange; /* The typwriter cursor */
white-space: nowrap; /* Keeps the content on a single line */
margin: 0 auto; /* Gives that scrolling effect as the typing happens */
letter-spacing: .15em; /* Adjust as needed */
animation:
typing 3.5s steps(40, end),
blink-caret .75s step-end infinite;
}
/* The typing effect */
#keyframes typing {
from { width: 0 }
to { width: 30% }
}
/* The typewriter cursor effect */
#keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: orange; }
}
</style>
</head>
<div class="typewriter">
<h4>Gaurang Shah</h4>
</div>
Above is my code, however in email signature I see no movement in Text.
Unfortunately, Outlook doesn’t support animation property. You could refer to this link:
https://www.campaignmonitor.com/css/animations/animation/
However, if possible, you could try use GIF to achieve your request.
For more information, please see the following link:
The animated graphic in my e-mail message doesn't work

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>

use background-color until background-image is loaded

I have a background image for a div.
I need the background to be a different colour other than white until the background image is loaded.
I can not use a background color on a container div, as my background image has transparency and I want to see page content underneath.
is there a way to have a background color which loads instantly, and then when the background image is loaded use that? I know I could do it with JS but is there any fallback method I can use with just css/ html?
You can simply stack the two CSS rules.
background-color: #000;
background-image: url("...");
The background color will display until the image is loaded.
If you are absolutely against Javascript for whatever reason, you can create an effect that mimics what you would obtain with Javascript.
http://jsfiddle.net/8Qk5K/5/
div {
background : url(http://www.st.hirosaki-u.ac.jp/~shimpei/GPS/GPSCMC/images/sphere-transparent.png);
width:500px;
height:500px;
position:relative;
}
.container:before{
width:500px;
height:500px;
position:absolute;
left:0;
top:0;
content:"";
background:#333;
-webkit-animation: fade-out 99999s 1 linear; /* Safari 4+ */
-moz-animation: fade-out 99999s 1 linear; /* Fx 5+ */
-o-animation: fade-out 99999s 1 linear; /* Opera 12+ */
animation: fade-out 99999s 1 linear; /* IE 10+ */
}
#-webkit-keyframes fade-out {
0% { opacity: 1; }
0.002% { opacity: 0; }
100% { opacity: 0; }
}
#-moz-keyframes fade-out {
0% { opacity: 1; }
0.002% { opacity: 0; }
100% { opacity: 0; }
}
#-o-keyframes fade-out {
0% { opacity: 1; }
0.002% { opacity: 0; }
100% { opacity: 0; }
}
#keyframes fade-out {
0% { opacity: 1; }
0.002% { opacity: 0; }
100% { opacity: 0; }
}
What this does is:
add a block element above your image, with your desired background.
fade that background after little time (you have to find the right amount that works for your content).
keep the background faded with infinite time.
The down side of this as you probably noticed is that you can't predict the exact time. For some, the image would load, for others it may still have a little bit till it loaded.
You can also adjust do fade-out time, depending on browser. If someone access the website with IE8 for example, you can add a higher fade-out time.
Also, a delay can be added to the animation, to only start it after some time.

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;
}

CSS animated typing

I'm trying make an animation as if I was typing. To achieve this I'm using CSS animation 'steps'.
The animation itself works just fine. However, if I want to animate multiple lines of text, they all start playing at the same time. Which isn't giving me the desired effect. (Tried using <br> in a single <h1>, which cut off the text, but again started the animations simultaneously.)
To counter this, I put the next line of text in an <h2> and set an animation-delay for every line of text. Which works, but the text is visible before the animation starts.
I want the text to be hidden until the animation starts playing, to really get that 'live typing' effect.
Anyone got any ideas on how I can achieve this?
HTML
<div class="content">
<h1>Hi there! My name is Jeff.</h1>
<h2>And I create cool stuff.</h2>
</div>
CSS
.content h1 {
background:white;
opacity:0.7;
white-space:nowrap;
overflow:hidden;
border-right: 3px solid black;
-webkit-animation: typing 2s steps(26, end),
blink-caret 1s step-end 2s;
}
.content h2 {
background:white;
opacity:0.7;
white-space:nowrap;
overflow:hidden;
border-right: 3px solid black;
-webkit-animation: typing 2s steps(26, end),
blink-caret 1s step-end infinite;
-webkit-animation-delay:3s;
}
#-webkit-keyframes typing {
from { width: 0; }
to { width:400px; }
}
#-webkit-keyframes blink-caret {
from, to { border-color: transparent }
50% { border-color: black }
}
jsFiddle
The simplest solution is to add:
animation-fill-mode:both;
to your h2 (with the necessary prefixes). That way, you aren't setting it to a zero width outside of your animation, so browsers that don't support this CSS will display the heading (which I guess is what you're after). See this fiddle.
The animation-fill-mode:
specifies how a CSS animation should apply styles to its target before
and after it is executing
Setting it to both in this instance means that your h2 will have a width of 0 before it starts executing, and a width of 400px after.
As the comments already include a solution, perhaps this might be another way of doing it - by using timeouts and setting visibility: hidden at the beginning (For simplification I just used jQuery to set the visiblitiy).
Include the following CSS rule:
.content {
visibility: hidden;
}
As JavaScript you would have:
window.setTimeout(function() {
$('#contentdiv h1').css('visibility', 'visible');
}, 100);
window.setTimeout(function() {
$('#contentdiv h2').css('visibility', 'visible');
}, 3100);
See the jsFiddle
p
{
font:500 22px consolas;
width:20ch;
white-space:nowrap;
overflow:hidden;
animation:type 5s steps(20) infinite;
}
#keyframes type
{
0%{ width:0; }
}
<p>Text Type Animation</p>
Not quite the OP's question, but in case someone else finds this useful:
I wanted to be able to typing-animate a pararaph of text, a single <p> tag which might contain text that would wrap, and produce an unknown number of actual lines. Applying a simple linear animation to the p tag itself wouldn't work, so instead, I took the approach of having several "hider" elements that would cover the paragraph of text, each one line high, and then I would animate each of those so they would shrink away, reveal characters from the line of text beneath them.
The HTML looks like this:
<div class="container">
<!-- container div is required to set absolute positions within it, so that .typing and .hiders exactly overlap -->
<p class="typing">
This paragraph of text will be animated
with a "typewriter" style effect, and it
will continue to work even if it splits across
multiple lines. Well, in this case, up to a
maximum of 5 lines, but you get the picture.
</p>
<div class="hiders">
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
</div>
</div>
You need a container, and position the .typing element and the .hiders using absolute so that they're on top of each other:
.container {
position: relative;
font-family: Consolas, monospace;
}
.typing {
position: absolute;
top: 0;
margin: 0;
z-index: -1;
}
.hiders {
margin: 0;
position: absolute;
top: 0;
width: 100%;
}
And the animation gets applied to each p inside the .hiders:
.hiders p {
position: relative;
clear: both;
margin: 0;
float: right; /* makes animation go left-to-right */
width:0; /* graceful degradation: if animation doesn't work, these are invisible by default */
background: white; /* same as page background */
animation: typing 2s steps(30, end);
animation-fill-mode: both; /* load first keyframe on page load, leave on last frame at end */
}
.hiders p:nth-child(2) {
animation-delay: 2s;
}
.hiders p:nth-child(3) {
animation-delay: 4s;
/* etc */
Here's the final fiddle:
https://jsfiddle.net/hjwp/514cLzxn/
Original credit for inspiration: Lea Verou