Utilities
It is not necessary to use utilities, but they simplify life in some cases. Each StyleSheet maker function takes as an argument an object with utilities.
key
Unique stylesheet key.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ key }) => {
const selector = `.${key}-container_fullWidth`;
return {
[selector]: {
width: '100%'
}
};
};dash
Joins primitives with dash.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ dash }) => {
const width = {
none: '0',
half: '50%',
full: '100%'
};
const widthRules = Object.entries(width).reduce((acc, [key, val]) => {
const selector = dash('w', key);
acc[selector] = {
width: val,
};
return acc;
}, {});
return {
...widthRules
};
};comma
Joins primitives with comma.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ comma }) => {
const fonts = ['Georgia', 'serif'];
return {
html: {
fontFamily: comma(...fonts)
}
};
};space
Joins primitives with space.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ space }) => {
const borderStyle = 'solid';
const borderWidth = {
s: '2px',
l: '4px'
};
return {
'.container': {
border: space(borderWidth.s, borderStyle)
}
};
};range
Iterates over an array of a specified length.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ range }) => {
const rules = range(5, (sz) => {
return {
[`.h-${sz}`]: {
height: sz + 'rem'
}
};
});
return {
...rules
};
};each
Iterates over object entries or array values.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ each }) => {
const rules = range(5, (sz) => {
return {
[`.h-${sz}`]: {
height: sz + 'rem'
}
};
});
return {
...rules
};
};merge
Performs deep object merging.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ merge }) => {
const base = {
body: {
width: '100%'
},
div: {
width: '100%',
span: {
width: '100%'
}
}
};
const custom = {
body: {
width: '100vw',
height: '100%'
},
div: {
span: {
background: 'transparent'
}
}
};
return merge(base, custom);
};when
Returns the second argument if the first is true.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ when }) => {
const values = [1, 2, 3, 4, 5, 6];
const rules = values.reduce((acc, value) => {
return {
...acc,
...when(!(value % 2), {
[`sz-${value}`]: {
width: value + 'rem',
aspectRatio: 1
}
})
}
}, {})
return {
...rules
};
};vars
Resolves global vars.
Example
import { TStyleSheetMaker } from 'effcss';
type TGlobalVars = {
sz: {
m: string;
l: string
}
};
export const maker: TStyleSheetMaker = ({ vars }) => {
return {
'.sz-m': {
width: vars<TGlobalVars>('sz.m')
}
};
};time (^3.2.0)
Caclulates time value depending on global time variable.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ time }) => {
return {
'.dur-2': {
// if global root time is 200ms (by default),
// then result will be 400ms
transitionDuration: time(2)
}
};
};size (^3.5.0)
Caclulates size value depending on global size variable.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ size }) => {
return {
'.w-2': {
// if global root size is 16px (by default),
// then result will be 32px
width: size(2)
}
};
};angle (^3.5.0)
Caclulates angle value depending on global angle variable.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ angle }) => {
return {
'.w-2': {
// if global root angle is 30deg (by default),
// then result will be 60deg
transform: `skew(${angle(2)})`
}
};
};bem
Resolves scoped BEM-selector.
Example
import { TStyleSheetMaker } from 'effcss';
export type TStyleSheet = {
block: {
'': {
hidden: '';
};
elem: {
sz: 's' | 'm';
};
};
};
export const maker: TStyleSheetMaker = ({ bem }) => {
const block = bem<TStyleSheet>('block');
const blockHidden = bem<TStyleSheet>('block..hidden');
const elementSzS = bem<TStyleSheet>('block.elem.sz.s');
const elementSzM = bem<TStyleSheet>('block.elem.sz.m');
return {
[block]: {
overflow: 'hidden'
},
[blockHidden]: {
visibility: 'hidden'
},
[elementSzS]: {
width: '2rem'
},
[elementSzM]: {
width: '5rem'
}
};
};units
Group of CSS-units functions.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ units }) => {
const { px, rem } = units;
return {
'.custom': {
width: px(100),
height: rem(1.5)
}
};
};pseudo
Group of pseudoclass/pseudoelement functions.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ pseudo }) => {
const { h, aft, has, is } = pseudo;
return {
// .custom::after:hover
[h(aft('.custom'))]: {
color: 'transparent'
},
// .custom:hover
['.custom' + h]: {
border: '2px solid gray'
},
// button:is(.custom):has(image)
[has('image', is('.custom', 'button'))]: {
cursor: 'pointer'
}
};
};at
Group of at-rules functions.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ at }) => {
const { cq, kf } = at;
const query = cq('min-width: 5rem');
const keyframes = kf();
const property = pr();
return {
...property.r,
[keyframes.s]: {
from: { width: '10px' },
to: { width: property.v }
},
'.animated': {
animationName: keyframes.k,
animationDuration: '5s',
animationIterationCount: 'infinite'
},
'.container': {
containerName: query.c,
containerType: 'inline-size',
[property.k]: '30px'
},
[query.s]: {
'.nested': {
width: '100%'
}
}
};
};at.property (^3.6.0)
Resolves scoped @property rule.
Example
import { TStyleSheetMaker } from 'effcss';
// all the @property names don't make any sense - the provider will create them unique for each utility call
export const maker: TStyleSheetMaker = ({ at: { property } }) => {
const firstProperty = property();
const secondProperty = property({
ini: '25px',
inh: false,
def: '10px' // will be used as reserve value in `var()` expression
});
const thirdProperty = property();
return {
...firstProperty, // => @property --first-property-name {...}
...secondProperty,
'.mod': firstProperty('150px'), // => '.mod': {'--first-property-name': '150px'}
'.full': {
...secondProperty('100px'),
...thirdProperty('red'),
aspectRatio: 1
},
'.cls': {
width: firstProperty, // => width: `var(--first-property-name)`
height: `calc(2 * ${secondProperty})` // => height: `calc(2 * var(--second-property-name,10px))`
},
'.cls2': {
height: `calc(2 * ${secondProperty.fallback('35px')})`
}
};
};at.keyframes (^3.6.0)
Resolves scoped @keyframes rule.
Example
import { TStyleSheetMaker } from 'effcss';
// all the @keyframes names don't make any sense - the provider will create them unique for each utility call
export const maker: TStyleSheetMaker = ({ at: { keyframes } }) => {
const widthKf = keyframes({
from: { width: '10px' },
to: { width: '20px' }
});
const heightKf = keyframes({
from: { height: '10px' },
to: { height: '20px' }
});
return {
...widthKf, // => `@keyframes width-kf-name`: {...}
...heightKf,
'.cls1': {
...widthKf()
}, // => `.cls1`: {animationName: 'width-kf-name'}
'.cls2': {
animation: `3s linear 1s ${heightKf}` // => animation: `3s linear 1s height-kf-name`
},
'.cls3': heightKf({
dur: '300ms',
tf: 'ease'
}) // => `.cls3`: {animation: `300ms ease height-kf-name`}
};
};at.scope (^3.7.0)
Resolves @scope rule.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ at: { scope } }) => {
// set root selector
const baseScope = scope.root('.base');
// set limit selector
const limitedScope = baseScope.limit('.limit');
return {
// put rules in base scope
...baseScope({
span: {
textOverflow: 'hidden'
}
}),
// put rules in limited scope
...limitedScope({
div: {
width: '100%'
}
}),
// put rules in limited scope excluding bounds
...limitedScope.none()({
p: {
fontSize: '1.5rem'
}
}),
// put rules in limited scope including low bound
...limitedScope.low()({
p: {
fontSize: '2rem'
}
}),
// put rules in limited scope including both bounds
...limitedScope.both()({
p: {
fontSize: '0.5rem'
}
})
};
};at.media (^3.8.0)
Resolves @media rule.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ at: { media } }) => {
const firstQuery = media.or('width < 600px', 'width > 1000px');
const secondQuery = media.and(firstQuery, 'orientation: landscape');
return {
// @media (width < 600px) or (width > 1000px) {...}
...firstQuery({
'.cls': {
width: '100%'
}
}),
// @media ((width < 600px) or (width > 1000px)) and (orientation: landscape) {...}
...secondQuery({
'.cls': {
width: '50%'
}
})
};
};at.container (^3.9.0)
Resolves @container rule.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ at: { container } }) => {
const firstQuery = container.or('width < 600px', 'width > 1000px');
const secondQuery = container.named.and('width > 100px');
return {
'.container': {
...secondQuery // container: cust-cq-1 / normal
},
// @container (width < 600px) or (width > 1000px) {...}
...firstQuery({
'.cls': {
width: '100%'
}
}),
// @container cust-cq-1 (width > 100px) {...}
...secondQuery({
'.cls': {
width: '50%'
}
})
};
};at.startingStyle (^3.11.0)
Resolves @starting-style rule.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ at: { startingStyle } }) => {
return {
'.target': {
transition: 'background-color 1.5s',
backgroundColor: 'green',
...startingStyle({opacity: 0})
},
...startingStyle({
'.target': {
backgroundColor: 'transparent'
}
})
};
};color
Group of color functions.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ units }) => {
const { create, fadeout } = color;
let baseColor = create();
baseColor = baseColor.c(0.2);
const additionalColor = fadeOut(baseColor);
return {
'.custom': {
background: additionalColor + '',
color: baseColor.s
}
};
};palette (^3.4.0)
Palette class instance. It allows to use colors in oklch from with predefined lightness, chroma and hue values.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ palette }) => {
// `palette.fg` returns foreground color, while `palette.bg` returns background color.
// Background and foreground have different lightness and chroma values for each variant.
// Hue variants are `pri`, `sec`, `suc`, `inf`, `war`, `dan`.
// Chroma variants are `grey`, `pale`, `base`, `rich`
// Lightness variants are `xs`, `s`, `m`, `l`, `xl`.
// Lightness options increase as you approach contrast (0 in light mode and 1 in dark mode), so `xs` = 0.48, `xl` = 0.24 in dark mode background and `xs` = 0.78, `xl` = 0.98 in light mode background
return {
'.palette-complex': {
color: palette.fg.gray.inf.l,
backgroundColor: palette.bg.pale.sec.xl,
borderColor: palette.fg.rich.xs.suc.alpha(0.75)
}
};
};limit
Group of width limit functions.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ limit }) => {
const{ down, between } = limit;
return {
// @media (max-width: 48rem)
[down('md')]: {
flexGrow: 1
},
// '@container (min-width: 30rem) and (max-width: 80rem)
[between('xs', 'xl', '')]: {
flexShrink: 0
}
};
};coef (^3.5.0)
Coefficient class instance. It allows to use coefficient ranges with predefined global variables.
Example
import { TStyleSheetMaker } from 'effcss';
export const maker: TStyleSheetMaker = ({ coef, size }) => {
return each(coef.$2_.short, (k, v) => ({
[`.size-` + k]: {
width: size(v)
}
}));
};