How to attach behavior, styles, and DOM-aware setup to host elements with `mix`. Read this when the task involves:
- DOM event handling with `on(...)`
- Static styling with `css(...)` and dynamic styling with `style`
- Imperative DOM access via `ref(...)`
- Navigation behavior on non-anchor elements with `link(...)`
- Native click, pointer, and keyboard behavior with `on(...)`, plus attributes with `attrs(...)`
- Element-level animation mixins from `remix/ui/animation`
For richer animation work (springs, tweens, layout transitions), see `animate-elements.md`. For authoring custom mixins, see `create-mixins.md`. For component lifecycle and updates, see `component-model.md`.
Compose behavior on host elements with `mix`. Pass a single mixin directly (`mix={on(...)}`), or an array when composing multiple mixins (`mix={[css(...), on(...)]}`). Core mixins are imported from `remix/ui`; animation mixins are imported from `remix/ui/animation`.
## `on(type, handler, capture?)`
Attaches a typed DOM event handler. The handler receives the event and an `AbortSignal` that aborts when the handler is re-entered or the component is removed — this prevents race conditions:
Applies generated class names for CSS object styles. Produces static CSS rules inserted into the document. Supports pseudo-selectors, pseudo-elements, attribute selectors, descendant selectors, and media queries using `&` to reference the current element:
```tsx
<button
mix={css({
color:'white',
backgroundColor:'blue',
padding:'12px 24px',
borderRadius:'4px',
border:'none',
cursor:'pointer',
'&:hover':{backgroundColor:'darkblue'},
'&:active':{transform:'scale(0.98)'},
'&:disabled':{opacity: 0.5,cursor:'not-allowed'},
'& .title':{fontSize:'20px',fontWeight:'bold'},
'@media (max-width: 768px)':{width:'100%'},
})}
/>
```
### `css(...)` vs `style` prop
Use `css(...)` for static styles, selectors, and media queries. Use `style` for dynamic values that change often. Prefer CSS nested selectors for parent-state-affects-children over managing hover/focus state in JavaScript:
On a native anchor, the `history` option renders the corresponding `rmx-history="push|replace"` attribute so the enhanced navigation uses the same history behavior.
Use native DOM events directly with `on(...)`. For buttons and links, `click` already includes keyboard activation when the element has the right semantics: