With component libraries

Use NibCSS alongside headless libraries, design systems and third-party CSS.

1 min readv1

Headless libraries (Radix, Headless UI, Ark, Reka)#

They render unstyled, accessible primitives and accept className. Style them with useNib, or with nib where the primitive forwards unknown props to the DOM:

TSX
import * as Dialog from "@radix-ui/react-dialog";
import { useNib } from "@nibcss/react";

export function Modal({ children }: { children: React.ReactNode }) {
  const overlay = useNib("pos=fixed; ins=0; bgc=rgba(2,6,23,.5)");
  const content = useNib("pos=fixed; t=50%; l=50%; tf=translate(-50%,-50%); w=min(92vw, 480px); p=24px; bdrd=16px; bgc=#fff; dark:bgc=#0f172a");
  return (
    <Dialog.Portal>
      <Dialog.Overlay className={overlay} />
      <Dialog.Content className={content}>{children}</Dialog.Content>
    </Dialog.Portal>
  );
}

State attributes#

Libraries expose state as data-* attributes (data-state="open"). Attribute-selector modifiers are not available yet; switch styles in code instead:

TSX
const cls = useNib(open ? "bgc=#EEEFFE" : "bgc=transparent");

Next to existing CSS#

NibCSS selectors have one class of specificity, so an existing stylesheet can override them with a single class. Set preflight: false to keep an existing reset.

Next steps#