Styling

CommandPalette ships no styles. Style cmdk's [cmdk-*] parts and the adapter's data-cmdk-engine-* attributes from any global stylesheet. The Base UI adapter has no [cmdk-*] attributes: style its parts with the *ClassName props and the attributes below.

In a shadcn/ui project, the shadcn/ui registry item already styles the palette with your theme's tokens, so you can skip the stylesheet.

Starter stylesheet

This CSS gives a centered dialog on a dimmed overlay. It is written for the cmdk adapter with dialog:

palette.css
[cmdk-overlay] { position: fixed; inset: 0; z-index: 50; background: rgb(0 0 0 / 0.4); }
[cmdk-dialog] {
  position: fixed; top: 15vh; left: 50%; z-index: 50; transform: translateX(-50%);
  width: min(560px, calc(100vw - 32px));
}
[cmdk-root] {
  overflow: hidden; border: 1px solid #e5e7eb; border-radius: 12px;
  background: #fff; color: #111827; font: 14px/1.4 system-ui, sans-serif;
  box-shadow: 0 16px 48px rgb(0 0 0 / 0.2);
}
[cmdk-input] {
  box-sizing: border-box; width: 100%; padding: 14px 16px; border: 0;
  border-bottom: 1px solid #e5e7eb; font: inherit; font-size: 16px; outline: none;
}
[cmdk-input]:focus-visible { border-bottom-color: #6366f1; box-shadow: inset 0 -1px 0 #6366f1; }
[cmdk-list] { max-height: 320px; overflow-y: auto; padding: 8px; }
[cmdk-group-heading] { padding: 8px 8px 4px; font-size: 12px; color: #6b7280; }
[cmdk-item] { padding: 8px; border-radius: 8px; cursor: pointer; }
[cmdk-item][data-selected='true'] { background: #f3f4f6; }
[cmdk-item][data-disabled='true'] { opacity: 0.5; cursor: default; }
[data-cmdk-engine-item] { display: flex; align-items: center; gap: 8px; }
[data-cmdk-engine-item-content] { display: flex; flex: 1; flex-direction: column; }
[data-cmdk-engine-item-description] { font-size: 12px; color: #6b7280; }
[data-cmdk-engine-item-shortcut] kbd {
  margin-left: 4px; padding: 0 6px; border: 1px solid #e5e7eb; border-radius: 4px;
  font: inherit; font-size: 12px;
}
[data-cmdk-engine-empty],
[data-cmdk-engine-loading] { padding: 16px; text-align: center; color: #6b7280; }

The accent underline on [cmdk-input]:focus-visible replaces the outline the input drops, so keyboard users can see where focus is. Keep a focus style if you restyle the input.

With Tailwind

With Tailwind (v3 or v4), @apply the same utilities to the same selectors in your main CSS file:

css
[cmdk-overlay] { @apply fixed inset-0 z-50 bg-black/40; }
[cmdk-dialog] { @apply fixed left-1/2 top-[15vh] z-50 w-[min(560px,calc(100vw-32px))] -translate-x-1/2; }
[cmdk-root] { @apply overflow-hidden rounded-xl border border-gray-200 bg-white text-sm text-gray-900 shadow-2xl; }
[cmdk-input] { @apply w-full border-0 border-b border-gray-200 px-4 py-3.5 text-base outline-none focus-visible:border-indigo-500 focus-visible:shadow-[inset_0_-1px_0_#6366f1]; }
[cmdk-list] { @apply max-h-80 overflow-y-auto p-2; }
[cmdk-group-heading] { @apply px-2 pb-1 pt-2 text-xs text-gray-500; }
[cmdk-item] { @apply cursor-pointer rounded-lg p-2 data-[selected=true]:bg-gray-100 data-[disabled=true]:opacity-50; }
[data-cmdk-engine-item] { @apply flex items-center gap-2; }
[data-cmdk-engine-item-content] { @apply flex flex-1 flex-col; }
[data-cmdk-engine-item-description] { @apply text-xs text-gray-500; }
[data-cmdk-engine-item-shortcut] kbd { @apply ml-1 rounded border border-gray-200 px-1.5 font-sans text-xs; }
[data-cmdk-engine-empty], [data-cmdk-engine-loading] { @apply p-4 text-center text-gray-500; }

Class name props

To style per instance instead, pass class names. They reach these parts:

Propcmdk adapterBase UI adapter
className[cmdk-root]A wrapper div around the breadcrumbs, input, list and footer
inputClassName[cmdk-input]The input
listClassName[cmdk-list]The list
itemClassName[cmdk-item]Each option
groupClassName[cmdk-group]Each group
emptyClassName[cmdk-empty]The empty-state element, only while it shows
overlayClassName[cmdk-overlay]The dialog backdrop
contentClassName[cmdk-dialog]The dialog popup

Item states

Statecmdk adapterBase UI adapter
Highlighted item[cmdk-item][data-selected="true"][role="option"][data-highlighted]
Disabled item[cmdk-item][data-disabled="true"][role="option"][data-disabled]

Markup inside each item

Both adapters render the same default markup inside each item, so CSS written against these attributes carries over when you switch adapters:

AttributeElement
data-cmdk-engine-itemThe wrapper for one row
data-cmdk-engine-iconThe icon (hidden from assistive technology)
data-cmdk-engine-item-contentWraps the label and the description
data-cmdk-engine-item-labelThe label
data-cmdk-engine-item-descriptionThe description
data-cmdk-engine-item-shortcutThe shortcut keys, each one a <kbd>
data-cmdk-engine-item-chevronThe chevron on an item that has children
data-cmdk-engine-emptyThe "no results" text
data-cmdk-engine-loadingThe loading text while async sources load
data-cmdk-engine-breadcrumbsThe trail shown inside a sub-menu
data-cmdk-engine-breadcrumb-backThe back button in the trail
data-cmdk-engine-breadcrumbOne crumb in the trail
data-cmdk-engine-breadcrumb-separatorThe separator between crumbs

The cmdk adapter renders the empty state and the loading row right after the results list, not inside it, because a list box may only hold groups and options. Style them with [cmdk-empty] and [cmdk-loading] (or the data-cmdk-engine-* attributes above) directly, not as list descendants such as [cmdk-list] [cmdk-empty]. The Base UI adapter already worked this way.

cmdk documents its parts in Parts and styling and has drop-in stylesheets. For the Base UI adapter, see its notes on the Adapters page.