I wanted to create a scrolling text banner custom HTML element. And I found the first example that is in this site(https://blog.hubspot.com/website/scrolling-text-css) does very close to what I want to do.
The one problem that I have with above is that if I have a long text (i.e. like a paragraph) so that it goes over the width of the container, I see the text showing in multiple lines so that multiple lines of text scroll at the same time.
I'd like to make it so that a single line of text shows and it scrolls until it shows all the text then repeat the scrolling cycle. I am guessing it will have to be some css setting that I have to update. What kind of setting do I need to add or change to make long text to show in a single scrolling line? Any help will be appreciated.
Below is my custom element .js file that I came up with based on the contents from the site I mentioned above. It does some extra stuff of taking color and text attributes and applies them, but you can ignore that part. createStyle() function is where I have the css stuff for styling:
my-scrolling-text-v3.js:
class MyScrollingTextV3CustomElement extends HTMLElement {
attrObj = {
color: '#000',
text: 'Please set "text" attribute in the custom element'
};
attrs = ['color', 'text'];
constructor() {
super();
console.log("myScrollingText.constructor()");
// attributes aren't available in constructor.
}
connectedCallback() {
try {
console.log("myScrollingText.connectedCallback()");
this.setAttributes();
console.log("myScrollingText.connectedCallback(): attrObj=" JSON.stringify(this.attrObj));
this.appendChild(this.createStyle(this.attrObj.color));
this.appendChild(this.createScrollingTextInsideTextContainer(this.attrObj.text));
} catch (error) {
console.log("myScrollingText.connectedCallback(): catch: " error);
}
}
setAttributes() {
let value = "";
for (let attr of this.attrs) {
console.log("setAttributes(): attr=" attr);
try {
value = this.getAttribute(attr);
console.log("setAttributes(): value=" value);
if (this.attrObj.hasOwnProperty(attr) && value && (value !== '')) {
this.attrObj[attr] = value;
}
} catch (error) {
// ignore and use default
}
}
}
createStyle(color) {
const styleElement = document.createElement('style');
styleElement.innerHTML = `
#scroll-container {
border: 3px solid black;
border-radius: 5px;
overflow: hidden;
}
#scroll-text {
font-size: 34px;
color: ${color};
/* animation properties */
-moz-transform: translateX(100%);
-webkit-transform: translateX(100%);
transform: translateX(100%);
-moz-animation: my-animation 15s linear infinite;
-webkit-animation: my-animation 15s linear infinite;
animation: my-animation 15s linear infinite;
}
/* for Firefox */
@-moz-keyframes my-animation {
from { -moz-transform: translateX(100%); }
to { -moz-transform: translateX(-100%); }
}
/* for Chrome */
@-webkit-keyframes my-animation {
from { -webkit-transform: translateX(100%); }
to { -webkit-transform: translateX(-100%); }
}
@keyframes my-animation {
from {
-moz-transform: translateX(100%);
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
to {
-moz-transform: translateX(-100%);
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
}
`;
return styleElement;
}
createScrollingTextInsideTextContainer(text) {
const textContainerDiv = document.createElement('div');
textContainerDiv.id = 'scroll-container';
textContainerDiv.appendChild(this.createScrollingText(text));
return textContainerDiv;
}
createScrollingText(text) {
const textDiv = document.createElement('div');
textDiv.id = 'scroll-text';
textDiv.textContent = text;
return textDiv;
}
}
customElements.define('my-scrolling-text-v3', MyScrollingTextV3CustomElement);
<my-scrolling-text-v3 color="#0f0" text="This is the text value from my-scrolling-text-v3 element"></my-scrolling-text-v3>
CodePudding user response:
I know it is deprecated, but it still works.
A LOT less code and no wrapping
marquee {
color: #0f0;
border: 3px solid black;
border-radius: 5px;
overflow: hidden;
font-size: 34px;
}
<marquee>This is the text value from my-scrolling-text-v3 element</marquee>
CodePudding user response:
After looking at different css examples and trying different properties, I found the combination of properties that make it behave the way that I want it to. The trick was to add these two properties:
#scroll-container {
display:flex;
}
#scroll-text {
flex-shrink: 0;
}
And so the final solution with complete code is like below:
class MyScrollingTextV3CustomElement extends HTMLElement {
attrObj = {
color: '#000',
text: 'Please set "text" attribute in the custom element'
};
attrs = ['color', 'text'];
constructor() {
super();
console.log("myScrollingText.constructor()");
// attributes aren't available in constructor.
}
connectedCallback() {
try {
console.log("myScrollingText.connectedCallback()");
this.setAttributes();
console.log("myScrollingText.connectedCallback(): attrObj=" JSON.stringify(this.attrObj));
this.appendChild(this.createStyle(this.attrObj.color));
this.appendChild(this.createScrollingTextInsideTextContainer(this.attrObj.text));
} catch (error) {
console.log("myScrollingText.connectedCallback(): catch: " error);
}
}
setAttributes() {
let value = "";
for (let attr of this.attrs) {
console.log("setAttributes(): attr=" attr);
try {
value = this.getAttribute(attr);
console.log("setAttributes(): value=" value);
if (this.attrObj.hasOwnProperty(attr) && value && (value !== '')) {
this.attrObj[attr] = value;
}
} catch (error) {
// ignore and use default
}
}
}
createStyle(color) {
const styleElement = document.createElement('style');
styleElement.innerHTML = `
#scroll-container {
display: flex;
border: 3px solid black;
border-radius: 5px;
overflow: hidden;
}
#scroll-text {
font-size: 2em;
color: ${color};
flex-shrink: 0;
/* animation properties */
-moz-transform: translateX(100%);
-webkit-transform: translateX(100%);
transform: translateX(100%);
-moz-animation: my-animation 15s linear infinite;
-webkit-animation: my-animation 15s linear infinite;
animation: my-animation 15s linear infinite;
}
/* for Firefox */
@-moz-keyframes my-animation {
from { -moz-transform: translateX(100%); }
to { -moz-transform: translateX(-100%); }
}
/* for Chrome */
@-webkit-keyframes my-animation {
from { -webkit-transform: translateX(100%); }
to { -webkit-transform: translateX(-100%); }
}
@keyframes my-animation {
from {
-moz-transform: translateX(100%);
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
to {
-moz-transform: translateX(-100%);
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
}
}
`;
return styleElement;
}
createScrollingTextInsideTextContainer(text) {
const textContainerDiv = document.createElement('div');
textContainerDiv.id = 'scroll-container';
textContainerDiv.appendChild(this.createScrollingText(text));
return textContainerDiv;
}
createScrollingText(text) {
const textDiv = document.createElement('div');
textDiv.id = 'scroll-text';
textDiv.textContent = text;
return textDiv;
}
}
customElements.define('my-scrolling-text-v3', MyScrollingTextV3CustomElement);
<my-scrolling-text-v3 color="#0f0" text="This is the text value from my-scrolling-text-v3 element"></my-scrolling-text-v3>