API

Style Helper

The style helper can be used for writing pseudo, attribute and prop selectors.

Pseudo Elements

Available pseudo elements:

  • after
  • backdrop
  • before
  • cue
  • cueRegion
  • firstLetter
  • firstLine
  • fileSelectorButton
  • marker
  • placeholder
  • selection

Pseudo element functions:

NameArg type
partstring
slottedstring

Pseudo Classes

Available pseudo classes:

  • active
  • anyLink
  • autofill
  • checked
  • default
  • defined
  • disabled
  • empty
  • enabled
  • first
  • firstChild
  • firstOfType
  • fullscreen
  • focus
  • focusVisible
  • focusWithin
  • hover
  • indeterminate
  • inRange
  • invalid
  • lastChild
  • lastOfType
  • left
  • link
  • modal
  • onlyChild
  • onlyOfType
  • optional
  • outOfRange
  • pictureInPicture
  • placeholderShown
  • paused
  • playing
  • readOnly
  • readWrite
  • required
  • right
  • root
  • scope
  • target
  • valid
  • visited

Pseudo class functions:

NameArg type
hoststring
langstring
isstring[]
notstring[]
wherestring[]
nthChildnumber or string
nthLastChildnumber or string
nthLastOfTypenumber or string
nthOfTypenumber or string

Attribute builder

Methods available on the style.attribute('...') builder are:

MethodArg typeCSS syntax
equalsstring[][attr=value]
containsstring[][attr~=value]
containsAnystring[][attr*=value]
startsWithstring[][attr^=value]
endsWithstring[][attr$=value]

Combinators

style.or for creating nested selector lists (comma separated).

style.or(style.before, style.after)
// ::before, ::after

style.and for combining nested selectors.

style.and(style.hover, style.focus)
// :hover:focus

Media Query builder

Writing media queries can be made easy with the help of the mq helper that provides a nice DSL. Simply chain the exposed methods to build the desired media query string.

import styled, { mq } from '@n3e/styled';

const Container = styled.div({
  // @media screen and (min-width: 768px) and (max-width: 991px) { ... }
  [mq().screen().from(768).to(991)]: {
    maxWidth: '45rem'
  }
});

Media Types

The mq helper exposes 2 media type methods:

  • screen which outputs @media screen
  • print which outputs @media print

Defined media query features

These methods accept a string argument which is from a pre-defined set.

MethodAllowed args
anyPointer'fine' or 'coarse' or 'none'
colorGamut'srgb' or 'p3' or 'rec2020'
displayMode'fullscreen' or 'standalone' or 'minimal-ui' or 'browser'
orientation'landscape' or 'portrait'
overflowBlock'none' or 'scroll' or 'optional-paged' or 'paged'
pointer'fine' or 'coarse' or 'none'
prefersColorScheme'light' or 'dark'
prefersContrast'no-preference' or 'more' or 'less'
scripting'none' or 'initial-only' or 'enabled'
update'none' or 'slow' or 'fast'
anyHover'none' or 'hover'
hover'none' or 'hover'
forcedColors'none' or 'active'
grid'0' or '1'
invertedColors'none' or 'inverted'
overflowInline'none' or 'scroll'
prefersReducedMotion'no-preference' or 'reduce'

Range media query features

As the CSS specification defines, these are features prefixed with min or max and the joining hyphen.

MethodArg type
heightstring
widthstring
aspectRatiostring
colornumber (optional)
colorIndexnumber (optional)
monochromenumber (optional)
resolutionstring

All the methods in the above table also have min and max versions. eg: width(arg: string) me can be used as minWidth(arg: string) as well as maxWith(arg: string)

There is also:

MethodArg typeReturns
fromnumbermin-width
tonumbermax-width

NOTE: number argument supplied to the above methods is converted to a px value.

Escape hatch

There is also an escape hatch to use media features not supplied by mq helper or an unofficial or experimental one.

The feature method takes 2 arguments, the feature name string and the feature value number or string.

mq().feature('awesome-new-feature', '100ghz')

Global styles

To set default styles for body, headings etc. just use the withCSS method which accepts normal CSS as its arguments.

const boxSizing =
  `*,
    :after,
    :before {
      box-sizing: border-box;
  }`;

const htmlAndBody =
  `body, html {
    margin: 0;
    padding: 0;
    width: 100%;
  }`;

const AppWrapper = styled
  .div()
  .withCSS(
    boxSizing,
    htmlAndBody
  );

Keyframe animations can be declared and used like so:

const shimmer = 'shimmer';

const SomeElement = styled
  .div({
    animation: `${shimmer} 1.5s ease-in-out infinite`
  })
  .withCSS(
    `@keyframes ${shimmer} {
      0% { opacity: 0.5; }
      50% { opacity: 0.8; }
      100% { opacity: 0.5; }
    }`
  );

Font face rules:

const AppWrapper = styled
  .div()
  .withCSS(
    `@font-face {
      font-family: 'Montserrat';
      font-style: normal;
      font-weight: 500;
      font-display: swap;
      src: url('path/to/font/file.woff2') format('woff2');
    }`
  );

Supported CSS

The following at-rules are supported:

  • container
  • counter-style
  • font-face
  • keyframes
  • media
  • property
  • starting-style
  • supports

Theming

CSS variable themes can be used as part of global style definitions.

const AppWrapper = styled
  .div()
  .withCSS(
    `:root {
      --background-primary: #fff;
      --color-primary: #262223;
    }`,

    `@media (prefers-color-scheme: dark) {
      :root {
        --background-primary: #121212;
        --color-primary: #fff;
      } 
    }`
  );

Variants

Variants can be defined using prop styles and object mapping.

import type { CSSProperties } from '@n3e/styled';

type MarvelLegends =
  | 'parker'
  | 'stark'
  | 'banner';

type BoxProps = {
  children?: React.ReactNode;
  variant?: MarvelLegends;
};

const variantStyle: Record<MarvelLegends, CSSProperties> = {
  parker: {
    background: 'blue',
    color: 'red'
  },
  stark: {
    background: 'red',
    color: 'gold'
  },
  banner: {
    background: 'green',
    color: 'purple'
  }
};

const Box = styled.div<BoxProps>({
  padding: '1.5rem 1rem',
  borderRadius: '0.25rem',
  
  [style.prop('variant')]: (variant: MarvelLegends) => variantStyle[variant]
});