Skip to content
Version 1.0.0-rc.2 is out. Twelve CSS modules and one optional script. See what changed
PolyFish CSS

Version 1.0.0-rc.2, no dependencies

Take the header. Leave the footer.

PolyFish is an HTML and CSS framework split into eleven files you load individually. Building a docs page with no hero and no pricing table? Then you never download the styles for one. Drop the files in, write plain HTML, ship.

  • No build step
  • No required JavaScript
  • MIT licensed
index.htmlpick your modules
<!-- required -->
<link rel="stylesheet" href="PolyFishCSS-Core.css">

<!-- everything below is optional -->
<link rel="stylesheet" href="PolyFishCSS-Headers.css">
<link rel="stylesheet" href="PolyFishCSS-Content.css">
<link rel="stylesheet" href="PolyFishCSS-Footers.css">
<link rel="stylesheet" href="PolyFishCSS-Utilities.css">
  • 5CSS files, loaded independently
  • 36 KBAll five, minified
  • 11 KBCore alone, the only required file
  • 0Scripts required to render

The five files

Every file does one part of the page

Core carries the tokens, the reset and the type scale, so it always ships. The other four map to the parts of a page you either have or don't.

PolyFishCSS-Core.css

Design tokens, reset, type scale, layout primitives, buttons, pills and focus states. Required — the other files read its custom properties.

  • Container, grid, stack, cluster, split
  • Four button variants, three sizes
  • Light-mode flip with .pf-invert

11 KB · required

PolyFishCSS-Headers.css

Everything above the fold: announcement bar, sticky navigation with a working mobile menu, four hero variants, interior page headers, breadcrumbs.

  • Mobile menu runs on a checkbox, not a script
  • Split, centred, compact and photo heroes
  • Backdrop blur with a solid fallback

7 KB · optional

PolyFishCSS-Content.css

The middle of the page. Sections, cards, feature and pricing grids, stats, tables, alerts, forms, accordions, code blocks, galleries, CTA bands.

  • Accordion is a native <details> element
  • Form controls styled down to the select arrow
  • Tables scroll horizontally instead of squashing

12 KB · optional

PolyFishCSS-Footers.css

Column footer, slim footer, green footer. Brand block, link columns, inline signup, social row, legal bar and a back-to-top link.

  • Columns collapse in one step, not four
  • Signup form reuses the Content field styles
  • Green variant recolours itself in full

4 KB · optional

PolyFishCSS-Utilities.css

Spacing, alignment, colour and visibility helpers, all reading the same tokens. The first file to drop if your project already has its own.

  • Margins and gaps on the 4px scale
  • Print rules that hide the chrome
  • Two responsive visibility classes, not twenty

4 KB · optional

Prefer one file?

PolyFishCSS.css is all five concatenated in load order. Use it while prototyping, then swap in the two or three you actually referenced.

Install

Three steps, none of them npm

  1. Copy the files you need

    Drop them next to your HTML. Core first — the rest of the files read tokens that Core defines, so load order matters.

  2. Link the fonts

    Bricolage Grotesque for display, IBM Plex Sans for body, IBM Plex Mono for code. Self-host them or use the link tag; Core falls back to system sans if neither is present.

  3. Write ordinary HTML

    Class names are prefixed pf- so nothing collides with what you already have. No wrapper divs are required beyond a container.

page skeletonhtml
<body>
  <header class="pf-nav">
    <div class="pf-container pf-nav__inner"></div>
  </header>

  <section class="pf-hero pf-hero--split"></section>

  <section class="pf-section">
    <div class="pf-container">
      <div class="pf-grid pf-grid--3"></div>
    </div>
  </section>

  <footer class="pf-footer"></footer>
</body>

Load order

Core, then Headers, Content and Footers in any order, then Utilities last so its helpers win a specificity tie.

Theming

Repaint the whole thing from eleven properties

Components never reference the palette directly. They reference roles — background, surface, text, accent, border — so overriding the roles in one block changes every module at once.

your-theme.csscss
/* loads after Core, overrides the roles */
:root {
  --pf-bg: #000823;
  --pf-bg-deep: #00030f;
  --pf-accent: #8fe06a;
  --pf-accent-2: #e5b189;
  --pf-text: #e9eefa;
  --pf-text-muted: #a1b2cf;
  --pf-radius-lg: 22px;
  --pf-cut: 18px;
}

The cut corner is a variable

Angular surfaces come from one clipped corner, sized by --pf-cut. Set it to 0 and every facet surface becomes a plain rectangle without touching a component rule.

Light islands

Add .pf-invert to any wrapper — this card, a section, the whole body — and the roles flip to a light palette locally. Nested components follow along.

Where it fits

What PolyFish does and doesn't compete with

  PolyFish Utility-first frameworks Component kits
Build step None Compiler required Usually bundled
JavaScript None None Often required
Partial loading Per file, by page region By purge output All or nothing
Markup noise One or two classes per element Long class strings Low
Theming Custom properties at runtime Config file, rebuild Sass variables, rebuild
Best for Marketing pages, docs, dashboards App UIs with a toolchain Teams wanting behaviour included

Out of scope, on purpose

PolyFish ships no modal, no carousel, no dropdown menu, no tab panel and no toast. Those need state, state needs JavaScript, and the moment a CSS framework starts shipping scripts it stops being five files you can read in an afternoon. The mobile menu is the one exception and it runs on a checkbox.

Questions

Before you download anything

Do I have to load all five files?

Only Core. Every other file assumes Core's custom properties exist and otherwise stands alone — a docs page that loads Core and Content, and nothing else, renders correctly.

Does it work without the web fonts?

Yes. The display, body and mono stacks each fall back to a system face. The type scale, spacing and layout are unchanged; only the letterforms differ.

Why is the mobile menu a checkbox?

So the framework has no script to load, no init call to forget and nothing to break when your bundler moves. The checkbox sits before the menu in the markup and a sibling selector opens it. The label is keyboard focusable and the state is real.

Can I use it on a light background?

The default palette is dark navy because that is what the framework was designed against. Add .pf-invert to the body — or to one section — for a light palette that reuses the same accents.

Is there a Sass source?

No. The files are hand-written CSS with custom properties, which is the point: what you download is what you read, and you can edit it in place without a compiler.

Five files. Start with one.

Take Core, add whatever the page actually has, and delete the rest from your project folder.