Skip to content

Selectors

Use default selectors, priority selectors, and custom selector maps.

The default style export includes a useful selector preset:

  • pseudo classes like hover, active, focusVisible, disabled;
  • pseudo elements like before and after;
  • argument selectors like not, is, where, has, nthChild;
  • custom self-selector helpers like select;
  • at-rules like media, container, and supports.

DefaultPrioritySelectors assigns priority to common interaction states:

link -> visited -> hover -> focusWithin -> focus -> focusVisible -> active -> disabled

This helps generated rules land in a predictable order.

const item = style()
.not('[aria-disabled="true"]', {
cursor: 'pointer',
})
.has('[data-icon]', {
paddingInlineStart: 10,
});

.select(...) is for custom selectors on the same element as the generated class. It is not a deep selector API for styling nested elements.

const trigger = style({
border: 0,
}).select('&[aria-expanded="true"]', {
backgroundColor: 'CanvasText',
color: 'Canvas',
});

For child elements or component parts, expose a slot and override it through a scope:

const menu = {
root: style.slot({ display: 'grid' }),
item: style.slot(),
};
const paddedItems = style.scope([
menu.item({ padding: 8 }),
]);

Use createStyleFn when you want your own selector names or a smaller preset.

import { createStyleFn, selector, type } from '@fluentic/style';
import type { CSSProperties } from '@fluentic/style';
const { style: ds } = createStyleFn({
style: type<CSSProperties>,
selectors: {
hover: selector(':hover'),
pressed: selector('[aria-pressed="true"]'),
media: selector('@media $$', 'media'),
},
});
const toggle = ds({ border: 0 }).pressed({
backgroundColor: 'black',
color: 'white',
});

Custom selector maps are useful for design systems that want a controlled styling vocabulary.