I have a simple CSS marquee scrolling up across a screen, essentially using the code found here (JSFiddle):
https://jsfiddle.net/c8r5kc1L/1/
<style style="text/css">
.marquee-outer {
height: 100px;
overflow: hidden;
position: relative;
color: orange;
}
.marquee-inner {
position: absolute;
width: 100%;
height: 100%;
margin: 0;
line-height: 50px;
text-align: center;
/* Starting position */
-moz-transform:translateY(100%);
-webkit-transform:translateY(100%);
transform:translateY(100%);
/* Apply animation to this element */
-moz-animation: scroll-up 5s linear infinite;
-webkit-animation: scroll-up 5s linear infinite;
animation: scroll-up 5s linear infinite;
}
/* Move it (define the animation) */
#-moz-keyframes scroll-up {
0% { -moz-transform: translateY(100%); }
100% { -moz-transform: translateY(-100%); }
}
#-webkit-keyframes scroll-up {
0% { -webkit-transform: translateY(100%); }
100% { -webkit-transform: translateY(-100%); }
}
#keyframes scroll-up {
0% {
-moz-transform: translateY(100%); /* Browser bug fix */
-webkit-transform: translateY(100%); /* Browser bug fix */
transform: translateY(100%);
}
100% {
-moz-transform: translateY(-100%); /* Browser bug fix */
-webkit-transform: translateY(-100%); /* Browser bug fix */
transform: translateY(-100%);
}
}
</style>
<div class="marquee-outer">
<div class="marquee-inner">Text</div>
</div>
I am trying to enter several paragraphs worth of content into the actual scroll area, which means that the animation resets before I've gotten through all the content. If I increase the animation duration (say, to 100s), the animation slows down, and ends up going through the same (partial) amount to the information.
Is there a way to keep the speed of the scroll constant, but actually just increase the duration of the scroll prior to reset?
I found a solution, if you "sync" the -100% with the amount of paragraphs that you want (And uses <p> inside <div class="marquee-inner"> because it gives you more control in the scrolling animation):
100% {
transform: translateY(-100%);
}
So is you want to have 4 paragraphs do something like this:
100% {
transform: translateY(-400%);
}
And also don't use line-height: 50px; in .marquee-inner instead use margin-bottom:
.marquee-inner p{
margin-bottom: 30px;
}
Look the example: https://jsfiddle.net/u2j2679u/
I've been trying to understand the CSS animation property, I've got this sprite gridsheet I need to run through, I've seen examples of Animations both in row and grid style, but when I try to apply and adapt to my sprite sheet I'm having issues with the display.
Here is my current CSS & Html:
.logo {
width: 120px;
height: 100px;
margin: 2% auto;
background: url('http://res.cloudinary.com/df0nhzq7v/image/upload/v1484325835/bvd2_1024_fxwhvl.png') left top;
-webkit-animation: playv .6s steps(6) infinite, playh 1s steps(6) infinite;
}
#-webkit-keyframes playv {
0% { background-position-y: 0px; }
100% { background-position-y: 100%; }
}
#-webkit-keyframes playh {
0% { background-position-x: 0px; }
100% { background-position-x: 100%; }
}
<div class="logo"></div>
Codepen: http://codepen.io/BenSagiStuff/pen/ZLOJKM
There's a couple issues at play here. The first is that your animation property has the incorrect values. You need to change it from:
animation:
playv .6s steps(6) infinite,
playh 1s steps(6) infinite;
to:
animation:
playv 5s steps(5) infinite,
playh 1s steps(7) infinite;
It's important that the steps function takes in the correct parameters, such that playv is contains the number of sprites there are in the y direction and playh contains the number of sprites there are in the x direction. The timing for playv also needs to be slow enough to animate the grid properly and is actually equivalent to being your duration multiplied by the amount of rows in the sprite grid. This can be simplified into the following formula:
animation:
playv (duration * rows) steps(rows) infinite,
playh duration steps(cols) infinite;
Secondly, the image you have provided as the sprite grid is too large. It contains blank space/padding to the right and bottom of the image. As a result of this, the following lines are calculated incorrectly:
#-webkit-keyframes playv {
0% { background-position-y: 0px; }
100% { background-position-y: 100%; }
}
#-webkit-keyframes playh {
0% { background-position-x: 0px; }
100% { background-position-x: 100%; }
}
You either need to update the sprite grid so that it matches perfectly, or specify the pixels exactly like so:
#-webkit-keyframes playv {
0% { background-position-y: 0; }
100% { background-position-y: -550px; }
}
#-webkit-keyframes playh {
0% { background-position-x: 0; }
100% { background-position-x: -903px; }
}
Here's the working codepen.
If I have two lines of text one on top of the other. Content of each line is dynamic.
Is there a way to set animation speed in pixels per second? So that line would scroll with same speed regardless of their length?
Example of the situation:
div {
width: 50%;
padding-left: 10%;
float: left;
height: 50px;
overflow: hidden;
position: relative;
}
#line1 {
background-color: green;
}
#line2 {
background-color: yellow;
}
h4 {
position: absolute;
height: 100%;
margin: 0;
line-height: 50px;
text-align: left;
/* Apply animation to this element */
/* Animation delay 0.5s */
-moz-animation: line-scroll 15s linear 0.5s infinite;
-webkit-animation: line-scroll 15s linear 0.5s infinite;
animation: line-scroll 15s linear 0.5s infinite;
}
#line1 h4 {
/* width must be big enought to fit in whole text othrwise
whole text will not scroll into view */
width: 200%;
}
#line2 h4 {
/* width must be big enought to fit in whole text othrwise
whole text will not scroll into view */
width: 600%;
}
#keyframes line-scroll {
0% {
-moz-transform: translateX(0%);
/* Firefox bug fix */
-webkit-transform: translateX(0%);
/* Firefox bug fix */
transform: translateX(0%);
}
100% {
-moz-transform: translateX(-100%);
/* Firefox bug fix */
-webkit-transform: translateX(-100%);
/* Firefox bug fix */
transform: translateX(-100%);
}
}
<div id="line1">
<h4>I don't want to come off as arrogant here, but I'm the greatest botanist on this planet.</h4>
</div>
<div id="line2">
<h4>Every human being has a basic instinct: to help each other out. If a hiker gets lost in the mountains, people will coordinate a search. If a train crashes, people will line up to give blood. If an earthquake levels a city, people all over the world will send emergency supplies. This is so fundamentally human that it's found in every culture without exception. Yes, there are assholes who just don't care, but they're massively outnumbered by the people who do. ~ Mark Watney, The Martian</h4>
</div>
Means of AngularJS directive and CSS are welcome.
You can use JQuery (javascript) to get the width of headings and than calculate the duration based on the width i.e duration per pixel
width() method of jquery is used to get width of the headings.
I calculate the the duration as follows:
1s = 20px
Therefore 100px = 100/20
= 5s
You can increase the denominator (see the number10) in var dur1=Math.ceil(w1/10) to speed up the scrolling.
Here is the code
//getting the width of both the headings
var w1=$("#line1>h4").width();
var w2=$("#line2>h4").width();
//calculating the duration of the animation dynamically based on the width
var dur1=Math.ceil(w1/10);
var dur2=Math.ceil(w2/10);
//setting the duration dynamically
$("#line1>h4").css("animation-duration",dur1+"s");
$("#line2>h4").css("animation-duration",dur2+"s");
div {
width: 50%;
padding-left: 10%;
float: left;
height: 50px;
overflow: hidden;
position: relative;
}
#line1 {
background-color: green;
}
#line2 {
background-color: yellow;
}
h4 {
position: absolute;
height: 100%;
margin: 0;
line-height: 50px;
text-align: left;
/* Apply animation to this element */
/* Animation delay 0.5s */
-moz-animation: line-scroll 15s linear 0.5s infinite;
-webkit-animation: line-scroll 15s linear 0.5s infinite;
animation: line-scroll 15s linear 0.5s infinite;
}
#line1 h4 {
/* width must be big enought to fit in whole text othrwise
whole text will not scroll into view */
width: 200%;
}
#line2 h4 {
/* width must be big enought to fit in whole text othrwise
whole text will not scroll into view */
width: 600%;
}
#keyframes line-scroll {
0% {
-moz-transform: translateX(0%);
/* Firefox bug fix */
-webkit-transform: translateX(0%);
/* Firefox bug fix */
transform: translateX(0%);
}
100% {
-moz-transform: translateX(-100%);
/* Firefox bug fix */
-webkit-transform: translateX(-100%);
/* Firefox bug fix */
transform: translateX(-100%);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="line1">
<h4>I don't want to come off as arrogant here, but I'm the greatest botanist on this planet.</h4>
</div>
<div id="line2">
<h4>Every human being has a basic instinct: to help each other out. If a hiker gets lost in the mountains, people will coordinate a search. If a train crashes, people will line up to give blood. If an earthquake levels a city, people all over the world will send emergency supplies. This is so fundamentally human that it's found in every culture without exception. Yes, there are assholes who just don't care, but they're massively outnumbered by the people who do. ~ Mark Watney, The Martian</h4>
</div>
In CSS you must provide the animation duration in time units, which is currently seconds / miliseconds.
You could, however, adapt the width of the transition by switching from a %-value to px-values like shown below:
div {
width: 50%;
padding-left: 10%;
float: left;
height: 50px;
overflow: hidden;
position: relative;
}
#line1 {
background-color: green;
}
#line2 {
background-color: yellow;
}
h4 {
position: absolute;
height: 100%;
margin: 0;
line-height: 50px;
text-align: left;
/* Apply animation to this element */
/* Animation delay 0.5s */
-moz-animation: line-scroll 15s linear 0.5s infinite;
-webkit-animation: line-scroll 15s linear 0.5s infinite;
animation: line-scroll 15s linear 0.5s infinite;
}
#line1 h4 {
/* width must be big enought to fit in whole text othrwise
whole text will not scroll into view */
width: 200%;
}
#line2 h4 {
/* width must be big enought to fit in whole text othrwise
whole text will not scroll into view */
width: 600%;
}
#keyframes line-scroll {
0% {
-moz-transform: translateX(0%);
/* Firefox bug fix */
-webkit-transform: translateX(0%);
/* Firefox bug fix */
transform: translateX(0%);
}
100% {
-moz-transform: translateX(-1000px);
/* Firefox bug fix */
-webkit-transform: translateX(-1000px);
/* Firefox bug fix */
transform: translateX(-1000px);
}
}
<div id="line1">
<h4>I don't want to come off as arrogant here, but I'm the greatest botanist on this planet.</h4>
</div>
<div id="line2">
<h4>Every human being has a basic instinct: to help each other out. If a hiker gets lost in the mountains, people will coordinate a search. If a train crashes, people will line up to give blood. If an earthquake levels a city, people all over the world will send emergency supplies. This is so fundamentally human that it's found in every culture without exception. Yes, there are assholes who just don't care, but they're massively outnumbered by the people who do. ~ Mark Watney, The Martian</h4>
</div>
I'm coding a CSS3 effect fired on mouseover; this effect simply animate an inner div scaling it endlessly.
All works great, but when I move the mouse away the div suddenly return to its original size. I would like to add a smooth effect to scale the div back.
I already checked the suggestion of this post:
Make CSS Hover state remain after "unhovering"
Unfortunately the code posted doesn't work :(
In my opinion my issue could be related with the "infinite" loop of the scale effect.
THe goal I would like to gain is the on mouse-out the image could return to its original size smoothly.
Here's the code: https://jsfiddle.net/9dtqpsLa/1/
CSS
#keyframes imageZoom{
0% { transform: scale(1); }
50% { transform: scale(1.24); }
100% { transform: scale(1);}
}
#-moz-keyframes imageZoom{
0% { -moz-transform: scale(1);}
50% { -moz-transform: scale(1.24); }
100% { -moz-transform: scale(1); }
}
#-webkit-keyframes imageZoom{
0% { -webkit-transform: scale(1); }
50% {-webkit-transform: scale(1.24); }
100% { -webkit-transform: scale(1); }
}
#-ms-keyframes imageZoom{
0% { -ms-transform: scale(1); }
50% { -ms-transform: scale(1.24); }
100% { -ms-transform: scale(1); }
}
.article:hover .imageWrapper {
animation: imageZoom linear 10s;
animation-iteration-count: infinite;
-webkit-animation: imageZoom linear 10s;
-webkit-animation-iteration-count: infinite;
-moz-animation: imageZoom linear 10s;
-moz-animation-iteration-count: infinite;
-ms-animation: imageZoom linear 10s;
-ms-animation-iteration-count: infinite;
transform-origin: 50% 80%;
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
}
HTML
<div class="article">
<div class="imageWrapper">
</div>
</div>
Please, could you help me?
Thanks so much
GOALS:
1. Have the image animate expansion and contraction on hover
2. Have the image animate to original state on mouseleave
PROBLEMS:
With CSS, I don't know how to use both an animation and a transition. The animation is the pulsing on hover. The transition is the return to default animation. The only way I could envision doing it is with JS. See each section for notes
https://jsfiddle.net/Bushwazi/9dtqpsLa/5/
HTML:
notes: same as example provided
<div class="article">
<div class="imageWrapper"></div>
</div>
CSS:
notes:
1. animation removed.
2. The scale is only fired with the existence of [data-dir='expand'].
3. transform-origin and transition moved into the default state of .imageWrapper
4. need to add prefixes
.article[data-dir='expand'] .imageWrapper {
transform:scale(1.24)
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
transform-origin: 50% 80%;
transition:all 10.0s linear 0.0s;
}
JAVASCRIPT:
notes:
1. all new
/*
1. on hover aka 'mouseenter' start the animation
2. 10 seconds in, change direction of the animation based on the `isHovering` variable
3. on exit aka 'mouseleave', return to default
*/
var thisArticle = document.querySelector('.article'),
thisTimer = '',
isHovering = false;
thisArticle.addEventListener('mouseenter', function(){
console.log('mouseenter');
thisArticle.setAttribute('data-dir', 'expand');
thisTimer = setInterval(fireAnimation, 10000);
isHovering = true
}, false);
thisArticle.addEventListener('mouseleave', function(){
console.log('mouseleave');
thisArticle.removeAttribute('data-dir');
isHovering = false;
clearInterval(thisTimer);
}, false);
var fireAnimation = function(){
if(isHovering){
if(thisArticle.getAttribute('data-dir') === 'expand'){
thisArticle.removeAttribute('data-dir');
} else {
thisArticle.setAttribute('data-dir', 'expand');
}
} else {
clearInterval(thisTimer);
}
alert('change direction');
}
MORE IDEAS
1. I used a data attribute, but I would prefer to use classList. Wasn't sure how to incorporate that into the fiddle in 30 seconds, so skipped it.
2. The return to default animation has no awareness of the scale when you leave, so it takes 10 seconds no matter what. I'm sure there is a way to make this better.
Once you the mouse is moved away from the element, the styles in the :hover pseudo class gets removed from your element, effectively putting it back where it started.
What you want to do is start and pause the animation:
Here is your fiddle, I edited it a bit and exploded the short-hand and removed -webkit, -ms, etc:
https://jsfiddle.net/9dtqpsLa/4/
#keyframes imageZoom {
100% {
transform: scale(4);
}
}
.article:hover .imageWrapper {
animation-play-state: running;
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
transform-origin: 50% 80%;
animation-name: imageZoom;
animation-duration: 2s;
animation-delay: 0s;
animation-iteration-count: 1;
animation-direction: both;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
animation-play-state: paused;
}
Notice that all the animation logic has moved to the base class, and the :hover only kicks off the animation.
I try to make an animation that run every 3 seconds without JavaScript. My animation's duration is 1 second.
I'm only able to wait 3seconds the first occurence then it's a loop of 1s animation.
My code so far: https://jsfiddle.net/belut/aojp8ozn/32/
.face.back {
-webkit-animation: BackRotate 1s linear infinite;
-webkit-animation-delay: 3s;
animation: BackRotate 1s linear infinite;
animation-delay: 3s;
}
.face.front {
-webkit-animation: Rotate 1s linear infinite;
-webkit-animation-delay: 3s;
animation: Rotate 1s linear infinite;
animation-delay: 3s;
}
#-webkit-keyframes Rotate {
from {-webkit-transform:rotateY(0deg);}
to {-webkit-transform:rotateY(360deg);}
}
#-webkit-keyframes BackRotate {
from {-webkit-transform:rotateY(180deg);}
to {-webkit-transform:rotateY(540deg);}
}
#keyframes Rotate {
from {-webkit-transform:rotateY(0deg);}
to {-webkit-transform:rotateY(360deg);}
}
#keyframes BackRotate {
from {-webkit-transform:rotateY(0deg);}
to {-webkit-transform:rotateY(360deg);}
}
I know how to do it with javascript: https://jsfiddle.net/belut/fk3f47jL/1/
I tried this answer without success: Cycling CSS3 animation with a pause period?
Can you help me please?
EDIT
Thanks great answers i'm also able to make this scenario:
wait 2s, run 1s flip, wait 2s, run 1s back_flip, wait 2s.
#f1_container {
position: relative;
margin: 10px auto;
width: 90px;
height: 90px;
z-index: 1;
}
#f1_container {
perspective: 1000;
}
#f1_card {
width: 100%;
height: 100%;
}
img {
width: 90px;
height: 90px;
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.face.back {
display: block;
transform: rotateY(180deg);
}
.face.back {
-webkit-animation: BackRotate 5s linear infinite;
}
.face.front {
-webkit-animation: Rotate 5s linear infinite;
}
#-webkit-keyframes Rotate {
0%,40% {-webkit-transform:rotateY(0deg);}
50%,90% {-webkit-transform:rotateY(180deg);}
100% {-webkit-transform:rotateY(360deg);}
}
#-webkit-keyframes BackRotate {
0%,40% {-webkit-transform:rotateY(180deg);}
50%,90% {-webkit-transform:rotateY(360deg);}
100% {-webkit-transform:rotateY(540deg);}
}
It seems like the only way to achieve this is to extend the animation so that it lasts 4s instead of 1s. Then you could delay the animation by animating from 75% to 100% (rather than 0% to 100%).
In doing so, there is essentially an artificial delay in the animation itself. You just have to do the math to figure out how long this delay is in correlation with the total length of the animation itself.
Updated Example
.face.back {
display: block;
transform: rotateY(180deg);
}
.face.back {
-webkit-animation: BackRotate 4s linear infinite;
animation: BackRotate 4s linear infinite;
}
.face.front {
-webkit-animation: Rotate 4s linear infinite;
animation: Rotate 4s linear infinite;
}
#-webkit-keyframes Rotate {
75% {-webkit-transform:rotateY(0deg);}
100% {-webkit-transform:rotateY(360deg);}
}
#-webkit-keyframes BackRotate {
75% {-webkit-transform:rotateY(180deg);}
100% {-webkit-transform:rotateY(540deg);}
}
#keyframes Rotate {
75% {-webkit-transform:rotateY(0deg);}
100% {-webkit-transform:rotateY(360deg);}
}
#keyframes BackRotate {
75% {-webkit-transform:rotateY(180deg);}
100% {-webkit-transform:rotateY(540deg);}
}
I am not sure exactly when it was released, and it's not the most cross-browser approach (does not cover older browsers like I.E. 9) but you could use the animationPlayState style prop. Theres some documentation on this found here if you want to check it out.
animationPlayState=false
webkitAnimationPlayState=false
function pause() {
var animationElement = document.getElementById('animatedItem');
animationElement.style.animationPlayState='paused';
animationElement.style.webkitAnimationPlayState='paused';
}
As you can see this put's the items animation into a "paused"state, to put it back where it left the animation off at, you can set it to the "running" state that this prop accepts.
Here is a quick example I found when browsing Google.
I was able to do this, as #Josh mentioned, by extending the animation. For example, if you want your animation to last 0.5 seconds with a 3 second pause, you make the entire animation 3.5 seconds, and then use percentages to extend it. (0.5 seconds is about 14% of 3.5 seconds.)
In the code below, I created a DIV with transparent gradient that is the same width as the parent, and then animated it from left to right to give a shimmer effect.
.shimmer {
height: 100%;
width: 100%;
position: absolute;
top: 0px;
background-image: -moz-linear-gradient(160deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 25%, rgba(255,255,255,0.85) 60%, rgba(255,255,255,0) 100%); /* FF3.6+ */
background-image: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,0)), color-stop(25%,rgba(255,255,255,0)), color-stop(60%,rgba(255,255,255,0.85)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
background-image: -webkit-linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
background-image: -o-linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* Opera11.10+ */
background-image: -ms-linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* IE10+ */
background-image: linear-gradient(160deg, rgba(255,255,255,0) 0%,rgba(255,255,255,0) 25%,rgba(255,255,255,0.85) 60%,rgba(255,255,255,0) 100%); /* W3C */
background-repeat: repeat-y;
background-size: 30% 100%;
left: -100%;
z-index: 101;
animation-name: shine;
animation-duration: 3.5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
}
#keyframes shine {
0% { left: -100%; }
14% { left: 100%; }
100% { left: 100%; }
}
From 14% to 100%, the DIV doesn't move, but the animation continues for additional time, giving the effect of a pause.
You can add an ending state in the animation which will play like a delay. Check the example below, simple animation that runs for 4 sec but the last 3 sec is delayed.
body {
perspective: 500px;
}
/* clear background */
h2 {
text-align: center;
padding: 16px;
margin: 0;
}
/* crops animations that exceeds one line area */
.line {
width: 100%;
height: 4rem;
overflow: hidden;
padding: 0;
margin-bottom: 16px;
}
/* flipping class and key frames*/
.flipX {
animation: 4s anim-flipX ease infinite;
}
#keyframes anim-flipX {
0% {
opacity: 0;
transform: rotateX(9def);
}
20% {
/* animate nothing to pause animation at the end */
opacity: 1;
transform: rotateX(360deg);
}
60% {
/* animate nothing to pause animation at the end */
opacity: 1;
transform: rotateX(360deg);
}
100% {
/* animate nothing to pause animation at the end */
opacity: 1;
transform: rotateX(360deg);
}
}
<body>
<div class='line'>
<h2 class='flipX'>flip vertical</h2>
</div>
</body>