Skip to content

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
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ key }) => {
    const selector = `.${key}-container_fullWidth`;
    return {
        [selector]: {
            width: '100%'
        }
    };
};

dash

Joins primitives with dash.

Example
ts
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
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ comma }) => {
    const fonts = ['Georgia', 'serif'];
    return {
        html: {
            fontFamily: comma(...fonts)
        }
    };
};

space

Joins primitives with space.

Example
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
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
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ coef, size }) => {
    return each(coef.$2_.short, (k, v) => ({
        [`.size-` + k]: {
            width: size(v)
        }
    }));
};

Released under the Apache-2.0 License.