Skip to content
PolyFish CSS

Changelog

Every release, newest first. Bullets are tagged Added Changed Fixed Removed, and anything requiring a change to your markup carries a migration note.

Current: 1.0.0-rc.2 11 CSS modules Semantic versioning

What a version number promises

Inside a major version, class names and token names keep their meaning. Values may be tuned and components may gain variants, but existing markup keeps rendering. Removals wait for a major and are deprecated in a minor first. Token values are not covered by that promise — if you pin a hex instead of reading the token, a palette change will reach you.

show
Filters every release at once. Radio inputs and :has().
1.0.0-rc.2 September 2026 Added

Print, font-loading stability, and the contribution path.

No entries of this kind in this release.

  • Added Metric-matched fallback fonts. Three @font-face declarations give Arial and Courier New the real faces' ascent, descent and average width, and each stack names its fallback before the generic families. The browser lays out at the right line height and width immediately, so the web font lands into a box that already fits instead of rewrapping every heading. Every number is read out of the shipped woff2 with fontTools, not estimated.
  • Added A real print stylesheet. It was one line — hiding four elements. It now forces a black-on-white palette, drops navigation, sidebars, tab controls and copy buttons, opens every tab panel and accordion so nothing hides behind a control that cannot be clicked, prints the address after each external link, and sets page-break rules so headings are not stranded at the foot of a page and tables are not split across two.
  • Added .pf-no-print and .pf-print-only.
  • Added CONTRIBUTING.md stating the eight conventions a new component has to follow, and GitHub issue templates that ask for the viewport width — the static checks cannot see layout, and a width is usually the whole clue.
  • Added A build check on .well-known/security.txt: it fails on a lapsed Expires date and warns within thirty days of one. A stale contact is worse than no file.
  • Added Print and font-loading documentation on the performance page, including the measured metrics table.
1.0.0-rc.1 September 2026 Added · Changed

API freeze candidate. Cascade layers, full RTL support, and the last renames this framework intends to make.

No entries of this kind in this release.

  • Added Every module is in a cascade layer. Rules live in polyfish.<module>, and each file declares the full layer order so it holds whatever order you link them in. Unlayered CSS beats layered CSS regardless of specificity, so your own stylesheet now overrides any framework rule with a plain class selector — no !important, and no dependence on Utilities loading last.Migration: If you were beating the framework with !important or duplicated selectors, you can delete that. If you want your own CSS layered too, declare @layer polyfish, app; and put your rules in app.
  • Changed Every physical property is now logical. 182 margin-left, 34 padding-left, 18 border-left, 20 positioning offsets and 16 text alignments became their inline-start and inline-end equivalents. A document with dir="rtl" mirrors itself with no second stylesheet and no [dir] selectors.
  • Changed Directional spacing utilities are .pf-ms-*, .pf-me-*, .pf-ps-* and .pf-pe-*; alignment is .pf-text-start and .pf-text-end. The old names implied a physical side while applying a logical one.Migration: All 48 old names are aliased one-for-one in PolyFishCSS-Compat.min.css. Rename at your leisure and drop the file.
  • Added Right-to-left example — the same components with Arabic copy and one dir attribute.
  • Added Two build guards: a physical-property check that fails if margin-left and friends reappear in a module, and a layer check that fails if a module stops declaring the layer order. Both protect a guarantee that is otherwise invisible until someone reads the site in Arabic or fights the cascade.
  • Added Cascade-layer and RTL documentation on the installation page, and the directional renames in the migration table.
0.16.0 September 2026 Changed · Added

The release-blocking work for 1.0: token names, licences, versioning, tooling and distribution.

No entries of this kind in this release.

  • Changed Palette tokens name position, not hue. The neutral ramp is --pf-base-50 through --pf-base-950; the accents are --pf-hue-1 and --pf-hue-2. A token called --pf-blue-800 held #f4f7fa in the cream theme and --pf-green held #ccff00 in the electric one — correct in one palette, lying in every other.Migration: Load PolyFishCSS-Compat.min.css after Core and existing markup keeps working. Full mapping on the tokens page. If you retinted by declaring --pf-green yourself, rename it to --pf-hue-1 — the shim lets old names read new values, not the reverse.
  • Changed Colour-named helpers now name the role: .pf-fg-accent, .pf-bg-accent-wash, .pf-btn--accent-2, .pf-pill--accent, .pf-footer--accent and the rest.Migration: Covered by the compatibility file, or rename twelve classes and delete it.
  • Added PolyFishCSS-Compat.css, 1 KB, aliasing every renamed token and class. It will be removed at 2.0, not before.
  • Added Font licences. The SIL Open Font License text for Inter, Bricolage Grotesque, IBM Plex Sans and IBM Plex Mono now ships in fonts/ alongside the woff2 files, with a README naming each family, its copyright and its upstream. Redistributing the fonts without them was a licence violation.
  • Added One version, derived everywhere. VERSION is the only place a number is typed. tools/release.py stamps the sources, rebuilds the minified modules and bundle, rewrites every asset URL with a content hash, refreshes the integrity hash, regenerates CHANGELOG.md, and aborts if verification fails.
  • Changed Asset URLs carry a content hash rather than a hand-typed version. Editing one module re-downloads that module, not the other eleven, and a stale query string is now impossible to forget — the verifier recomputes every hash and fails on a mismatch.
  • Added The tooling ships with the source. tools/verify.py (thirteen check groups), tools/release.py and tools/test-polyfish.cjs (fifteen jsdom assertions) live in the repository rather than in somebody's terminal history.
  • Added Browser tests. tests/polyfish.spec.js covers Chromium, Firefox, WebKit, iPhone and Pixel at 320, 768 and 1440: horizontal overflow, touch-target size, the 16px field floor, palette agreement, contrast, the no-script contract, the enhancements, reduced motion, and full-page screenshot baselines.
  • Added Distribution: package.json with per-module exports, README.md, a generated CHANGELOG.md, and a CI pipeline running static verification, W3C validation, an nginx -t on the published config, the jsdom suite, five browser matrices, and a check that re-running the release produces no diff.
0.15.0 September 2026 Fixed · Changed · Added

A layout bug in the steps component, and more room between everything.

No entries of this kind in this release.

  • Fixed .pf-steps put every child after the first into the next grid row, inside the 2.2rem number column. A step with a heading and a paragraph rendered the paragraph roughly one character wide. Children are now placed in the content column explicitly.Migration: No markup change. If you worked around this by using one child per step, you can now use a heading plus body text as documented.
  • Changed More space between major blocks on the component reference and the documentation home: larger stack gaps, hairline dividers between example groups, and a step up in heading size for each group.
  • Added The documentation home is now a landing page — three entry points by intent, a directory of all eleven interactive panels, the module decision table and the browser baseline.
  • Added The about page explains what the framework is actually for: it is the front end of a technical publication, and every constraint in it came from shipping one.
  • Added Platform credit in the footer on every page.
0.14.0 September 2026 Added · Fixed

Interactive documentation on every page.

No entries of this kind in this release.

  • Added .pf-text-2xl through .pf-text-5xl. The display steps had tokens but no utilities, so a heading that needed one had no class to reach for.
  • Added Eleven interactive panels across the documentation: page-region swapping, live retinting, a type-scale explorer, a module composer showing what each file unlocks, a link-block assembler, a real iframe previewer at device widths, a per-page-type weight breakdown, an attribute builder for the optional script, accessibility guards you can switch on, a component state matrix and a changelog filter. 109 controls, all radio inputs, checkboxes and :has().
  • Added tools/verify.py ships with the site: thirteen groups of checks over every page and stylesheet, exiting non-zero on failure so it works as a deploy gate. tools/README.md documents what each group catches.
  • Fixed pf-no-ring was used on the accessibility page and defined nowhere. It is docs-only, so it is now demo-no-ring in the site stylesheet.Migration: If you copied that class from the page source, it never existed in the framework.
  • Changed Site chrome no longer uses the pf- prefix. pf-chips, pf-ref__head and pf-ref__family were documentation styles squatting in the framework namespace, which is how a reader ends up copying a class that does not ship.
0.13.0 September 2026 Changed · Fixed · Added

Darker palette, cache-busted assets.

No entries of this kind in this release.

  • Changed Background ramp is darker again: --pf-base-900 #00030f, --pf-base-800 #000823 (page), --pf-base-700 #000f3f (raised surfaces), --pf-base-600 #17306e. Contrast improved across the board — body text 17.1:1, accent 12.3:1.Migration: Re-check any custom accent against the new backgrounds; a colour tuned for the old page will now sit on something two steps darker.
  • Fixed Stylesheet and script URLs now carry ?v=. They are served immutable for a year, so a returning visitor kept the previous CSS until the cache expired — a palette change reached new visitors only, and the same page could render in two different colour schemes depending on who was looking.Migration: If you copy this site's nginx config, keep the immutable header and version the URL. One without the other is the bug.
  • Fixed Three rules still carried the original 2016-era navy as a hardcoded rgba(): the light-mode surface tints, the photo-hero gradient and the gallery tile overlay. They ignored the palette entirely.
  • Fixed Home page described the framework as five files; examples index claimed nine pages. Eleven and eleven.
  • Added Audit checks for unversioned assets and for palette agreement — every page must resolve the same dark ramp.
0.12.0 September 2026 Changed · Added

Brighter accent, wider default spacing, expanded docs.

No entries of this kind in this release.

  • Changed --pf-accent is now #8fe06a (was #a9cc9a); --pf-hue-1-deep is #6dc44a (was #87ab79). Contrast against --pf-bg is 11.6:1, and 12.4:1 for --pf-base-950 on an accent fill.Migration: If you pinned the old hex anywhere instead of reading --pf-accent, update it or set the token back in your own stylesheet.
  • Changed --pf-section-pad is clamp(5rem, 11vw, 9.5rem), --pf-gap is clamp(1.5rem, 3vw, 2.5rem) and --pf-gap-lg is clamp(2.5rem, 5.5vw, 4.5rem). Hero padding, page-head padding, card padding, step gaps and footer padding all scale with them.Migration: Pages will get taller. Override the three tokens on a wrapper to restore the previous rhythm.
  • Changed .pf-space-7 through -9 are now 3.5rem, 5.5rem and 8.5rem (were 3rem, 4.5rem, 7rem). .pf-stack now uses --pf-gap rather than --pf-space-5.
  • Added Prose rhythm in Content: .pf-prose children get vertical spacing from the space scale, with larger gaps above h2 and h3 than below them.
  • Added Browser-baseline table in the docs listing each CSS feature the framework uses, the version it landed in, and the degradation if it is missing.
  • Added Theming docs: annotated theme file, all eleven theme-carrying roles, the five contrast pairs to re-check after a retint, and how to scope a theme to a subtree.
0.11.0 September 2026 Added · Changed · Removed

Site-wide header and footer templating. Framework unchanged apart from brand tokens.

No entries of this kind in this release.

  • Added --pf-brand, --pf-brand-2 and --pf-brand-deep for the mark's violet and teal, plus .pf-brand-well, .pf-fg-brand and .pf-brand-rule. These are deliberately separate from --pf-accent so a retint does not recolour your logo.
  • Changed The documentation site now builds its header from one template. Not a framework change, but the examples show the pattern if you are hand-writing the same nav on twenty pages.
  • Removed /docs/preview. The app-shell demo moved to /examples/app-shell; the old URL 301s.
0.10.2 September 2026 Changed · Fixed

Build-time module derivation.

No entries of this kind in this release.

  • Changed Module sets are derived from the classes a page actually uses, rather than from a declared list. Pages that used no Effects classes stopped loading Effects (1.6 KB gzipped each).
  • Fixed Class reference page was not linked from anywhere on the site.
  • Fixed Bottom bar on one demo page lacked pf-has-bottombar on <body>, so the bar overlapped the footer.Migration: Any page using .pf-bottombar needs .pf-has-bottombar on the body element for the padding compensation.
0.10.1 September 2026 Changed · Fixed

Bundle threshold and heading order.

No entries of this kind in this release.

  • Changed Pages loading eight or more modules now ship PolyFishCSS.min.css. Measured crossover: eight separate modules are 19.8 KB gzipped in eight requests, the whole bundle is 19.3 KB in one.
  • Fixed Generated reference skipped from h2 to h4; one example page from h1 to h3. Both broke heading-list navigation.
  • Fixed Six example pages had no aria-current on their navigation.
0.10.0 September 2026 Added

Complete class reference, proportional widths, two real-world examples.

No entries of this kind in this release.

  • Added Class reference covering all 1,443 public classes, grouped by module and family, generated from the CSS on every build.
  • Added Proportional width utilities: .pf-w-0 through .pf-w-100 in steps of five, plus .pf-w-1-2, -1-3, -2-3, -1-4, -3-4 and fifths.Migration: Use these for progress bars and meters instead of an inline style, so your Content-Security-Policy does not need unsafe-inline.
  • Added Examples: corporate site and product page.
0.9.0 September 2026 Added · Changed

Effects module.

No entries of this kind in this release.

  • Added PolyFishCSS-Effects.css: transforms, filters, gradients, rings, six opt-in animations, scroll-snap helpers, transition control and the .pf-group hover pattern. 92 rules, 6 KB minified.
  • Added Transforms compose through custom properties, so .pf-translate-y-2 and .pf-rotate-45 combine instead of the second overwriting the first.
  • Added .pf-gradient-text declares a flat fallback colour before background-clip: text, so unsupported engines show colour rather than invisible text.
  • Added Playground: swap header, hero, body and footer variants and retint the result. Radio inputs and :has(), no script.
  • Changed Animations live inside prefers-reduced-motion: no-preference rather than relying on a global duration override. An animation starting at opacity: 0 is now not applied at all when motion is reduced.
0.8.0 September 2026 Changed

Darker palette.

No entries of this kind in this release.

  • Changed Background ramp is #000824 (deepest), #000d3d (page) and #001158 (raised surfaces). --pf-base-50 is #e9eefa, --pf-base-300 is #a9bcd8, --pf-base-950 is #00081f.Migration: All thirteen contrast pairs were re-checked and land AAA. If you themed on top of the old blues, re-check your own accent against the new backgrounds.
  • Changed theme-color and the web manifest updated to match.
0.7.0 September 2026 Added

Mobile navigation patterns.

No entries of this kind in this release.

  • Added .pf-drawer offcanvas panel, .pf-bottombar mobile tab bar and .pf-toast live region in Components.
  • Added .pf-table--stack turns a table into labelled rows below 620px, reading each cell's label from data-pf-label.
0.6.0 September 2026 Added

Documentation pages for accessibility, performance and responsive behaviour.

No entries of this kind in this release.

0.5.0 September 2026 Added · Removed · Fixed

Space module and mobile hardening.

No entries of this kind in this release.

  • Added PolyFishCSS-Space.css: padding, margin, gap, grid tracks, flex sizing and placement, with six families repeated at four breakpoints. 265 rules, 19.5 KB minified, 2.8 KB gzipped.
  • Added .pf-scroller, a snap-point horizontal row. This is the framework's answer to a carousel: no autoplay, no hidden slides, no script.
  • Removed Spacing, margin and gap utilities from PolyFishCSS-Utilities.css; Space owns them now.Migration: Load Space alongside Utilities if you use .pf-mt-*, .pf-p-* or .pf-gap-*. Two modules declaring the same class was a maintenance trap.
  • Fixed Form fields are floored at 16px under pointer: coarse. Anything smaller makes iOS Safari zoom on focus and never zoom back.
  • Fixed The mobile menu now caps at 100dvh minus the bar and scrolls; a long menu on a short screen was unreachable.
  • Fixed min-height: 100vh on body paired with 100dvh.
  • Fixed Menu popover capped with max-width: min(18rem, calc(100vw - 2rem)).
  • Fixed Tab strip scrolls horizontally below 620px instead of overflowing.
  • Added env(safe-area-inset-*) on container gutters, mobile menu and footer; touch-action: manipulation on interactive elements.
0.4.0 September 2026 Added · Changed

Optional JavaScript layer.

No entries of this kind in this release.

  • Added polyfish.js, 7.9 KB minified. Nine opt-in enhancements: data-pf-menu, data-pf-tabs, data-pf-dialog, data-pf-copy, data-pf-counter, data-pf-dismiss, data-pf-sort, data-pf-spy and data-pf-theme-toggle.Migration: Every component still works without it. Adding the file changes nothing until you mark an element up.
  • Added PolyFish.init(container) for content injected after load. Idempotent — elements record which enhancements they already have.
  • Added .pf-code__copy and .pf-th-sort in Content, styling the two elements the script creates. The script never injects CSS.
  • Changed If you copy this site's Content-Security-Policy, script-src goes from 'none' to 'self'. The script tag carries a sha384 integrity hash.
0.3.0 September 2026 Added

Automatic light mode, container queries, forms.

No entries of this kind in this release.

  • Added PolyFishCSS-Forms.css: input sizes, floating labels, validation feedback, fieldsets, range and file inputs, option cards, form rows and counters.
  • Added Light mode follows prefers-color-scheme. Pin it with data-pf-theme="light" or "dark" on <html>.Migration: Only the palette is redeclared, so your components follow automatically. The accent darkens in light mode — a pastel that passes on navy fails on near-white.
  • Added Container queries: .pf-container-q with .pf-cq-row, .pf-cq-2, -3, -4, .pf-cq-side.
  • Added Validation styling keys off aria-invalid and :user-invalid, not a class. :invalid matches an empty required field on load.
  • Added Icon buttons, link buttons, aria-busy loading state, .pf-stretched-link, a three-step shadow scale, divide utilities, and six table variants including sticky headers.
0.2.0 September 2026 Added · Changed

Grid and Components modules.

No entries of this kind in this release.

  • Added PolyFishCSS-Grid.css: twelve columns across five breakpoints, with offsets, order and per-row gutters. Use it when proportions change per breakpoint; .pf-grid--3 is one class and handles its own.
  • Added PolyFishCSS-Components.css: badges, chips, button groups, pagination, progress, meters, spinners, list groups, avatars, switches, input groups, tabs, disclosure menus, dialogs, tooltips, ratio boxes, skeletons, empty states, dividers and toolbars.
  • Added Responsive utility variants at four breakpoints, using infixes (.pf-md-hidden) rather than an escaped colon — there is no compiler here to do the escaping.
  • Changed .pf-col now belongs to Grid (a twelve-column span). The flex-direction helpers are .pf-flex-col and .pf-flex-row.Migration: Breaking if you used .pf-col for flex-direction: column. Rename to .pf-flex-col.
  • Changed The removable chip is .pf-chip, not .pf-tag. Content uses .pf-tag for markup-tag colour inside code blocks.Migration: Breaking if you used .pf-tag for chips. Rename to .pf-chip.
0.1.0 September 2026 Added

First release. Five files, one required.

No entries of this kind in this release.

  • Added Core: two-layer design tokens, reset, fluid type scale, layout primitives, buttons, focus handling, reduced-motion block.
  • Added Headers: announcement bar, sticky navigation with a checkbox-driven mobile menu, four hero variants, page headers, breadcrumbs.
  • Added Content: sections, cards, feature and pricing grids, stats, tables, alerts, code blocks, forms, accordions, galleries, steps, CTA bands.
  • Added Footers: column, slim and accent footers.
  • Added Utilities: spacing, alignment, colour and visibility helpers.

Other things you can poke

Every documentation page on this site has something interactive in it: swap page regions, retint a live page, change the type scale, see what each module unlocks, assemble your link block, frame a real page at 320px, weigh a page type, build an attribute list, turn the invisible guards on, flip a component through its states and filter the changelog by tag. All of it is radio inputs, checkboxes and :has() — no script runs any of it.