function isEllipsisActive(e) {
const temp = e.cloneNode(true);
temp.style.position = "fixed";
temp.style.overflow = "visible";
temp.style.whiteSpace = "nowrap";
temp.style.visibility = "hidden";
e.parentElement.appendChild(temp);
try {
const fullWidth = temp.getBoundingClientRect().width;
const displayWidth = e.getBoundingClientRect().width;
return {
offsetWidth: e.offsetWidth,
scrollWidth: e.scrollWidth,
fullWidth,
displayWidth,
truncated: fullWidth > displayWidth
};
} finally {
temp.remove();
}
}
function showSize(element, props) {
const offset = element.nextElementSibling;
const scroll = offset.nextElementSibling;
const display = scroll.nextElementSibling;
const full = display.nextElementSibling;
const truncated = full.nextElementSibling;
offset.textContent = props.offsetWidth;
scroll.textContent = props.scrollWidth;
display.textContent = props.displayWidth;
const fixed = props.fullWidth.toFixed(3);
full.innerHTML = fixed.replace(
/\.?0+$/,
"<span class='invisible'>$&</span>"
);
truncated.textContent = props.truncated ? "✔" : undefined;
}
function showAllSizes() {
const query = ".container > .row:nth-child(n + 2) > *:first-child";
for (const element of document.querySelectorAll(query)) {
showSize(element, isEllipsisActive(element));
}
}
document.addEventListener("readystatechange", () => {
if (document.readyState !== "complete") {
return;
}
const width = document.getElementById("width");
width.addEventListener("change", () => {
document.querySelector(".container").style.gridTemplateColumns =
`${width.value}px repeat(5, auto)`;
showAllSizes();
});
showAllSizes();
});
* {
font-family: 'Roboto', sans-serif;
font-size: 14px;
}
.container {
display: inline-grid;
grid-template-columns: 295px repeat(5, auto);
gap: 8px;
padding: 8px;
border: 1px solid gray;
}
.container > .row {
display: contents;
}
.container > .row > * {
display: block;
border-width: 1px;
border-style: solid;
}
.container > .row:first-child > * {
font-weight: bold;
padding: 3px;
text-align: center;
border-color: gray;
background-color: silver;
}
.container > .row:nth-child(n + 2) > *:first-child {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
border: 1px solid steelblue;
background-color: lightsteelblue;
}
.container
> .row:nth-child(n + 2)
> *:nth-child(n + 2):not(:last-child) {
border-color: khaki;
background-color: lemonchiffon;
text-align: right;
}
.container
> .row:nth-child(n + 2)
> *:last-child {
text-align: center;
}
.container
> .row:nth-child(n + 2)
> *:last-child:not(:empty) {
border-color: darkgreen;
background-color: green;
color: white;
}
.container
> .row:nth-child(n + 2)
> *:last-child:empty {
border-color: firebrick;
background-color: crimson;
}
.invisible {
visibility: hidden;
}
.test {
margin-top: 8px;
}
input[type="number"] {
margin-top: 4px;
text-align: right;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
opacity: 1;
}
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
</head>
<div class="container">
<div class="row">
<span>Text</span>
<span>Offset</span>
<span>Scroll</span>
<span>Display</span>
<span>Full</span>
<span>Truncated</span>
</div>
<div class="row">
<span>
<a>Analytics reports comes through garbled. Plsss</a>
</span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="row">
<span>
<a>Analytics reports comes through garbled. Plsssssss</a>
</span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="row">
<span>
<a>Normal text</a>
</span>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="test">
<strong>
Try changing the width up or down a few pixels.<br />
</strong>
<label>
Width:
<input type="number" id="width" value="295" min="10" max="400" size="4" />
</label>
</div>