Skip to content

Styling & Theming

The default look is ugly. That's the whole point.

Black borders, black text, white background, zero border radius. It looks like an unstyled HTML table from 2003. And that makes it trivially easy to restyle to match whatever Figma your designer threw at you.

Here are four layers of customization, from simplest to most control.

Layer 1: Theme file

Import a pre-built theme. Right now there's just plain (more coming):

js
import 'mundane-ui/css/plain.css'

This gives you the structural CSS (layout, positioning) plus the default visual styles. You'll always import this — it's the foundation.

Layer 2: CSS custom properties

The fastest way to make it look different. Every visual property is a CSS variable:

css
.mu-datatable {
  --mu-color-border: #e2e8f0;
  --mu-color-bg-header: #f8fafc;
  --mu-color-bg-hover: #eff6ff;
  --mu-color-accent: #2563eb;
  --mu-border-radius: 6px;
}

That's 5 lines and suddenly it looks like a completely different component. No !important, no specificity battles.

Full list of CSS variables

VariableDefaultWhat it does
--mu-font-familysystem stackThe font
--mu-font-size14pxBase text size
--mu-font-size-sm12pxSmall text (info, pagination)
--mu-line-height1.5Line height
--mu-color-text#000Primary text
--mu-color-text-secondary#666Muted text
--mu-color-bg#fffBackground
--mu-color-bg-header#fffHeader row background
--mu-color-bg-hover#f5f5f5Row hover
--mu-color-bg-even#fafafaAlternating row
--mu-color-border#000All borders
--mu-color-accent#000Active states (current page, sorted column)
--mu-color-loading-bgrgba(255,255,255,0.8)Loading overlay
--mu-spacing-xs through --mu-spacing-xl4px to 24pxSpacing scale
--mu-border-width1pxBorder thickness
--mu-border-radius0pxCorner rounding
--mu-transition150ms easeHover/state transitions
--mu-shadownoneBox shadow
--mu-input-height32pxSearch input / select height

Layer 3: Direct CSS class overrides

Every element has a BEM class. Target them directly:

css
.mu-datatable__header-cell {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 11px;
}

.mu-datatable__cell {
  padding: 16px 20px;
}

.mu-datatable__row:hover {
  background: #dbeafe;
}

Full class list in the Types reference.

Layer 4: Tailwind via config

If you're a Tailwind person, pass utility classes directly in the config object. No CSS files needed:

js
DataTable.create({
  // ...
  classes: {
    root: 'rounded-xl border border-gray-200 shadow-sm',
    headerCell: 'bg-gray-50 text-xs font-semibold uppercase tracking-wide',
    row: 'hover:bg-blue-50 transition-colors',
    cell: 'px-4 py-3 text-sm',
    pageButtonActive: 'bg-blue-600 text-white rounded',
  },
})

These classes are added alongside the BEM classes, not replacing them. So structural CSS (layout, flex, positioning) keeps working while your Tailwind classes handle the visuals.

Every element has a corresponding key in the classes config. See the full list.

Live demo

Same component. Zero code changes. Just CSS. This is what it looks like as a SaaS customer table — rounded card container, gray header with uppercase labels, colored status badges, orange accent on sort and pagination. The kind of table you'd see in Stripe or Linear:

Same component as the ugly black-bordered default. Just CSS. No !important. No crying at 2am.

MIT Licensed. Built with frustration and love.