JSFiddle - React, Tailwind, and code Playground
by stitot
HTML
<table class="tbl">
<thead>
<tr>
<!-- LEFT ALIGNED -->
<th class="hdr align-left">
<div class="hdr-inner">
<span class="hdr-text">V ery long left aligned header text goes hereery long left aligned header text goes hereery long left aligned header text goes hereery long left aligned header text goes here</span>
<span class="icon-box">
<button>✏️</button>
<button>🗑️</button>
<button>⋮</button>
</span>
</div>
</th>
<!-- CENTER ALIGNED -->
<th class="hdr align-center">
<div class="hdr-inner">
<span class="hdr-text">Centered header</span>
<span class="icon-box">
<button>✏️</button>
<button>⋮</button>
</span>
</div>
</th>
<!-- RIGHT ALIGNED -->
<th class="hdr align-right">
<div class="hdr-inner">
<span class="hdr-text">Right aligned header text can also be long</span>
<span class="icon-box">
<button>✏️</button>
<button>🗑️</button>
<button>⋮</button>
</span>
</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
CSS
.tbl {
width: 100%;
border-collapse: collapse;
table-layout: fixed; /* important: keeps column widths stable */
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.tbl th,
.tbl td {
border: 1px solid #ccc;
}
/* Normal table header cell */
.hdr {
padding: 0; /* padding goes on inner wrapper */
white-space: nowrap;
overflow: hidden;
}
/* Inner layout: text | icons */
.hdr-inner {
display: grid;
grid-template-columns: minmax(0, 1fr) auto; /* text | icons */
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0.75rem;
overflow: hidden; /* clip text+icons at cell edge */
}
/* Text that can truncate */
.hdr-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Alignment variants */
.align-left .hdr-text { text-align: left; }
.align-center .hdr-text { text-align: center; }
.align-right .hdr-text { text-align: right; }
/* Icon container:
- starts at max-width: 0 (no space taken)
- on hover grows, taking space from text
*/
.icon-box {
display: flex;
gap: 0.25rem;
justify-content: flex-end;
max-width: 0; /* hidden, no width at rest */
overflow: hidden; /* clip icons during slide-in */
transition: max-width 0.2s ease-out;
}
/* Icons themselves slide in */
.icon-box > * {
flex: 0 0 auto;
transform: translateX(100%);
opacity: 0;
transition: transform 0.2s ease-out, opacity 0.2s ease-out;
}
/* On hover: reveal space for icons + slide them in */
.hdr:hover .icon-box {
max-width: 6rem; /* adjust depending on how many icons max */
}
.hdr:hover .icon-box > * {
transform: translateX(0);
opacity: 1;
}
/* Simple button reset */
.icon-box button {
border: none;
background: none;
padding: 0;
cursor: pointer;
font-size: 0.9rem;
outline: 3px solid #000;
}