Skip to content

Responsive And Selectors

Selectors are where PikaCSS stops feeling like a small helper and starts feeling like a system. They let you encode states, themes, and breakpoints once, then reuse them everywhere.

Define selectors in config

ts
// pika.config.ts
import { defineEngineConfig } from '@pikacss/unplugin-pikacss'

export default defineEngineConfig({
	selectors: {
		selectors: [
			// Static selectors: [name, replacement]
			// Use $ as a placeholder for the atomic style's own selector
			['hover', '$:hover'],
			['focus', '$:focus'],
			['first-child', '$:first-child'],
			['@dark', '[data-theme="dark"] $'],
			['@md', '@media (min-width: 768px)'],
			['@lg', '@media (min-width: 1024px)'],

			// Dynamic selectors: [pattern, resolver, autocomplete?]
			[
				/^@screen-(\d+)$/,
				m => `@media (min-width: ${m[1]}px)`,
				['@screen-640', '@screen-768', '@screen-1024'], // autocomplete hints
			],
		],
	},
})

Use them in style definitions

ts
const className = pika({
	'color': 'black',
	'hover': {
		color: 'blue',
	},
	'@dark': {
		color: 'white',
	},
	'@md': {
		fontSize: '1.25rem',
	},
})
css
.pk-a { color: black; }
.b:hover { color: blue; }
[data-theme="dark"] .pk-c { color: white; }
@media (min-width: 768px) {
  .pk-d { font-size: 1.25rem; }
}

Keep responsive naming boring

Your selectors should be easy to scan and easy to remember. Prefer project-wide aliases like screen-sm, screen-md, and screen-lg over one-off media query strings spread through component files.

Nested selectors are still static

Nested selector blocks stay within the build-time model because the structure is declared in source.

vue
<template>
	<button
		:class="pika({
			'padding': '0.5em 1em',
			'borderRadius': '0.25em',
			'border': 'none',
			'backgroundColor': '#0ea5e9',
			'color': 'white',
			'cursor': 'pointer',
			'transition': 'transform 0.2s ease',

			':hover': {
				transform: 'scale(1.05)',
			},

			':active': {
				transform: 'scale(0.95)',
			},
		})"
	>
		Hover me
	</button>
</template>
  • Put breakpoint aliases in config, not in individual components.
  • Keep selector names semantic enough for team-wide reuse.
  • Use selectors for state structure and variables for value changes.
  • Use shortcuts when a selector-driven pattern repeats across components.

Do not overload selectors

If a selector name hides too many unrelated rules, reviews become harder and local overrides become unpredictable. A selector alias should describe a stable condition, not a whole component contract.

Next