Field notes
Issue #12
A monthly newsletter about CSS and HTML.
mCSS is a CSS framework and component library for websites. It gives each element one semantic class, keeps its own rules in cascade layers, and needs no build step.
One mCSS class replaces 23 utility classes on the same button.
mCSS puts all of its own CSS in native @layer cascade layers, so specificity conflicts never start: anything you write outside those layers wins automatically. No !important, no fighting your framework.
helpers!important, opt-inexternalthird-party CSStheme.useryour themetheme.defaultevery design valuecomponentsthe component librarygloballayouts, prose, a11yelementsHTML element defaultsbasereset/* mcss.css: the framework's layers, lowest first */
@layer base, elements, global, components, theme.default, theme.user, external, helpers;
/* your CSS: no layer */
/* <a class="bt bt-primary signup_cta"> */
.signup_cta {
border-radius: 0; /* beats .bt.bt-primary */
}The last few years quietly made CSS spectacular. mCSS is what a framework looks like when it’s designed after that happened.
| Feature | What mCSS does with it | Support |
|---|---|---|
@layer | The whole architecture. Import order stops mattering, and your overrides always win. | Baseline Widely available (opens in a new tab) |
light-dark() | Dark mode lives in the same tokens: each color holds its light and its dark value. | Baseline 2024 (opens in a new tab) |
:has() & nesting | Components with zero specificity hacks, written the way you’d write them yourself. | Baseline Widely available (opens in a new tab) |
@scope | Prose styling that can’t leak into your components. The one feature here newer than the Baseline 2024 floor. | Baseline 2025 (opens in a new tab) |
@container | Layouts that size their columns to the space they’re in. | Baseline Widely available (opens in a new tab) |
| Custom properties | Three tiers of tokens: raw scales, semantic theme values, and per-component properties. | Baseline Widely available (opens in a new tab) |
Every color, size, and radius comes from one token file, in light and dark. Start from a theme, change a value, and every component that uses it changes with it.
Default and Wireframe ship with mCSS, Sunset is made up for this page.
:root {
--text: ui-sans-serif, system-ui, sans-serif;
--heading-font: var(--display);
--primary-600: #0284c7;
--border-sm: 1px;
--ui-border-color: light-dark(var(--base-200), var(--base-500));
--card-border-radius: var(--radius-lg);
--card-shadow: var(--shadow-md);
--bt-border-radius: var(--radius-lg);
--bt-primary-background-color: var(--primary-600);
--input-border-radius: var(--radius-md);
}:root {
--text: "Comic Sans MS", "Chalkboard SE", Chalkboard, "Comic Neue", "Segoe Print", "Bradley Hand", casual, cursive;
--heading-font: var(--text);
--heading-weight: var(--bold);
--primary-600: #525252;
--border-sm: 2px;
--ui-border-color: light-dark(var(--base-800), var(--base-200));
--wobble-1: 115px 8px 95px 9px / 7px 110px 8px 125px;
--wobble-2: 9px 105px 7px 120px / 115px 8px 100px 9px;
--wobble-3: 100px 9px 120px 7px / 8px 90px 10px 110px;
--card-border-radius: var(--wobble-2);
--bt-border-radius: var(--wobble-1);
--input-border-radius: var(--wobble-3);
--ui-shadow-color: light-dark(rgb(0 0 0 / 0.85), rgb(255 255 255 / 0.55));
--shadow-md: 4px 4px 0 var(--ui-shadow-color);
}:root {
--heading-font: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
--heading-weight: var(--semi-bold);
--base-50: #fbf3ea;
--base-950: #1d1520;
--primary-700: #b23a26;
--body-background-color: light-dark(var(--base-50), var(--base-950));
--card-bg-color: light-dark(var(--base-0), var(--base-900));
--card-border-radius: 20px;
--card-secondary-text-color: light-dark( var(--primary-700), var(--primary-300) );
--card-shadow: 0 1px 2px rgb(61 42 51 / 0.08), 0 18px 40px -18px light-dark(rgb(178 58 38 / 0.35), rgb(0 0 0 / 0.6));
--bt-border-radius: 1e5px;
--bt-primary-background-color: var(--primary-700);
--input-border-radius: 12px;
}Heroes, sections, feature grids, pricing, testimonials, FAQs, forms, article lists, and pagination, as plain HTML or as Astro components. Most of them need no JavaScript.
Card
Issue #12
A monthly newsletter about CSS and HTML.
Pricing
$0/ forever
The whole framework.
Testimonial
I stopped fighting my framework. There was nothing left to fight.
FAQ
Form field
Pagination
This site (docs, blog, this page) is built from them. Browse all the components →
mCSS doesn’t install from a package registry. You copy its source into your project, build it with PostCSS, and edit it like any other code in it. When a default doesn’t suit you, you change that line.
node_modules.styles/
├── framework/ # copied once, yours to edit
│ ├── mcss.css
│ ├── settings.*.css
│ ├── base.reset.css
│ ├── elements.*.css
│ ├── global.*.css
│ ├── component.*.css
│ ├── help.*.css
│ └── theme.*.css
├── site/
│ ├── theme.mysite.css # your design lives here
│ └── component.*.css
└── main.cssTwo lines in your <head> link the compiled framework and, if you want them, the components, with no build step. The docs cover the other installs, including how to build from source with PostCSS.
<!-- mCSS, ~16 KB min+gzip -->
<link rel="stylesheet" href="/css/mcss.min.css" />
<!-- components, ~5 KB -->
<link rel="stylesheet" href="/css/mcss.components.min.css" />Get mcss.min.css and mcss.components.min.css on GitHub.