【问题标题】:How to animate background-position using percentages when background-size is 100%?当背景大小为 100% 时,如何使用百分比为背景位置设置动画?
【发布时间】:2019-07-24 06:02:17
【问题描述】:
举个例子:
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。
【问题讨论】:
标签:
css
css-animations
background-position
background-size
【解决方案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>
在所有情况下,诀窍是避免在background-size 中包含100% 100%,否则将无法使用百分比制作动画。
我使用left/right 进行简化,相当于0% 50%/100% 50%。只需在两者之间切换即可改变方向。
更多详情:https://stackoverflow.com/a/51734530/8620333
而且由于我们使容器的尺寸更大,我们还可以使用 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>