I have created multilevel navigation menu using jquery dlmenu plugin v1.0.2 demo2.
Everything works fine, except CSS3 menu navigation is not smooth as jQuery left/right slide functionality is.
Is there any solution to resolve this issue without changing plugin?
/* Animation classes for moving out and in */
.dl-menu.dl-animate-out-2 {
-webkit-animation: MenuAnimOut2 0.3s ease-in-out forwards;
-moz-animation: MenuAnimOut2 0.3s ease-in-out forwards;
animation: MenuAnimOut2 0.3s ease-in-out forwards;
}
#-webkit-keyframes MenuAnimOut2 {
100% {
-webkit-transform: translateX(-100%);
opacity: 0;
}
}
#-moz-keyframes MenuAnimOut2 {
100% {
-moz-transform: translateX(-100%);
opacity: 0;
}
}
#keyframes MenuAnimOut2 {
100% {
transform: translateX(-100%);
opacity: 0;
}
}
.dl-menu.dl-animate-in-2 {
-webkit-animation: MenuAnimIn2 0.3s ease-in-out forwards;
-moz-animation: MenuAnimIn2 0.3s ease-in-out forwards;
animation: MenuAnimIn2 0.3s ease-in-out forwards;
}
#-webkit-keyframes MenuAnimIn2 {
0% {
-webkit-transform: translateX(-100%);
opacity: 0;
}
100% {
-webkit-transform: translateX(0px);
opacity: 1;
}
}
#-moz-keyframes MenuAnimIn2 {
0% {
-moz-transform: translateX(-100%);
opacity: 0;
}
100% {
-moz-transform: translateX(0px);
opacity: 1;
}
}
#keyframes MenuAnimIn2 {
0% {
transform: translateX(-100%);
opacity: 0;
}
100% {
transform: translateX(0px);
opacity: 1;
}
}
You have to use the plugin like this : with animationClasses "in" and "out" not "classin" and "classout"
$(function() {
$( '#dl-menu' ).dlmenu({
animationClasses : { in : 'dl-animate-in-2', out : 'dl-animate-out-2' }
});
});
Related
so apologies that there are similar questions to this. I've done my best to look so any help would be appreciated.
I'm using a new library of animations from Animista to animate certain elements on a practice site.
I have no issues with animating elements as the page loads but I'm not sure how to go about getting them to trigger as they become visible like is common on so many sites nowadays.
Take this example;
.bounce-in-top {
-webkit-animation: bounce-in-top 1.1s both;
animation: bounce-in-top 1.1s both;
}
#-webkit-keyframes bounce-in-top {
0% {
-webkit-transform: translateY(-500px);
transform: translateY(-500px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: translateY(-65px);
transform: translateY(-65px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: translateY(-28px);
transform: translateY(-28px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
#keyframes bounce-in-top {
0% {
-webkit-transform: translateY(-500px);
transform: translateY(-500px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: translateY(-65px);
transform: translateY(-65px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: translateY(-28px);
transform: translateY(-28px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
.trigger {
/* The plan was to add this to all elements and then trigger animations each time the class is in the viewport*/
}
<h1 class="bounce-in-top trigger">Page title, animates on load</h1>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h2 class="bounce-in-top trigger">Lower down, should animate when visible</h2>
The animation is applied to both header 1 and header 2 but the header 2 animation runs before the user sees it.
.bounce-in-top {
-webkit-animation: bounce-in-top 1.1s both;
animation: bounce-in-top 1.1s both;
}
#-webkit-keyframes bounce-in-top {
0% {
-webkit-transform: translateY(-500px);
transform: translateY(-500px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: translateY(-65px);
transform: translateY(-65px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: translateY(-28px);
transform: translateY(-28px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
#keyframes bounce-in-top {
0% {
-webkit-transform: translateY(-500px);
transform: translateY(-500px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: translateY(-65px);
transform: translateY(-65px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: translateY(-28px);
transform: translateY(-28px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
.trigger {
/* The plan was to add this to all elements and then trigger animations each time the class is in the viewport*/
}
<h1 class="bounce-in-top trigger">Page title, animates on load</h1>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<h2 class="bounce-in-top trigger">Lower down, should animate when visible</h2>
I'd use some sort of query selector so each time an element to be animated would appear it should then run its animation.
Any help and working code would be more than appreciated because I cannot find how to implement this.
Thanks in advance.
I think what you should do is track the scrolling state of the page, and start the animation if the scrolling position is superior to a certain value, and then change the animation value of CSS by using Javascript.
A simple example would be like this:
<html lang="en">
<head>
<style>
#header2 {
width: 100px;
height: 100px;
background: red;
position: relative;
-webkit-animation: none 1s infinite; /* Safari 4.0 - 8.0 */
animation: none 1s infinite;
}
/* Chrome, Safari, Opera */
#-webkit-keyframes mymove {
from {left: 0px;}
to {left: 200px;}
}
#keyframes mymove {
from {left: 0px;}
to {left: 200px;}
}
</style>
</head>
<body>
<h1 id="header1" style="height: 1200px;">This is first paragraph</h1>
<br>
<h1 id="header2">This is second paragraph</h1>
<script>
let myHeader2 = document.getElementById("header2");
window.setInterval(checkScrollingPosition, 200);
function checkScrollingPosition(){
console.log(window.scrollY)
if (window.scrollY > 200){
//starting animation if scrollPosition > 200
console.log("starting animation...")
startAnimation()
return;
}
}
function startAnimation(){
myHeader2.style.animation = "mymove 5s 1"
myHeader2.style.WebkitAnimation = "mymove 5s 1"
}
</script>
</body>
</html>
Depending of what you want to do, may be you could replace the threshold value to a certain percentage of the height of the page. For this just research the differents ways to get the scrolling state of the page.
Use the IntersectionObserver API. It makes it possible to check if the elements are in view of the user and call a function when that happens.
In the InterSectionObserver you call a function which will loop over all of the elements that have come in or out the view. In that function you can check each individual element to see its current position.
So check if an element is in the view, and if so, add the animation class to it.
Here below I've made a modification of your code. I've created a container around each title so that the title can animate within that container as well as to control the overflow.
So the .trigger elements are being watched. When they enter into view they get the class .bounce-in-top added to them.
To prevent the animation from suddenly animating from the top I've added a starting position for the .title elements. The starting position is always the same as the first keyframe of the animation.
// Create the observer.
const observer = new IntersectionObserver(entries => { // entries is a list of elements that have come in our out of view
entries.forEach(entry => { // Loop over every single entry
if (entry.isIntersecting || entry.intersectionRatio > 0) { // Check that an entry has come INTO view.
entry.target.classList.add('bounce-in-top'); // Add the class to the element.
}
});
});
// Select the triggers
const triggers = document.querySelectorAll('.trigger');
// Observe the triggers.
triggers.forEach(trigger => {
observer.observe(trigger);
});
/* Create a default begin state */
.title {
-webkit-transform: translateY(-500px);
transform: translateY(-500px);
}
/* Hide overflow of title container. */
.trigger {
overflow: hidden;
}
/* Select title for animation */
.bounce-in-top .title {
-webkit-animation: bounce-in-top 1.1s both;
animation: bounce-in-top 1.1s both;
}
#-webkit-keyframes bounce-in-top {
0% {
-webkit-transform: translateY(-500px);
transform: translateY(-500px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: translateY(-65px);
transform: translateY(-65px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: translateY(-28px);
transform: translateY(-28px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
#keyframes bounce-in-top {
0% {
-webkit-transform: translateY(-500px);
transform: translateY(-500px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
opacity: 0;
}
38% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
opacity: 1;
}
55% {
-webkit-transform: translateY(-65px);
transform: translateY(-65px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
72% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
81% {
-webkit-transform: translateY(-28px);
transform: translateY(-28px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
90% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
95% {
-webkit-transform: translateY(-8px);
transform: translateY(-8px);
-webkit-animation-timing-function: ease-in;
animation-timing-function: ease-in;
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
}
<div class="trigger">
<h1 class="title">Page title, animates on load</h1>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<div class="trigger">
<h2 class="title">Lower down, should animate when visible</h2>
</div>
I'm trying to implement a CSS typing indicator in Vue. Without Vue, it looks like this:
.typing-indicator {
background-color: #E6E7ED;
width: auto;
border-radius: 50px;
padding: 20px;
display: table;
margin: 0 auto;
position: relative;
-webkit-animation: 2s bulge infinite ease-out;
animation: 2s bulge infinite ease-out;
}
.typing-indicator:before, .typing-indicator:after {
content: '';
position: absolute;
bottom: -2px;
left: -2px;
height: 20px;
width: 20px;
border-radius: 50%;
background-color: #E6E7ED;
}
.typing-indicator:after {
height: 10px;
width: 10px;
left: -10px;
bottom: -10px;
}
.typing-indicator span {
height: 15px;
width: 15px;
float: left;
margin: 0 1px;
background-color: #9E9EA1;
display: block;
border-radius: 50%;
opacity: 0.4;
}
.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink infinite 0.3333s;
animation: 1s blink infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink infinite 0.6666s;
animation: 1s blink infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink infinite 0.9999s;
animation: 1s blink infinite 0.9999s;
}
#-webkit-keyframes blink {
50% {
opacity: 1;
}
}
#keyframes blink {
50% {
opacity: 1;
}
}
#-webkit-keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
#keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
html {
display: table;
height: 100%;
width: 100%;
}
body {
display: table-cell;
vertical-align: middle;
}
<div class="typing-indicator">
<span></span>
<span></span>
<span></span>
</div>
– source: http://jsfiddle.net/Arlina/gtttgo93/
The problem is that the animation does not work when adding the scoped attribute to the component's style definition (<style lang="scss" scoped>). I believe it may be related to keyframes that should be declared globally.
The element with .typing-indicator is in the template of the component with scoped styling.
Does anyone have an idea of how I can allow my component to have scoped styling while making the keyframe animations work?
Problem
The problem is down to how the Webpack loader for Vue (vue-loader), incorrectly, parses animation names when adding IDs to scoped selectors and other identifiers. This is important because vue-loader's CSS scoping uses unique attributes added to elements to replicate the behaviour of CSS scoping. While your keyframe names get IDs appended, references to keyframes in animation rules in scoped styles do not.
Your CSS:
#-webkit-keyframes blink {
50% {
opacity: 1;
}
}
#keyframes blink {
50% {
opacity: 1;
}
}
#-webkit-keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
#keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
.typing-indicator {
...
-webkit-animation: 2s bulge infinite ease-out;
animation: 2s bulge infinite ease-out;
}
.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink infinite 0.3333s;
animation: 1s blink infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink infinite 0.6666s;
animation: 1s blink infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink infinite 0.9999s;
animation: 1s blink infinite 0.9999s;
}
Should get transformed to:
#-webkit-keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}
#keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}
#-webkit-keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
#keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
.typing-indicator {
...
-webkit-animation: 2s bulge-data-v-xxxxxxxx infinite ease-out;
animation: 2s bulge-data-v-xxxxxxxx infinite ease-out;
}
.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink-data-v-xxxxxxxx infinite 0.3333s;
animation: 1s blink-data-v-xxxxxxxx infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink-data-v-xxxxxxxx infinite 0.6666s;
animation: 1s blink-data-v-xxxxxxxx infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink-data-v-xxxxxxxx infinite 0.9999s;
animation: 1s blink-data-v-xxxxxxxx infinite 0.9999s;
}
However it only get's transformed to:
#-webkit-keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}
#keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}
#-webkit-keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
#keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
.typing-indicator {
...
-webkit-animation: 2s bulge infinite ease-out;
animation: 2s bulge infinite ease-out;
}
.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink infinite 0.3333s;
animation: 1s blink infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink infinite 0.6666s;
animation: 1s blink infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink infinite 0.9999s;
animation: 1s blink infinite 0.9999s;
}
Something to note: in the actual transformation, references to keyframe names in animation rules are missing the -data-v-xxxxxxxx at the end. This is the bug.
Currently (as of 47c3317) the animation name in shorthand animation rule declarations is identified by getting the first value out of splitting the animation rule by any whitespace character[1]. However the formal definition for the animation property states the animation name could appear anywhere within the rule definition.
<single-animation> = <time> || <single-timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state> || [ none | <keyframes-name> ]
– animation formal syntax[2]
Therefore, while your animation declarations are valid, vue-loader is not able to parse it.
Workaround
The current workaround for this is to move your animation names to the beginning of animation rule declarations. Your keyframe declarations do not need changing, they remain inside the scoped stylesheet. Your animation declarations should now look like this:
.typing-indicator {
...
-webkit-animation: bulge 2s infinite ease-out;
animation: bulge 2s infinite ease-out;
}
.typing-indicator span:nth-of-type(1) {
-webkit-animation: blink 1s infinite 0.3333s;
animation: blink 1s infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: blink 1s infinite 0.6666s;
animation: blink 1s infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: blink 1s infinite 0.9999s;
animation: blink 1s infinite 0.9999s;
}
References
[1] vue-loader/lib/style-compiler/plugins/scope-id.js#L67 # 47c3317
[2] Definition for animation in the Editor's Draft of W3C specification CSS Animations Level 1
I met the same problem and the first answer did tell me why it does not work, but the workaround part did not quite fix my issue... this is my code:
/* Animations */
#keyframes moveOut1 {
from {
transform: translateY(0) scale(0);
}
3% {
transform: translateY(0.2em) scale(1);
}
97% {
transform: translateY(7.3em) scale(1);
}
to {
transform: translateY(7.5em) scale(0);
}
}
#keyframes moveOut2 {
from {
transform: rotate(60deg) translateY(0) scale(0);
}
3% {
transform: rotate(60deg) translateY(0.2em) scale(1);
}
97% {
transform: rotate(60deg) translateY(7.3em) scale(1);
}
to {
transform: rotate(60deg) translateY(7.5em) scale(0);
}
}
#keyframes moveOut3 {
from {
transform: rotate(120deg) translateY(0) scale(0);
}
3% {
transform: rotate(120deg) translateY(0.2em) scale(1);
}
97% {
transform: rotate(120deg) translateY(7.3em) scale(1);
}
to {
transform: rotate(120deg) translateY(7.5em) scale(0);
}
}
#keyframes moveOut4 {
from {
transform: rotate(180deg) translateY(0) scale(0);
}
3% {
transform: rotate(180deg) translateY(0.2em) scale(1);
}
97% {
transform: rotate(180deg) translateY(7.3em) scale(1);
}
to {
transform: rotate(180deg) translateY(7.5em) scale(0);
}
}
#keyframes moveOut5 {
from {
transform: rotate(240deg) translateY(0) scale(0);
}
3% {
transform: rotate(240deg) translateY(0.2em) scale(1);
}
97% {
transform: rotate(240deg) translateY(7.3em) scale(1);
}
to {
transform: rotate(240deg) translateY(7.5em) scale(0);
}
}
#keyframes moveOut6 {
from {
transform: rotate(300deg) translateY(0) scale(0);
}
3% {
transform: rotate(300deg) translateY(0.2em) scale(1);
}
97% {
transform: rotate(300deg) translateY(7.3em) scale(1);
}
to {
transform: rotate(300deg) translateY(7.5em) scale(0);
}
}
#keyframes ripple {
from,
to {
width: 0.2em;
}
33% {
width: 2.4em;
}
}
so I asked a friend and the solution he provided me with is simply to place the css code out side and then import it into the vue component via
<style>
#import url(./{css_file_name}.css);
</style>
but I do not understand the mechanism behind this... but to me, it's fine as long as it works.
I'm creating a CSS3/HTML5 banner ad and want to loop the animations over once they're all complete. I know there's a method to check with Javascript to check if a particular animation has ended, however I cannot figure out how to then restart the animations from all of their start points.
Essentially I have 3 'frames' with different information, each one will fade in and then fade back out, to be replaced with the next frame - once the last frame has faded back out, I want the animations to start over again. Doing this solely with CSS3 is way too tricky, because the timings of the animations and points in which the opacity is set to 0 have to be different for each animation.
As you can see from the JSFiddle, it plays once, then stops which is great, now I just need to re-trigger the animation once click_through2 finishes executing the animation.
JSFiddle
.test {
height: 250px;
position: relative;
width: 300px;
overflow: hidden;
}
.test div, .test a, .logo, .sfv2 {
position: absolute;
}
.title {
bottom: 45px;
left: 5px;
right: 5px;
}
.title h2 {
color: #fff;
font-family: Helvetica,arial,sans-serif;
font-size: 21px;
font-weight: 400;
line-height: 1;
margin: 0;
text-align: center;
}
.click_through {
background-color: #fff200;
border-radius: 5px;
bottom: 12px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.35);
color: #ce1e25;
font-family: Helvetica,arial,sans-serif;
font-size: 14px;
font-weight: 700;
left: 0;
line-height: 1;
margin: 0 auto;
padding: 5px;
right: 0;
text-align: center;
width: 70px;
text-decoration: none;
}
.click_through1 {
animation: tbio 7s ease-out 0s both;
-moz-animation: tbio 7s ease-out 0s both;
-webkit-animation: tbio 7s ease-out 0s both;
-ms-animation: tbio 7s ease-out 0s both;
-o-animation: tbio 7s ease-out 0s both;
}
.click_through2 {
animation: tbio 7s ease-out 10s both;
-moz-tbio tbio 7s ease-out 10s both;
-webkit-tbio tbio 7s ease-out 10s both;
-ms-tbio tbio 7s ease-out 10s both;
-o-tbio tbio 7s ease-out 10s both;
width: 80px;
}
.logo {
top: 8px;
left: 8px;
}
.title1 {
animation: ltrio 6s ease 0s both;
-moz-animation: ltrio 6s ease 0s both;
-webkit-animation: ltrio 6s ease 0s both;
-ms-animation: ltrio 6s ease 0s both;
-o-animation: ltrio 6s ease 0s both;
}
.title2, .title3 {
opacity: 0;
}
.title2 {
animation: ltrio 6s ease 5.5s both;
-moz-animation: ltrio 6s ease 5.5s both;
-webkit-animation: ltrio 6s ease 5.5s both;
-ms-animation: ltrio 6s ease 5.5s both;
-o-animation: ltrio 6s ease 5.5s both;
}
.title3 {
animation: ltrio 6s ease 10s both;
-moz-nimation: ltrio 6s ease 10s both;
-webkit-nimation: ltrio 6s ease 10s both;
-ms-onimation: ltrio 6s ease 10s both;
-o-nimation: ltrio 6s ease 10s both;
}
.sfv2 {
right: 12px;
top: 34px;
animation: fio 6s ease 11s both;
-moz-animation: fio 6s ease 11s both;
-webkit-animation: fio 6s ease 11s both;
-ms-animation: fio 6s ease 11s both;
-o-animation: fio 6s ease 11s both;
}
#keyframes ltrio {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-moz-keyframes ltrio {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-ms-keyframes ltrio {
0% {
-ms-transform: translateY(-350px);
opacity: 0;
}
25% {
-ms-transform: translateY(0);
opacity: 1;
}
75% {
-ms-transform: translateY(0);
opacity: 1;
}
100% {
-ms-transform: translateY(350px);
opacity: 0;
}
}
#-o-keyframes ltrio {
0% {
-o-transform: translateX(-350px);
opacity: 0;
}
25% {
-o-transform: translateX(0);
opacity: 1;
}
75% {
-o-transform: translateX(0);
opacity: 1;
}
100% {
-o-transform: translateX(350px);
opacity: 0;
}
}
#keyframes tbio {
0% {
transform: translateY(350px);
opacity: 0;
}
25% {
transform: translateY(0);
opacity: 1;
}
75% {
transform: translateY(0);
opacity: 1;
}
100% {
transform: translateY(350px);
opacity: 0;
}
}
#-moz-keyframes tbio {
0% {
-moz-transform: translateY(350px);
opacity: 0;
}
25% {
-moz-transform: translateY(0);
opacity: 1;
}
75% {
-moz-transform: translateY(0);
opacity: 1;
}
100% {
-moz-transform: translateY(350px);
opacity: 0;
}
}
#-webkit-keyframes tbio {
0% {
-webkit-transform: translateY(350px);
opacity: 0;
}
25% {
-webkit-transform: translateY(0);
opacity: 1;
}
75% {
-webkit-transform: translateY(0);
opacity: 1;
}
100% {
-webkit-transform: translateY(350px);
opacity: 0;
}
}
#-ms-keyframes tbio {
0% {
-ms-transform: translateY(350px);
opacity: 0;
}
25% {
-ms-transform: translateY(0);
opacity: 1;
}
75% {
-ms-transform: translateY(0);
opacity: 1;
}
100% {
-ms-transform: translateY(350px);
opacity: 0;
}
}
#-o-keyframes tbio {
0% {
-o-transform: translateY(350px);
opacity: 0;
}
25% {
-o-transform: translateY(0);
opacity: 1;
}
75% {
-o-transform: translateY(0);
opacity: 1;
}
100% {
-o-transform: translateY(350px);
opacity: 0;
}
}
#keyframes fio {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
<div class="test">
<img class="sfv1" src="http://i.imgur.com/3VWKopF.jpg">
<div class="title title1">
<h2>Great value<br/> <strong>Spanish Properties</strong><br/> starting at £65k</h2>
</div>
<div class="title title2">
<h2>Stunning properties in <br/><strong>Costa del Sol, <br/>Blanca & Murcia</strong></h2>
</div>
<div class="title title3">
<h2>Over <strong>10,000 <br/>Spanish properties sold</strong></h2>
</div>
<a class="click_through click_through1" href="/">View here</a>
<a class="click_through click_through2" href="/">Learn more</a>
</div>
You could check for the end of the animation by responding to the endanimation event (of which there are several browser-dependent variants), reloading the relevant nodes, and repeating the whole process. Note I applied a factor 10 to the speed of the animations so you can see the effect faster:
// Define a function that listens to all prefix variants of endanimation events:
function whenAnimationEnd(element, callback) {
element.addEventListener('animationend', callback, false);
element.addEventListener('webkitAnimationEnd', callback, false);
element.addEventListener('oanimationend', callback, false);
element.addEventListener('MSAnimationEnd', callback, false);
}
(function repeat() {
whenAnimationEnd(document.querySelector('.click_through2'), function(e) {
var container = document.querySelector('.ad_container');
var dupe = container.cloneNode(true);
container.parentNode.replaceChild(dupe, container);
repeat();
});
}());
.ad_container {
height: 250px;
position: relative;
width: 300px;
overflow: hidden;
}
.ad_container div, .ad_container a, .logo, .sfv2 {
position: absolute;
}
.title {
bottom: 45px;
left: 5px;
right: 5px;
}
.title h2 {
color: #fff;
font-family: Helvetica,arial,sans-serif;
font-size: 21px;
font-weight: 400;
line-height: 1;
margin: 0;
text-align: center;
}
.click_through {
background-color: #fff200;
border-radius: 5px;
bottom: 12px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.35);
color: #ce1e25;
font-family: Helvetica,arial,sans-serif;
font-size: 14px;
font-weight: 700;
left: 0;
line-height: 1;
margin: 0 auto;
padding: 5px;
right: 0;
text-align: center;
width: 70px;
text-decoration: none;
}
.click_through1 {
animation: tbio 0.7s ease-out 0s both;
-moz-animation: tbio 0.7s ease-out 0s both;
-webkit-animation: tbio 0.7s ease-out 0s both;
-ms-animation: tbio 0.7s ease-out 0s both;
-o-animation: tbio 0.7s ease-out 0s both;
}
.click_through2 {
animation: tbio 0.7s ease-out 1s both;
-moz-tbio tbio 0.7s ease-out 1s both;
-webkit-tbio tbio 0.7s ease-out 1s both;
-ms-tbio tbio 0.7s ease-out 1s both;
-o-tbio tbio 0.7s ease-out 1s both;
width: 80px;
}
.logo {
top: 8px;
left: 8px;
}
.title1 {
animation: ltrio 0.6s ease 0s both;
-moz-animation: ltrio 0.6s ease 0s both;
-webkit-animation: ltrio 0.6s ease 0s both;
-ms-animation: ltrio 0.6s ease 0s both;
-o-animation: ltrio 0.6s ease 0s both;
}
.title2, .title3 {
opacity: 0;
}
.title2 {
animation: ltrio 0.6s ease 0.55s both;
-moz-animation: ltrio 0.6s ease 0.55s both;
-webkit-animation: ltrio 0.6s ease 0.55s both;
-ms-animation: ltrio 0.6s ease 0.55s both;
-o-animation: ltrio 0.6s ease 0.55s both;
}
.title3 {
animation: ltrio 0.6s ease 1s both;
-moz-nimation: ltrio 0.6s ease 1s both;
-webkit-nimation: ltrio 0.6s ease 1s both;
-ms-onimation: ltrio 0.6s ease 1s both;
-o-nimation: ltrio 0.6s ease 1s both;
}
.sfv2 {
right: 12px;
top: 34px;
animation: fio 0.6s ease 1.1s both;
-moz-animation: fio 0.6s ease 1.1s both;
-webkit-animation: fio 0.6s ease 1.1s both;
-ms-animation: fio 0.6s ease 1.1s both;
-o-animation: fio 0.6s ease 1.1s both;
}
#keyframes ltrio {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-moz-keyframes ltrio {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#-ms-keyframes ltrio {
0% {
-ms-transform: translateY(-350px);
opacity: 0;
}
25% {
-ms-transform: translateY(0);
opacity: 1;
}
75% {
-ms-transform: translateY(0);
opacity: 1;
}
100% {
-ms-transform: translateY(350px);
opacity: 0;
}
}
#-o-keyframes ltrio {
0% {
-o-transform: translateX(-350px);
opacity: 0;
}
25% {
-o-transform: translateX(0);
opacity: 1;
}
75% {
-o-transform: translateX(0);
opacity: 1;
}
100% {
-o-transform: translateX(350px);
opacity: 0;
}
}
#keyframes tbio {
0% {
transform: translateY(350px);
opacity: 0;
}
25% {
transform: translateY(0);
opacity: 1;
}
75% {
transform: translateY(0);
opacity: 1;
}
100% {
transform: translateY(350px);
opacity: 0;
}
}
#-moz-keyframes tbio {
0% {
-moz-transform: translateY(350px);
opacity: 0;
}
25% {
-moz-transform: translateY(0);
opacity: 1;
}
75% {
-moz-transform: translateY(0);
opacity: 1;
}
100% {
-moz-transform: translateY(350px);
opacity: 0;
}
}
#-webkit-keyframes tbio {
0% {
-webkit-transform: translateY(350px);
opacity: 0;
}
25% {
-webkit-transform: translateY(0);
opacity: 1;
}
75% {
-webkit-transform: translateY(0);
opacity: 1;
}
100% {
-webkit-transform: translateY(350px);
opacity: 0;
}
}
#-ms-keyframes tbio {
0% {
-ms-transform: translateY(350px);
opacity: 0;
}
25% {
-ms-transform: translateY(0);
opacity: 1;
}
75% {
-ms-transform: translateY(0);
opacity: 1;
}
100% {
-ms-transform: translateY(350px);
opacity: 0;
}
}
#-o-keyframes tbio {
0% {
-o-transform: translateY(350px);
opacity: 0;
}
25% {
-o-transform: translateY(0);
opacity: 1;
}
75% {
-o-transform: translateY(0);
opacity: 1;
}
100% {
-o-transform: translateY(350px);
opacity: 0;
}
}
#keyframes fio {
0% {
opacity: 0;
}
20% {
opacity: 1;
}
50% {
opacity: 1;
}
80% {
opacity: 0;
}
100% {
opacity: 0;
}
}
<div class="ad_container">
<img class="sfv1" src="http://i.imgur.com/3VWKopF.jpg">
<div class="title title1">
<h2>Great value<br/> <strong>Spanish Properties</strong><br/> starting at £65k</h2>
</div>
<div class="title title2">
<h2>Stunning properties in <br/><strong>Costa del Sol, <br/>Blanca & Murcia</strong></h2>
</div>
<div class="title title3">
<h2>Over <strong>10,000 <br/>Spanish properties sold</strong></h2>
</div>
<a class="click_through click_through1" href="/">View here</a>
<a class="click_through click_through2" href="/">Learn more</a>
</div>
Use a setTimeout and try setting the animation property to something else and then set it to the classname again so that it restarts the animation.
Something like:
setTimeout(function(){
document.querySelector('.someclass').classList.remove("run-animation").classList.add("run-animation");
}, 1000)
Remove the class to which the animation is assigned to and add it again (maybe with timeout) and the animation starts again.
I want a CSS3 transition to start after click.
Now it works fine if the element gets added a class with jQuery (see span.toggle-nav.two) which knows then what to do.
I've tried with :focus (see span.toggle-nav.one) but that doesn't work. How can I make it work without jQuery?
Please have a look here: http://jsfiddle.net/aE4C7/ clicking on Two works but clicking on One does not.
<span class="toggle-nav one">One</span>
<span class="toggle-nav two">Two</span>
<script type="text/javascript">
$('.toggle-nav.two').on('click',function(){
$(this).addClass("click");
});
</script>
<style type="text/css">
.toggle-nav {
background-image:url(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS8hRiDDs6RJRzelpuFRX2wG5Wx2cQPOBWKYCOmlA2Wr34dx1vv);
background-repeat:no-repeat;
width:50px;height:50px;
display:inline-block;
}
.toggle-nav.one:focus {
-webkit-animation: spin 0.6s infinite linear;
-moz-animation: spin 0.6s infinite linear;
-o-animation: spin 0.6s infinite linear;
-ms-animation: spin 0.6s infinite linear;
}
.toggle-nav.two.click {
-webkit-animation: spin 0.6s infinite linear;
-moz-animation: spin 0.6s infinite linear;
-o-animation: spin 0.6s infinite linear;
-ms-animation: spin 0.6s infinite linear;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg);}
100% { -webkit-transform: rotate(180deg);}
}
#-moz-keyframes spin {
0% { -moz-transform: rotate(0deg);}
100% { -moz-transform: rotate(180deg);}
}
#-o-keyframes spin {
0% { -o-transform: rotate(0deg);}
100% { -o-transform: rotate(180deg);}
}
#-ms-keyframes spin {
0% { -ms-transform: rotate(0deg);}
100% { -ms-transform: rotate(180deg);}
}
</style>
Is there a way to make this work without jQuery?
To let span getting focus, you need to set tabindex attribute:
<span class="toggle-nav one" tabindex="-1">One</span>
Then you could wish for styling to set CSS outline property too:
outline: none;
DEMO
You can actually do this using purely CSS - The only way to correctly simulate click events in CSS is to fake it with a checkbox, otherwise using :active or :focus will stop any applied transition or animation as soon as the element loses focus, not when it is clicked on again.
Demo Fiddle
HTML
<div>
<input id='box' type='checkbox' />
<label for='box'>Click Me!</label>
</div>
CSS
div {
position:relative;
}
label {
position:absolute;
left:0;
background:white;
}
input[type=checkbox] {
opacity:0;
}
input[type=checkbox]:checked + label {
-webkit-animation: spin 0.6s infinite linear;
-moz-animation: spin 0.6s infinite linear;
-o-animation: spin 0.6s infinite linear;
-ms-animation: spin 0.6s infinite linear;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(180deg);
}
}
#-moz-keyframes spin {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(180deg);
}
}
#-o-keyframes spin {
0% {
-o-transform: rotate(0deg);
}
100% {
-o-transform: rotate(180deg);
}
}
#-ms-keyframes spin {
0% {
-ms-transform: rotate(0deg);
}
100% {
-ms-transform: rotate(180deg);
}
}
How might I do this? I'm trying to use css3 only for performance reasons (fade in can get kind of choppy).
Right now they all happen at the same time.
function fadeInPlaylist(elem) {
elem.css('opacity',1);
}
$(window).load(function() {
$('.playlist').each(function(i) {
setTimeout(fadeInPlaylist($(this)),2500*i);
});
});
You are calling setTimeout incorrectly.
setTimeout(fadeInPlaylist($(this)),2500*i);
should be:
setTimeout(function(){fadeInPlaylist($(this));},2500*i);
Also, here's a working fiddle: http://jsfiddle.net/q7Wa8/
If you really need to do it with CSS3 only, use this code:
#keyframes reset {
0% { opacity: 0; }
100% { opacity: 0; }
}
#keyframes fade-in {
0% { opacity: 0; }
60% { opacity: 0; }
100% { opacity: 1; }
}
.playlist {
animation-name: reset, fade-in;
animation-duration: 2.5s;
animation-timing-function: ease-in;
animation-iteration-count: 1;
animation-delay: 0, 0;
}
But you'll have compatibility issues.
Here's the cross-browser code, doesn't work in IE:
#keyframes reset { 0% { opacity: 0; } 100% { opacity: 0; } }
#keyframes fade-in { 0% { opacity: 0; } 60% { opacity: 0; } 100% { opacity: 1; } }
#-webkit-keyframes reset { 0% { opacity: 0; } 100% { opacity: 0; } }
#-webkit-keyframes fade-in { 0% { opacity: 0; } 60% { opacity: 0; } 100% { opacity: 1; } }
#-moz-keyframes reset { 0% { opacity: 0; } 100% { opacity: 0; } }
#-moz-keyframes fade-in { 0% { opacity: 0; } 60% { opacity: 0; } 100% { opacity: 1; } }
#-o-keyframes reset { 0% { opacity: 0; } 100% { opacity: 0; } }
#-o-keyframes fade-in { 0% { opacity: 0; } 60% { opacity: 0; } 100% { opacity: 1; } }
.playlist {
animation-name: reset, fade-in;
animation-duration: 2.5s;
animation-timing-function: ease-in;
animation-iteration-count: 1;
animation-delay: 0, 0;
-webkit-animation-name: reset, fade-in;
-webkit-animation-duration: 2.5s;
-webkit-animation-timing-function: ease-in;
-webkit-animation-iteration-count: 1;
-webkit-animation-delay: 0, 0;
-moz-animation-name: reset, fade-in;
-moz-animation-duration: 2.5s;
-moz-animation-timing-function: ease-in;
-moz-animation-iteration-count: 1;
-moz-animation-delay: 0, 0;
-o-animation-name: reset, fade-in;
-o-animation-duration: 2.5s;
-o-animation-timing-function: ease-in;
-o-animation-iteration-count: 1;
-o-animation-delay: 0, 0;
}
You could use fadeTo with delay but if you want to do it your way try this:
function fadeInPlaylist() {
$(this).css('opacity',1);
}
$(window).load(function() {
$('.playlist').each(function(i, e) {
setTimeout(function(){ fadeInPlaylist.call(e); }, 1000 * i);
});
});
Demo: http://jsbin.com/oyazof/1/edit
Edit:
If you want to do it with CSS3 transitions you can just add a class instead of changing the css from jQuery.
jQuery:
function fadeInPlaylist() {
$(this).addClass('opacity');
}
CSS:
.opacity {
-webkit-transition: opacity .5s ease-in-out;
-moz-transition: opacity .5s ease-in-out;
-ms-transition: opacity .5s ease-in-out;
-o-transition: opacity .5s ease-in-out;
transition: opacity .5s ease-in-out;
opacity: 1;
}
Demo with CSS3 transitions: http://jsbin.com/oyazof/3/edit
Just change:
elem.css('opacity',1);
To:
elem.fadeTo('fast', 1);