CSS3 transition messing up fonts in webkit? - html

Ever since I added a css transition (first one was on hover, second was an animation) it seems to have messed up my fonts, they look 'different'.
It's totally bizarre, I've looked for hours and can't find anything on it, nor can I figure out exactly why it's happening.
It seems to be ok in firefox, but safari and chrome are having problems.
http://www.simplerweb.co.uk
Everything below the gear animation at the bottom left seems to look like a lighter font weight and the navigation menu seems to look the same.
I am totally lost on this one.
Here's the CSS for the animation.
.gearone {height:100px;
width:100px;
top:-10px;
left:-10px;
position:absolute;
background-position:center;
background-repeat:no-repeat;
background-image:url(../images/gearone.png);
-webkit-animation-name: backrotate;
-webkit-animation-duration: 13s;
-webkit-animation-iteration-count: infinite;
-webkit-transition-timing-function:linear;
-moz-animation-name: backrotate;
-moz-animation-duration: 13s;
-moz-animation-timing-function: linear;
-moz-animation-iteration-count: infinite;
}
.geartwo {height:100px;
width:100px;
position:absolute;
background-position:center;
background-repeat:no-repeat;
background-image:url(../images/gearone.png);
top:20px;
left:10px;
-webkit-animation-name: rotate;
-webkit-animation-duration: 13s;
-webkit-animation-iteration-count: infinite;
-webkit-transition-timing-function:linear;
-moz-animation-name: rotate;
-moz-animation-duration: 13s;
-moz-animation-timing-function:linear;
-moz-animation-iteration-count: infinite;
}
#-webkit-keyframes rotate {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
#-moz-keyframes rotate {
from {
-moz-transform: rotate(0deg);
}
to {
-moz-transform: rotate(360deg);
}
}
#-webkit-keyframes backrotate {
0% {
-webkit-transform: rotate(360deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
#-moz-keyframes backrotate {
0% {
-moz-transform: rotate(360deg);
}
100% {
-moz-transform: rotate(0deg);
}
}

I think I had a similar issue, and what fixed it for me was adding
-webkit-font-smoothing: antialiased;
to my body css. When animation of any kind happens, webkit tries to antialias the text to help with the animation, so adding it to begin with prevents it from changing or looking different.

i had the same problem. wile the execution of a webkit transition some anchor text became antialiased.
after many tries i've found that this happen just in elements that are positioned and have z-index with inside other elements positioned too and with z-index.
#footer {
bottom: 0;
left: 330px;
right: 100px;
height: 75px;
background-color: #231f20;
min-width: 540px;
min-height: 75px;
position: fixed;
z-index: 10;
}
inside the footer i have
#cityNav > ul > li a {
font-size: 24px;
text-transform: uppercase;
position: relative;
z-index: 110;
line-height: 24px;
height: 24px;
display: block;
}
and this is my transition
.circle {
position: absolute;
top: 0;
left: 0;
display: block;
background-color: #ff0000;
width: 20px;
height: 20px;
cursor: pointer;
text-indent: -999em;
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
-o-border-radius: 50%;
border-radius: 50%;
-webkit-transition: all .2s ease-out;
-moz-transition: all .2s ease-out;
-o-transition: all .2s ease-out;
transition: all .2s ease-out;
}
.circle:hover {
-webkit-transform: scale(2);
-moz-transform: scale(2);
-o-transform: scale(2);
transform: scale(2);
}

I was having this issue in Chrome for OSX. Using -webkit-backface-visibility: hidden; fixed the problem.

I've faced this issue numerous times and have had success adding the following css to the animated element:
z-index: 60000;
position: relative;
It seems it needs both z-index and position to be effective. In my case I was using it with Font Awesome animated spinners.

What you're seeing is webkit anti-alias your text because it's treating it as a texture as opposed to a vector. There's not much you can do, other than not using transformations, or using an text replacement to provide an image instead of your type.
There's a few related threads regarding webkit aliasing, but I haven't personally had much luck keeping the type as type, and still using transformations.

I'm not exactly sure of the reason why it's happening, but it looks like when your .geartwo element (100px x 100px) overlaps your text, it seems to lighten it. When it rolls off of it, it's back to normal. I too, notice this only in webkit browsers.
To fix it, you can set the gear width and height to 40px (that's the size of the image anyway -- I don't see the need for it to be 100px x 100px), and then re-position it accordingly.
EDIT: I'm not sure that you need to do this after my proposition, but I found this related discussion after a bit of searching.

As stated above, -webkit-font-smoothing: antialiased; works on desktop Safari.
But on iOS, you need to use -webkit-backface-visibility: hidden; in order to fix this.

While -webkit-backface-visibility: hidden; is a partial solution; it really ruins the display of your text, especially if you have smoothing / AA enabled. This bug is nasty too, because it happens only when you are using the transform property as well.
After roughly 2 years of sporadically visiting this topic every other month, I found a fix. You need to add a position:relative to the css element that is being animated. There is a catch though, you need to give it a z-index value that is greater than or lower then the element that you see the distortion on. This fixes it 100%.
Since topic doesn't have a 'definite' answer, I hope this answer helps someone who was in the same boat I was in for years.

For iOS8, the only way I succeeded in removing the transformation flickers was by adding
body * { -webkit-transform: translate3d(0, 0, 0); }
to my stylesheet.

All you need to do is add this CSS rule to any element that you are seeing the flicker on:
-webkit-transform-style: preserve-3d;
And that's it.

Related

CSS keyframes animation works on Chrome desktop but not mobile?

I'm using a keyframes animation for a transformation. It works perfectly on desktop, but it acts extremely strange on mobile. I'm testing on Chrome on my Macbook and on Chrome on my iPhone X. Another user found the same issue on Safari on iPhone.
Basically, when the page loads, the animation doesn't play. The delay works, but the actual transition and fade doesn't happen. You can see what it should look like (from a computer) at asilhavy.com. It doesn't play on load, but if I go to a new page and select the back button, it will play after I scroll. So weird. The scroll bar is also weird when I go back after visiting a new page.
I'm suspicious that it might be something very wrong somewhere else in my code, but I don't know where. Any pointers on where to look are helpful. The full code is available at the link above, but here's the code I have now specifically for that animation. I've gone through a few other solutions, like setting display: block, using -webkit-, and avoiding shorthand animation.
Update: Through more debugging it appears ios and safari aren't rendering properly. The animation is technically playing, but the transition (ease) isn't following. They move, just not smoothly.
#-webkit-keyframes slide-in {
from {
-webkit-transform: translateX(-150%);
transform: translateX(-150%);
}
to {
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
}
}
#keyframes slide-in {
from {
transform: translateX(-150%);
}
to {
transform: translateX(-50%);
}
}
.land-cont {
overflow: hidden;
position: absolute;
top: 30px;
left: 0;
height: 80px;
width: 250px;
}
.reveal-cont {
transform: translateX(-150%);
-webkit-animation-duration: 0.6s;
-webkit-animation-timing-function: ease;
-webkit-animation-delay: 1.6s;
-webkit-animation-iteration-count: 1;
-webkit-animation-direction: normal;
-webkit-animation-fill-mode: forwards;
-webkit-animation-play-state: running;
-webkit-animation-name: slide-in;
animation-duration: 0.6s;
animation-timing-function: ease;
animation-delay: 1.6s;
animation-iteration-count: 1;
animation-direction: normal;
animation-fill-mode: forwards;
animation-play-state: running;
animation-name: slide-in;
display: block;
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
top: calc(50% - 50px);
background: rgb(32, 6, 6);
left: 50%;
z-index: 2;
color: #FFF;
z-index: 2;
background: -webkit-linear-gradient($gradient);
background: -o-linear-gradient($gradient);
background: linear-gradient($gradient);
-webkit-box-shadow: $shadow;
-moz-box-shadow: $shadow;
box-shadow: $shadow;
opacity: 1;
}
<div class="land-cont">
<div class="reveal-cont">
<h2>Alicia</h2>
</div>
</div>
Finally fixed it. I can't point to one exact change, but I know this question was the one that got it working in the end. Turns out the problem was in iOS and Safari, not Chrome. Here's a list of changes I made:
Implemented proper use of -webkit-
Didn't use shorthand animation
Used display: block
Added animation class after page load
I'm not sure why that last one works, but it fixed it. If anyone knows why it worked please let me know.

How can I flip and animate icon together?

How can I flip the "font awesome" icon horizontally, and animate it at the same time. I used two classes (fa-flip and fa-bounce), but when I'm putting these together I can only get animation, the receiver is still returned to the left side, it have to be returned to the right
<i class="fas fa-phone fa-flip-horizontal fa-bounce"></i>
So essentially, and by no means said to sound rude, but you'll need to dig in and learn how the animations work if you want to start creating custom stuff outside of the pre-bottled stuff that comes with things like font awesome. I'm not sure I know exactly what you're after but here's a quick proof of concept (pretend div is your icon) to maybe get you in the direction you're after and you can load it on to codepen or something to tinker to fit your needs.
In the future though, some of the folks here can be a bit demanding about showing effort or providing a minimal reproduction of an issue to make a question more concise. Either way hope this helps, cheers!
div {
height: 5rem;
width: 5rem;
background-color: green;
will-change: background-color;
transition: all .25s ease;
animation: flipThenBounce 2s linear;
transform-style: preserve-3d;
}
#keyframes flipThenBounce {
0% {
background-color: red;
}
50% {
transform: rotateY(180deg);
}
80% {
transform: translateY(20px);
}
85% {
transform: translateY(0);
}
90% {
transform: translateY(20px);
}
95% {
transform: translateY(0);
}
100% {
background-color: green;
}
}
<div></div>

How to smoothly revert CSS animation to its current state?

I've got not animated element as default. There's also a trigger that lets me turn on & off animation on that element. The animation itself is very simple: moves element from left to the right and back.
When I stop animation, then my element obviously goes back to initial position. But it goes back suddenly, not smoothly. So it just changes its position from the one when I turned off animation to initial one. My question is: is there a way to stop it smoothly, so when I turn off the animation it goes back to initial position but smoothly/animating.
Here's my element and animation: http://jsfiddle.net/2Lwftq6r/
HTML:
<input type="checkbox" id="anim">
<label for="anim">Start / stop animation</label>
<div></div>
CSS:
div {
margin-top: 50px;
width: 50px; height: 10px;
background: #000;
transform: translateX(0);
}
#anim:checked ~ div {
-webkit-animation: dance 2s infinite ease-in-out;
-moz-animation: dance 2s infinite ease-in-out;
}
#-webkit-keyframes dance {
0%, 100% { -webkit-transform: translateX(0); }
50% { -webkit-transform: translateX(300px); }
}
#-moz-keyframes dance {
0%, 100% { -moz-transform: translateX(0); }
50% { -moz-transform: translateX(300px); }
}
I just had the same problem and I solved it by not using animation and it works perfectly! Check out my solution:
So I had this spatula that I had to move when hovered over only, and I wanted it to transition back smoothly, so this is what I did:
#Spatula:hover{
animation-direction:alternate;
transform: translate(1.2cm,1cm);
transition: all 1.5s;
-webkit-transition: all 1.5s;
}
#Spatula{
-webkit-transition: all 1.5s;
transition: all 1.5s;
}
Good luck!
You can't archive this effect only CSS3 way, but if you really need it, you could use jQuery + CSS3 Transitions. My solution (http://jsfiddle.net/sergdenisov/3jouzkxr/10/):
HTML:
<input type="checkbox" id="anim-input">
<label for="anim-input">Start / stop animation</label>
<div class="anim-div"></div>
CSS:
.anim-div {
margin-top: 50px;
width: 50px;
height: 10px;
background: #000;
}
.anim-div_active {
-webkit-animation: moving 2s ease-in-out infinite alternate;
animation: moving 2s ease-in-out infinite alternate;
}
.anim-div_return {
-webkit-transition: -webkit-transform 0.5s ease-in-out;
transition: transform 0.5s ease-in-out;
}
#-webkit-keyframes moving {
0% { -webkit-transform: translateX(0); }
100% { -webkit-transform: translateX(300px); }
}
#keyframes moving {
0% { transform: translateX(0); }
100% { transform: translateX(300px); }
}
Javascript:
$('#anim-input').on('change', function() {
var $animDiv = $('.anim-div');
if (this.checked) {
$animDiv.removeClass('anim-div_return')
.addClass('anim-div_active');
return;
}
var transformValue = $animDiv.css('webkitTransform') ||
$animDiv.css('transform');
$animDiv.css({'webkitTransform': transformValue,
'transform': transformValue})
.removeClass('anim-div_active');
requestAnimationFrame(function() {
$animDiv.addClass('anim-div_return')
.css({'webkitTransform': 'translateX(0)',
'transform': 'translateX(0)'});
});
});
P.S.
Vendor prefixes are based on actual browsers list from http://caniuse.com.
Check out This StackOverflow question.
You aren't going to like this answer, but reality is that CSS3
animations aren't really useful to achieve this. To make this work you
would need to replicate a lot of your CSS in your Javascript which
kind of destroys the point (Like for example in this closely related
answer
Change speed of animation CSS3?).
To really make it stop smoothly your best bet would be to write the
animation on a platform like the Greensock animation library
which provides all the tools you need to make it actually smoothly
stop instead of suddenly stop.
There's also another answer below it that does make an effort at using CSS, you can look at that one.
There is also an alternate solution, it might not give you the desired effect of going back to it's original state, but since nobody mentioned it and this problem seems to have no solution, it's possible to pause the animation purely in css, locking it's state until it's started again
To pause the animation you need first to make the animation available even when the checkbox is not checked
And make use of the animation-play-state property
div {
margin-top: 50px;
width: 50px; height: 10px;
background: #000;
animation: dance 2s infinite ease-in-out paused;
}
#anim:checked ~ div {
animation-play-state: running;
}
#keyframes dance {
0%, 100% { transform: translateX(0); }
50% { transform: translateX(300px); }
}
<input type="checkbox" id="anim">
<label for="anim">Start / stop animation</label>
<div></div>

How to scale an element when it loads using only CSS?

I'm loading an element that has the initial css values of :
.popOver {
height: 100%;
width: 100%;
position: fixed;
background-color: #d9dfe5;
transition: all 2s ease-in-out;
transform: scale(0,0);
}
I need to change to scale(1, 1) when the element loads in the page and see the transition. Anyone can help?
transition will apply the moment you load the page so that is not an ideal solution in your situation, what you will need is CSS #keyframes where you need to set scale(0,0) to the class and then scale(1,1) for 100% as keyframes will shoot after the page is completely loaded.
Demo (Refactored the code a bit and added animation-fill-mode to prevent the popup from scaling back to 0 so using rev 2)
.popOver {
height: 100%;
width: 100%;
position: fixed;
background-color: #d9dfe5;
-webkit-animation: bummer 2s;
animation: bummer 2s;
-webkit-transform: scale(0,0);
transform: scale(0,0);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards; /* Add this so that your modal doesn't
close after the animation completes */
}
#-webkit-keyframes bummer {
100% {
-webkit-transform: scale(1,1);
}
}
#keyframes bummer {
100% {
transform: scale(1,1);
}
}
Here as I explained before, am setting the initial scale of the element to 0,0 and than am animating it to 1,1 using keyframes. The time of the animation can be controlled by tweaking the 2s which is nothing but 2 Seconds.

CSS keyframe animation with translation transform snaps to whole pixels in IE 10 and Firefox

It appears both IE 10 and Firefox snaps elements to whole pixels when animating their position using translate 2d transform in a css keyframe animation.
Chrome and Safari does not, which looks a lot better when animating subtle movements.
The animation is done the following way:
#keyframes bobbingAnim {
0% {
transform: translate(0px, 0px);
animation-timing-function:ease-in-out
}
50% {
transform: translate(0px, 12px);
animation-timing-function:ease-in-out
}
100% {
transform: translate(0px, 0px);
animation-timing-function:ease-in-out
}
}
Here's an example of what I mean:
http://jsfiddle.net/yZgTM/.
Just open it in Chrome and IE 10 (or Firefox) and you should notice the difference in smoothness of the motion.
I realise there might be many factors affecting this behaviour such as if the element is drawn with hardware acceleration or not.
Does anyone know of a fix to try to force browsers to always draw the elements on subpixels?
I found this similar question, but the answer was to animate using a translate transform, which is exactly what I'm doing:
CSS3 Transitions 'snap to pixel'.
Update:
After playing around a bit I found a fix for Firefox, doesn't do anything in IE 10 though. The trick is to scale down the element ever so slightly and use translate3d with a 1px offset in the Z-axis:
#keyframes bobbingAnim {
0% {
transform: scale(0.999, 0.999) translate3d(0px, 0px, 1px);
animation-timing-function:ease-in-out
}
50% {
transform: scale(0.999, 0.999) translate3d(0px, 12px, 1px);
animation-timing-function:ease-in-out
}
100% {
transform: scale(0.999, 0.999) translate3d(0px, 0px, 1px);
animation-timing-function:ease-in-out
}
}
I love your question!
Good job in noticing the pixel-snap in firefox and IE10.
I've researched this subject a while ago and I advise you to check the GSAP forums, as they contain a lot of useful information on web animations.
Here's a topic regarding IE10 pixel-snap issue.
What you need to do is add a minimal rotation to the element. This is so IE and Firefox will redraw it in a different way - which will stop pixel-snap for good :)
Tyr this:
#keyframes bobbingAnim {
0% {
transform: translate(0px, 0px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
50% {
transform: translate(0px, 12px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
100% {
transform: translate(0px, 0px) rotateZ(0.001deg);
animation-timing-function:ease-in-out
}
}
#Nemanja is correct you will find that if you tweak the speed you will see better results this is fairly typical with css animations. Also it doesn't really make a difference in this case if you enable hardware acceleration. I tidied up the code a little bit and ran it without any issues, i do not have ie10; However, I have 11. You may have to just remove the second transform of translateZ if it doesn't run in 10
body {
background-color: #ccc;
}
.bobbing {
position: absolute;
animation: bobbingAnim ease-in-out .5s infinite;
-moz-animation: bobbingAnim ease-in-out .5s infinite;
-webkit-animation: bobbingAnim ease-in-out .5s infinite;
}
.bobbing.text {
font-size: 50px;
color: #000;
left: 30px;
top: 30px;
}
.bobbing.image {
left: 30px;
top: 150px;
background: url(http://placehold.it/300x100/aa0000&text=Bobbing+image) 50% 50% no-repeat;
width: 310px;
height: 110px;
}
#keyframes bobbingAnim {
50% {
transform: translate(0, 12px) translateZ(0);
}
}
#-webkit-keyframes bobbingAnim {
50% {
-webkit-transform: translate3d(0, 12px, 0);
}
}
#-moz-keyframes bobbingAnim {
50% {
-moz-transform: translate3d(0, 12px, 0);
}
}
There cant be half a pixel movement, there is no such thing.
Your problem is the speed and smoothness of the animation, not the "pixel snapping".