Style any component or any part of it with className, classNames, CSS or Tailwind.
Every krz-ui component can be restyled from your side — the whole component, any part of it, or just its colors. Use whichever fits your stack: plain CSS, CSS modules, Tailwind, or inline styles.
The same props on every component
<Button className="w-full" style={{ letterSpacing: 1 }} data-testid="save" ref={buttonRef}>
Save
</Button>Changing colors with className
Give the component a class and set background and color — it wins in every state, including hover. Add your own :hover rule if you want a hover color.
<Button className="btn-success">Approve</Button>.btn-success {
background: #16a34a;
color: #fff;
}
.btn-success:hover {
background: #15803d;
}Use the background shorthand rather than background-color: some variants use a gradient, and the shorthand replaces it.
Where the props go
For most components everything lands on the outer element. A few components put native attributes somewhere more useful:
Styling inner parts with classNames
Pass classNames to reach any part of a component — including parts rendered in a portal, like a modal's backdrop. Each component's part names are listed in its API Reference.
<Input
label="Email"
className="max-w-sm"
classNames={{ label: "uppercase text-xs", control: "rounded-full", input: "font-mono" }}
/>
<Modal
open={open}
onClose={close}
title="Invite"
classNames={{ overlay: "backdrop-blur-md", footer: "justify-between" }}
/>
<Table
data={invoices}
rowKey={(r) => r.id}
columns={columns}
rowClassName={(r) => (r.overdue ? "bg-red-50" : undefined)}
/>Targeting parts from CSS
Every part also has a stable krz-* class, and interactive states are exposed as data-* attributes, so you can style them from any stylesheet:
/* Every primary button */
.krz-btn--primary { border-radius: 999px; }
/* Only inside your settings page */
.settings .krz-card { box-shadow: none; }
/* States */
.krz-accordion__item[data-state="open"] { background: #fafafa; }
.krz-tabs__tab[data-state="active"] { font-weight: 700; }
.krz-field[data-invalid] .krz-field__label { color: crimson; }To change colors, radius or fonts everywhere at once, override the --krz-* CSS variables — see Theming.
Using Tailwind CSS
Tailwind v4 puts its utilities in a CSS cascade layer, and layered styles always lose to unlayered ones. Import the layered stylesheet and declare the layer order once, so your utility classes always win over krz-ui's defaults:
@layer theme, base, krz-ui, components, utilities;
@import "tailwindcss";
@import "krz-ui/styles.layer.css";<Button className="rounded-none px-8">Tailwind wins</Button>Gradient backgrounds: primary buttons, primary badges, switches and progress bars use a gradient, which is a background-image. Tailwind's bg-* color utilities only set background-color, so add bg-none to remove the gradient first:
<Button className="bg-none bg-emerald-600 hover:bg-emerald-700">Solid green</Button>Or keep a gradient and change its colors for just that element:
<Button className="[--krz-gradient:linear-gradient(135deg,#059669,#10b981)]">Green gradient</Button>(To recolor every component at once, set --krz-primary and --krz-primary-2 on :root — see Theming.)
Plain CSS without specificity fights
With the default krz-ui/styles.css, a single-class rule of yours may lose to a more specific krz-ui rule. If you'd rather have any of your rules win, import krz-ui/styles.layer.css instead — every unlayered rule you write then overrides krz-ui automatically.
import "krz-ui/styles.layer.css";Note that this also applies to broad page styles (e.g. button { background: none }), so keep global resets in their own layer if you use them.
Making your own variants
Because every component forwards its ref and props, wrapping one keeps everything working:
import { forwardRef } from "react";
import { Button, cx, type ButtonProps } from "krz-ui";
export const BrandButton = forwardRef<HTMLButtonElement, ButtonProps>(function BrandButton(
{ className, ...props },
ref,
) {
return <Button ref={ref} className={cx("brand-button", className)} {...props} />;
});