keyframe not working on Chrome - html

I have this very simple code to simulate a marquee.it's working on all browser except Chrome.
I have tried the -webkit- but still no luck, and what drives me crazy is when I try it here http://jsfiddle.net/XxUXD/2566/ it works like a charm on Chrome.
So could you please tell me what did I do wrong?
HTML
<div class="marquee"> the brown fox jumped over the lazy dog </div>
CSS
/* Make it a marquee */
.marquee {
width:100%;
margin: 0 auto;
overflow: hidden;
white-space: nowrap;
box-sizing: border-box;
animation: marquee 50s linear infinite;
}
.marquee:hover {
animation-play-state: paused
}
/* Make it move */
#keyframes marquee {
0% { text-indent: 27.5em }
100% { text-indent: -105em }
}

It's necessary to use -webkit- in this instance.
That means for-webkit-animation, #-webkit-keyframes, and webkit-animation-play-state.
See the following JSFiddle:
http://jsfiddle.net/nd3oebsb/

Related

How do I turn every element on a page into a scrolling marquee?

Is there something I can do to a web application that would turn every div into a scrolling marquee? Maybe a CSS class or something? It's Angular 4 and bootstrap.
The following demo is a Pure CSS Solution using CSS animation.
Demo
.marquee {
width: 60%;
/* Required on Parent */
overflow: hidden;
font: 400 32px/1.5 Consolas;
background: rgba(0, 0, 0, 0.7);
padding-left: 15px;
margin: 20px auto;
}
.marquee b {
/* Required on Child*/
white-space: nowrap;
display: table-cell;
color: cyan;
vertical-align: baseline;
/* Infinite Loops */
animation: rightToLeft 12s linear infinite;
/* Right to left direction */
animation-fill-mode: backwards;
/* Set to 0s in order to have a point of reference */
animation-delay: 0s;
}
.marquee b a {
color: gold
}
/* Required for complex CSS animation */
#keyframes rightToLeft {
0% {
transform: translateX(20%);
}
100% {
transform: translateX(-100%);
}
}
<div class='marquee'>
<b>You should read <i>“how to ask”</i>: https://stackoverflow.com/help/how-to-ask</b>
</div>
<div class='marquee'>
<b>You can change the CSS ".marquee" class selector to "div" and then sit back and watch the chaos unfold.</b>
</div>
<div class='marquee'>
<b>Making every div a scrolling marquee seems excessive and pointless.</b>
</div>
Have you tried the marquee html element? Do note this is deprecated.
<marquee>This text will scroll from right to left</marquee>
<marquee direction="up">This text will scroll from bottom to top</marquee>
<marquee direction="down" width="250" height="200" behavior="alternate" style="border:solid">
<marquee behavior="alternate">
This text will bounce
</marquee>
</marquee>
MDN reference

CSS animation of scale & color together causes font pixelation

I fire css animation of font-icon by adding it a class. The animation scaling icon from 1 to 30, and change color from #000 to #ff0000.
While it works fine in mozilla, it will make icon scales like if it was low quality png image in chrome, opera and safari. Can't check ie.
It can be fixed in chrome and opera by isolating color animation in ::before pseudoelement.
But in safari even just scale animation alone treats font-icon like png image.
As animation is finished, icon recover its font nature, and pixelation disappears.
Examples:
works only in mozilla http://codepen.io/g1un/pen/Kgrpjq
works in mozilla, chrome, opera http://codepen.io/g1un/pen/BLzoWp
Code, that works properly only in mozilla:
<div>
<h1></h1>
</div>
div {
display: flex;
justify-content: center;
height: 100vh;
align-items: center;
}
h1 {
position: relative;
font-size: 34px;
cursor: pointer;
}
h1::before {
content: 'A';
}
h1.anima {
animation: anima;
-webkit-animation: anima;
animation-duration: 3s;
-webkit-animation-duration: 3s;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes anima {
0% {
transform: scale(1);
color: #000;
}
100% {
transform: scale(30);
color: #ff0000;
}
}
#keyframes anima {
0% {
transform: scale(1);
color: #000;
}
100% {
transform: scale(30);
color: #ff0000;
}
}
$('h1').on('click', function(){
$(this).addClass('anima');
var _this = $(this);
setTimeout(function(){
_this.removeClass('anima');
}, 5000);
});
CSS changes, that helps chrome and opera:
h1.anima::before {
animation: anima-before;
-webkit-animation: anima-before;
animation-duration: 3s;
-webkit-animation-duration: 3s;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes anima {
0% {
transform: scale(1);
}
100% {
transform: scale(30);
}
}
#keyframes anima {
0% {
transform: scale(1);
}
100% {
transform: scale(30);
}
}
#keyframes anima-before {
0% {
color: #000;
}
100% {
color: #ff0000;
}
}
#-webkit-keyframes anima-before {
0% {
color: #000;
}
100% {
color: #ff0000;
}
}
Does anyone know better way to make chrome and opera animates properly without pseudoelement hack? And who knows what's wrong with safari, and how pixelated scaling can be fixing in it?
UPDATE:
As #ZBerg has mentioned in his comment: "font smoothing options have a wide array support varients. If something has affected your desktop profile it may have a knock on effect (google - smooth edges of screen fonts)".
Taking into account, that I haven't no more problems with chrome (but really had it as you can see via screenshot, linked in comment), something has really affected my desktop (but I can't google smth exactly about smoothing issue while scaling).
On the whole, I guess that the full answer to my question must include:
the decision for safari (or explanation what's wrong with it);
(optionally) explanation of what was wrong with chrome.
Under explanation I mean link to the issue report or regarding chrome the way to reproduce the error.
One solution that works for me is scale the parent, 'div' in this case and made the scale over him.
CSS
div.anima {
animation: anima;
-webkit-animation: anima;
animation-duration: 3s;
-webkit-animation-duration: 3s;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
JS:
$('div').on('click', function(){
as follows:
updated

Why doesn't the marquee stop on hover?

To stop the marquee for mouse-hover I did this:
CSS:
<style type="text/css">
.wm {
border: solid 2px;
border-color:#0aa2e3;
border-radius: 10px;
font-family:Georgia, "Times New Roman", Times, serif;
font-size:13px;
}
marquee:hover {
animation-play-state:paused;
}
</style>
HTML :
<p class="wm"> <marquee> ... </marquee> </p>
But nothing happens as I point my mouse over the moving paragraph. Why is that ?
That's because marquee isn't a CSS3 animation and that's about all you can pause via animation-play-state:paused;
But more importantly: You should no longer be using marquee at all
If you need something similar, like a moving link list that can be clicked and stops on hovering, you should be looking for alternatives, I could bet there are some jQuery news ticker plug-ins out there.
Edit: Since you're looking for a pauseable CSS3 Animation according to your comments, you'll require the following markup:
<p class="marquee"> <!-- the wrapping container -->
<span> ... </span> <!-- the tray moving around -->
</p>
The content in your span will be the one moving around your wrapping container with the marquee class.
/* define the animation */
#keyframes marquee {
0% { transform: translate(0, 0); }
100% { transform: translate(-100%, 0); }
}
/* define your limiting container */
.marquee {
width: 450px;
margin: 0 auto;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
}
/* this is the tray moving around your container */
.marquee span {
display: inline-block;
padding-left: 100%;
text-indent: 0;
animation: marquee 15s linear infinite; /* here you select the animation */
}
/* pause the animation on mouse over */
.marquee span:hover {
animation-play-state: paused
}
Also as an jsfiddle: http://jsfiddle.net/MaY5A/209/
Additional note:
Since CSS3 animations are still experimental in some browsers, you might have to add vendor prefixes. Which can be weird especially for the animation definition itself:
#-webkit-keyframes marquee {
...
}
#-moz-keyframes marquee {
...
}
But transform, translate, animation and animation-play-state might require vendor prefixes, depending on how far back you want to support browsers.

How can I create a marquee effect?

I'm creating a marquee effect with CSS3 animation.
#caption {
position: fixed;
bottom: 0;
left: 0;
font-size: 20px;
line-height: 30px;
height:30px;
width: 100%;
white-space: nowrap;
-moz-animation: caption 50s linear 0s infinite;
-webkit-animation: caption 50s linear 0s infinite;
}
#-moz-keyframes caption {
0% { margin-left:120%; } 100% { margin-left:-4200px; }
}
#-webkit-keyframes caption {
0% { margin-left:120%; } 100% { margin-left:-4200px; }
}
<div id="caption">
The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. the quick brown fox jumps over the lazy dog.
</div>
Now I can get the basic marquee effect, but the code is too specific for this demo.
Is there a way to avoid using specific values like margin-left:-4200px;, so that it can adapt text in any length?
Here is a similar demo: http://jsfiddle.net/jonathansampson/XxUXD/ that uses text-indent but still with specific values.
With a small change of the markup, here's my approach (I've just inserted a span inside the paragraph):
.marquee {
width: 450px;
margin: 0 auto;
overflow: hidden;
box-sizing: border-box;
}
.marquee span {
display: inline-block;
width: max-content;
padding-left: 100%;
/* show the marquee just outside the paragraph */
will-change: transform;
animation: marquee 15s linear infinite;
}
.marquee span:hover {
animation-play-state: paused
}
#keyframes marquee {
0% { transform: translate(0, 0); }
100% { transform: translate(-100%, 0); }
}
/* Respect user preferences about animations */
#media (prefers-reduced-motion: reduce) {
.marquee span {
animation-iteration-count: 1;
animation-duration: 0.01;
/* instead of animation: none, so an animationend event is
* still available, if previously attached.
*/
width: auto;
padding-left: 0;
}
}
<p class="marquee">
<span>
When I had journeyed half of our life's way, I found myself
within a shadowed forest, for I had lost the path that
does not stray. – (Dante Alighieri, <i>Divine Comedy</i>.
1265-1321)
</span>
</p>
No hardcoded values — dependent on paragraph width — have been inserted.
The animation applies the CSS3 transform property (use prefixes where needed) so it performs well.
If you need to insert a delay just once at the beginning then also set an animation-delay. If you need instead to insert a small delay at every loop then try to play with an higher padding-left (e.g. 150%)
Based on the previous reply, mainly #fcalderan, this marquee scrolls when hovered, with the advantage that the animation scrolls completely even if the text is shorter than the space within it scrolls, also any text length takes the same amount of time (this may be a pros or a cons) when not hovered the text return in the initial position.
No hardcoded value other than the scroll time, best suited for small scroll spaces
.marquee {
width: 100%;
margin: 0 auto;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
display: inline-flex;
}
.marquee span {
display: flex;
flex-basis: 100%;
animation: marquee-reset;
animation-play-state: paused;
}
.marquee:hover> span {
animation: marquee 2s linear infinite;
animation-play-state: running;
}
#keyframes marquee {
0% {
transform: translate(0%, 0);
}
50% {
transform: translate(-100%, 0);
}
50.001% {
transform: translate(100%, 0);
}
100% {
transform: translate(0%, 0);
}
}
#keyframes marquee-reset {
0% {
transform: translate(0%, 0);
}
}
<span class="marquee">
<span>This is the marquee text (hover the mouse here)</span>
</span>
The accepted answers animation does not work on Safari, I've updated it using translate instead of padding-left which makes for a smoother, bulletproof animation.
Also, the accepted answers demo fiddle has a lot of unnecessary styles.
So I created a simple version if you just want to cut and paste the useful code and not spend 5 mins clearing through the demo.
http://jsfiddle.net/e8ws12pt/
.marquee {
margin: 0 auto;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
padding: 0;
height: 16px;
display: block;
}
.marquee span {
display: inline-block;
text-indent: 0;
overflow: hidden;
-webkit-transition: 15s;
transition: 15s;
-webkit-animation: marquee 15s linear infinite;
animation: marquee 15s linear infinite;
}
#keyframes marquee {
0% { transform: translate(100%, 0); -webkit-transform: translateX(100%); }
100% { transform: translate(-100%, 0); -webkit-transform: translateX(-100%); }
}
<p class="marquee"><span>Simple CSS Marquee - Lorem ipsum dolor amet tattooed squid microdosing taiyaki cardigan polaroid single-origin coffee iPhone. Edison bulb blue bottle neutra shabby chic. Kitsch affogato you probably haven't heard of them, keytar forage plaid occupy pitchfork. Enamel pin crucifix tilde fingerstache, lomo unicorn chartreuse plaid XOXO yr VHS shabby chic meggings pinterest kickstarter.</span></p>
The following should do what you want.
#keyframes marquee {
from { text-indent: 100% }
to { text-indent: -100% }
}

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