I'm trying out a CSS3 animation on a background image. Everything's working well, the problem is that on Chrome the text ends up being blurred when the animation is in progress:
During Animation:
Turning off the animation:
As you can see the text rendering is fine when the animation is turned off, I know there's the usual issue with text rendering but I can't understand why the rendering is poor on Chrome when the animation is in progress. I'm not sure there's anything I can do about it really. I've tested the animation on Firefox and IE and it's ok. By the way I'm working on Windows.
Firefox:
IE:
EDIT
.bg-div {
position: fixed;
width: 110%;
height: 110%;
transform: translate(-5%, -5%);
-moz-transform: translate(-5%, -5%) rotate(0.02deg); /* rotation to solve choppy animation on Firefox */
-ms-transform: translate(-5%, -5%);
background-image: url('images/colour-test.jpg');
background-size: cover;
-webkit-animation: bg-animation 10s linear infinite;
-moz-animation: bg-animation 10s linear infinite;
-ms-animation: bg-animation 10s linear infinite;
}
#-webkit-keyframes bg-animation {
25% { transform: translate(-5.5%, -5.5%); }
50% { transform: translate(-5.3%, -4.9%); }
75% { transform: translate(-4.8%, -4.3%); }
}
#-moz-keyframes bg-animation {
25% { -moz-transform: translate(-5.5%, -5.5%) rotate(0.02deg); }
50% { -moz-transform: translate(-5.3%, -4.9%) rotate(0.02deg); }
75% { -moz-transform: translate(-4.8%, -4.3%) rotate(0.02deg); }
}
#-ms-keyframes bg-animation {
25% { -ms-transform: translate(-5.5%, -5.5%); }
50% { -ms-transform: translate(-5.3%, -4.9%); }
75% { -ms-transform: translate(-4.8%, -4.3%); }
}
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
height: 65%;
text-align: center;
}
After reading the question and answer posted in the comments I've tried to adding -webkit-font-smoothing: subpixel-antialiased; to .bg-div but that didn't make any difference.
EDIT 2
Okay so this is a bit of a weird one, during the animation apparently the position: fixed is making the text blurry. I don't know how that is possible, anyway once I removed the position: fixed and the background was animating the text was displayed correctly. It's still not what I want because I need the background to be fixed.
In my testing, the problem is fixed if the transform is not used on .content. Luckily, you don't need to use transform to position your content div.
Use this margin: auto trick to position instead
Using this method, you do not need to use transform: translate(-50%, -50%)
The content is centered with the combination of top, right, bottom, left, margin: auto and the percentage width and height.
.content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 50%;
height: 65%;
text-align: center;
}
Working Example
body { margin: 0 auto; width: 500px }
.bg-div {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
width: 800px;
height: 800px;
transform: translate(-5%, -5%);
background: url('http://www.placehold.it/800') no-repeat;
-webkit-animation: bg-animation 2s linear infinite;
animation: bg-animation 2s linear infinite;
}
#-webkit-keyframes bg-animation {
0% {
transform: translate(-5.5%, -5.5%);
}
50% {
transform: translate(-5%, -5%);
}
100% {
transform: translate(-5.5%, -5.5%);
}
}
#keyframes bg-animation {
0% {
transform: translate(-5.5%, -5.5%);
}
50% {
transform: translate(-5%, -5%);
}
100% {
transform: translate(-5.5%, -5.5%);
}
}
.content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 50%;
height: 65%;
text-align: center;
}
<div class="bg-div"></div>
<div class="content">
<h1>This looks better</h1>
<input value="Text" />
</div>
Related
Good day, there was the task to make the animation of an airplane flying around a path. I decided to take advantage of the opportunities in CSS3. But all I have achieved is one animation cycle. The plane flies one circle around the path and the animation stops. I tried using animation-iteration-count with infinite, but all I got was the flight of a plane in chaotic directions. Below is my code, please tell me how to loop this animation so that the plane constantly flies in a circle without stopping.
Code
.wrap {
margin: 100px;
}
.route {
height: 200px;
width: 400px;
border: 3px dotted #000;
position: relative;
}
.plane {
position: absolute;
bottom: -13px;
left: 100%;
animation-iteration-count: 3;
animation: flyLeft 1.5s linear forwards, rotatePlane 0.5s linear 1.5s forwards, flyUp 1s linear forwards 2s, RotateRight 0.5s linear 2.8s forwards, MoveRight 3s linear forwards 3s, RotateDown 1s linear 6s forwards, flyDown 1s linear forwards 7s, RotateLeft 1s linear 7.8s forwards;
}
#keyframes flyLeft {
100% {
left: -14px;
}
}
#keyframes rotatePlane {
100% {
transform: rotateZ(90deg);
}
}
#keyframes flyUp {
100% {
bottom: 100%;
}
}
#keyframes RotateRight {
0% {
transform: rotateZ(90deg);
}
100% {
transform: rotateZ(180deg);
}
}
#keyframes MoveRight {
0% {
left: -14px;
}
100% {
left: 380px;
}
}
#keyframes RotateDown {
0% {
transform: rotateZ(180deg);
}
100% {
transform: rotateZ(270deg);
}
}
#keyframes flyDown {
0% {
bottom: 100%;
}
100% {
bottom: -8%;
}
}
#keyframes RotateLeft {
0% {
transform: rotateZ(270deg);
}
100% {
transform: rotateZ(360deg);
}
}
<div class="wrap">
<div class="route">
<img class="plane" src="http://p36099-290-14699.s290.upress.link/wp-content/uploads/2020/05/plane.png">
</div>
</div>
You need to wrap all the animations in one #keyframes CSS at-rules to easily make repetitions. Here's a working solution below that wraps all the animations in one #keyframes.
.wrap {
margin: 100px;
}
.route {
height: 200px;
width: 400px;
border: 3px dotted #000;
position: relative;
}
.plane {
position: absolute;
right: 0;
bottom: 0;
transform: translate(50%, 50%);
animation: travelRoundTheBorder 10s linear infinite;
}
#keyframes travelRoundTheBorder {
30% {
bottom: 0;
right: 100%;
transform: translate(50%, 50%);
}
32.5% {
bottom: 0;
right: 100%;
transform: translate(50%, 50%) rotate(90deg);
}
47.5% {
right: 100%;
bottom: 100%;
transform: translate(50%, 50%) rotate(90deg);
}
50% {
right: 100%;
bottom: 100%;
transform: translate(50%, 50%) rotate(180deg);
}
80% {
right: 0;
bottom: 100%;
transform: translate(50%, 50%) rotate(180deg);
}
82.5% {
right: 0;
bottom: 100%;
transform: translate(50%, 50%) rotate(270deg);
}
97.5% {
right: 0;
bottom: 0;
transform: translate(50%, 50%) rotate(270deg);
}
100% {
right: 0;
bottom: 0;
transform: translate(50%, 50%) rotate(360deg);
}
}
<div class="wrap">
<div class="route">
<img class="plane" src="http://p36099-290-14699.s290.upress.link/wp-content/uploads/2020/05/plane.png">
</div>
</div>
Splitting the movement along the path and the turns into TWO separate keyframes makes this easier.
The math of the percentages is based on a square but with a rectangle the percentages change.
CSS variable could help here to work out those percentages but I haven't gone deeper into that for the demo purposes.
.wrap {
margin: 10px;
}
.route {
height: 150px;
width: 150px;
margin: auto;
border: 3px dotted #000;
position: relative;
}
.plane {
position: absolute;
transform: translate(-50%, -50%) rotate(180deg);
top: 0;
left: 0;
animation: path 6s linear infinite, turn 6s ease infinite;
}
#keyframes path {
0%,
100% {
left: 0;
top: 0;
}
25% {
left: 100%;
top: 0;
}
50% {
left: 100%;
top: 100%;
}
75% {
left: 0;
top: 100%;
}
}
#keyframes turn {
0%,
24% {
transform: translate(-50%, -50%) rotate(180deg);
}
25%,
49% {
transform: translate(-50%, -50%) rotate(270deg);
}
50%,
74% {
transform: translate(-50%, -50%) rotate(0deg);
}
75%,
99% {
transform: translate(-50%, -50%) rotate(90deg);
}
100% {
transform: translate(-50%, -50%) rotate(90deg);
}
}
<div class="wrap">
<div class="route">
<img class="plane" src="http://p36099-290-14699.s290.upress.link/wp-content/uploads/2020/05/plane.png">
</div>
</div>
Just to begin testing new CSS posibilities, offset-path (not supported in IE, experimental in FF)
reference
#container {
width: 400px;
height: 300px;
border: dotted 5px black;
margin: 30px;
}
#motion-demo {
offset-path: path('M0 -10 H400 A 10 10 1 0 1 410 0 V300 A 10 10 1 0 1 400 310 H0 A 10 10 1 0 1 -10 300 V0');
animation: move 10s infinite linear;
width: 40px;
height: 40px;
background: cyan;
}
#keyframes move {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
<div id="container">
<div id="motion-demo">A</div>
</div>
The issue is visible when animating the skewY() property. Looks like the element's width shrinks down a little and no longer touches the sides of an equally wide container.
The same does not happen when animating with skewX() - the height is animated as expected.
I'm experiencing the bug in Safari only, both desktop and mobile browsers. Firefox and Chrome work as expected. This issue is visible during transition or animations only.
GIF previews:
Animation in Firefox/Chrome
Animation in Safari
.arrow {
position: absolute;
top: 20px;
left: 20px;
bottom: 20px;
right: 20px;
background-color: rgb(230, 230, 230);
}
.rect-x {
position: absolute;
left: calc(50vw - 50px);
top: 0;
width: 100px;
height: 100%;
background-color: blue;
animation: skew-x 1s linear alternate infinite;
transform-origin: center;
}
.rect-y {
position: absolute;
left: 0;
top: calc(50vh - 50px);
width: 100%;
height: 100px;
background-color: red;
animation: skew-y 1s linear alternate infinite;
transform-origin: center;
}
#keyframes skew-x {
0% { transform: skewX(15deg) skewY(0); }
to { transform: skewX(-15deg) skewY(-0);}
}
#keyframes skew-y {
0% { transform: skewX(0) skewY(15deg); }
to { transform: skewX(0) skewY(-15deg); }
}
<div class="arrow">
<div class="rect-y"></div>
<div class="rect-x"></div>
</div>
Try to use browser prefix.
.arrow {
position: absolute;
top: 20px;
left: 20px;
bottom: 20px;
right: 20px;
background-color: rgb(230, 230, 230);
}
.rect-x {
position: absolute;
left: calc(50vw - 50px);
top: 0;
width: 100px;
height: 100%;
background-color: blue;
animation: skew-x 1s linear alternate infinite;
-webkit-animation: skew-x 1s linear alternate infinite;
transform-origin: center;
-webkit-transform-origin: center;
}
.rect-y {
position: absolute;
left: 0;
top: calc(50vh - 50px);
width: 100%;
height: 100px;
background-color: red;
animation: skew-y 1s linear alternate infinite;
-webkit-animation: skew-y 1s linear alternate infinite;
transform-origin: center;
-webkit-transform-origin: center;
}
#keyframes skew-x {
0% { transform: skewX(15deg) skewY(0); }
to { transform: skewX(-15deg) skewY(-0);}
}
#-webkit-keyframes skew-x {
0% { -webkit-transform: skewX(15deg) skewY(0); }
to { -webkit-transform: skewX(-15deg) skewY(-0);}
}
#keyframes skew-y {
0% { transform: skewX(0) skewY(15deg); }
to { transform: skewX(0) skewY(-15deg); }
}
#-webkit-keyframes skew-y {
0% { -webkit-transform: skewX(0) skewY(15deg); }
to { -webkit-transform: skewX(0) skewY(-15deg); }
}
<div class="arrow">
<div class="rect-y"></div>
<div class="rect-x"></div>
</div>
I am experimenting with some keyframe animations in css which seem to work fine in IE, Chrome, Firefox but not in Microsoft Edge for some reason. I get this flicker at the end of the animation where I guess it shows their final position and sets the opacity to 1 before hiding them once again and restarting the animation. My code is as follows (This is minified for one bubble, but the link below is a codepen for the whole animation):
HTML:
<div class="canvas">
<div class="bubble"></div>
</div>
CSS:
.canvas {
min-height: 100%;
width: 100%;
background: green;
position: absolute;
overflow: hidden;
}
.bubble {
display: block;
border-radius: 100%;
opacity: 0.8;
position: absolute;
}
.bubble:nth-child(1) {
background: radial-gradient(ellipse at center, #E6EBF2 0%, #E6EBF2 46%, #EFF0EC 100%);
width: 7px;
height: 7px;
left: 13vw;
bottom: 52vh;
-webkit-animation: move1 infinite 10s;
animation: move1 infinite 10s;
}
#-webkit-keyframes move1 {
0% {
bottom: -100px;
}
100% {
bottom: 44vh;
-webkit-transform: translate(10px, 0);
transform: translate(10px, 0);
opacity: 0;
}
}
#keyframes move1 {
0% {
bottom: -100px;
}
100% {
bottom: 44vh;
-webkit-transform: translate(10px, 0);
transform: translate(10px, 0);
opacity: 0;
}
}
Here is a codepen i created:
https://codepen.io/anon/pen/BqqMKe
Any help would be appreciated as I can't seem to figure it out.
I have a fixed background image within a div that will not display consistently in mobile Safari. It displays fine when a page is refreshed, but the main issue arises when I try to prompt backward and forward to other site pages, which causes the browser to reposition the background's origin point awkwardly.
Note: The first image shows the background image displaying correctly, while the second image displays the transform-origin shift that occurs upon navigating back/forward in the Safari mobile browser, (the main issue).
Here's a snippet, for further reference:
body,
html {
height: 100%;
width: 100%;
background-size: cover;
background-repeat: no-repeat;
}
body {
background: white;
margin: 0;
padding: 0;
border: 0;
outline: 0;
z-index: -2;
}
.sitebg {
background: url("http://maxpixel.freegreatpicture.com/static/photo/1x/Seamless-Repeating-Tiling-Tile-able-Tileable-1889447.jpg");
background-repeat: repeat;
background-position: center;
background-size: 720px 720px;
-webkit-animation: 180s rotatebg infinite linear;
-moz-animation: 180s rotatebg infinite linear;
-o-animation: 180s rotatebg infinite linear;
-ms-animation: 180s rotatebg infinite linear;
animation: 180s rotatebg infinite linear;
width: 750px;
height: 750px;
position: fixed;
top: 50%;
left: 50%;
}
.sitebg-parent {
position: absolute;
height: 100%;
width: 100%;
margin: auto;
padding: 0;
overflow: hidden;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}
#-webkit-keyframes rotatebg {
0% {
-webkit-transform: rotate(0deg) translate(-50%, -50%);
-webkit-transform-origin: top left;
}
100% {
-webkit-transform: rotate(360deg) translate(-50%, -50%);
-webkit-transform-origin: top left;
}
}
#keyframes rotatebg {
0% {
transform: rotate(0deg) translate(-50%, -50%);
transform-origin: top left;
}
100% {
transform: rotate(360deg) translate(-50%, -50%);
transform-origin: top left;
}
}
<body>
<div class="sitebg-parent">
<div class="sitebg"></div>
</div>
</body>
Please try the code below.
I've slightly changed your code and removed unnecessary and ivalid css rules.
html, body {
height: 100%; width: 100%;
margin: 0; padding: 0;
}
.sitebg {
position: absolute;
top: 50%; left: 50%;
width: 2000px; height: 2000px;
margin: -1000px 0 0 -1000px;
background: url("http://s3.gomedia.us/wp-content/uploads/2008/06/skullbg-green.gif");
transform-origin: 50% 50%;
-webkit-animation: 180s rotatebg infinite linear;
animation: 180s rotatebg infinite linear;
}
.sitebg-parent {
position: absolute; z-index: -1;
top: 0; right: 0; bottom: 0; left: 0;
overflow: hidden;
}
#-webkit-keyframes rotatebg {
0% {-webkit-transform: rotateZ(0deg)}
100% {-webkit-transform: rotateZ(360deg)}
}
#keyframes rotatebg {
0% {transform: rotateZ(0deg)}
100% {transform: rotateZ(360deg)}
}
<body>
<div class="sitebg-parent">
<div class="sitebg"></div>
</div>
</body>
I am trying to move a background but it seems quite stuck.
How can I move it?
body {
background-color: black !important;
}
#background_div {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: -1;
width: 100%;
height: 100%;
background-image: url("http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg");
background-position: center;
background-repeat: no-repeat;
animation-name: background_animation;
}
#keyframes background_animation {
0% {
transform: translate(0%, -100%) scale(4, 4);
}
25% {
transform: translate(100%, 0%) scale(5, 5);
}
50% {
transform: translate(50%, 100%) scale(6, 6);
}
100% {
transform: translate(0%, -100%) scale(4, 4);
}
}
<div id="background_div"></div>
https://jsfiddle.net/5he2otzL/
The problem in your case is that you've set only the animation-name to #background_div but have not set any value for the animation-duration. The default value for animation-duration is 0s and that for the animation-fill-mode is none. So, as per the spec, the animation has no visible effect.
Below is the extract from the specs: (emphasis is mine).
If the <time> is 0s, like the initial value, the keyframes of the animation have no effect, but the animation itself still occurs instantaneously. Specifically, start and end events are fired; if animation-fill-mode is set to backwards or both, the first frame of the animation, as defined by animation-direction, will be displayed during the animation-delay. Then the last frame of the animation, as defined by animation-direction, will be displayed if animation-fill-mode is set to forwards or both. If animation-fill-mode is set to none then the animation has no visible effect.
Once you set some value other than 0s to animation-duration property, the animation works fine.
body {
background-color: black !important;
}
#background_div {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: -1;
width: 100%;
height: 100%;
background-image: url("http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg");
background-position: center;
background-repeat: no-repeat;
animation-name: background_animation;
animation-duration: 2s; /* set this */
}
#keyframes background_animation {
0% {
transform: translate(0%, -100%) scale(4, 4);
}
25% {
transform: translate(100%, 0%) scale(5, 5);
}
50% {
transform: translate(50%, 100%) scale(6, 6);
}
100% {
transform: translate(0%, -100%) scale(4, 4);
}
}
<div id="background_div"></div>
body {
background-color: black !important;
}
#background_div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: -1;
width: 100%;
height: 100%;
background-image: url("http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg");
background-position: center;
background-repeat: no-repeat;
-webkit-animation: background_animation 5s infinite; /* Chrome, Safari, Opera */
animation: background_animation 5s infinite;
}
#keyframes background_animation {
0% {
transform: translate(0%,-100%) scale(4,4);
}
25% {
transform: translate(100%,0%) scale(5,5);
}
50% {
transform: translate(50%,100%) scale(6,6);
}
100% {
transform: translate(0%,-100%) scale(4,4);
}
}
Fixed it for you hope it helps,
Easy reads:
http://www.w3schools.com/cssref/css3_pr_animation.asp
https://jsfiddle.net/5he2otzL/