misha.korolcov, вас интересует отображение только текста, то вы можете использовать мой пример, который вам показал
рони, возможности по его стилизации безграничны! Однако если вас интересует бегущая строка (или новостная лента) в которой бы в качестве передвижного элемента использовался любой HTML, возникает интересный вопрос!
Как отобразить содержимое элемента так, чтобы конец содержимого соединялся с началом его, как это происходит в бегущей строке с текстом?
Можно расширить тот элемент, чтобы он работал с любым содержимым!
<text-display>Hello!</text-display>
<text-display>
<p> Пример ленты с ссылкой:
<a href="https://javascript.ru/forum">форум на тему JavaScript</a>
А вообще может быть <em>любой</em> <span style="color: red;">HTML</span>
</p>
</text-display>
<text-display>
<img src="https://picsum.photos/300/100?1">
<img src="https://picsum.photos/300/100?2">
<img src="https://picsum.photos/300/100?3">
<img src="https://picsum.photos/300/100?4">
<img src="https://picsum.photos/300/100?5">
<img src="https://picsum.photos/300/100?6">
<img src="https://picsum.photos/300/100?7">
<img src="https://picsum.photos/300/100?8">
<img src="https://picsum.photos/300/100?9">
</text-display>
<style>
text-display {
background: linear-gradient(to bottom, #333, black);
background-color: #111;
color: white;
font: 900 1em / 1.5 monospace, system-ui;
border-radius: 0.2em;
white-space: nowrap;
margin: 0.2em 0;
}
</style>
<script>
class TextDisplay extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "closed" });
const document = shadow.ownerDocument;
const firstElement = document.createElement("div");
const secondElement = document.createElement("div");
const slot = document.createElement("slot");
const observer = new MutationObserver(mutationHandler);
shadow.innerHTML = `<style>
:host {
display: flex;
overflow: hidden;
}
:host > div {
min-width: 100%;
will-change: transform;
animation: text-display var(--text-display-duration, 15s) linear infinite;
animation-direction: inherit;
display: flex;
flex: 1 0 auto;
text-align: center;
}
:lang(ar), :lang(he) {
animation-direction: reverse;
}
@keyframes text-display {
to {
transform: translateX(-100%);
}
}
</style>`;
firstElement.append(slot);
shadow.append(firstElement, secondElement);
mutationHandler();
observer.observe(this, {
subtree: true,
characterData: true,
attributes: true,
childList: true
});
function mutationHandler() {
secondElement.textContent = "";
for(const assignedNode of slot.assignedNodes())
secondElement.append(assignedNode.cloneNode(true));
}
}
}
customElements.define("text-display", TextDisplay);
</script>