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:
| Name | Arg type |
|---|---|
| part | string |
| slotted | string |
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:
| Name | Arg type |
|---|---|
| host | string |
| lang | string |
| is | string[] |
| not | string[] |
| where | string[] |
| nthChild | number or string |
| nthLastChild | number or string |
| nthLastOfType | number or string |
| nthOfType | number or string |
Attribute builder
Methods available on the style.attribute('...') builder are:
| Method | Arg type | CSS syntax |
|---|---|---|
| equals | string[] | [attr=value] |
| contains | string[] | [attr~=value] |
| containsAny | string[] | [attr*=value] |
| startsWith | string[] | [attr^=value] |
| endsWith | string[] | [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:
screenwhich outputs@media screenprintwhich outputs@media print
Defined media query features
These methods accept a string argument which is from a pre-defined set.
| Method | Allowed 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.
| Method | Arg type |
|---|---|
| height | string |
| width | string |
| aspectRatio | string |
| color | number (optional) |
| colorIndex | number (optional) |
| monochrome | number (optional) |
| resolution | string |
All the methods in the above table also have min and max versions. eg: width(arg: string) can be used as minWidth(arg: string) as well as maxWith(arg: string)
There is also:
| Method | Arg type | Returns |
|---|---|---|
| from | number | min-width |
| to | number | max-width |
NOTE: number argument supplied to the above methods is converted to a px value.
Escape hatch
The feature method allows using media features that are not supplied by the mq helper. It accepts 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]
});