What's new in 5.0
Jellyfish 5.0 is a ground-up modernisation: a semantic colour system with dark mode, a full design-token layer, fluid type, a CSS Grid engine, and native <details> / <dialog> components. This page is the map — each item links to the detail.
New
| Feature | What it is |
|---|---|
| Dark mode | On by default. .jf-dark / .jf-light on <html> force a mode, data-default-theme="dark|light|system" declares the site default (ignoring the OS), and failing both, prefers-color-scheme decides. JellyfishTheme JS + [data-theme-toggle] markup persist a visitor's choice with no flash. |
| Semantic colour system | Every family exposes --jf-color-{family}-{subtle | muted | emphasis | strong} role aliases and paired --jf-color-on-* text colours. Components consume roles, so they flip and re-theme for free. |
| Surfaces | .bg-{family}, .bg-soft, .bg-inverse and .bg-base (reset to the page canvas) set a self-contained surface — background, text, headings and the muted / subtle tiers, all readable and theme-aware. Cards, callouts and modals are surfaces too. |
| Design tokens beyond colour | Spacing, line-height, radius, border width, elevation and motion are all token scales (--jf-space-*, --jf-radius-*, --jf-shadow-*, --jf-transition…) with get-space() / get-radius() / … accessors. |
| Fluid type | A rem scale where md–6xl are build-time clamp(), sliding with the viewport. New type($step) mixin sets size + paired line-height together. |
| CSS Grid engine | A real .grid alongside the flex .row. Fluid .container, an optional .page cap, .bleed* full-bleed helpers, .auto-grid and .subgrid-rows. |
| Native accordions | <details> / <summary>. Open / close, keyboard and screen-reader support are the browser's; JS is optional (events, deep-linking). |
| Native modals | <dialog>. Focus trap, top layer and Esc are native; the script adds a close button, backdrop-click, groups and events. |
| Native validation states | :user-invalid / [aria-invalid] style controls automatically; new .form-hint / .form-error and fieldset.is-plain. |
| Sections | .section — a full-width band with consistent, fluid vertical space and a single seam between stacked sections. |
| Icons | .icon + @mixin icon() — a mask-based SVG icon in the current text colour, sized to the font. Point --jf-icon at a URL. |
| Image ratios & fit | .ratio-* on an <img> crops it; .object-cover / .object-contain utilities. |
| Scroll offset | --jf-scroll-offset — set it to a sticky header's height so #fragment landings clear it. |
| Contrast linter | Colour pairs are scored against WCAG 2.x contrast ratios (4.5:1) at build time; a failure is a build warning. |
Changed
| Area | Change |
|---|---|
| Motion | prefers-reduced-motion: reduce now zeroes every framework transition (the indeterminate progress bar slows rather than stopping). |
| Forced colours | Windows High Contrast fixups for the masked chevron, progress bar and modal buttons. |
| Logical properties | Framework CSS is writing-mode-relative, so RTL works with just dir="rtl". Spacing / border / float utilities gained logical names (physical names kept as deprecated aliases — see below). |
| Reset | Meyer→modern reset: <img> is display: block; list-marker removal is opt-in via role="list"; box-sizing is set directly, not inherited. |
| Block-flow spacing | $element-margin is now $flow-step → --jf-flow (same 1.5rem default), applied to the same elements as before plus block media (<img> / <picture> / <video> / <audio> / <figure> / <address>), .progress and .form-row — things the aggressive reset had left bare. Removed again for object-fit images, aspect-ratio crops, .card-image, a figure's own child, and media used directly as a grid column. |
| Grid & row spacing | .grid, .row and .auto-grid all space the same way: column-gap (--jf-grid-gutter) + row-gap (--jf-flow), a trailing --jf-flow margin so they flow like a block, and the last child of each .col stripped of its trailing margin (multi-element columns keep their internal rhythm). Drop the per-item .mbe-0 you used to need. |
| Floats | A block that directly contains a floated .align-* child contains the float itself — no .clearfix needed. |
| .container | Full-width + fluid side padding (was fixed-px with auto margins at lg / xl). Content still caps at --jf-container-max. |
| Forms | Control font-size is max(16px, 1em) (was a hard 16px !important); <select> is width: fit-content; max-width: 100% (was 300px / 60%). |
| Page background | $body-background-color default #fff → #faf9f6 (a warm off-white). |
| Component tokens | --jf-card-* / --jf-chip-* / --jf-modal-* / --jf-table-* are declared on their component, not :root — override them there or on a scoped selector. |
Breaking changes & migration
| Change | Migrate |
|---|---|
| Every custom property is namespaced --jf-* | Rename --border-color → --jf-border-color etc. Or set $token-prefix: "" before import to keep the un-prefixed names. |
| v() Sass function removed | Use token($name, $fallback). |
| $chip-border-style removed | It only ever reached .chip.outline — the base .chip border was hard-coded solid, so setting it appeared to do nothing on a filled chip. Chip borders are now always solid; write your own border-style rule if you need otherwise. |
| .small removed (clashed with size modifiers) | Use .font-size-small. |
| .bg-white and .*.white removed | Use .bg-soft, .button.soft, .chip.soft, .callout.soft, .progress.soft. |
| .clearfix removed | Usually nothing — floats self-contain now. Otherwise display: flow-root on the parent. |
| Grid: .offset-* and push / pull removed | Use .col-start / .col-end (grid) or .order-*. |
| Spacing / border / float utilities renamed logical | .ml/.mr/.mt/.mb → .mis/.mie/.mbs/.mbe; .align-left/-right → .align-start/-end. Old names still work but are deprecated — they may be dropped in later versions. |
| Font-size scale keys renamed | -2 … 8 → xs, sm, base, md, lg, xl, 2xl … 6xl (Tailwind convention). Update token(font-size-*) / $font-sizes references. |
| $weight-* Sass variables removed | Use get-weight(bold) or the --jf-font-weight-* tokens. |
| $element-margin / $element-padding removed | Block-flow spacing is $flow-step → --jf-flow. |
| $global-transition / $transition-timing removed | Use --jf-transition / the --jf-duration-* + --jf-ease-* scales. |
| $font-sizes-h1…h6 / $heading-line-height removed | Use $heading-scale (which step each level uses) and $type-leading. |
| Colour role scalars → one map | $color-subtle-shade / -muted-shade / … → $color-role-shades map. |
| $link-color is now a family name | primary, not get-color(primary). $link-active / $link-visited removed — derived from $link-color's roles. |
| --jf-color-headings-preferred → --jf-color-headings; *-fg → --jf-color-on-* | Rename any references. |
| --jf-color-section-background / -section-text / -section-headings removed | Renamed to --jf-color-surface / --jf-color-text / --jf-color-headings. A .bg-* section re-declares them locally; --jf-color-surface defaults to the page canvas. |
| $card-border-color / $table-border-color / $accordion-border-color removed | Those borders now resolve var(--jf-{c}-border-color, var(--jf-border-color)). Set the component custom property to move one, or $border-color to move all three. Themed .{family} modifiers keep their own family border. |
| Accordion and table colour settings removed — $accordion-heading-bg-color / -hover-bg-color / -text-color / -hover-text-color, $table-stripe-color, $table-hover-background / $table-hover-color | Each component commits to a semantic role now (rest subtle, hover muted), with text from that role's --jf-color-on-* companion. Override the paired custom properties instead — see Accordions and Tables. |
| $accordion-transition-duration removed | Accordion motion runs on --jf-transition like everything else. Redeclare it on .accordion to change the tempo. |
| makeColorPalette($color, $gen-bg) → makeColorPalette($color) | You no longer call it at all — give $colors a bare seed colour (("brand": #0b7)) and the ramp is generated for you. An explicit map is still accepted for a hand-tuned ramp. The old second argument, which auto-generated .bg-* modifiers, is gone — a .bg-{family} is now generated for every family automatically; extra modifiers go in $background-colors. |
| --jf-space-3xl (192px) removed | The spacing scale tops out at --jf-space-2xl (128px). Use get-size() for a one-off larger value, or merge the step back into $space-scale. |
| v4 class + JS accordion removed | Move to native <details class="accordion-item"> — see Accordions. name replaces data-allow-multiple; open replaces data-start-collapsed. |
| Modal trigger | onclick="toggleModal('id')" → data-modal-target="id" on a button (CSP-safe). .has-open-modal body class removed. |
| abstracts/02-settings/_grid.scss deleted | $breakpoints is a flat constant (sm 600, md 900, lg 1200, xl 1800); $cols / $grid-has-order / $grid-has-offset / $base-* gone. |
| Debug overlay removed | .jf-debug, jfDebug(), $debug-mode-on and debug.html are gone. |
Also changed
Smaller housekeeping that shouldn't need any action:
- Dropped the stickybits and es6-promise dependencies; lazyload-bg.js for backgrounds is kept. hamburgers is still vendored for the navbar toggle.
- smooth() is deprecated in favour of motion(). It still compiles as an alias, so existing SCSS keeps working — switch when convenient.
- .hide-xl fixed — it was emitted outside any media query, so it hid at every width instead of only from 1800px. It's now an alias of .hide-above-xl. If you were using it to hide something everywhere, switch to .hide. New .hide-xs closes the other end, so the band classes now cover xs–xl with no gaps — see Utilities.
- Dead .radio-control / .checkbox-control focus rules dropped — the component they styled was replaced by native accent-color back in 4.x; the rules had been shipping ever since.
- Removed all IE-only vendor pseudo-elements (::-ms-*) and hand-written prefixes autoprefixer now manages.
- Removed dead Sass helpers (map-deep-get, n, h, nh, hn).
- gulp-uglify → gulp-terser (handles modern JS).
- Spacing literals snapped to the nearest scale step; a few component paddings and grid gutters shifted a pixel or two as a result.
- ::selection, mark, figcaption / caption now set an explicit colour so they read on any surface.