# assembly **Repository Path**: mirrors_mapbox/assembly ## Basic Information - **Project Name**: assembly - **Description**: Making the hard parts of designing for the web easy. - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-08-09 - **Last Updated**: 2026-11-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Assembly assembly logo A CSS framework that makes the hard parts of building anything on the web easy. We define the hard parts as: managing class specificity, designing cross-browser form components that work well with each other, creating a harmonious typographic scale, maintaining a baseline grid, and keeping responsive designs simple. For usage guidelines and documentation, check out https://labs.mapbox.com/assembly/. ## Browser support Assembly targets modern versions of Chrome, Firefox, Safari, and Edge on desktop; Safari on iOS; and Chrome on Android. ## Usage See https://labs.mapbox.com/assembly/ for usage guidelines. ## Migration See our [`Migration guides`](https://github.com/mapbox/assembly/blob/main/MIGRATION_GUIDES.md) to understand what changes you might need to make when upgrading Assembly in your project. ## Custom Builds Assembly exposes a JS module for creating custom builds. Why might you want to create a custom build? - You want to customize variables (like colors and font stacks) or media queries. - You want to append extra stylesheets that also use Assembly's variables and media queries. - You want to reduce file-size by picking and choosing the color variants you need. ### presetAssembly([options]) Returns an [UnoCSS preset](https://unocss.dev/guide/presets) that generates Assembly class names on demand. Utilities, media variants, `dark:` variants, and color modifiers are tree-shaken from your source. Reset, form, and other component CSS is included as preflight. See [Dark mode](#dark-mode) for the `dark:` prefix. ```js import { defineConfig } from 'unocss'; import { presetAssembly } from '@mapbox/assembly'; export default defineConfig({ presets: [presetAssembly()] }); ``` The generated CSS uses Assembly's CSS variables (`var(--blue)`) and custom media queries (`@media (--m-screen)`), which browsers can't resolve on their own. Run it through PostCSS with the same plugins `buildUserAssets` uses, pointed at Assembly's variable and media query definitions: ```js // postcss.config.js const variables = require('@mapbox/assembly/src/variables.json'); const mediaQueries = require('@mapbox/assembly/src/media-queries.json'); module.exports = { plugins: [ require('postcss-custom-properties')({ preserve: false, importFrom: { customProperties: variables } }), require('postcss-custom-media')({ importFrom: { customMedia: mediaQueries } }) ] }; ``` `importFrom` requires `postcss-custom-properties@12` and `postcss-custom-media@8`; later major versions removed it. To change a variable or breakpoint, override its entry in these objects. `examples/jit/build.mjs` shows the full pipeline. The prebuilt `assembly.css` is generated with `presetAssembly({ safelist: true })` so every class is present. Do not pass `safelist: true` in an app that wants on-demand CSS. `options.colorVariants` and `options.files` match the `buildUserAssets` options of the same names. Variable overrides are applied in the PostCSS step above, not by the preset. ### buildUserAssets(outdir[, options]) Returns a Promise that resolves when all assets have been written to `outdir`. ```js const Assembly = require('assembly'); Assembly.buildUserAssets('path/to/my/outdir', myOptions) .then(() => /* something */) .catch((err) => /* handle error */); ``` **Options**, all of which are optional: - **`files`**: An array of file paths to stylesheets you would like to append to `assembly.css`. These will be processed through Assembly's PostCSS pipeline. - **`variables`**: An object whose properties will override and add to `src/variables.json`. Use this option to change or add variables. These variables are accessible in any stylesheets you append via the CSS custom properties syntax, e.g. `var(--property-name)`. - **`mediaQueries`**: An object whose properties will override and add to `src/media-queries.json`. Use this option to change or add media queries. These media queries are accessible in any stylesheets you append via the CSS custom media query syntax, e.g. `@media --media-query-name`. - **`colorVariants`**: An object or array specifying the color variants you would like added to `assembly.css`. This is documented in detail below. - **`icons`**: An array of icons names to include in Assembly. Names correspond to file names in `src/svgs/`. Use this option to decrease the size of assembly.js by only including the icons you need. - **`browsersList`**: A [Browserslist](https://github.com/ai/browserslist) array to be used by [Autoprefixer](https://github.com/postcss/autoprefixer). Default: ``` [ 'last 4 Chrome versions', 'last 4 Firefox versions', 'last 4 Safari versions', 'last 2 Edge versions', 'last 2 iOS versions', 'last 2 Android versions', 'not IE 11', 'not dead' ] ``` - **`quiet`**: Suppress logs. ### `colorVariants` option If the `colorVariants` value is an array, it must be an array of color names corresponding to variables. All components will have color variants generated for all colors in the array. The following configuration specifies an array of default colors. All components will have these (and _only these_) color variants. ```json ["red", "green-light"] ``` If the `colorVariants` value is an object, each property value must be an array of color names corresponding to variables. The property names designate which component each color array applies to: - `default`: These colors apply to all components that are not otherwise specified. - `buttonFill`: `*-dark` colors will not be used. - `buttonStroke`: `*-dark` colors will not be used. - `inputTextarea`: `*-dark` colors will not be used. - `selectFill`: `*-dark` colors will not be used. - `selectStroke`: `*-dark` colors will not be used. - `checkbox`: `*-dark` colors will not be used. - `radio`: `*-dark` colors will not be used. - `switch`: `*-dark` colors will not be used. - `toggle`: `*-dark` colors will not be used. - `range`: `*-dark` colors will not be used. - `color` - `background` - `link`: `*-dark` colors will not be used. - `border` - `hoverShadow`: Only `lighten*` and `darken*` colors will be used. - `hoverBackground` - `hoverColor` - `hoverBorder` The following configuration specifies colors for individual components. In this configuration, every component not specified will have the `default` color variants; specified components will have their specified color variants; and `switch` and `range` components will have no color variants (only the default will be available). ```json { "default": ["lighten50", "lighten25", "gray"], "buttonFill": ["green", "purple"], "selectFill": ["green"], "background": ["orange", "yellow", "pink"], "link": ["orange"], "hoverShadow": ["lighten50"], "switch": [], "range": [] } ``` ## Development principles ### Writing rules Assembly strives for flat, single rule declarations and avoids overrides whenever possible. Declarations are marked as `!important` for classes whose names directly correspond with what they do — e.g. `bg-blue`, `px12`. This way they cannot be overridden and so are guaranteed to actually do what they say they do. ### Naming classes - Keep names as short as reasonable. - Use real number values in utility class names to describe the value the utility class applies _in cases where the number of utility classes describing a particular property could be unlimited_. For example, `.pt6` for `padding-top: 6px` instead an abstract scale like `.pt-small` or `.pt-1`. - If the number of utility classes describing a property is limited and the variants are about size, Assembly classes use the suffixes `xl`, `l`, `m`, `s`, `xs`. - Assembly provides a reset that will affect the entire page, but other than that reset none of its rules should affect the styling of elements that don't bear Assembly classes. ### Media query class variants Media query class variants (e.g. `block-mm` as a variant of `block`) are generated by the Assembly UnoCSS preset (`src/preset/variants.js`). The prebuilt stylesheet includes `-mm`, `-ml`, and `-mxl` variants for the classes listed in `src/preset/media-classes.js` plus every layout-scale utility. If you use `presetAssembly()` on demand, those suffixes work for any matching utility. ### Dark mode With `presetAssembly()` on demand, prefix any Assembly class with `dark:` to apply it only inside `@media (prefers-color-scheme: dark)`. The prebuilt `assembly.css` doesn't include `dark:` classes. Assembly has no dark palette of its own, so pair the classes you already use: ```html
``` - `dark:` works with every class, including component classes such as `btn`, `loading`, `table--dark`, and `prose--dark`, along with their hover and active states. - It combines with media query suffixes: `dark:block-mm` applies `block` at the `--m-screen` breakpoint in dark mode. - A `dark:` class follows its light and breakpoint counterparts in the output, so with `block-mm dark:none` the element is hidden in dark mode at every width. Write `dark:block-mm` to keep it visible from that breakpoint up. ## Development ### Tools - [UnoCSS](https://unocss.dev/) generates Assembly utilities from `presetAssembly()` (`src/preset/utilities.js`, layout scales, color rules, media-query variants, and `src/preset/base.css` for reset/forms). - [PostCSS](http://postcss.org/) for processing CSS. PostCSS parses CSS and runs it through plugins, and these are the plugins we're using: - [Autoprefixer](https://autoprefixer.github.io/) automatically adds vendor prefixes. - [postcss-custom-properties](https://github.com/postcss/postcss-custom-properties) allows us to use variables for values, with the [CSS custom properties syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/--*). - [postcss-custom-media](https://github.com/postcss/postcss-custom-media) allows us to use variables for media queries, with the [CSS custom media queries syntax](https://www.w3.org/TR/2016/WD-mediaqueries-4-20160126/#custom-mq). - SVGs - [svgstore](https://github.com/svgstore/svgstore) compiles our SVGs into a SVG "sprite" of sorts, allowing us to use [the latest and greatest SVG-based icon system](https://css-tricks.com/svg-sprites-use-better-icon-fonts/). - [VitePress](https://vitepress.dev/) powers the website. ### Install and start ```bash npm ci # Installs your `node_modules` npm run dev # Builds CSS/JS, starts the VitePress docs server npm run build:js # Build SVGs and other JS ``` For other scripts, look in `package.json`. ### Releasing Development is done in the `main` branch, but releases are made from the `publisher-production` branch (it will go away once the old Publisher-triggered deploy is retired). Here's how you cut a release: - From `main`: - Document changes in the [`CHANGELOG`](https://github.com/mapbox/assembly/blob/main/CHANGELOG.md). - Increment the version key in `package.json` and `package-lock.json`. - Make sure all this is committed, typically with a commit message like `Prepare 0.8.0`. - Merge these changes into the `publisher-production` branch. _Conduct the following steps from `publisher-production`_. - From `publisher-production`: - Create a tag matching the version, prefixed with `v`. For example: `git tag v0.8.0`. - Push the tag: `git push origin v0.8.0`. - This triggers the `NPM release` GitHub Actions workflow, which publishes to npm via [Trusted Publishing](https://docs.npmjs.com/trusted-publishers/) (OIDC) — no npm token needed. - Any prerelease tag (a version containing `-`, e.g. `v0.8.0-dev.0`) publishes under the npm `dev` dist-tag instead of `latest`, and can be cut from any branch for testing. - Non-dev tags must point to a commit on `publisher-production`, or the workflow fails fast.