Skip to content
PolyFish CSS

Migrating to 0.20

Class by class from Bootstrap, Tailwind and earlier PolyFish releases, and what has no equivalent.

Documentation menu

01 / 01

Migrating

Coming from Bootstrap, Tailwind or a classless framework: what maps onto what, what deliberately has no equivalent, and an order of work that does not stall halfway.

Coming from another framework, most of the work is unlearning rather than learning. The tables below map what you already know onto what exists here, and name the places where there is deliberately no equivalent.

From Bootstrap

BootstrapPolyFishNote
.container.pf-containerOne measure, 987px, plus --narrow
.row / .col-md-6.pf-grid.pf-grid--2, or .pf-sidebar for unequal halvesThe twelve-column system was removed in 0.20 — the primitives carry their own thresholds
.btn .btn-primary.pf-btnPrimary is the default; --secondary, --ghost for the rest
.card / .card-body.pf-card / .pf-card__bodyAlso --numbered, --media, --facet
.alert-warning.pf-alert.pf-alert--warn--inline for a one-liner
.table-striped.pf-table--zebraWrap in .pf-table-wrap
.badge.pf-badge--dot for status
.d-flex .gap-3.pf-clusterWrapping row with a shared gap
.modal + JS<dialog class="pf-dialog">Opens from markup with invoker commands
data-bs-toggle="tab".pf-tabs with radiosWorks with no script; the optional script adds ARIA
Sass variablesCustom propertiesChange at runtime, no rebuild

No equivalent, on purpose: a carousel, a JavaScript grid system, utility classes for every property, and jQuery-era data attributes for behaviour the platform now does itself.

From Tailwind

The mental shift is larger. Tailwind composes a component out of dozens of atoms in the markup; here a component is one class and the atoms exist only for the gaps between components.

TailwindPolyFish
flex flex-col gap-4.pf-stack
flex flex-wrap items-center gap-2.pf-cluster
grid grid-cols-3 gap-6.pf-grid.pf-grid--3
mx-auto max-w-5xl px-4.pf-container
rounded-lg border bg-white/5 p-6.pf-card
hover:bg-emerald-500.pf-hover-bg-accent (Variants)
dark:text-whiteRoles flip with the scheme; no per-class variant needed
@applyWrite the rule. There is no build step to apply into
tailwind.config.js:root custom properties

What you gain: no compiler, no purge step, markup you can read aloud, and a theme that changes at runtime. What you give up: the enormous atomic vocabulary. If you want a utility for every property, keep Tailwind — that is a real preference, not a mistake.

From Pico or another classless framework

Load PolyFishCSS-Classless.css and your existing semantic HTML gets styled with no classes at all. It sits in the lowest layer, so the moment you add a pf- class, that class wins. That makes the migration incremental: start classless, add components where you need more than the defaults.

A migration that does not stall

  1. Load PolyFish after your current framework

    Both will fight for a while. Keep your old stylesheet last so nothing breaks visually on day one.

  2. Move the tokens first

    Map your brand colours onto --pf-accent, --pf-bg and --pf-text. The whole framework follows immediately.

  3. Convert page furniture next

    Header, footer, containers and sections. These are the least risky and the most visible.

  4. Then components, page by page

    Cards, tables, forms. Delete the old classes as you go rather than leaving both.

  5. Drop the old stylesheet and measure

    Check contrast and check the page at 320px. Both are where migrations leave debris.

Renamed since you last looked

Pre-1.0, a minor release may rename or remove things. Every change is listed here with its replacement, and the class reference always lists the current name. Renames from 0.16 and 0.17 are in the token table.

Renamed in 0.20

Six classes renamed to the rule the rest of the framework follows, before the API freezes for 1.0.

WasUseWhy
.pf-none.pf-hiddenBase of the pf-md-hidden/pf-lg-hidden family.
.pf-hide-sm.pf-hide-mobileHides below the 860px nav breakpoint, not the sm tier its name implied.
.pf-hide-lg.pf-hide-desktopSame, above it.
.pf-display.pf-font-displayA font-family utility named like a display utility. Now matches --pf-font-display.
.pf-mono.pf-font-monoMatches --pf-font-mono.
.pf-bordered-accent.pf-bordered-strongIt always set --pf-border-strong; the name lied.

Removed in 0.20

The aliases file is gone, so these need an edit rather than a compatibility link. Every removal has a one-for-one replacement except where the note says otherwise.

WasUseNote
PolyFishCSS-Compat.css—The alias file for the 0.16 and 0.17 renames. Rename to the current names instead; the tables above list them.
.pf-w-1-2, -1-3, -2-3, -1-4, -3-4, -1-5 ….pf-w-50, .pf-w-35, .pf-w-65, .pf-w-25, .pf-w-75, .pf-w-20Two names for one width. The percentage scale stays.
.pf-w-100, .pf-w-half.pf-w-full, .pf-w-50Same.
.pf-md-gap-*, .pf-lg-gap-* and the -px steps.pf-gap-*A gap that changes at a breakpoint is what the layout primitives already do intrinsically.
.pf-basis-*, .pf-flex-auto, .pf-flex-initial, .pf-flex-none, .pf-grow-0/1, .pf-shrink-1.pf-flex-1, .pf-grow, .pf-shrink-0Six ways to say three things.
.pf-span-1..6, .pf-row-span-2, .pf-place-*.pf-span-full, .pf-grid--2/3/4, .pf-items-* with .pf-justify-*Remains of the grid system.
Responsive alignment, order, width and text mirrors (.pf-md-items-center, .pf-lg-order-last …)The base utility, or a container query22 classes. Responsive visibility and display stay: .pf-md-hidden, .pf-md-block, .pf-md-flex, .pf-md-grid-d.
Transform utilities: .pf-translate-*, .pf-rotate-*, .pf-scale-*, .pf-flip-x, .pf-origin-*, .pf-transformA transform in your own stylesheetA static transform is one declaration and is almost always part of a component, not a page-level helper.
Filters: .pf-blur*, .pf-grayscale, .pf-saturate, .pf-desaturate, .pf-bright, .pf-dim, .pf-backdrop-blur*, .pf-filter-none.pf-frost, or your own filter.pf-frost is the one that needed the fallback work; the rest are a single declaration.
.pf-ring-1, .pf-ring-2, .pf-ring-accent, .pf-ring-danger, .pf-ring-offset.pf-ring, .pf-focus-ringThe ring section duplicated the ring utility.
Transition and timing extras: .pf-duration-*, .pf-delay-*, .pf-ease-*, .pf-transition-opacity/shadow/transform, .pf-will-change-*.pf-transition, .pf-transition-colors, and the motion tokensThe tokens (--pf-ease-out, --pf-duration-2) remain and are the supported way to time your own transitions.
Scroll snap: .pf-snap-*Your own scroll-snap-typeNothing on the site used them and snap needs per-case tuning.
.pf-blend-*, .pf-resize-*, .pf-appearance-none, .pf-caret-accent, .pf-list-disc, .pf-list-decimal, .pf-fade-bottom, .pf-fade-right, .pf-animate-bounce, .pf-animate-slide-in, .pf-group-hide, .pf-focus-border, .pf-hover-border, .pf-hover-bright, .pf-max-w-noneYour own declaration, or the nearest kept helperOne-declaration helpers nothing reached for.
Variant cross-product: .pf-disabled-*, and most .pf-hover-, .pf-focus-, .pf-active- and group combinationsThe curated nineteenKept: hover background, foreground, border, underline, shadow and lift; focus and focus-within ring; active sink and scale-down; group-hover and group-focus foreground and lift.