我已经制作了此加载占位符CSS动画。在白色背景上看起来是正确的,因为动画/移动渐变是白色的,不透明度为20%。
但是,有时占位符将位于不同颜色的背景上,并且移动的部分也将在背景上可见,而不仅仅是在变暗的颜色(这是不希望的)上。请参见下面的代码段:
.ph-item {
position: relative;
margin-bottom: 10px;
overflow: hidden;
border-radius: 2px;
}
.ph-item,
.ph-item *,
.ph-item ::after,
.ph-item ::before {
box-sizing: border-box;
}
.ph-item::before {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 50%;
z-index: 1;
width: 500%;
margin-left: -250%;
animation: phAnimation 0.8s linear infinite;
background: linear-gradient(to right, rgba(255, 255, 255, 0) 46%, rgba(255, 255, 255, 0.35) 50%, rgba(255, 255, 255, 0) 54%) 50% 50%;
}
.ph-item > * {
padding-right: 10px;
}
.ph-row {
margin-bottom: 5px;
}
.ph-row div {
border-radius: 3px;
height: 10px;
background-color: rgba(0, 0, 0, 0.2);
}
.ph-row .standard,
.ph-row.big div {
height: 20px;
margin-right: 10px;
}
.ph-float-right {
float: right;
padding-left: 10px;
margin-right: auto;
}
.ph-col-2 {
width: 16.66667%;
display: inline-block;
}
.ph-col-4 {
width: 33.33333%;
display: inline-block;
}
.ph-col-6 {
width: 50%;
display: inline-block;
}
.ph-col-8 {
width: 66.66667%;
display: inline-block;
}
.ph-col-10 {
width: 83.33333%;
display: inline-block;
}
.ph-col-12 {
width: 100%;
display: inline-block;
}
.ph-avatar {
position: relative;
width: 100%;
min-width: 50px;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
overflow: hidden;
}
.ph-avatar::before {
content: "";
display: block;
padding-top: 100%;
}
@keyframes phAnimation {
0% {
transform: translate3d(-30%, 0, 0);
}
100% {
transform: translate3d(30%, 0, 0);
}
}
<div style="width: 500px; height: 50px; background-color: darkblue; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: white; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
我的问题是,是否有可能以某种方式将动画蒙版仅渲染在变暗部分(ph-avatar
和ph-col-xx
)的顶部?
这是如何实现的?
答案 0 :(得分:4)
编辑这实际上是Background animation performance
的副本另一种方法是将after伪函数与background-position
一起使用线性梯度重置。为了使每个伪对象具有连贯的梯度,background-attachment
会将所有东西放在一起。背景尺寸也有帮助。
以下想法的演示。 CSS注释了更新或修改的地方
.ph-item {
position: relative;
margin-bottom: 10px;
overflow: hidden;
border-radius: 2px;
}
.ph-item,
.ph-item *,
.ph-item ::after,
.ph-item ::before {
box-sizing: border-box;
}
/* selector removed
.ph-item::before
and replaced by : */
.ph-avatar::after,
.ph-row .standard::after,
.ph-row .ph-col-10::after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 50%;
z-index: 1;
width: 500%;
margin-left: -250%;
animation: phAnimation 2s linear infinite;/* duration to set to your needs */
background: linear-gradient(
to right,
rgba(255, 255, 255, 0) 46%,
rgba(255, 255, 255, 0.35) 50%,
rgba(255, 255, 255, 0) 54%
)
50% 50%
rgba(0, 0, 0, 0.2);/* move here & added */
background-attachment: fixed;/* added */
background-size: 1000px auto;/* added */
}
.ph-item > * {
padding-right: 10px;
}
.ph-row {
margin-bottom: 5px;
}
.ph-row div {
border-radius: 3px;
height: 10px;
/*background-color: rgba(0, 0, 0, 0.2); or move animation here from pseudo*/
}
.ph-row .standard,
.ph-row.big div {
height: 20px;
margin-right: 10px;
}
.ph-float-right {
float: right;
padding-left: 10px;
margin-right: auto;
}
.ph-col-2 {
width: 16.66667%;
display: inline-block;
}
.ph-col-4 {
width: 33.33333%;
display: inline-block;
}
.ph-col-6 {
width: 50%;
display: inline-block;
position: relative;/* added */
overflow: hidden;/* added */
}
.ph-col-8 {
width: 66.66667%;
display: inline-block;
}
.ph-col-10 {
width: 83.33333%;
display: inline-block;
position: relative;/* added */
overflow: hidden;/* added */
}
.ph-col-12 {
width: 100%;
display: inline-block;
}
.ph-avatar {
position: relative;
width: 100%;
min-width: 50px;
border-radius: 50%;
overflow: hidden;
}
.ph-avatar::before {
content: "";
display: block;
padding-top: 100%;
}
@keyframes phAnimation {
0% {
background-position: -1000px 0;/* modified */
}
100% {
background-position: 1000px 0;/* modified */
}
}
<div style="width: 500px; height: 50px; background-color: darkblue; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: white; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: tomato; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: gold; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: purple; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: turquoise; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: gray; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: teal; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard"></div>
<div class="ph-col-10"></div>
</div>
</div>
</div>
</div>
注意,可以直接在元素内部设置背景动画,除非有其他用途,否则不需要伪元素。可能的选项https://codepen.io/gc-nomade/pen/byJOJa
答案 1 :(得分:2)
也许一种选择是遮罩两个svg图像并设置遮罩属性的动画。我个人并不真正熟悉该技术,但这也许会有所帮助:
https://tympanus.net/codrops/css_reference/mask-composite/
但是,如果您想使用html格式(我个人也希望这样做),则可以通过一些技巧来达到这种效果:
.ph-item {
position: relative;
margin-bottom: 10px;
overflow: hidden;
border-radius: 2px;
}
.ph-item,
.ph-item *,
.ph-item ::after,
.ph-item ::before {
box-sizing: border-box;
}
.highlighted {
position: relative;
overflow: hidden;
}
.highlighted::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
z-index: 1;
width: 100px;
animation: 1s linear infinite;
animation-name: phAnimation;
background: red;
/* background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.35) 50%, rgba(255, 255, 255, 0) 100%) 50% 50%; */
}
.ph-avatar.highlighted::before {
animation-name: phAnimationAvatar;
}
.ph-item > * {
padding-right: 10px;
}
.ph-row {
margin-bottom: 5px;
}
.ph-row div {
border-radius: 3px;
height: 10px;
background-color: rgba(0, 0, 0, 0.2);
}
.ph-row .standard,
.ph-row.big div {
height: 20px;
margin-right: 10px;
}
.ph-float-right {
float: right;
padding-left: 10px;
margin-right: auto;
}
.ph-col-2 {
width: 16.66667%;
display: inline-block;
}
.ph-col-4 {
width: 33.33333%;
display: inline-block;
}
.ph-col-6 {
width: 50%;
display: inline-block;
}
.ph-col-8 {
width: 66.66667%;
display: inline-block;
}
.ph-col-10 {
width: 83.33333%;
display: inline-block;
}
.ph-col-12 {
width: 100%;
display: inline-block;
}
.ph-avatar {
position: relative;
width: 100%;
min-width: 50px;
height: 50px;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 50%;
overflow: hidden;
}
@keyframes phAnimationAvatar {
0% {
transform: translate3d(-100px, 0, 0);
}
10% {
transform: translate3d(-50px, 0, 0);
}
20% {
transform: translate3d(0px, 0, 0);
}
30% {
transform: translate3d(50px, 0, 0);
}
100% {
transform: translate3d(100px, 0, 0);
}
}
@keyframes phAnimation {
0% {
transform: translate3d(-100px, 0, 0);
}
11% {
transform: translate3d(-100px, 0, 0);
}
50% {
transform: translate3d(85px, 0, 0);
}
100% {
transform: translate3d(335px, 0, 0);
}
}
<div style="width: 500px; height: 50px; background-color: darkblue; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar highlighted"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard highlighted"></div>
<div class="ph-col-10 highlighted"></div>
</div>
</div>
</div>
</div>
<div style="width: 500px; height: 50px; background-color: white; padding: 20px;">
<div class="ph-item" style="max-width: 360px;">
<div class="ph-col-2">
<div class="ph-avatar highlighted"></div>
</div>
<div class="ph-col-10 ph-float-right">
<div class="ph-row">
<div class="ph-col-6 standard highlighted"></div>
<div class="ph-col-10 highlighted"></div>
</div>
</div>
</div>
</div>
缺点是您需要为不同的占位符重新校准动画,但是比为每个占位符元素使用静态svg更好。
编辑:单挑,尽管chrome和firefox可以正常工作,但似乎存在一个关于野生动物园如何呈现此问题的问题。