Skip to content

Styling

Style Plain Elements through Light DOM, native selectors, and stable data attributes.

Plain Elements ships without visual styles and uses Light DOM. This page covers how to treat host elements, the documented data-* hooks, state selectors, and the inline styles used for positioning.

Use display: contents when hosts should not create layout boxes:

pe-dialog,
pe-popover,
pe-tabs,
pe-accordion,
pe-collapsible,
pe-tooltip {
display: contents;
}

Target native elements and the documented data-* hooks:

dialog {
border: 0;
border-radius: 0.75rem;
padding: 1.5rem;
}
dialog::backdrop {
background: rgb(0 0 0 / 50%);
}
[data-tabs-list] {
display: flex;
gap: 0.25rem;
}
[data-tabs-trigger][data-state="active"] {
border-block-end: 2px solid currentColor;
}

Component pages list the public hooks. Do not depend on generated IDs or undocumented inline styles.

Use native selectors where possible and data-state to coordinate related elements.

[data-collapsible-trigger][data-state="open"] .icon {
rotate: 180deg;
}
[data-popover-content]:popover-open {
display: grid;
gap: 0.5rem;
}
:where(button, a, input):focus-visible {
outline: 2px solid CanvasText;
outline-offset: 3px;
}

Popover and Tooltip set only the inline values required for placement. Keep all visual styles in your stylesheet.

Apply utility and design-system classes directly to authored elements:

<pe-dialog id="settings">
<dialog class="surface radius-lg shadow-lg">
<!-- ... -->
</dialog>
</pe-dialog>