Skip to content

Utilities

It is not necessary to use utilities, but in some cases they make life easier. Each StyleSheet maker function takes an object with utilities as an argument.

dash

Combines primitives using a hyphen.

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

Combines primitives using a comma.

Example
ts
import { TStyleSheetMaker } from 'effcss';

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

space

Combines primitives using the 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 a sequence of numbers 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 the key-value pairs of an object or the values of an array.

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
    };
};

themeVar

Creates a var() expression with global theme variables.

Example
ts
import { TStyleSheetMaker } from 'effcss';

type TGlobalVars = {
    sz: {
        m: string;
        l: string
    }
};

export const maker: TStyleSheetMaker = ({ themeVar }) => {
    return {
        '.sz-m': {
            width: themeVar<TGlobalVars>('sz.m', '100px') // '100px' - fallback value
        }
    };
};

time

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

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

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)})`
        }
    };
};

easing (^4.4.0)

Calculates a value of type <easing-function>. When called without an argument, it returns the global value; when called with an argument, it returns the configured value of the cubic-bezier function.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ easing }) => {
    return {
        [`.cust`]: {
            transitionTimingFunction: easing({
                x1: 0.42,
                x2: 0.58
            }) // transition-timing-function:cubic-bezier(0.42,0,0.58,1)
        },
        [`.global`]: {
            transitionTimingFunction: easing() // transition-timing-function:var(--f0-easing)
        },
    };
};

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'
        }
    };
};

color

A group of functions for working with color.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ units }) => {
    const { fadeout, darken } = color;
    const baseColor = 'green';
    const additionalColor = fadeOut(baseColor);
    return {
        '.custom': {
            background: additionalColor,
            color: darken(baseColor)
        }
    };
};

palette

An instance of the palette class. It allows you to use colors in the oklch format with predefined brightness, chromaticity, and hue values that are taken from theme variables.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ palette }) => {
    // `palette.fg` returns the foreground color, while `palette.bg" returns the background color.
    // The background and foreground have different brightness and chromaticity values for each option.
    // The options for shades are `pri`, `sec`, `suc`, `inf`, `war`, `dan`.
    // The options for chromaticity are `grey`, `pale`, `base`, `rich`
    // The options for brightness are `xs`, `s`, `m`, `l`, `xl`.
    // The brightness settings increase as you approach the contrast (0 in light mode and 1 in dark mode), so "xs" = .48, "xl" = 0.24 on a dark background, and "xs" = 0.78, "xl" = 0.98 on a light 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)
        }
    };
};

coef

An instance of the coefficient class. Allows you to use coefficient ranges with predefined values that are taken from theme variables.

Example
ts
import { TStyleSheetMaker } from 'effcss';

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

at.property

Creates a @property rule for the table scope.

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

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

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'
            }
        }),
        // поместим правила в ограниченную область видимости
        ...limitedScope({
            div: {
                width: '100%'
            }
        }),
        // поместим правила в ограниченную область видимости, исключая обе границы
        ...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

Resolves @media rule.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { media } }) => {
    const firstCondition = or('width < 600px', 'width > 1000px');
    const firstQuery = media(firstCondition);
    const secondQuery = media.where(and(firstCondition, '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

Resolves @container rule.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { container, $logic: {or} } }) => {
    const firstQuery = container.where(or('width < 600px', 'width > 1000px'));
    const secondQuery = container.named.where('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

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'
            }
        })
    };
};

at.supports

Resolves @supports rule.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { supports } }) => {
    const supportsRule = supports.where('not (text-align-last:justify)');
    return supportsRule({
        div: {
            textAlignLast: 'justify'
        }
    });
};

at.layer

Resolves @layer rule.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { layer } }) => {
    const layer1 = layer.named;
    const layer2 = layer.named;
    return {
        ...layer.list(layer1, layer2), // @layer cust-lay-1, cust-lay-2;
        ...layer1({ // @layer cust-lay-1{
            '.padding-sm': {
                padding: '0.5rem'
            }
        }),
        ...layer2({ // @layer cust-lay-2{
            '.padding-sm': {
                padding: '0.75rem'
            }
        })
    };
};

at.$logic

A set of functions for specifying complex logical conditions using @container and @media.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { media, $logic: {and, or, not} } }) => {
    const logic1 = and('prefers-reduced-motion: reduce', 'hover');
    const query = media.where(or(logic1, 'width > 600px'));
    return {
        ...query12({ // @media (prefers-reduced-motion: reduce) and (hover) or (width > 600px)
            '.cls': {
                maxWidth: '130px'
            }
        })
    };
};

at.$width, at.$height, at.$inline, at.$block

A set of functions for creating the width/height/inline size/block size conditions of @container and @media.

Example
ts
import { TStyleSheetMaker } from 'effcss';

export const maker: TStyleSheetMaker = ({ at: { media, $width: {between} } }) => {
    return media.where(between(30,80))({ // @media (min-width:30rem) and (max-width:80rem)
        '.cls': {
            flexShrink: 0
        }
    });
};

Released under the Apache-2.0 License.