Анимация текста как у Spotify
Источник: Stack Overflow на русском
Если всегда известен цвет заднего фона, то можно сделать вот так на чистом CSS/HTML:
* {
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.title {
--bg: rgb(20, 20, 25);
--transparency-width: 30px;
--title-width: 100vw;
background-color: var(--bg);
color: rgb(255, 255, 255);
padding: 1em;
font-size: 32px;
overflow: hidden;
position: relative;
}
.title::before,
.title::after {
content: '';
display: block;
position: absolute;
top: 0;
height: 100%;
width: var(--transparency-width);
z-index: 10;
}
.title::before {
background-image: linear-gradient(to right, var(--bg), transparent);
left: 0;
}
.title::after {
background-image: linear-gradient(to left, var(--bg), transparent);
right: 0;
}
.title__text {
width: -webkit-max-content; /* Для поддержки старых браузеров */
width: max-content;
animation: movingTitleText infinite 6s alternate ease-in-out running;
}
@keyframes movingTitleText {
0%, 20% {
transform: translate(0px);
}
40%, 60% {
transform: translate(calc(-100% + var(--title-width) - var(--transparency-width) * 2));
}
80%, 100% {
transform: translate(0px);
}
}
<div class="title">
<div class="title__text">
1234567890123456789012345678901234567890
</div>
</div>
Конечно, у такого способа есть свои минусы, допустим:
.title
.Хотя данные проблемы можно решить JavaScript-ом
.title
и сохранить её, чтобы не нужно было указывать ещё в ручнуюanimation-play-state: paused
можно добавить если, ширина .title__text
< ширина .title
document.querySelectorAll('.title').forEach(title => {
const titleText = title.querySelector('.title__text')
if(titleText.offsetWidth < title.offsetWidth) {
titleText.style.animationPlayState = 'paused'
}
title.style.setProperty('--title-width', title.offsetWidth + 'px')
})
* {
margin: 0;
padding: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.title {
--bg: rgb(20, 20, 25);
--transparency-width: 30px;
background-color: var(--bg);
color: rgb(255, 255, 255);
padding: 1em;
font-size: 32px;
overflow: hidden;
position: relative;
}
.title::before,
.title::after {
content: '';
display: block;
position: absolute;
top: 0;
height: 100%;
width: var(--transparency-width);
z-index: 10;
}
.title::before {
background-image: linear-gradient(to right, var(--bg), transparent);
left: 0;
}
.title::after {
background-image: linear-gradient(to left, var(--bg), transparent);
right: 0;
}
.title__text {
width: -webkit-max-content; /* Для поддержки старых браузеров */
width: max-content;
animation: movingTitleText infinite 6s alternate ease-in-out running;
}
@keyframes movingTitleText {
0%, 20% {
transform: translate(0px);
}
40%, 60% {
transform: translate(calc(-100% + var(--title-width) - var(--transparency-width) * 2));
}
80%, 100% {
transform: translate(0px);
}
}
<div class="title">
<div class="title__text">
1234567890123456789012345678901234567890
</div>
</div>
<div class="title">
<div class="title__text">
12345678901234567890
</div>
</div>