My goal is to create a little slideshow, and I already made it here : https://jsfiddle.net/cas1g2ch/2/
Here's the code :
HTML
<div id="first-block">
<div id="background-header">
<div class="bg-wrapper">
<div class="background-img-1"></div>
</div><!--
--><div class="bg-wrapper">
<div class="background-img-2"></div>
</div>
</div>
</div>
CSS
#first-block{
position: relative;
width: 100%;
height: 100vh;
}
#keyframes zoomPicture {
0%{
transform: scale(1.0);
}
50%{
transform: scale(1.1);
}
100%{
transform: scale(1.0);
}
}
#background-header{
position: absolute;
top : 0;
left : 0;
width: 200vw;
height: 100vh;
box-shadow: 0px 1px 1px #333;
}
#background-header > .bg-wrapper
{
width: 100vw;
height: 100vh;
display: inline-block;
float: left;
overflow: hidden;
}
#background-header > .bg-wrapper > div{
width: 100vw;
height: 100vh;
background-attachment: fixed;
animation-duration: 20s;
background-size: cover;
animation-timing-function: ease-in-out;
animation-name: zoomPicture;
animation-iteration-count: infinite;
}
#background-header .background-img-1 {
background-image: url("http://www.hd-wallpaper.images-fonds.com/modules/mg3/albums/Paysages_(landscapes)_Wallpaper_HD/Paysages/Paysage_(landscape)_wallpaper_HD_0025.jpg");
}
#background-header .background-img-2 {
background-image: url("http://unreveunvoyage.fr/wp-content/uploads/2015/04/parc-national-de-banff-paysage-canada.jpg");
}
Right now the slideshow has two pictures, and each picture covers the entire screen size (width : 100vw ; height : 100vh ; background-size : cover).
To display the pictures I used background-image, and the backgrounds are fixed.
Because I cannot animate a background with background-size : cover, I used transform : scale to add a little zoom effect.
The problems :
On Chrome there's a weird Glitch (Chrome 56 on Windows), just use the scrollbar
in the demo to see the problem, here's a video I made that shows the
problem : https://www.youtube.com/watch?v=NHCLBTpxCAs (In this video I chose a high transform: scale value to better recognize the bug)
On Firefox the backgrounds are not fixed, but the pictures are
displayed correctly
Surprisingly it works great on Internet Explorer 11
It also seems to work on mobile
How can I fix this? What is the best workaround?
Related
I've been trying to get a marquee effect with a fog image to work for several days now. I tried several tutorials (videos and written ones), but the effect keeps visibly skipping/restarting and the effect is not seamless. The image itself is 1000px wide and is loopable. The two fog images are different and move at a different speed to have a better effect.
I did manage to get it to work with text, with the help of another tutorial, but the img version still poses problems. To clarify: The images are displayed, they move properly, but at some point the animation restarts/skips/jumps instead of seamlessly repeating the images.
My current version looks like the following (its a vue project):
.fog-container {
top: 0;
height: 100%;
overflow: hidden;
position: absolute;
width: 100%;
z-index: 0;
}
.fog-img {
height: 100%;
position: absolute;
width: 300vw;
}
.fog-img-first {
animation: marquee 120s linear infinite;
background-position: center;
background-repeat: repeat;
background-size: contain;
}
.fog-img-second {
animation: marquee 60s linear infinite;
background-position: center;
background-size: contain;
background-repeat: repeat;
}
#keyframes marquee {
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(-200vw, 0, 0);
}
}
<v-main>
<div class="fog-container">
<div
:style="{'background-image':
`url(${require('./assets/pictures/background/fog_1.png')})`}"
class="fog-img fog-img-first"
/>
<div
:style="{'background-image':
`url(${require('./assets/pictures/background/fog_2.png')})`}"
class="fog-img fog-img-second"
/>
</div>
</v-main>
I'm working on a simple CSS animation and came across a curious problem.
When animating several small divs, if I zoom in or out on Chrome/Firefox the heights of the divs becomes inconsistent - despite them all sharing the same size styles.
Is there any way to address this using CSS? I want the bars to maintain a consistent height without regard to the zoom level. I realize this is something of an edge case, but want to cover as many bases as possible!
Example is here.
HTML
<div class='animation-box animate'>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
</div>
CSS
.animation-box {
width: 100px;
}
.animation-bar {
animation-duration: 3s;
animation-iteration-count: infinite;
animation-name: bargraph;
animation-timing-function: linear;
background-color: #0d97c1;
height: 3px;
margin: 2px;
}
#keyframes bargraph {
0% {
width: 100%;
}
50% {
width: 10%;
}
100% {
width: 100%;
}
}
What about a simplification with only one element and less of code:
.animation-bar {
animation: bargraph 1.5s infinite linear alternate;
width: 100px;
height: 25px;
background-image: linear-gradient(#0d97c1 50%, transparent 50%);
background-position:0 0;
background-size: 100% 5px;
background-repeat: repeat-y;
}
#keyframes bargraph {
0% {
background-size: 100% 5px;
}
100% {
background-size: 10% 5px;
}
}
<div class="animation-bar"></div>
This is a problem of subpixel rendering. The issue here is that when you are zooming, the space between two bars will have to snap to a given pixel on your screen.
If you have a 3px margin # 150% zoom, the computed space is 4,5px. Meaning that the zoomed space on screen will be inconsistently rendered at 4 or 5px.
On a regular CPU computed dom, your bar will be placed at the closest value, producing those weird gaps.
What you could do to minimize the effect is applying some GPU rendered CSS (opposed to the regular CPU rendering) which is way better at rendering subpixel graphics.
One way of doing that is applying transforms.
.animation-box {
width: 55px;
margin: 0 15px 0 -5px;
}
.animation-bar {
animation: bargraph 1s infinite linear;
transform-origin: top left;
height: 3px;
background-color: #0d97c1;
margin-bottom: 3px;
}
#keyframes bargraph {
0% {
transform: scaleX(1);
}
25% {
transform: scaleX(.8);
}
50% {
transform: scaleX(.6);
}
75% {
transform: scaleX(.8);
}
100% {
transform: scaleX(1);
}
}
<div class='animation-box animate'>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
</div>
I recommend an excellent article on Smashing Magazine on that topic : CSS GPU Animation: Doing It Right
I wanted to ask, what is wrong with this CSS code? It is used to animate background image - zoom effect.
#media (min-width: 1000px) {
.anim-on {
background-size: 110% 110%;
background-position: center center;
animation: shrink 12s infinite alternate;
}
.anim-out {
background-size: 120% 120%;
background-position: center center;
animation: small 6s infinite alternate;
}
#keyframes shrink {
0% {
background-size: 110% 110%;
}
100% {
background-size: 100% 100%;
}
}
#keyframes small {
0% {
background-size: 100% 100%;
}
100% {
background-size: 110% 110%;
}
}
}
This code generates nice effect, but i saw, that on slower machines, affect is bad.
What is wrong? Or maybe someone has better idea, how create this effect, in better technique?
Background size is a visual property and so any change to its value would cause repainting to occur. Painting is a very expensive operation and is bound to have an impact on the performance in low end machines. One way to overcome this would be to use CSS transform (scale to be precise) instead of background-size change to produce the animation.
Snippet which will cause performance impact:
The below snippet uses the same animation as in the question. When you run this snippet and inspect it using Chrome Dev tools (by enabling "Show Paint Rects" option), you'd see that both images have a paint rect associated with them (green or red colored box) and that as the animation is happening the box keeps blinking (or stays as-is). This indicates that a repaint is happening often and thus it impacts performance.
.anim-on,
.anim-out {
height: 200px;
width: 200px;
background: url(http://lorempixel.com/200/200/nature/1);
}
.anim-on {
background-size: 110% 110%;
background-position: center center;
animation: shrink 12s infinite alternate;
}
.anim-out {
background-size: 120% 120%;
background-position: center center;
animation: small 6s infinite alternate;
}
#keyframes shrink {
0% {
background-size: 110% 110%;
}
100% {
background-size: 100% 100%;
}
}
#keyframes small {
0% {
background-size: 100% 100%;
}
100% {
background-size: 110% 110%;
}
}
/* Just for demo */
div {
float: left;
margin-right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='anim-on'></div>
<div class='anim-out'></div>
Snippet which will cause lesser performance impact:
In the below snippet, I have added the background-image to a pseudo-element and then used scale transform on it to produce the zoom-in/out effect. The parent's overflow: hidden setting prevents the animation from affecting its size. If you inspect this with Chrome Dev tools you'd see that the green or red colored box appears only once when the page is loaded and goes away. This indicates that there is no further repaint is happening during the animation itself and hence it is better from a performance point of view. You'd also notice that this animation is more smoother than the earlier one.
.anim-on,
.anim-out {
position: relative;
height: 200px;
width: 200px;
overflow: hidden;
}
.anim-on:after,
.anim-out:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0px;
left: 0px;
background: url(http://lorempixel.com/200/200/nature/1);
}
.anim-on:after {
animation: shrink 12s infinite alternate;
}
.anim-out:after {
animation: small 6s infinite alternate;
}
#keyframes shrink {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
#keyframes small {
0% {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}
/* Just for demo */
div {
float: left;
margin-right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='anim-on'></div>
<div class='anim-out'></div>
You can find more information about the various CSS properties and how a change to their value will impact the rendering process in the CSS Triggers website.
You can find more information about the rendering process and how using transform (as opposed to few other properties) results in a performance improvement in the below articles/sites:
HTML5 Rocks - Accelerated Rendering in Chrome
GPU Accelerated Compositing in Chrome.
Google Developers - Rendering Performance.
I edited Henry code, now css is reusable, so user can add background image to element via CMS, and css code will do the rest:
.anim {
position: relative;
height: 100vh;
width: 100%;
overflow: hidden;
**background-size: 0px!important;**
}
.anim:after {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0px;
left: 0px;
background-size: cover !important;
**background: inherit;**
z-index: -1;
}
.anim:after {
animation: shrink 12s infinite alternate;
}
#keyframes shrink {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
#keyframes small {
0% {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}
<section class="anim" style="background: url('images/1.png');"></section>
Thanks * :)
So on my page here: dunnrite.co.uk/frame2 you will find under the "text design" header some patterns beneath the 5 solid blocks of colour. They are set as background images for divs. The problem is because I want those divs so small it clips a load off of the original image. How do I get it so that the image shown is more zoomed out to show off the pattern more?
My css was just
background-image:url("Images/pattern12.jpg");
Thanks,
Jonathan
Use the background-size CSS property, and probably you want to use the cover value, which ensures that the background completely covers your container, without distorting the image (if the aspect ratio differs, then clipping will occur).
You can also specify an explicit size for your background image, for example 45px as in your case.
The documentation for background-size can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/background-size
I zoom in the element using the transform: scale(2,2); property.
here is demo link ..
http://jsfiddle.net/s3hWj/4/
<div class="wrap">
<div></div>
<p>hello</p>
</div>
html, body {
height: 100%;
}
div.wrap {
height: 33%;
width: 33%;
overflow: hidden;
position: relative;
}
div.wrap > div {
position: absolute;
height: 100%;
width: 100%;
-moz-transition: all .5s;
-webkit-transition: all .5s;
transition: all .5s;
-moz-transform: scale(1,1);
-webkit-transform: scale(1,1);
transform: scale(1,1);
background-image: url('http://pimg.tradeindia.com/00288122/b/0/Our-Valuable-Client-List-Click-on-Image-.jpg');
-moz-background-size: cover;
-webkit-background-size: cover;
background-size: cover;
z-index: -1;
}
div.wrap:hover > div {
-moz-transform: scale(2,2);
-webkit-transform: scale(2,2);
transform: scale(2,2);
}
In Google Chrome, when you have two elements, one that has a CSS3 animation and another with a background-image with a fixed position and an absolute positioned parent (important to keep that), the fixed property stops working when the animation is active.
Here is a JSFiddle, open in Chrome, scroll up and down to see the image be fixed, and then hover over the red square to see the fixed property break:
http://jsfiddle.net/keleturner/44mjq/
<div class="animation">
</div>
<div class="background">
<span></span>
</div>
.animation { display: block; width: 300px; height: 300px; background: red; -webkit-transition: 1.8s -webkit-transform ease; }
.animation:hover { -webkit-transform: scale(1.1, 1.1); transform: scale(1.1, 1.1);}
.background { position: absolute; left:0; top: 300px; display: block; width: 100%; height: 500px; }
.background span { background-attachment: fixed; background-size: cover; background-image: url(http://image.jpg); width: 100%; height: 100%; display: block; }
Any ideas why?
Why not make the body element have the background? Demo
But to answer your question, it's rendering error due to the body increasing size due to the scale. To fix it add -webkit-transform:translateZ(1px); to either .animation or .background
But your setup is a silly one to have, it can be done in much better ways