Doesn't work inline css animation like this:
<h1 class="test" style="animation: bg 2s linear infinite">Hello {name}!</h1>
<style>
.test {
background: yellow;
}
#keyframes bg {
from {
background: red;
}
to {
background: green;
}
}
</style>
https://svelte.dev/repl/e32b72cb98cb4b78a47b1bcb1ecab9e9?version=3.53.1
But if delete style attribute
<h1 class="test">Hello {name}!</h1>
and add
.test
background: yellow;
animation: bg 2s linear infinite;
}
It works!
But I want to add animation as inline style.
Everything within a component style is scoped to the component by default and the inline style apparently is not recognized as referring to the defined #keyframes.
Regular selectors can be made global using :global() around the selector but for #keyframes you would have to prefix the name with -global- (which is removed again on compilation).
#keyframes -global-bg { ... }
REPL
Note that this really is defined as global then and any other component that defines global keyframes with the name bg will cause interference.
Related
Generally you would define a onHover animation of a square class like this:
.square:hover {
animation-duration: 0.5s;
animation-name: square_hover;
}
#keyframes square_hover {
to {background-color: yellow;}
}
Is there a way to define it like this:
.square:hover {
animation-duration: 0.5s;
animation: {
to { background-color: yellow; }
};
}
#keyframes square_hover
?
According to MDN the correct way of declaring an animation is using this syntax:
#keyframes <keyframes-name> {
<keyframe-block-list>
}
And then call it back using animation properties:
animation-duration: time;
animation-name: animation;
Where you will is a string that will identify the animation name. And is the sequence you will follow to create the animation.
So in short, CSS has a strict syntax you have to follow. But it seems like you're trying to find a simpler way to declare/create animation on hover.
You can simply get rid of the animation and directly add the properties you want to change on hover. For instance, if you want to change the background colour of the square class you will simply start with the initial state/base styles:
.square {
background-color: black;
}
And then apply the styles you want to change:
.square:hover {
background-color: yellow;
}
And if you want smooth out the transition simply add the transition property to the base styles. And the syntax looks something like
transition: property-to-transition time ease;
A working example:
.square {
background-color: black;
transition: background-color .5s ease;
}
References:
MDN Docs #keyframes: #keyframes
MDN Docs transitions: transitions
MDN Docs animations: animations
I have some paper-tabs and some CSS code like the following code snippets, but I can't figure out how to pass in an animation name or #keyframes into the mixin that Polymer uses for paper-tabs (--paper-tabs-selection-bar). How would I go about doing this? Preferably with only CSS, but a best practice with JavaScript is also welcome.
HTML:
<paper-tabs selected="0">
<paper-tab name="test">Test</paper-tab>
</paper-tabs>
CSS:
/* keyframes can't be accessed without the deprecated /deep/ selector */
paper-tabs {
--paper-tabs-selection-bar: {
animation: selection-bar-clear 0.4s ease forwards;
}
}
#keyframes selection-bar-clear {
from {
border-bottom: 2px solid var(--app-header-light-text-color);
}
to {
border-bottom: 2px solid var(--app-header-dark-text-color);
}
}
/* keyframes aren't parsed in mixins */
paper-tabs {
--paper-tabs-selection-bar: {
animation: selection-bar-clear 0.4s ease forwards;
#keyframes selection-bar-clear {
from {
border-bottom: 2px solid var(--app-header-light-text-color);
}
to {
border-bottom: 2px solid var(--app-header-dark-text-color);
}
}
}
}
Take a look at https://www.polymer-project.org/2.0/docs/devguide/custom-css-properties#custom-properties-shim-limitations to see if this is actually feasible with plain CSS mixins/variables. My guess is no, but I haven't read the full docs, let alone tried this.
I would probably go the Web Animations route, since that way you can implement your animations as a separate class (in JavaScript), mix that into your element's implementation and use one of your own, shiny animation methods.
I know there are a lot of other questions on using transitions on CSS pseudo element but after going through a whole bunch of them I still can't get my scenario to work.
Basically, I want to add a class to an element, the class has a :after pseudo element with some content and a background. I'd like a fading effect on the :after element when adding or removing the class.
I've been trying this out in this jsfiddle and the code I have so far it this:
HTML
<div id="divA">Div test</div>
<button id="btnAdd">Add it</button>
<button id="btnRemove">Take Away</button>
CSS
div {
width: 200px;
transition: all .5s linear;
background: red;
}
.test{
background: blue;
}
.test:after{
background: #0c0;
content: "Test";
}
jQuery
$("#btnAdd").click(function() {
$("#divA").addClass("test");
});
$("#btnRemove").click(function() {
$("#divA").removeClass("test");
});
Any help and hints would be most appreciated.
Forking #NilsKaspersson answer to make it work with your requirements.
Transition means from X to Y, you can't expect it to work with newly created attributes.
Then you have to create an initial attribute, and alter it later.
Since you don't want it to be there at the beginning, just use color: transparent; and background: transparent;
Running Demo
Code:
div {
width : 200px;
transition : all .5s linear;
background : red;
}
div:after {
transition : all .5s linear;
background : transparent;
color : transparent;
content : "Test";
}
.test{
background : blue;
}
.test:after{
background : #0c0;
color : black;
}
There are two things going on here.
1.) transition only works when there's something to transition from. Since your :after element is essentially created when the class test is added to it, there's no transition going on.
2.) transition doesn't inherit, so you'll need to declare it once again on the pseudo element.
Here's a quick n' dirty fork of your JSFiddle.
I moved the generic rules for the pseudo element to the classless div and added a transition to it. Then when the class test is added to it, the background changes and it can transition from it's old value.
If you don't want the pseudo element's content to be visible all the time, consider hiding it with opactiy: 0 and transition that to 1, or use the transparent color value for background and/or color.
Edit: Changing answer based on new fiddle.
On most case, CSS transition must apply on already-defined properties.
Additionnaly, the changing of a pseudo :after element content will make the element be removed and re-added, which removes the said properties at the same time.
I have made a demo with animating the text color and background-color while pre-setting the content, so the properties are already present.
CSS :
div {
width: 200px;
transition: all .5s linear;
background: red;
}
div:after {
transition: all .5s linear;
background: red;
color: red;
content: 'Test';
}
.test{
background: blue;
}
.test:after{
background: #0c0;
color: black;
}
Fiddle : http://jsfiddle.net/W5e9Q/10/
I have the following CSS example:
.message{
background-color: red;
transition: background-color 5s;
-webkit-transition: background-color 5s; /* Safari */
transition-delay: 2s;
-webkit-transition-delay: 2s; /* Safari */
}
.unreadMessage{
background-color: blue;
}
Then, i have a DIV with .message class, and by pressing a Button, i add the class .unreadMessage, and by pressing another Button, i remove it.
With this example, every time i change background-color, by adding or removing .unreadMessage, it does the CSS transition.
What i want to do, is, if possible, to have an instant color change when i add .unreadMessage, and have the transition only when removing it.
The first thing that come in my mind, was to have a different class containing the CSS transition properties, and add it after adding .unreadMessage.
But it is possible to do it with only one class, or using a Javascript workaround?
If you want to only apply a transition when the .message element does not have the unreadMessage class, then put the transition properties in the .message:not(.unreadMessage) selector:
.message{
background-color: red;
}
.message:not(.unreadMessage) {
-webkit-transition: background-color 5s; /* Safari */
transition: background-color 5s;
-webkit-transition-delay: 2s; /* Safari */
transition-delay: 2s;
}
.unreadMessage{
background-color: blue;
}
Demo: http://jsfiddle.net/Hs8fa/
Documentation for :not()
There are two things to remember when using CSS transitions:
Transitions happen when an element's state is modified "using pseudo-classes like :hover or :active or dynamically set using JavaScript."
You have to have a starting point and an ending point or they won't work.
The biggest issue with OP's question isn't their CSS, it's their naming structure. A major pattern of CSS transitions is to modify an element's class (or in the MDN's language "dynamically set using Javascript"). In OP's example they're not modifying an element's class structure, they're changing classes. CSS transitions won't work when an element changes from one class to another, but they will work when a class is added or taken away.
The easiest example of this is going from .element to .element.active. If we put the transition on the base class, .element, and then add a modifying class, .active, the transitions applied to .element will transition from .element settings to .element.active. settings.
Here's a JSFiddle example of modifying a base class
Secondly, and this is one I forget all the time, the base class must have a starting style. I can't transition left in the modified state if I don't have left set in the base state.
This code snippet contains a div with transition: none;
On click, override transition property by adding a new class add-transition
On the second click, the same class is removed & no transition.
var elm = document.querySelector('.no-transition');
elm.onclick = () => (
elm.classList.toggle('add-transition')
);
.no-transition {
background-color: aliceblue;
transition: none;
}
.add-transition {
background-color: deepskyblue;
transition: background-color 3s;
}
/* Note: As like other any other CSS property
Specificity or CSS Order can make the difference.
Styles below are for code the snippet to look better. */
.wrapper {
padding: 20px;
margin: 20px;
text-align: center;
cursor: pointer;
border: 1px solid lightgray;
}
<div class="wrapper no-transition">
Run code snippet & click here !!!<hr/>
on load, No transition. <br/>
on click, transition added(bg color). <br/>
on second click, no transtion.
</div>
https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
As far as I understand, there is no such thing we can implement using css transitions, but we can not to implement using css animations, but not vice versa.
That is, any transition has a css animation equivalent.
For example, this one
.ablock:hover {
position: relative;
-moz-transition-property: background-color, color;
-moz-transition-duration: 1s;
-webkit-transition-property: background-color, color;
-webkit-transition-duration: 1s;
color: red;
background-color:pink;
}
is an equivalent of following:
.ablock:hover {
-moz-animation-duration:1s;
-moz-animation-name:transition;
-webkit-animation-duration:1s;
-webkit-animation-name:transition;
}
#-moz-keyframes transition {
to {
color: red;
background-color: pink;
}
}
#-webkit-keyframes transition {
to {
color: red;
background-color: pink;
}
}
My question is - if we a talking about browser supporting both css transitions and animations, what are use cases for choosing one or another approach?
As for transitions, I can name only one - they have more succinct syntax, we don't have to copy paste huge chucks of code for #-moz-keyframes, #-webkit-keyframes and so on.
As for control from javascript, flexibility and complexity animations are much more appropriate tool (at least, at first glance). So, what are use cases?
UPD:
OK, let me try to list interesting info found in questions.
This one is contributed by Roman Komarov. Say, we have a div and child div. While parent div is hovered, we are transitioning the child element. Once we are taking away the mouse, transition is cancelled. Duration of this cancellation is exactly the time we've already spend for transitioning. Animation is cancelled "immediately". I don't know, nevertheless, how standard are those two behaviours.
Animations can be looped (and there can be keyframes, yeeah).
Transitions can be more flexible and you can easily make transitions to different values and in different circumstances.
While you can emulate some transitions by animations (like you mentioned in your post), the transitions are just more powerful:
You just tell which properties you must animate and in which conditions (using the different selectors)
You can trigger the transition in different ways:
Changing properties in CSS for pseudo-classed :hover, :active etc. (Creating pure CSS UI)
Changing properties in different classes for different purposes.
Changing properties in inline styles: in conjunction with JS it's just more powerful than animations.
With transitions you are able to transition between any value of the defined property, which you want to be transitioned. As an example, you want to transition the color of a link, when it's hovered and active:
a {
color: #000;
transition: color .4s ease;
}
a:hover {
color: #888;
}
a:active {
color: #faa;
}
You are independent, which color you choose.
Now if you want to use the animation style, you have to explicitly set the color value for the animation states. And you are not able to easily animate between the three states: normal, hover and active. You need more complex definitions. I'll try this one with animations:
a {
color: #000;
animation-duration: 0.4s;
animation-fill-mode: forwards;
animation-name: toDefault;
}
a:hover {
animation-duration: 0.4s;
animation-fill-mode: forwards;
animation-name: toHover;
}
a:active {
animation-duration: 0.4s;
animation-fill-mode: forwards;
animation-name: toActive;
}
#keyframes toDefault {
to {
color: #000;
}
}
#keyframes toHover {
to {
color: #888;
}
}
#keyframes toActive {
to {
color: #faa;
}
}
Now this does not include the animation back to the state before. I'm not sure if you can even fetch that.
So in short: with transitions you are able to animate an undefined set of properties and values, whilst keyframe animations are used for well defined animations and/or transitions.