Table
A CSS wrapper around native <table> elements that applies pixel-art styling. Write standard HTML tables inside <px-table>.
| Name | Category | Description | Type | Default |
|---|---|---|---|---|
type | Style | Color type variant | 'primary' | 'success' | 'info' | 'warning' | 'danger' | — |
zebra | Style | Zebra stripes (alternating row highlight) | boolean | false |
stripe | Style | Alias for zebra | boolean | false |
hover | Style | Row hover highlight | boolean | false |
border | Style | Full cell borders | boolean | false |
outline | Style | Wireframe border (no fill) | boolean | false |
ghost | Style | No border, no shadow | boolean | false |
size | Size | Table size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
pinRows | Behavior | Sticky header and footer | boolean | false |
pinCols | Behavior | Sticky first column | boolean | false |
showHeader | Behavior | Whether to show table header | boolean | true |
hoverable | Behavior | Lift effect on hover | boolean | false |
default | Slot | Table content (native <table> element) | — |
Basic Usage
<template>
<px-table>
<table>
<thead>
<tr>
<th>Name</th>
<th>Class</th>
<th>Level</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sakana</td>
<td>Warrior</td>
<td>12</td>
</tr>
<tr>
<td>Pixel</td>
<td>Mage</td>
<td>8</td>
</tr>
<tr>
<td>Retro</td>
<td>Archer</td>
<td>15</td>
</tr>
</tbody>
</table>
</px-table>
</template>Zebra Stripes
Use zebra (or stripe) to alternate row backgrounds.
<template>
<px-table zebra>
<table>
<thead>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Potion</td>
<td>5</td>
<td>50g</td>
</tr>
<tr>
<td>Ether</td>
<td>3</td>
<td>100g</td>
</tr>
<tr>
<td>Phoenix Down</td>
<td>1</td>
<td>300g</td>
</tr>
<tr>
<td>Elixir</td>
<td>2</td>
<td>500g</td>
</tr>
</tbody>
</table>
</px-table>
</template>Hover Highlight
Use hover to highlight rows on mouse hover.
<template>
<px-table hover>
<table>
<thead>
<tr>
<th>Player</th>
<th>Score</th>
<th>Rank</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>9800</td>
<td>#1</td>
</tr>
<tr>
<td>Bob</td>
<td>8500</td>
<td>#2</td>
</tr>
<tr>
<td>Carol</td>
<td>7200</td>
<td>#3</td>
</tr>
</tbody>
</table>
</px-table>
</template>Full Borders
Use border to add borders to all cells.
<template>
<px-table border>
<table>
<thead>
<tr>
<th>Stat</th>
<th>Base</th>
<th>Bonus</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>STR</td>
<td>10</td>
<td>+3</td>
<td>13</td>
</tr>
<tr>
<td>DEX</td>
<td>14</td>
<td>+2</td>
<td>16</td>
</tr>
<tr>
<td>INT</td>
<td>8</td>
<td>+5</td>
<td>13</td>
</tr>
</tbody>
</table>
</px-table>
</template>Color Types
Use type to apply color variants: primary, success, warning, danger, info.
<template>
<div style="display: flex; flex-direction: column; gap: 16px">
<px-table type="primary">
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
</tbody>
</table>
</px-table>
<px-table type="success">
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
</tbody>
</table>
</px-table>
<px-table type="warning">
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
</tbody>
</table>
</px-table>
<px-table type="danger">
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
</tbody>
</table>
</px-table>
<px-table type="info">
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
</tbody>
</table>
</px-table>
</div>
</template>Size Variants
Five sizes: xs, sm, md (default), lg, xl.
<template>
<div class="demo-table-size">
<div v-for="s in sizes" :key="s">
<p>size: {{ s }}</p>
<px-table :size="s">
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>HP</td>
<td>120</td>
</tr>
<tr>
<td>MP</td>
<td>45</td>
</tr>
</tbody>
</table>
</px-table>
</div>
</div>
</template>
<script setup lang="ts">
const sizes = ['xs', 'sm', 'md', 'lg', 'xl'] as const;
</script>
<style scoped>
.demo-table-size {
display: flex;
flex-direction: column;
gap: 24px;
}
.demo-table-size p {
margin: 0 0 8px;
font-weight: 600;
}
</style>Sticky Header (Pin Rows)
Use pin-rows with a fixed max-height to make the header sticky while the body scrolls.
<template>
<px-table pin-rows style="max-height: 200px">
<table>
<thead>
<tr>
<th>Quest</th>
<th>Reward</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr v-for="i in 10" :key="i">
<td>Quest #{{ i }}</td>
<td>{{ i * 100 }}g</td>
<td>{{ i % 3 === 0 ? 'Complete' : 'Active' }}</td>
</tr>
</tbody>
</table>
</px-table>
</template>Sticky First Column (Pin Cols)
Use pin-cols with a fixed max-width to pin the first column while scrolling horizontally.
<template>
<px-table pin-cols style="max-width: 400px">
<table>
<thead>
<tr>
<th>Name</th>
<th>HP</th>
<th>MP</th>
<th>STR</th>
<th>DEX</th>
<th>INT</th>
<th>LUK</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sakana</td>
<td>120</td>
<td>40</td>
<td>15</td>
<td>10</td>
<td>8</td>
<td>12</td>
</tr>
<tr>
<td>Pixel</td>
<td>80</td>
<td>100</td>
<td>6</td>
<td>12</td>
<td>18</td>
<td>9</td>
</tr>
<tr>
<td>Retro</td>
<td>100</td>
<td>60</td>
<td>12</td>
<td>16</td>
<td>10</td>
<td>14</td>
</tr>
</tbody>
</table>
</px-table>
</template>Outline
Use outline to render a wireframe border with no fill. Combines with type for colored outlines.
<template>
<div style="display: flex; flex-direction: column; gap: 16px">
<px-table outline>
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
<tr><td>Retro</td><td>Archer</td><td>15</td></tr>
</tbody>
</table>
</px-table>
<px-table outline type="primary">
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
<tr><td>Retro</td><td>Archer</td><td>15</td></tr>
</tbody>
</table>
</px-table>
</div>
</template>Ghost
Use ghost to remove the border and shadow entirely, keeping only the internal table styling.
<template>
<div style="display: flex; flex-direction: column; gap: 16px">
<px-table ghost>
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
<tr><td>Retro</td><td>Archer</td><td>15</td></tr>
</tbody>
</table>
</px-table>
<px-table ghost type="danger" hover>
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
<tr><td>Retro</td><td>Archer</td><td>15</td></tr>
</tbody>
</table>
</px-table>
</div>
</template>Hoverable
Use hoverable to add a pixel-style lift effect on hover and press-down on click.
<template>
<div style="display: flex; flex-direction: column; gap: 16px">
<px-table hoverable type="primary">
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
<tr><td>Retro</td><td>Archer</td><td>15</td></tr>
</tbody>
</table>
</px-table>
<px-table hoverable type="success" outline>
<table>
<thead>
<tr><th>Name</th><th>Class</th><th>Level</th></tr>
</thead>
<tbody>
<tr><td>Sakana</td><td>Warrior</td><td>12</td></tr>
<tr><td>Pixel</td><td>Mage</td><td>8</td></tr>
<tr><td>Retro</td><td>Archer</td><td>15</td></tr>
</tbody>
</table>
</px-table>
</div>
</template>Combined Features
All features can be used together.
<template>
<px-table zebra hover border pin-rows size="sm" style="max-height: 240px">
<table>
<thead>
<tr>
<th>#</th>
<th>Monster</th>
<th>HP</th>
<th>EXP</th>
<th>Drop</th>
</tr>
</thead>
<tbody>
<tr v-for="m in monsters" :key="m.id">
<td>{{ m.id }}</td>
<td>{{ m.name }}</td>
<td>{{ m.hp }}</td>
<td>{{ m.exp }}</td>
<td>{{ m.drop }}</td>
</tr>
</tbody>
</table>
</px-table>
</template>
<script setup lang="ts">
const monsters = [
{ id: 1, name: 'Slime', hp: 10, exp: 5, drop: 'Gel' },
{ id: 2, name: 'Bat', hp: 15, exp: 8, drop: 'Wing' },
{ id: 3, name: 'Goblin', hp: 30, exp: 15, drop: 'Dagger' },
{ id: 4, name: 'Skeleton', hp: 45, exp: 25, drop: 'Bone' },
{ id: 5, name: 'Orc', hp: 80, exp: 40, drop: 'Axe' },
{ id: 6, name: 'Dragon', hp: 200, exp: 100, drop: 'Scale' },
{ id: 7, name: 'Demon', hp: 150, exp: 80, drop: 'Horn' },
{ id: 8, name: 'Ghost', hp: 60, exp: 30, drop: 'Ectoplasm' },
];
</script>