I am trying to put three elements that contain text on one line using only HTML tags and the style property. One of the elements is a counter that is counting up. Unfortunately the elements are too far from each other in my solution as I am trying to get them to stick together seamlessly. Cold you please help me out?
FYI: I have read several posts here on SO before posting and tried my best to make a solution below.
<span style="display: flex; justify-content: space-between;">
<span> There is </span>
<strong><span class="counter" style="font-family:Courier New; style:bold" data-target="100">0</span></strong>
<span>kg spam.</span>
</span>
<script>
const counters = document.querySelectorAll('.counter');
for(let n of counters) {
const updateCount = () => {
const target = n.getAttribute('data-target');
const count = n.innerText;
const speed = 5000; // change animation speed here
const inc = target / speed;
if(count < target) {
n.innerText = Math.ceil(count inc);
setTimeout(updateCount, 1);
} else {
n.innerText = target;
}
}
updateCount();
}
</script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Removing justify-content: space-between;
and adding padding to the left and right of the counter should work:
<span style="display: flex;">
<span>There is </span>
<strong><span class="counter" style="font-family: Courier New; style: bold; padding: 0 0.2em" data-target="100">0</span></strong>
<span> kg spam.</span>
</span>
<script>
const counters = document.querySelectorAll('.counter');
for(let n of counters) {
const updateCount = () => {
const target = n.getAttribute('data-target');
const count = n.innerText;
const speed = 5000; // change animation speed here
const inc = target / speed;
if(count < target) {
n.innerText = Math.ceil(count inc);
setTimeout(updateCount, 1);
} else {
n.innerText = target;
}
}
updateCount();
}
</script>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
You might need to tweak the margin size, but this is the best idea I came up with.
CodePudding user response:
If your goal is to form a sentence then you don't need these many spans
they are all inline elements. I think one span is enough:
<style>
.counter {
style="font-family:Courier New;"
}
</style>
<span>
There is <em class="counter" data-target="100">0</em>kg spam.
And <em class="counter" data-target="200">0</em> buns.
</span>
<script>
const counters = document.querySelectorAll('.counter');
for (let n of counters) {
const updateCount = () => {
const target = n.getAttribute('data-target');
const count = n.innerText;
const speed = 5000; // change animation speed here
const inc = target / speed;
if (count < target) {
n.innerText = Math.ceil(count inc);
setTimeout(updateCount, 15);
} else {
n.innerText = target;
}
}
updateCount();
}
</script>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If screen width reduces the line will wrap automatically. Same text with 100px wide box wraps perfectly. You don't have to do anything:
<style>
.counter {
style="font-family:Courier New;"
}
div{
width: 100px;
border: 1px solid gray;
}
</style>
<div><span>
There is <em class="counter" data-target="100">0</em>kg spam.
And <em class="counter" data-target="200">0</em> buns.
</span></div>
<script>
const counters = document.querySelectorAll('.counter');
for (let n of counters) {
const updateCount = () => {
const target = n.getAttribute('data-target');
const count = n.innerText;
const speed = 5000; // change animation speed here
const inc = target / speed;
if (count < target) {
n.innerText = Math.ceil(count inc);
setTimeout(updateCount, 15);
} else {
n.innerText = target;
}
}
updateCount();
}
</script>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>