Как анимировать background-position используя проценты, когда background-size равен 100%?
Возьмите следующий пример:
html {
height: 100%;
}
body {
display: flex;
justify-content: center;
align-items: center;
background-color: black;
height: 100%;
margin: 0;
}
#main {
background: #222222;
position: relative;
flex: 640px 0 0;
height: 360px;
}
@keyframes stars {
0% {
background-position: 0 0;
}
100% {
background-position: -100% 0;
}
}
#stars {
animation: stars 10s linear infinite;
background-image: url('https://i.imgur.com/nyFndCj.png');
background-size: 100% 100%;
background-repeat: repeat repeat;
position: absolute;
width: 100%;
height: 100%;
}
<div id="main">
<div id="stars"></div>
</div>
Идея здесь состоит в том, чтобы анимировать звезды, движущиеся от одной стороны к другой, изменяя положение фона с использованием процентов. Я могу заставить это работать, используя px
Например, но это требует от меня знать ширину заранее (в этом случае 640px
) и если я хочу изменить ширину / высоту #main
Мне нужно изменить значения анимации, и я хочу избежать этого, таким образом, проценты. Кроме того, я хочу сделать это только с помощью CSS, без JavaScript вообще.
1 ответ
Уменьшите размер фона и используйте масштаб, чтобы исправить это, увеличив размер контейнера. Тогда вы сможете анимировать фон так, как хотите:
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>
Вот еще одна идея без масштаба, где вы также увеличиваете элемент в два раза, используя right:-100%
или же left:-100%
или же 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>
Вот еще одно упрощение с учетом псевдоэлемента:
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>
В любом случае, хитрость заключается в том, чтобы избежать 100% 100%
в background-size
или это будет невозможно анимировать с использованием процентов.
я использовал left
/ right
для упрощения, которое эквивалентно 0% 50%
/ 100% 50%
, Просто переключайтесь между ними, чтобы изменить направление.
Более подробная информация здесь: /questions/28327775/ispolzovanie-protsentnyih-znachenij-s-background-position-na-linejnom-gradiente/28327778#28327778
И так как мы увеличили размер контейнера, мы также можем анимировать его, используя translate, чтобы повысить производительность:
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>
С масштабированием:
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>
В другом направлении
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>