Make the size of the background smaller and use scale to rectify this by increasing the size of the container. Then you will be able to animte the background like you want:
body {
background-color: black;
height: 100vh;
margin: 0;
}
#main {
background: #222222;
position: relative;
width: 100%;
height: 360px;
overflow: hidden;
}
#stars {
animation: stars 10s linear infinite;
background-image: url('https://i.imgur.com/nyFndCj.png');
background-size: 50% 100%;
position: absolute;
left: 0;
right: 0;
height: 100%;
transform: scaleX(2);
}
@keyframes stars {
0% {
background-position: left;
}
100% {
background-position: right;
}
}
<div id="main">
<div id="stars"></div>
</div>
Here is another idea without scale where you also make the element twice bigger using right:-100%
or left:-100%
or width:200%
body {
background-color: black;
height: 100vh;
margin: 0;
}
#main {
background: #222222;
position: relative;
width: 100%;
height: 360px;
overflow: hidden;
}
#stars {
animation: stars 10s linear infinite;
background-image: url('https://i.imgur.com/nyFndCj.png');
background-size: 50% 100%;
position: absolute;
left: 0;
right: -100%;
height: 100%;
}
@keyframes stars {
0% {
background-position: left;
}
100% {
background-position: right;
}
}
<div id="main">
<div id="stars"></div>
</div>
Here is another simplification considering pseudo element:
body {
background-color: black;
height: 100vh;
margin: 0;
}
#main {
position: relative;
width: 100%;
height: 360px;
overflow: hidden;
z-index:0;
}
#main:before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:-100%;
bottom:0;
animation: stars 10s linear infinite;
background:
url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
#222222;
}
@keyframes stars {
100% {
background-position: right;
}
}
<div id="main">
</div>
In all the case, the trick is to avoid having 100% 100%
in the background-size
or it will be impossible to animate using percentage.
I have used left
/right
for simplification which is equivalent to 0% 50%
/100% 50%
. Simply switch between both to change the direction.
More details here: https://stackoverflow.com/a/51734530/8620333
And since we have made the size of the container bigger, we can also animate it using translate to have better performance:
body {
background-color: black;
height: 100vh;
margin: 0;
}
#main {
position: relative;
width: 100%;
height: 360px;
overflow: hidden;
z-index:0;
}
#main:before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:-100%;
bottom:0;
animation: stars 10s linear infinite;
background:
url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
#222222;
}
@keyframes stars {
100% {
transform: translateX(-50%);
}
}
<div id="main">
</div>
With scaling:
body {
background-color: black;
height: 100vh;
margin: 0;
}
#main {
position: relative;
width: 100%;
height: 360px;
overflow: hidden;
z-index:0;
}
#main:before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
transform:scaleX(2);
transform-origin:left;
animation: stars 10s linear infinite;
background:
url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
#222222;
}
@keyframes stars {
100% {
transform:scaleX(2) translateX(-50%);
}
}
<div id="main">
</div>
In the other direction
body {
background-color: black;
height: 100vh;
margin: 0;
}
#main {
position: relative;
width: 100%;
height: 360px;
overflow: hidden;
z-index:0;
}
#main:before {
content:"";
position:absolute;
z-index:-1;
top:0;
left:0;
right:0;
bottom:0;
transform:scaleX(2);
transform-origin:right;
animation: stars 10s linear infinite;
background:
url('https://i.imgur.com/nyFndCj.png') left/50% 100%,
#222222;
}
@keyframes stars {
100% {
transform:scaleX(2) translateX(50%);
}
}
<div id="main">
</div>