Reputation: 602
I am trying to achieve a CSS animation which scrolls a repeating background image infinitely. To make the scrolling as smooth as possible, I want the animation to cycle at a point when the image is in the exact same position it was when it started. And in order to make the animation look good regardless of any particular user's viewport size, I will be using an SVG graphic and I would like the background-size
property to be set to 100%
or the cover
keyword.
My specified parameters do not work as expected. However, any other background-size
value I choose does.
Why does my scrolling animation not work when background-size
is 100%
?
For a working example, see this code pen or use the following code:
HTML
<div id="element">
<h1>Scroll endlessly I say!</h1>
</div>
CSS
@keyframes scroll {
0% { background-position: 0% center; }
100% { background-position: 100% center; }
}
#element{
padding: 10px;
color: white;
background: black;
text-shadow: 0 0 4px black;
animation: scroll 8s linear infinite;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg");
background-repeat: repeat;
/* Works:
========================= */
background-size: 50%;
/*background-size: 20%;*/
/*background-size: 200%;*/
/*background-size: 100px;*/
/*background-size: 10rem;*/
/* Does NOT work:
========================= */
/*background-size: 100%;*/
}
Although I could use another solution like this one by CSS-Tricks, I like mine better because it is more efficient, since I do not have use a large, redundant graphic.
Upvotes: 1
Views: 2016
Reputation: 64254
As per the w3c spec:
'background-position'
percentage
A percentage X aligns the point X% across (for horizontal) or down (for vertical) the image with the point X% across (for horizontal) or down (for vertical) the element's padding box. For example, with a value pair of '0% 0%',the upper left corner of the image is aligned with the upper left corner of the padding box. A value pair of '100% 100%' places the lower right corner of the image in the lower right corner of the padding box. With a value pair of '14% 84%', the point 14% across and 84% down the image is to be placed at the point 14% across and 84% down the padding box.
This means that the percentage that you set in the background-position specifies which point of the image should match with the same point in the element.
BUT when the size of the container and the image are equals, all the points of the image match the point of the container, any percentage in the background-position has the same result (that is, the image fitting the container, centered). So, then the background won't move !
Upvotes: 2
Reputation: 602
Because you are attempting to reposition the background image based on a distance between 2 points that are in the same place.
From the specification:
A percentage X aligns the point X% across (for horizontal) or down (for vertical) the image with the point X% across (for horizontal) or down (for vertical) the element's padding box.
This means that to decide where to position a background image:
Let's take for example an arbitrary situation where you want to position a background image inside of an element. There are two broad situations which exist:
In the former situation, it does not matter what percentage you chose. The distance between a point that percent from the edge of the image will be exactly the same as the distance between a point that percent from the edge of the element because they are both the same size (X% of Y is X% of Y). That means that no noticeable repositioning can be done because moving an image to where it already is is just like not moving it at all.
In the latter situation, however, the distance between a point X% from the edge of the image will always be different than the distance between a point X% from the edge of the element, so a move can be made.
Upvotes: 0
Reputation: 87303
It appears it won't work using percent (as vals so nicely answered), and I can't yet say why.
If to change to pixel it does work though, as you can see in this sample, so in combination with media query one might be able to "fill" the width anyway.
@keyframes scroll {
0% { background-position: 0px center; }
100% { background-position: 600px center; }
}
#element{
width: 600px;
padding: 10px;
color: white;
text-shadow: 0 0 4px black;
animation: scroll 8s linear infinite;
background: black url("https://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg") left center repeat;
background-size: 600px;
}
<div id="element">
<h1>Scroll endlessly I say!</h1>
</div>
As a workaround, which will do exactly what a percentage would do with the original set up, you could use pseudo element.
Set the pseudo to 200% width, the background size to 50% and background repeat to repeat, and it will make the visible part equal to 100% of your original image, and then animate its left value.
(and IMHO, it will be better than the one by CSS-Tricks, efficient and without the need of large, redundant graphics)
@keyframes scroll {
0% { left: -100%; }
100% { left: 0%; }
}
#element{
position: relative;
padding: 10px;
color: white;
background: black;
text-shadow: 0 0 4px black;
overflow: hidden;
}
#element:before {
content: " ";
position: absolute;
top: 0;
height: 100%;
width: 200%;
animation: scroll 8s linear infinite;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg");
background-position: left center;
background-repeat: repeat;
background-size: 50%;
z-index: 1;
}
h1 {
position: relative;
z-index: 2;
}
<div id="element">
<h1>Scroll endlessly I say!</h1>
</div>
Upvotes: 1
Reputation: 97
Your animation won't work when background size is 100% because of background-repeat: repeat;
property which cause your image to repeat it self, as your image size is 100% image actually repeats it self, we are just unable to see it. You may check it if you set your background size to 98%.
Upvotes: 0
Reputation: 21890
If you watch the animation, the image scrolls based upon the right edge of the image(svg), from the starting point (background-size
) to 100%, or until the right edge of the image reaches the right edge of the container. Then the animation repeats.
If the starting point of the animation is 100% (or cover
) you are placing the right edge of the image at the right edge of the container. So, the animation is visibly non-existent. Basically, the image is repeating in the same position.
This is a bit difficult to see based upon the image you are using. But if you use an image with a clear right and left edge, you can see it easier:
http://codepen.io/anon/pen/wMpYjN?editors=110
Watch the right edge of the image.
Upvotes: 1