AI CSS Animations

File Row Hover Actions

A file list where hovering a row swaps its size for a set of action buttons that slide in one after another. The actions overlay the size column, so the row never changes width.

Also known as: show buttons on hover css, list row actions on hover, file list hover.

  • PDF Q3 report.pdf 2.4 MB
  • FIG Brand kit.fig 18 MB
  • DOC Launch notes.docx 86 KB

HTML

<ul class="hfx-file-row-actions">
  <li>
    <span class="hfx-file-row-actions-type">PDF</span>
    <span class="hfx-file-row-actions-name">Q3 report.pdf</span>
    <span class="hfx-file-row-actions-meta">2.4 MB</span>
    <span class="hfx-file-row-actions-tools"><button aria-label="Download"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19.5h14"/></svg></button><button aria-label="Share"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12M7.5 7.5 12 3l4.5 4.5M5 13v5.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V13"/></svg></button><button aria-label="Delete"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 12.5A1.5 1.5 0 0 0 8.5 21h7a1.5 1.5 0 0 0 1.5-1.5L18 7M9 7V4.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5V7"/></svg></button></span>
  </li>
  <li>
    <span class="hfx-file-row-actions-type" style="--hue: 270deg">FIG</span>
    <span class="hfx-file-row-actions-name">Brand kit.fig</span>
    <span class="hfx-file-row-actions-meta">18 MB</span>
    <span class="hfx-file-row-actions-tools"><button aria-label="Download"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19.5h14"/></svg></button><button aria-label="Share"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12M7.5 7.5 12 3l4.5 4.5M5 13v5.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V13"/></svg></button><button aria-label="Delete"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 12.5A1.5 1.5 0 0 0 8.5 21h7a1.5 1.5 0 0 0 1.5-1.5L18 7M9 7V4.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5V7"/></svg></button></span>
  </li>
  <li>
    <span class="hfx-file-row-actions-type" style="--hue: 150deg">DOC</span>
    <span class="hfx-file-row-actions-name">Launch notes.docx</span>
    <span class="hfx-file-row-actions-meta">86 KB</span>
    <span class="hfx-file-row-actions-tools"><button aria-label="Download"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19.5h14"/></svg></button><button aria-label="Share"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12M7.5 7.5 12 3l4.5 4.5M5 13v5.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V13"/></svg></button><button aria-label="Delete"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 12.5A1.5 1.5 0 0 0 8.5 21h7a1.5 1.5 0 0 0 1.5-1.5L18 7M9 7V4.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5V7"/></svg></button></span>
  </li>
</ul>

CSS

.hfx-file-row-actions {
  --c: var(--hfx-color, #3b82f6);
  font-size: var(--hfx-size, 16px);
  width: 19em;
  margin: 0;
  padding: 0.3em;
  list-style: none;
  border: 1px solid color-mix(in srgb, var(--c) 22%, transparent);
  border-radius: 0.9em;
  font-family: system-ui, sans-serif;
}
.hfx-file-row-actions li {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75em;
  padding: 0.45em 0.55em;
  border-radius: 0.55em;
  transition: background-color 0.2s ease;
}
.hfx-file-row-actions-type {
  flex: none;
  display: grid;
  place-items: center;
  width: 3.4em;
  height: 3.4em;
  border-radius: 0.7em;
  background: color-mix(in srgb, var(--c) 16%, transparent);
  color: var(--c);
  font-size: 0.62em;
  font-weight: 800;
  letter-spacing: 0.04em;
  filter: hue-rotate(var(--hue, 0deg));
}
.hfx-file-row-actions-name {
  flex: 1;
  overflow: hidden;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hfx-file-row-actions-meta {
  color: color-mix(in srgb, currentColor 55%, transparent);
  font-size: 0.8em;
  transition: opacity 0.2s ease, transform 0.25s ease;
}
.hfx-file-row-actions-tools {
  position: absolute;
  top: 50%;
  right: 0.4em;
  display: flex;
  gap: 0.1em;
  transform: translateY(-50%);
}
.hfx-file-row-actions-tools button {
  display: grid;
  place-items: center;
  width: 1.9em;
  height: 1.9em;
  padding: 0;
  border: 0;
  border-radius: 0.45em;
  background: none;
  color: color-mix(in srgb, currentColor 70%, transparent);
  cursor: pointer;
  opacity: 0;
  transform: translateX(0.7em);
  transition: opacity 0.2s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.15s ease, color 0.15s ease;
}
.hfx-file-row-actions-tools svg { width: 1.05em; height: 1.05em; }
.hfx-file-row-actions li:is(:hover, :focus-within) { background: color-mix(in srgb, var(--c) 10%, transparent); }
.hfx-file-row-actions li:is(:hover, :focus-within) .hfx-file-row-actions-meta {
  opacity: 0;
  transform: translateX(-0.5em);
}
.hfx-file-row-actions li:is(:hover, :focus-within) .hfx-file-row-actions-tools button {
  opacity: 1;
  transform: none;
}
.hfx-file-row-actions li:is(:hover, :focus-within) .hfx-file-row-actions-tools button:nth-child(2) { transition-delay: 0.04s; }
.hfx-file-row-actions li:is(:hover, :focus-within) .hfx-file-row-actions-tools button:nth-child(3) { transition-delay: 0.08s; }
.hfx-file-row-actions .hfx-file-row-actions-tools button:is(:hover, :focus-visible) {
  background: color-mix(in srgb, var(--c) 18%, transparent);
  color: var(--c);
  transition-delay: 0s;
}

@media (prefers-reduced-motion: reduce) {
  .hfx-file-row-actions, .hfx-file-row-actions *, .hfx-file-row-actions::before, .hfx-file-row-actions::after, .hfx-file-row-actions *::before, .hfx-file-row-actions *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Tailwind CSS version

The same effect using Tailwind utility classes. No custom CSS or config needed.

<ul class="w-72 rounded-xl border border-blue-500/20 p-1">
  <li class="group relative flex items-center gap-3 rounded-lg px-2 py-1.5 transition-colors hover:bg-blue-500/10">
    <span class="grid h-8 w-8 place-items-center rounded-lg bg-blue-500/15 text-[10px] font-extrabold text-blue-500">PDF</span>
    <span class="flex-1 truncate font-medium">Q3 report.pdf</span>
    <span class="text-xs text-gray-500 transition group-hover:-translate-x-2 group-hover:opacity-0">2.4 MB</span>
    <span class="absolute right-1.5 top-1/2 flex -translate-y-1/2 gap-0.5">
      <button aria-label="Download" class="grid h-7 w-7 translate-x-2 place-items-center rounded-md opacity-0 transition duration-300 hover:bg-blue-500/20 hover:text-blue-500 group-hover:translate-x-0 group-hover:opacity-100"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4v11M7.5 10.5 12 15l4.5-4.5M5 19.5h14"/></svg></button>
      <button aria-label="Share" class="grid h-7 w-7 translate-x-2 place-items-center rounded-md opacity-0 transition delay-[40ms] duration-300 hover:bg-blue-500/20 hover:text-blue-500 group-hover:translate-x-0 group-hover:opacity-100"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3v12M7.5 7.5 12 3l4.5 4.5M5 13v5.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V13"/></svg></button>
      <button aria-label="Delete" class="grid h-7 w-7 translate-x-2 place-items-center rounded-md opacity-0 transition delay-[80ms] duration-300 hover:bg-blue-500/20 hover:text-blue-500 group-hover:translate-x-0 group-hover:opacity-100"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M10 11v6M14 11v6M6 7l1 12.5A1.5 1.5 0 0 0 8.5 21h7a1.5 1.5 0 0 0 1.5-1.5L18 7M9 7V4.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5V7"/></svg></button>
    </span>
  </li>
</ul>

Customizing this snippet

  • Color: set --hfx-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --hfx-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar hover effects

Sliding Pill Nav Hover Effect
Directional Underline Nav Hover Effect
Dot Indicator Nav Hover Effect
Vertical Nav Indicator Hover Effect