I have navigation tabs which are horizontaly scrollable and my task now is to add function that if you scroll this "menu" left or right and the title in nav tab overflows it should add "..." dots to that title. Basically when you scroll to right and you stop scrolling in the middle of the word it should replace this remaining part with dots (same thing when you scroll left )
At first this menu was implemented without these dots and arrows but customers were arguing that they did not know that there were another tabs they could click (on mobile phones)
preview of figma implementation with visible right and left arrow with text overflow dots
So far all my attempts failed and I'm trying to understand it from scratch but from what I see I do not know if it's even possible ?
<div class="with-elipsis">Test paragraph with <code>ellipsis</code>. It needs quite a lot of text in order to properly test <code>text-overflow</code>.</div>
<div class="with-elipsis-scroll">Test paragraph with <code>string</code>. It needs quite a lot of text in order to properly test <code>text-overflow</code>.</div>
.with-elipsis {
width: 500px;
text-overflow: ellipsis;
border: 1px solid #000000;
white-space: nowrap;
overflow: auto;
}
.with-elipsis-scroll {
border: 1px solid #000000;
white-space: nowrap;
overflow: auto;
height: 40px;
display: flex;
overflow-x: scroll;
width: 200px;
text-overflow: ellipsis;
}
In this code sample:
I would not try to use text-overflow
for this. For one thing, it’s not designed to work on both the left and right sides.
Instead, I would solve this as per the suggestion from Dale Landry. Personally I would leave out the ellipsis and simply have an arrow or an angle bracket to indicate that scrolling is possible.
const d1 = document.querySelector('.d1')
const d2 = document.querySelector('.d2')
const updateArrowState = () => {
if (d2.scrollLeft > 0)
d1.classList.add('show-left-arrow')
else
d1.classList.remove('show-left-arrow')
if (d2.scrollLeft + d2.offsetWidth < d2.scrollWidth)
d1.classList.add('show-right-arrow')
else
d1.classList.remove('show-right-arrow')
}
d2.addEventListener('scroll', updateArrowState, {passive: true})
updateArrowState()
.d1 {
position: relative;
}
.d1::before, .d1::after {
position: absolute;
top: 0;
opacity: 0;
background: white;
transition: 250ms;
color: red;
}
.d1::before {
content: '< ... ';
left: 0;
}
.d1::after {
content: ' ... >';
right: 0;
}
.d1.show-left-arrow::before, .d1.show-right-arrow::after {
opacity: 1;
}
.unhide {
opacity: 1;
}
.d2 {
display: flex;
gap: 1em;
overflow: auto;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.d2::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera */
}
<div class="d1">
<div class="d2">
<a>One</a>
<a>Two</a>
<a>Three</a>
<a>Four</a>
<a>Five</a>
<a>Six</a>
<a>Seven</a>
<a>Eight</a>
<a>Nine</a>
<a>Ten</a>
<a>Eleven</a>
<a>Twelve</a>
<a>Thirteen</a>
<a>Fourteen</a>
<a>Fifteen</a>
<a>Sixteen</a>
<a>Seventeen</a>
<a>Eighteen</a>
<a>Nineteen</a>
<a>Twenty</a>
</div>
</div>