Trembling css running text animation(margin + translate) in Safari - html

I made some running text animation animation in CSS same way, as it is in answer here. I tried to implement it like that to avoid any JS manipulation. And everything works fine in Chrome, but text is trembling in Safari.
.marquee {
position: relative;
overflow: hidden;
background: rgb(161, 61, 175);
color: #fff;
}
.marquee span {
display: inline-block;
min-width: 100%; /* this is to prevent shorter text animate to right */
white-space: nowrap;
font-size: 2.5em;
animation: marquee 4s ease-in-out infinite;
}
#keyframes marquee {
0% {
transform: translateX(0);
margin-left: 0;
}
10% {
transform: translateX(0);
margin-left: 0;
}
90% {
transform: translateX(-100%);
margin-left: 100%;
}
100% {
transform: translateX(-100%);
margin-left: 100%;
}
}
<h1 class="marquee">
<span>The only thing that matters now is everything You think of me</span>
</h1>
<p class="marquee">
<span>Beware of short texts!</span>
</p>
I was trying to fix that using only by using CSS, but I still cannot find the solution. Yeah, I can use JS and avoid giving animation to smaller elements. But maybe there is a way to fix this stuff for Safari with CSS only.

My colleague rewritten animation in that way, that it can be handled by Safari. It was obvious to us, that this trembling is caused by using translate + margin, that's why I mentioned it even in title. As you probably know, it is better to avoid margin animations. So, we added wrapper, which have opposite direction animation. Yeah, now we have 2 animations, but they are handled by browsers better, than one with both translation and margin
.marquee {
position: relative;
overflow: hidden;
background: rgb(161, 61, 175);
color: #fff;
}
.marquee-wrapper {
width: 100%;
animation: marquee-wrapper 4s ease-in-out infinite;
}
.marquee span {
display: inline-block;
min-width: 100%; /* this is to prevent shorter text animate to right */
white-space: nowrap;
font-size: 2.5em;
animation: marquee 4s ease-in-out infinite;
}
#keyframes marquee {
0% {
transform: translateX(0);
}
10% {
transform: translateX(0);
}
90% {
transform: translateX(-100%);
}
100% {
transform: translateX(-100%);
}
}
#keyframes marquee-wrapper {
0% {
transform: translateX(0);
}
10% {
transform: translateX(0);
}
90% {
transform: translateX(100%);
}
100% {
transform: translateX(100%);
}
}
<div class="marquee">
<div class="marquee-wrapper">
<span>
The only thing that matters now is everything You think of me
The only thing that matters now is everything You think of me
</span>
</div>
</div>
<br/>
<div class="marquee">
<div class="marquee-wrapper">
<span>Beware of short texts!</span>
</div>
</div>

Related

How to toggle HTML/CSS animation on hover and on click [duplicate]

This question already has answers here:
How to pause and resume CSS3 animation using JavaScript?
(5 answers)
Closed 2 years ago.
I am having trouble trying to stop and start animation whenever I hover over the element or on click. This is my HTML element:
<div class='marquee'>
<h1>Some Text</h1>
</div>
CSS:
.marquee {
width: 80%;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
}
.marquee h1 {
display: inline-block;
padding-left: 100%;
animation: marquee 15s linear infinite;
}
#keyframes marquee {
0% { transform: translate(0, 0); }
100% { transform: translate(-100%, 0); }
}
Right now, the animation just goes on forever by default. How can I have it so that whenever I hover over or click on the h1 or the div, the animation will pause and resume accordingly. I'm assuming to pause/restart the animation on click, I would need a JavaScript function. Any help is appreciated.
You can use animation-play-state rule:
.marquee {
width: 80%;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
}
.marquee h1 {
display: inline-block;
padding-left: 100%;
animation: marquee 15s linear infinite;
}
.marquee h1:hover {
animation-play-state: paused;
}
#keyframes marquee {
0% { transform: translate(0, 0); }
100% { transform: translate(-100%, 0); }
}
<div class='marquee'>
<h1>Some Text</h1>
</div>
Or with JS:
function stopAnimation(e){
if (e.target.style.animationPlayState == ""){
e.target.style.animationPlayState = "paused";
} else {
e.target.style.animationPlayState = "";
}
}
.marquee {
width: 80%;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
}
.marquee h1 {
display: inline-block;
padding-left: 100%;
animation: marquee 15s linear infinite;
}
#keyframes marquee {
0% { transform: translate(0, 0); }
100% { transform: translate(-100%, 0); }
}
<div class='marquee'>
<h1 onclick="stopAnimation(event)">Some Text</h1>
</div>
I would suggest using jquery to change the animation property.
$('.marquee').mouseenter(() => { $(this).css("animation: marquee 15s linear infinite"); } );
$('.marquee').mouseleave(() => { $(this).css("animation: none"); } );

css animation flicker issue

Css marquee like effect is flickering sometimes. The animation is not smooth as we expected. It stuck sometimes. I tried the solution available on diff stackoverflow posts but that did not help me much.
http://codepen.io/anon/pen/vmLGXJ
.marquee {
width: 100%;
line-height: 50px;
background-color: red;
color: white;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
}
.marquee p {
display: inline-block;
padding-left: 100%;
-webkit-backface-visibility: hidden;
-webkit-transform-style: preserve-3d;
animation: marquee 15s linear infinite;
}
#keyframes marquee {
from { transform: translate(0, 0); }
100% { transform: translate(-100%, 0); }
}
animation: marquee 15s linear infinite; // you can change the time like 15s to 50s
try to write
from { transform: translate(0, 0); }
to { transform: translate(-100%, 0); } /* Instead of 100% */
Also you can try to use all prefix, -moz- and -webkit-

Why doesn't my animation work in ie 11

I have the following animation (fiddle):
<style style="text/css">
#AdvertBox {
height: 55px;
overflow: hidden;
position: relative;
background:black;
color: white;
border: 1.75px solid yellow;
font-size: 35px;
font-style: italic;
border-radius: 1px;
width:45vw;
}
.scroll-left p
{
position: absolute;
width: 100%;
height: 100%;
margin: 0;
line-height: 55px;
text-align: center;
/* Starting position */
transform:translateX(100%);
/* Apply animation to this element */
animation: scroll-left 10s linear infinite;
}
#keyframes scroll-left {
0% {
transform: translateX(100%);
}
25% {
opacity: 1;
transform: translateX(0%);
}
39% {
opacity: 0;
transform: translateX(0%);
}
100% {
opacity: 0;
transform: translateX(0%);
}
}
.popIn p
{
position: absolute;
width: 100%;
height: 100%;
margin: 0;
line-height: 55px;
text-align: center;
/* Starting position */
transform:translateY(-100%);
/* Apply animation to this element */
animation: popIn 10s linear infinite;
}
#keyframes popIn {
/* Move it left */
0% {
transform: translateY(-100%);
}
/* Stop It */
30% {
transform: translateY(-100%);
}
/* fade out */
42% {
transform: translateX(0%);
}
/* fade out */
70% {
transform: translateX(0%);
}
100% {
transform: translateX(-100%);
}
}
</style>
<div id="AdvertBox" >
<div class="scroll-left">
<p style="position: absolute; z-index: 1 ">
First Message
</p>
</div>
<div class="popIn">
<p style="position: absolute; z-index: 2 ">
Second, longer message to drop down
</p>
</div>
</div>
It should have one item slide in from the right, fade out, then one item drop down on it. It looks fine in chrome and firefox, and the first item that slides left works in ie, but the second item, dropping down, doesn't do anything.
i have updated your fiddle please have a look again, it works on IE 11, but you may need to tweak the animation.
basically instead of translateX and translateY, i used translate(x,y);
it worked on IE 11
ok i forked that old one and i created my own fiddle. so your popIn animation has been changed to the following.
#keyframes popIn {
/* Move it left */
0% {
transform: translate(0%,-100%);
}
/* fade out */
50% {
transform: translate(0%,0%);
}
/* fade out */
75% {
transform: translate(0%,0%);
}
100% {
transform: translate(-100%,0%);
}
}
https://jsfiddle.net/qvx4b311/

Scrolling text - intems are display in the same time

I'm trying to write move/scroll text.
So finally I have this.
CODEPEN
There is a problem as you can see. The problem with diplay in the same time two text inside p tags. I want to display the 1st one and then should be show the 2nd one.
I was trying to change values of this
#-moz-keyframes left-one {
0% { -moz-transform: translateX(100%); }
100% { -moz-transform: translateX(-100%); }
}
#-webkit-keyframes left-one {
0% { -webkit-transform: translateX(100%); }
100% { -webkit-transform: translateX(-100%); }
}
#keyframes left-one {
0% {
-moz-transform: translateX(100%); /* Firefox bug fix */
-webkit-transform: translateX(100%); /* Firefox bug fix */
transform: translateX(100%);
}
100% {
-moz-transform: translateX(-100%); /* Firefox bug fix */
-webkit-transform: translateX(-100%); /* Firefox bug fix */
transform: translateX(-100%);
}
}
I mean 0% to 50% but it's not good.
How I can solve it?
The whole picture of the animation you want to show is 30s long, not 15s. Each individual animation is 15s on the screen, but the whole animation is 30s if you account for the time of the first animation + the time of the second animation, so they don't overlap.
So change the animation time of both to 30s, and do the first animation in the first 15s (0-50%), and do the second animation in the last 15s (50-100%)
.movetext {
width: 100%;
height: 50px;
overflow: hidden;
position: relative;
background-color: black;
}
.movetext p {
position: absolute;
font-family: Verdana, Arial;
width: 100%;
height: 100%;
margin: 0;
line-height: 50px;
text-align: center;
color: yellow;
font-weight: bold;
font-size: 20px;
transform: translateX(100%);
}
.movetext p:nth-child(1) {
animation: left-one 30s linear infinite;
}
.movetext p:nth-child(2) {
animation: left-two 30s linear infinite;
}
#keyframes left-one {
0% {
transform: translateX(100%);
}
50% {
transform: translateX(-100%);
}
100% {
transform: translateX(-100%);
}
}
#keyframes left-two {
50% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
<div class="container">
<div class="movetext">
<p>Something is here.</p>
<p>But maybe something will be here.</P>
</div>
</div>
Thanks man. It's working very well. :)
I saw there is a little problem on mobile view. The all text is not display properly. It's just cut off. For the other resolutions (>768) everything is good.
So how about this. How I can handle it?
EDIT
I saw the problem. P tag set width of class. I know I can set witdh eg. 700px but I would like to p tag set width of width text.

Flip after a certain period of time

I'm learning to use CSS to make some animations (start from zero). I saw this cool example on a website. I would like to apply this to my own CSS. However I'm thinking several changes to this
1) Can I change this by a timer. So it can flip automatically after a certain period (say flip every 10 seconds) without any mouse movement.
2) I have two <div> in my HTML file that I want to flip from one to anther. Unfortunately they have got the same class (Something like :widget-inner loadable .widget-size-2x1). So can I use #id (ID selector) instead of class selector in CSS file?
3) I saw other examples using an extra JS file to achieve the flipping animation. Ideally can I just use only CSS to do this?
I have a sample code below which only works partly. It doesn't show the first picture. Please guide on how to make the required changes.
#draggable {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
}
#dashboard {
perspective: 1000;
}
#dashboard {
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: all 1.0s linear;
}
.loadable {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
-webkit-animation: mymove 20s infinite; /* Chrome, Safari, Opera */
animation: mymove 20s infinite;
}
#b {
display: block;
box-sizing: border-box;
padding: 10px;
color: white;
text-align: center;
background-color: #aaa;
-webkit-animation: mymove 20s infinite; /* Chrome, Safari, Opera */
animation: mymove 20s infinite;
}
/* Chrome, Safari, Opera */
#-webkit-keyframes mymove {
40% {transform: rotateY(0deg);}
50% {transform: rotateY(180deg);}
90% {transform: rotateY(180deg);}
100% {transform: rotateY(0deg);}
}
<div id="draggable">
<div id="dashboard" class="shadow">
<div class="widget-inner loadable" id="a">
<img src="http://css3.bradshawenterprises.com/images/Windows%20Logo.jpg"/>
</div>
<div class="widget-inner loadable" id="b">
<p>This is nice for exposing more information about an image.</p>
<p>Any content can go here.</p>
</div>
</div>
</div>
Based on the information provided in the question and your comments, it seems like the below snippet is what you require. This would keep flipping infinitely without the need for any mouse interactions to trigger the flip action. When the image is shown, the text will get hidden behind and vice-versa.
The changes that I have made are as follows:
Added transform to rotate the div which contains the image (#a) by -180deg on load because this has to initially look as though it is behind the div that contains the text (#b).
When we flip, we have to flip both #a and #b synchronously but in exactly opposing manner. That is, when #a is made to come forward by using rotateY(0deg), the #b has to go behind and hence at that point in time, it should have rotateY(180deg) and vice-versa. This cannot be achieved using a single animation and hence I have added a separate animation keyframe setting for the front and back sides of the flip.
#draggable {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
}
#dashboard {
-webkit-perspective: 1000;
perspective: 1000;
}
#dashboard {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition: all 1.0s linear;
transition: all 1.0s linear;
}
.loadable {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#a{
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
-webkit-animation: mymoveback 20s infinite;
animation: mymoveback 20s infinite;
}
#b {
display: block;
box-sizing: border-box;
padding: 10px;
color: white;
text-align: center;
background-color: #aaa;
-webkit-animation: mymove 20s infinite;
animation: mymove 20s infinite;
}
/* Chrome, Safari, Opera */
#-webkit-keyframes mymove {
40% {
-webkit-transform: rotateY(0deg);
}
50% {
-webkit-transform: rotateY(180deg);
}
90% {
-webkit-transform: rotateY(180deg);
}
100% {
-webkit-transform: rotateY(0deg);
}
}
#-webkit-keyframes mymoveback {
40% {
-webkit-transform: rotateY(-180deg);
}
50% {
-webkit-transform: rotateY(0deg);
}
90% {
-webkit-transform: rotateY(0deg);
}
100% {
-webkit-transform: rotateY(-180deg);
}
}
#keyframes mymove {
40% {
transform: rotateY(0deg);
}
50% {
transform: rotateY(180deg);
}
90% {
transform: rotateY(180deg);
}
100% {
transform: rotateY(0deg);
}
}
#keyframes mymoveback {
40% {
transform: rotateY(-180deg);
}
50% {
transform: rotateY(0deg);
}
90% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(-180deg);
}
}
<div id="draggable">
<div id="dashboard" class="shadow">
<div class="widget-inner loadable" id="a">
<img src="http://lorempixel.com/450/281"/>
</div>
<div class="widget-inner loadable" id="b">
<p>This is nice for exposing more information about an image.</p>
<p>Any content can go here.</p>
</div>
</div>
</div>
Flip images to flip on some interval using setInterval method. Demo
$(function() {
setInterval(function() {
$('#f1_card').toggleClass("transformStyle transformRotate");
}, 3000)
})
Sure. you can use pseudo class :hover, and css property
transform: rotateY(180deg); for doing flipping you can control timing using animation and keyframes