Mixins are a powerful feature of Assembler CSS that allows you to write reusable style rules and apply them to various elements.

You can define a new mixin by using a CSS variable suffixed with --mixin. Applying a mixin is done by prefixing the mixin’s name with ^ symbol.

<style>
    :root {
        --stripes--mixin: "bg-color: slateblue; \
        bg-image:repeating-linear-gradient(45deg, transparent 0 3px, #0003 3px 9px)";
    }
</style>
<div x-style="^stripes; w:150px; h:150px; mx:auto; radius"></div>

You can also define and apply multiple mixins at the same time.

<style>
    :root {
        --stripes--mixin: "bg-color: slateblue; \
        bg-image:repeating-linear-gradient(45deg, transparent 0 3px, #0003 3px 9px)";
        --box--mixin: "w:150px; h:150px; mx:auto; radius";
    }
</style>
<div x-style="^box; ^stripes"></div>

Arguments

The true power of mixins stands in the fact that they allow you to pass values as arguments. You can refer to an argument inside a mixin by using ${index}, where index is the zero-based index of the argument.

:root {
    --stripes--mixin: "bg-color: ${0}; \
    bg-image:repeating-linear-gradient(45deg, transparent 0 3px, #0003 3px 9px)";
    --box--mixin: "w:150px; h:150px; mx:auto; radius";
}

Now you can pass custom colors to your mixin.

<div x-style="flex">
    <div x-style="^box; ^stripes:slateblue"></div>
    <div x-style="^box; ^stripes:tomato"></div>
    <div x-style="^box; ^stripes:lime"></div>
</div>

Fallback values

You can define fallback values for arguments by using ${index=value}.

:root {
    --stripes--mixin: "bg-color: ${0=slateblue}; \
    bg-image:repeating-linear-gradient(45deg, transparent 0 3px, #0003 3px 9px)";
    --box--mixin: "w:150px; h:150px; mx:auto; radius";
}

Now you can use the mixin with or without the first argument.

<div x-style="flex">
    <div x-style="^box; ^stripes"></div>
    <div x-style="^box; ^stripes:tomato"></div>
    <div x-style="^box; ^stripes:lime"></div>
</div>

Nested mixins

A great feature of mixins is the fact that they can be nested. Thus, you can use mixins inside other mixins.

    --stripes--mixin: "bg-color: ${0=slateblue}; \
    bg-image:repeating-linear-gradient(45deg, transparent 0 3px, #0003 3px 9px)";
    --box--mixin: "w:150px; h:150px; mx:auto; radius";
    --square--mixin: "^box; ^stripes";
<div x-style="^square; mx:auto"></div>

You can also pass arguments from the parent mixin to the nested mixin.

    --stripes--mixin: "bg-color: ${0=slateblue}; \
    bg-image:repeating-linear-gradient(45deg, transparent 0 3px, #0003 3px 9px)";
    --box--mixin: "w:${0=150px}; h:${1=150px}; mx:auto; radius";
    --square--mixin: "^box:${1=150px}, ${1=150px}; ^stripes:${0=slateblue}";
<div x-style="flex; align-items:center">
    <div x-style="^square"></div>
    <div x-style="^square:tomato, 250px"></div>
    <div x-style="^square:lime"></div>
</div>

JavaScript mixins

Another way of defining mixins is with the help of JavaScript.

AssemblerCSS.registerMixin("foo", function (settings, ...args) {
    // return properties
});

The callback function receives as arguments an object of type UserSettings and an array of strings passed as arguments to the mixin.

type UserSettings = {
    enabled: boolean,
    generate: boolean,
    constructable: boolean,
    cache: string|null,
    cacheKey: string,
    desktopFirst: boolean,
    breakpoints: string[],
    media: {xs: string, sm: string, md: string, lg:string, xl:string},
    states: string[],
    scopes: string[]
};

Built-in mixins

container

The container mixin is used to center, padding, and limit the width of an element, depending on the screen size. This mixin takes no arguments and applies different styles for mobile-first and desktop-first responsive designs.

Mobile-first
px: 1rem; 
mx:auto; 
max-w:100%; 
sm|max-w:@breakpoint-sm; 
md|max-w:@breakpoint-md; 
lg|max-w:@breakpoint-lg; 
xl|max-w:@breakpoint-xl;
Desktop-first
px: 1rem; 
mx:auto; 
max-w:@breakpoint-lg; 
lg|max-w:@breakpoint-md; 
md|max-w:@breakpoint-sm; 
sm|max-w:@breakpoint-xs; 
xs|max-w:100%;

grid

This simple mixin provides some minor tweaks to child elements that will make working with CSS grids more efficient.

grid; 
l1!wb:break-all; 
l2!max-w:100%; 
child!justify-self:normal; 
child!align-self:normal;

This mixin takes no arguments.

<div x-style="^grid; ^stripes:lightgray; grid-rows:3; grid-cols:3; h:300px">
    <div x-style="col-span:2; row-span:2; bg:slateblue"></div>
    <div x-style="bg:tomato"></div>
    <div x-style="bg:lime"></div>
    <div x-style="col-start:2; col-span:2; bg:orange"></div>
</div>

stack

As the name suggests, the stack mixin allows you to stack elements inside a parent element.

grid; 
grid-template-columns:minmax(0,1fr); 
grid-template-rows:minmax(0,1fr); 
grid-template-areas:"stackarea"; 
l1!grid-area:stackarea; 
l1!z:0; 
w:100%; 
h:100%;

This is also a mixin that takes no arguments.

Stacked elements
<div x-style="^stack; h:400px">
    <iframe x-style="w:100%; h:100%" src="..."></iframe>
    <div x-style="bg:slateblue; p:4; m:auto; radius; color:white">
        Stacked elements
    </div>
</div>

space-x

You can use this mixin to add horizontal space between child sibling elements.

sibling!ml:${0=0};

This mixin requires you to pass an argument representing the amount of space between elements.

<div x-style="^space-x:25px; ^stripes:lightgray; flex">
    <div x-style="w:100px; m:0; h:100px; radius; p:0; bg:slateblue"></div>
    <div x-style="w:100px; h:100px; radius; bg:tomato"></div>
    <div x-style="w:100px; h:100px; radius; bg:lime"></div>
</div>

If you are reversing the order of elements using row-reverse, then you can pass true as the second argument to the mixin, and it will use margin-right instead of margin-left.

sibling!mr:${0=0};
<div x-style="^space-x:25px,true; ^stripes:lightgray; flex; row-reverse">
    <div x-style="w:100px; m:0; h:100px; radius; p:0; bg:slateblue"></div>
    <div x-style="w:100px; h:100px; radius; bg:tomato"></div>
    <div x-style="w:100px; h:100px; radius; bg:lime"></div>
</div>

space-y

Similarly to space-x, this mixin can be used to add horizontal space between child sibling elements.

sibling!mt:${0=0};

This mixin requires you to pass an argument representing the amount of space between elements.

<div x-style="^space-y:25px; ^stripes:lightgray; flex; flex-col">
    <div x-style="w:100px; m:0; h:100px; radius; p:0; bg:slateblue"></div>
    <div x-style="w:100px; h:100px; radius; bg:tomato"></div>
    <div x-style="w:100px; h:100px; radius; bg:lime"></div>
</div>

If you are reversing the order of elements using column-reverse, then you can pass true as the second argument to the mixin, and it will use margin-bottom instead of margin-top.

sibling!mb:${0=0};
<div x-style="^space-y:25px,true; ^stripes:lightgray; flex; col-reverse">
    <div x-style="w:100px; m:0; h:100px; radius; p:0; bg:slateblue"></div>
    <div x-style="w:100px; h:100px; radius; bg:tomato"></div>
    <div x-style="w:100px; h:100px; radius; bg:lime"></div>
</div>

sr-only

You can use this mixin to visually hide an element while it still remains available for screen readers.

absolute; 
w:1px; 
h:1px; 
p:0; 
m:-1px;
bw:0; 
overflow:hidden; 
clip:rect(0, 0, 0, 0);
left:-9999px;