Releases: minimaldesign/mCSS
Release list
mCSS 1.4.1
mCSS 1.4.1 is a one-bug release, the .layout scaffold grew a horizontal scrollbar on PC (#72).
What's fixed
100vwremoved from layout. Where the vertical scrollbar takes layout space (Windows, Linux, and macOS set to "Always show scroll bars"), its gutter sits inside100vwbut outside the width the page actually has to fill..layoutput that on the<body>, so every scaffolded page overflowed by the scrollbar's width, and the browser added a horizontal scrollbar along the bottom.- Header menu and read progress bar size set to
width: 100%. Both areposition: fixed, so a percentage resolves against the initial containing block, without the gutter100vwcounts. It's more consistent and removes the precedent of using100vwanywhere.
If you already copied these files
Either swap those 3 files with the new version, or edit them as described:
global.layout.css: delete thewidth: 100vw;line from.layout.component.header.css: the fixed> divmenu panel goes fromwidth: 100vwtowidth: 100%.component.readProgressBar.css: in@keyframes bar, thetostep goes fromwidth: 100vwtowidth: 100%.
Nothing else changed.
The full list is in the changelog. Built something with mCSS? Come show it off in the discussions.
mCSS 1.4.0
mCSS 1.4.0 draws the line the framework was always reaching for: structure on one side, design on the other. Every design value now lives in the default theme, one swappable file your own theme overrides, and the new external layer finally makes third-party CSS trivial to override (#65).
mCSS follows the copy-it-you-own-it model: there is no package to update. Grab dist/mcss.css (or mcss.min.css), copy the pieces you want, and edit them like anything else you wrote.
What's new
- The default theme.
theme.default.css(importingtheme.default.tokens.css+theme.default.ui.css) holds every design value the framework uses: raw tokens on one side, UI tokens on the other. The framework files are pure structure and never need editing; a theme is now genuinely one file of design decisions, and small ones go far because every component reads UI tokens like--ui-border-colorinstead of raw values. theme.starter.cssis the starting point for your own theme, andtheme.wireframe.cssshows the full-theme pattern: an entry that composes the default theme and overrides on top, activated INSTEAD of the default.- The
externallayer. Import a vendor stylesheet with@import url(…) layer(external);and it beats the framework but loses to all your unlayered CSS, at any specificity. No more fighting a datepicker's selectors: your one-class rule wins. Fixes to vendor styles get their ownpatch.*.cssconvention. - The layer statement can't drift anymore. It's deliberately duplicated (theme files pin it, docs quote it, dist ships it), so
mcss.cssis now the single source of truth: the build derives the dist statement from it and a newcheck-layers.mjsguard (pre-commit + CI) fails when any copy disagrees. - The docs got a full restructure, organized around what you're doing instead of mirroring the file tree: Getting Started, Installation, Default HTML, Default Theme, Layout, Components, Helpers, Browser Support, AI Agents. Every page got a copy rewrite and a fact-check sweep against the framework source. Old URLs (and their
.mdtwins for AI agents) 301 to the new homes.
Breaking changes
- Your entry must activate the default theme.
mcss.cssno longer carries design values; nothing paints without@import url(./framework/theme.default.css);right after it. Drop-in users are unaffected:dist/mcss.cssbakes the default theme in. settings.tokens.css/settings.ui.cssare nowtheme.default.tokens.css/theme.default.ui.css, and thethemelayer split intotheme.defaultandtheme.user. The full statement isbase, elements, global, components, theme.default, theme.user, external, helpers. Your theme self-layers intotheme.userand beats the default regardless of import order.- The feedback alias tier is gone:
--success-*/--danger-*/--warning-*are removed; use the--yes-*/--no-*/--maybe-*palettes directly. - Docs URLs moved (tokens/themes → default-theme, reset/elements → default-html, global/media-queries → layout, template → components). All old URLs 301, including the markdown twins.
The full list is in the changelog. Built something with mCSS? Come show it off in the discussions.
mCSS 1.3.0
mCSS 1.3.0 makes the compile floor match what the docs have always claimed. The framework targets Baseline 2024 now, and postcss-preset-env stops polyfilling the features mCSS was built to use natively. The visible result: dist/ ships light-dark(), native nesting, and relative color syntax exactly as written, and gets smaller doing it (#56).
mCSS follows the copy-it-you-own-it model: there is no package to update. Grab dist/mcss.css (or mcss.min.css), copy the pieces you want, and edit them like anything else you wrote.
What's new
dist/is genuinely polyfill-free.dist/mcss.cssdrops 403--csstools-*scratch declarations and the@supportstriplets that came with them: 130 kB raw (was 159), 94 kB minified (was 121), 15.9 kB min+gzip (was 17.8). Nesting was being silently flattened by the same too-broad floor, so the shipped files now match the source rule for rule.- The polyfill was not only a weight problem. Inside
@layer theme, preset-env's@supports not (color: light-dark(…)) { :root * { … } }rule beat a component's own token override in@layer components. That whole class of cascade surprise is gone. - The PostCSS setup post documents the new floor: why the query is
baseline 2024and notbaseline widely available(which resolves to Chrome 121, belowlight-dark()'s Chrome 123, so the polyfill still fires), the browserslist 4.25 requirement, agrep -c "csstools"check that should print0, and a troubleshooting entry for when the toggle variables show up anyway. It also now shows wherepostcss-mixinsgoes in the plugins array, which it had told you to install without ever placing it (#58). - New post: Building a component system that scales. The one rule that keeps a component system from rotting, a selector may only contain classes from its own block, with what coupling looks like and the correct ways to create context.
- The AI agents rules block and Getting Started grew the conventions that post argues for: one block per file, no raw colors or type sizes in a component, the
global.print.cssexception, why globals lose to components, and the theme's real remit (theme files are the one place allowed to select framework classes from outside, and abodyrule belongs there rather than in project CSS).
Breaking changes
- The browser support floor is now Baseline 2024.
.browserslistrcisbaseline 2024, which resolves to Chrome/Edge 130, Firefox 132, Safari 18.2 or newer. The old floor (defaults and supports css-cascade-layers) bottomed out at Chrome 109, two years short oflight-dark(), which is why the polyfill was firing at all. - Browsers from the 2022 to 2024 window are no longer supported. In them, tokens holding
light-dark()make the properties that consume them invalid at computed-value time, so colors come out unset rather than falling back to the light palette. The docs used to claim the light palette as the fallback; that claim was wrong for tokens under either floor, and has been corrected.
If you still need that window, build from source with your own lower .browserslistrc (or force features: { 'light-dark-function': true } in your preset-env config) and accept the polyfill along with the cascade caveat above. The framework source is unchanged; only the target it compiles against moved.
The full list is in the changelog. Built something with mCSS? Come show it off in the discussions.
mCSS 1.2.0
mCSS 1.2.0 splits the drop-in framework file in two. mcss.css is now the framework core on its own (~17 KB min+gzip), and the component library moves into its own file, mcss.components.css (~5 KB min+gzip). If you build your own components on top of mCSS, you stop shipping a library you never use. If you want the library, you add one more line.
mCSS follows the copy-it-you-own-it model: there is no package to update. Grab dist/mcss.css (or mcss.min.css), copy the pieces you want, and edit them like anything else you wrote.
What's new
mcss.components.css: the component library has its own entry file. All 25component.*.cssfiles import there wrapped in@layer components, anddist/gains the matching drop-insmcss.components.cssandmcss.components.min.css.- Import order between the two files does not matter.
mcss.cssdeclares the layer order, so the library lands in itscomponentsslot wherever you put the link, exactly like the existingthemeslot:
<link rel="stylesheet" href="mcss.min.css" />
<link rel="stylesheet" href="mcss.components.min.css" /><!-- optional -->- Getting Started leads with installation now, comparing the source-plus-PostCSS route against the drop-in files so you can pick before reading the methodology.
- New post: How to Set Up PostCSS for mCSS. The full build setup, why the config is mostly a list of things PostCSS must not touch, how to verify it worked, and what each failure mode looks like.
Breaking changes
dist/mcss.cssanddist/mcss.min.cssare the framework core only. Settings, base, elements, global, and helpers, plus the emptycomponentsandthemelayer slots. If you use the component library, adddist/mcss.components.min.cssnext to it, or your components will lose their styles.- Source consumers:
framework/mcss.cssno longer importscomponent.*.css. Add@import url(./framework/mcss.components.css);to your entry file next to the existing framework import (see_global.css).
Nothing changed inside the components themselves. Every class, token, and Astro component works exactly as it did in 1.1.0; this release is only about which file they arrive in.
The full list is in the changelog. Built something with mCSS? Come show it off in the discussions.
mCSS 1.1.0
mCSS 1.1.0 folds CardList and FeatureGrid into a single container-responsive list component, Tiles. The same markup fits as many columns as the column it sits in can hold, so a list is 2-up in a docs column and 4-up in a wide one at the same window size, no viewport breakpoints involved. Read the Tiles docs.
mCSS follows the copy-it-you-own-it model: there is no package to update. Grab dist/mcss.css (or mcss.min.css), copy the pieces you want, and edit them like anything else you wrote.
What's new
- Tiles (
component.tiles.css,Tiles.astro): one container-responsive list for cards, feature items, pricing tiers, anything repeated at one size. Columns appear as the nearest size container crosses the tile size's thresholds, so the count answers the width of the column the list sits in, not the viewport. Sizes name the tile:.tiles/.tiles-mdfor card-sized tiles,.tiles-smfor icon + blurb items. No column cap, and--tiles-columnson a hook class pins the count when you need to. - Every
.layoutscaffold now declares its main column as a named size container (container: main / inline-size), which is what Tiles responds to inside a scaffold, and what your own@container main (…)rules can use. Outside a scaffold, wrap a list in.tiles_container. - The blog index goes 4-up on a laptop purely by widening its page column (
--layout-content-width), no per-list tuning: the pattern to copy for wide listing pages.
Breaking changes
.cardListand.featureGridare gone, replaced by Tiles.<ul class="cardList grid" col="1" col-md="2" col-lg="3">becomes<ul class="tiles">, and<ul class="featureGrid grid" …>becomes<ul class="tiles tiles-sm">. The.featureItemmarkup inside is unchanged.- The lists no longer ride on the
.gridattribute system (unchanged for your own grids): you pick the tile size, and the container's width decides the columns. CardList.astro/FeatureGrid.astroare replaced byTiles.astro(size="sm"for the former FeatureGrid); thecolsprop is gone.
Fixed
getInitials(the Avatar byline helper) doubled the first letter of a single-word name, so "Yann" rendered as "YY". Single-word names now yield one initial; pre-computed initials like "SR" still pass through untouched. (#51)- The wireframe theme's per-element sketch tilt is live again: postcss-preset-env's
random-functionpolyfill is disabled, so nativerandom()passes through instead of freezing into one static value (which also churneddist/on every edit).
The full list is in the changelog. Built something with mCSS? Come show it off in the discussions.
mCSS 1.0.0
The official launch. Everything from the 0.9 beta reviewed, restructured, and built out into a full component framework for websites. Read the announcement post, or jump straight to the docs.
mCSS follows the copy-it-you-own-it model: there is no package to install or update. Grab dist/mcss.css (or mcss.min.css), copy the pieces you want, and edit them like anything else you wrote.
Highlights
- Component library: 26 documented components, from atoms (button, badge, toggle) through content patterns (card, hero, FAQ, testimonial, pricing, pagination) to full page chrome (header with mobile menu, footer, banner). Plain HTML + CSS first, with optional Astro components. Every one is dogfooded on mcss.dev.
- Theme system: a theme is one CSS file that reskins your whole site. Themes get their own cascade layer, above the framework and below your own CSS.
theme.default.cssis a copyable starting point, andtheme.wireframe.css(a hand-drawn wireframe skin) is the worked example. See the themes docs. - Native cascade layers:
settings, base, elements, global, components, theme, helpers. Layer order, not import order or specificity, decides priority, and your own unlayered CSS beats the framework by default. - Layout library: six page-level scaffolds (
.layout,.layout-centered,.layout-sidebar,.layout-docs,.layout-split,.layout-cover) with full-page demos and thumbnail diagrams in the layouts docs. - Marketing template: a complete one-pager built only from the framework and library components, with a runtime theme switcher. Live demo.
dist/build: the whole framework pre-processed as a drop-in file, plus per-file copies indist/css/, committed and kept fresh by CI.- Docs for AI agents:
/llms.txt,/llms-full.txt, and a markdown twin of every docs page. See the AI docs. - MIT license.
Breaking changes since 0.9
- Helper class short forms removed; use the full names.
- Component
extraClassprops renamed toclass. - The
atomslayer collapsed intocomponents;atom.*files are gone. - The 0.9
global.layout.cssinternals replaced by the layout scaffolds above. - The unused
pageslayer removed from the layer order. settings.theme.default.cssrenamed tosettings.ui.css; "theme tokens" are now "interface tokens", and themes live intheme.*.cssfiles.--theme-border-colorand--theme-shadow-colorrenamed to--ui-border-colorand--ui-shadow-color.- Docs URLs lowercased on mcss.dev.
The full list of changes is in the changelog. The last pre-1.0 state of the old file tree is preserved under the v0.9.0 tag.
If you build something with mCSS, come show it off in the discussions.
v0.9.0
The last release with the atoms cascade layer.
mCSS v1 folds atoms into components:
atom.badge.css,atom.button.css, andatom.toggle.cssbecomecomponent.*.css- the
atomslayer is removed from the layer list (@layer settings, base, elements, global, components, pages, helpers) - class names (
.bt,.badge,.toggle), theme tokens, and docs URLs are unchanged
If you copied atoms-era files into your project and want matching versions, copy them from this tag.