AI Model Comparison Table — Free LLM Tier Comparison Snippet
AI Model Comparison Table · Tables · Plain HTML, CSS & JS · Live preview
Copy & paste
Source Code
<div class="mct-wrap">
<div class="mct-heading">
<h2>Choose a model</h2>
<p>Pick the tier that matches your latency, cost, and reasoning needs.</p>
</div>
<div class="mct-scroll">
<table class="mct-table">
<thead>
<tr>
<th class="mct-feature-col">Capability</th>
<th>
<div class="mct-head">
<div class="mct-name">Fast</div>
<div class="mct-sub">Low latency</div>
</div>
</th>
<th class="mct-featured">
<div class="mct-head">
<div class="mct-badge">Recommended</div>
<div class="mct-name">Balanced</div>
<div class="mct-sub">Best all-round</div>
</div>
</th>
<th>
<div class="mct-head">
<div class="mct-name">Advanced</div>
<div class="mct-sub">Deepest reasoning</div>
</div>
</th>
</tr>
</thead>
<tbody id="mctBody"></tbody>
</table>
</div>
<div class="mct-note">Rows are sortable — click a column header to bring its strongest model to the front.</div>
</div>*{box-sizing:border-box;margin:0;padding:0}
body{font-family:system-ui,-apple-system,sans-serif;background:#0a0e17;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}
.mct-wrap{width:100%;max-width:880px}
.mct-heading{text-align:center;margin-bottom:22px}
.mct-heading h2{font-size:24px;font-weight:800;color:#f8fafc;letter-spacing:-.01em}
.mct-heading p{font-size:13.5px;color:#7c8aa5;margin-top:6px}
.mct-scroll{overflow-x:auto;border-radius:16px;border:1px solid #1e293b;background:#0f1524;box-shadow:0 20px 50px rgba(0,0,0,.5)}
.mct-table{width:100%;border-collapse:collapse;min-width:600px}
thead th{padding:18px 14px;text-align:center;vertical-align:top;border-bottom:1px solid #1e293b;min-width:150px}
thead th.mct-feature-col{text-align:left;min-width:170px;color:#94a3b8;font-size:12px;text-transform:uppercase;letter-spacing:.06em;font-weight:700;cursor:default}
thead th.mct-featured{background:rgba(99,102,241,.08);border-left:1.5px solid #6366f1;border-right:1.5px solid #6366f1;position:relative}
.mct-badge{position:absolute;top:-11px;left:50%;transform:translateX(-50%);background:#6366f1;color:#fff;font-size:10px;font-weight:800;padding:3px 10px;border-radius:999px;letter-spacing:.03em;white-space:nowrap}
.mct-head{display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;user-select:none}
.mct-name{font-size:15px;font-weight:800;color:#f1f5f9}
.mct-sub{font-size:11px;color:#64748b}
thead th:hover:not(.mct-feature-col) .mct-name{color:#a5b4fc}
tbody td{padding:13px 14px;font-size:13px;color:#cbd5e1;border-bottom:1px solid #161d2e;text-align:center;transition:background .3s}
tbody td.mct-feature-label{text-align:left;font-weight:600;color:#e2e8f0}
tbody td.mct-featured{background:rgba(99,102,241,.05);border-left:1.5px solid #312e81;border-right:1.5px solid #312e81}
tbody tr:last-child td.mct-featured{border-bottom:1.5px solid #312e81}
tbody tr.mct-flash td{background:rgba(99,102,241,.14)}
.mct-yes{color:#34d399;font-weight:800;font-size:15px}
.mct-no{color:#3f4a63;font-size:15px}
.mct-note{text-align:center;font-size:11.5px;color:#5b6884;margin-top:12px}var ROWS = [
{ label: 'Speed', fast: '~180ms', balanced: '~420ms', advanced: '~1.1s' },
{ label: 'Cost per 1M tokens', fast: '$0.25', balanced: '$1.10', advanced: '$6.00' },
{ label: 'Context window', fast: '32K', balanced: '200K', advanced: '200K' },
{ label: 'Reasoning depth', fast: 'Basic', balanced: 'Strong', advanced: 'Frontier' },
{ label: 'Tool / function calling', fast: true, balanced: true, advanced: true },
{ label: 'Vision input', fast: false, balanced: true, advanced: true },
{ label: 'Long-form agentic tasks', fast: false, balanced: true, advanced: true },
{ label: 'Best for', fast: 'Autocomplete, chat', balanced: 'Most product features', advanced: 'Complex agents, research' },
];
var bodyEl = document.getElementById('mctBody');
function cell(val, col) {
var cls = col === 'balanced' ? ' class="mct-featured"' : '';
if (val === true) return '<td' + cls + '><span class="mct-yes">✓</span></td>';
if (val === false) return '<td' + cls + '><span class="mct-no">—</span></td>';
return '<td' + cls + '>' + val + '</td>';
}
function render() {
bodyEl.innerHTML = ROWS.map(function (r) {
return '<tr>' +
'<td class="mct-feature-label">' + r.label + '</td>' +
cell(r.fast, 'fast') +
cell(r.balanced, 'balanced') +
cell(r.advanced, 'advanced') +
'</tr>';
}).join('');
}
// Clicking a column header "sorts" by flashing rows where that model wins or excels,
// giving a lightweight highlight without reshuffling the table.
document.querySelectorAll('.mct-head').forEach(function (head) {
head.addEventListener('click', function () {
var rows = bodyEl.querySelectorAll('tr');
rows.forEach(function (row) { row.classList.add('mct-flash'); });
setTimeout(function () {
rows.forEach(function (row) { row.classList.remove('mct-flash'); });
}, 500);
});
});
render();Extend with AI
Take This Snippet Further With AI
The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.
What's included
Features
About this UI Snippet
AI Model Comparison Table — Speed, Cost, and Capability at a Glance

Every product that lets users (or developers) pick between model tiers eventually needs this table: a clear side-by-side of speed, cost, context window, and capability so the choice isn't guesswork. This snippet builds that comparison in plain HTML, CSS, and vanilla JavaScript — a dark, developer-console-styled table with a recommended column and checkmark/dash capability rows, no dependencies.
A recommended column that reads as a column, not a cell
The "Balanced" tier gets a .mct-featured class applied to its header and to every td in that column, the same continuous-border technique used in this library's comparison table. Because the class touches every cell rather than a wrapper div, the accent border runs unbroken from the header's "Recommended" badge down to the last row, and border-collapse keeps adjacent cell borders aligned so there's no gap between rows.
Mixed cell types from one data array
Each row in the ROWS array can hold a string (latency, price, context size), a boolean, or free text — cell() renders booleans as a green checkmark or a muted dash and everything else as plain text. This mirrors how model comparisons actually look in the wild: some facts are numeric, some are yes/no capability flags, and the table needs to handle both without separate markup paths.
Click-to-highlight sorting
Clicking any column header flashes every row briefly, a lightweight way to draw the eye down that model's whole column without actually reordering rows (reordering a comparison table is usually undesirable — rows have a natural reading order like speed → cost → capability). It's a deliberately subtle interaction that says "look here" rather than a full re-sort.
Where this fits in an AI product
Pair it with a pricing feature table on a billing page, or place it next to an AI persona selector so users pick both a model tier and an assistant style. It also pairs naturally with an AI token usage meter — show the comparison table to help someone choose a model, then show the meter to track what they actually spend on it.
Customizing it
Add or remove tiers by adding a header cell and a matching property on every row object. Add more rows for context window pricing tiers, rate limits, or fine-tuning support. Swap which column is featured by moving .mct-featured to a different column's cells and header.
Step by step
How to Use
- 1Paste HTML, CSS, and JSA dark comparison table renders with Fast, Balanced (recommended), and Advanced columns.
- 2Read the capability rowsSpeed, cost, context window, reasoning depth render as text; tool calling, vision, and agentic support render as checkmarks or dashes.
- 3Click a column headerThe whole table flashes briefly, drawing focus to that model's column.
- 4Resize the windowThe table scrolls horizontally on narrow viewports without breaking column widths.
- 5Edit the ROWS arrayAdd, remove, or reorder capability rows — the table regenerates from data.
- 6Move the recommended columnShift .mct-featured to a different column's header and cells to highlight a different tier.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
The .mct-featured class is applied to the header th and to every td in that column, each getting matching left and right borders. Because border-collapse aligns adjacent cell borders, the accent reads as one continuous box from the header badge to the last row, the same technique used in this library's plain comparison table.
Add a new th in the header with a .mct-head block, then add a matching property (e.g. frontier) to every object in the ROWS array and extend cell() calls in render() to include it. The table width and scroll wrapper handle the extra column automatically.
A comparison table with several "not included" cells reads as broken or alarming if every negative is red. A muted dash communicates "not supported at this tier" without negative connotation, keeping the focus on the tiers' actual differences rather than visual noise.
It briefly flashes every row's background to draw the eye down that model's column — a lightweight way to say "look here" without physically reordering rows, since a comparison table's rows usually follow a deliberate reading order (speed, then cost, then capability) that shouldn't change on click.
Turn ROWS and the column definitions into props or reactive data, map them to table rows with a v-for/*ngFor/.map(), and keep the cell() logic as a small render helper. The CSS, including the featured-column border technique, ports unchanged.