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;
}