8pt

Compare Table

Compare Table•Data display
Overview

An Us vs the default comparison table: our column has a soft highlight, checkmarks light up row by row as it scrolls into view, and hovering a row brightens it for easy reading.

Taken from the page template Nook Mac App Website. Use it on its own, or combine it with the other components from the same template to rebuild the full page.

Plain HTML, CSS and a little vanilla JS, with no framework dependency. Copy the prompt into Claude Code, Cursor, Trae or Codex and the model adds Compare Table to your project in your colors.

Where to use it

Dashboards, data tables, chart cards, comparison tables and status panels.

Install

With Builder, install it with the 8pt CLI or call it directly from an editor connected to 8pt MCP.

$ npm i -g @8pt-dev/cli && 8pt add compare-table
mcp › Use 8pt MCP to call get_component("compare-table")

Code

Source for Compare Table. Motion uses only transform and opacity and respects the Reduce motion setting.

<div class="x-vs">
  <div class="x-vs__in" style="width:700px;height:340px">
    <table>
      <thead><tr><th scope="col">To do</th><th scope="col"><span class="x-vs__me">Nook</span></th><th scope="col">Finder</th></tr></thead>
      <tbody>
        <tr><th scope="row">Two folders side by side</th><td>⌘D Dual pane; F5 to copy, F6 to move</td><td>Open two windows and arrange them by hand</td></tr>
        <tr><th scope="row">Project files scattered everywhere</th><td>One workspace page, files stay where they are</td><td>Tags, or a window per folder</td></tr>
        <tr><th scope="row">Reclaim disk space</th><td>Smart cleanup: grouped suggestions, undoable</td><td>Buried in System Settings, far from your files</td></tr>
        <tr><th scope="row">Downloads folder is a mess</th><td>Tidy previews first, then files into folders</td><td>Can sort and group, but moving files is on you</td></tr>
        <tr><th scope="row">Folder size</th><td>Shown for every folder, computed in the background</td><td>Off by default, list view only</td></tr>
        <tr><th scope="row">Git Projects</th><td>The path bar shows the branch and uncommitted changes</td><td>Hidden</td></tr>
      </tbody>
…
.x-vs{position:relative;flex:none}
.x-vs__in{position:absolute;left:0;top:0;transform-origin:0 0;border-radius:20px;overflow:hidden;background:var(--d-card,#14141c);border:1px solid var(--d-line,rgba(255,255,255,.1));box-shadow:0 14px 34px rgba(0,0,0,.08);font-family:var(--d-font,system-ui,sans-serif);color:var(--d-fg,#fff);box-sizing:border-box}
.x-vs table{width:100%;height:100%;border-collapse:collapse;text-align:left;font-size:13.5px}
.x-vs th,.x-vs td{padding:11px 18px;border-top:1px solid var(--d-line,rgba(255,255,255,.08));vertical-align:middle}
.x-vs thead th{border-top:0;font-size:12.5px;font-weight:600;color:var(--d-muted,#9b9ba8)}
.x-vs tbody th{width:24%;font-weight:600;white-space:nowrap}
.x-vs td{color:var(--d-muted,#9b9ba8);transition:background .2s,color .2s}
.x-vs td:nth-child(2){background:color-mix(in srgb,var(--d-accent,#4D74FF) 7%,transparent);color:var(--d-fg,#fff)}
.x-vs td:nth-child(2)::before{content:"✓";display:inline-block;margin-right:8px;color:var(--d-accent,#4D74FF);font-weight:700;opacity:0;transform:scale(.4);transition:opacity .3s,transform .45s cubic-bezier(.34,1.56,.64,1);transition-delay:calc(var(--i,0) * 90ms)}
.x-vs.in td:nth-child(2)::before{opacity:1;transform:none}
.x-vs tbody tr:hover th,.x-vs tbody tr:hover td{background:color-mix(in srgb,var(--d-fg,#fff) 4%,transparent)}
.x-vs tbody tr:hover td:nth-child(2){background:color-mix(in srgb,var(--d-accent,#4D74FF) 14%,transparent)}
…
const init = (root) => {
  const fit = (box, W, H) => {
    const inner = box.firstElementChild;
    const run = () => {
      const cs = getComputedStyle(root);
      const aw = root.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight);
      const ah = root.clientHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom);
      if (aw <= 0 || ah <= 0) return;
      const s = Math.max(0.2, Math.min(aw / W, ah / H, 1));
      box.style.width = W * s + 'px'; box.style.height = H * s + 'px'; inner.style.transform = `scale(${s})`;
    };
    const ro = new ResizeObserver(run); ro.observe(root); run();
…
Subscribe to Builder to see the full source.See pricing

Other components from this template

View all

Mac File Window

Disk Cleanup Panel

Glass Folder

File Preview Cards

Shortcut Keycaps

Ticket Pricing

Floating Folders CTA

More data display components

View all

Agent Chat Window

Mac File Window

Disk Cleanup Panel

Shortcut Keycaps

Orbit Timeline

Avatar Stack

Kanban Column

Code Diff Card

More components

View all

AI Prompt Composer

Film Strip Carousel

Auto Tab Showcase

Media Bento Grid

Model Pill Marquee

Director Art Cards

Glass Folder

File Preview Cards

Keep exploring