Getting started
Jellyfish is a mobile-first SCSS + vanilla-JS framework, consumed as an npm dependency and compiled into your project's stylesheet. Settings are Sass !default variables; a subset are also exposed as --jf-* custom properties for runtime theming.
The HTML/PHP starter repo provides a good example of use.
npm install jellyfish-ui
SCSS import order
Jellyfish follows the 7-1 pattern. Import each Jellyfish layer, then your matching layer, so your rules land after the framework's:
@charset "UTF-8";
@import "jellyfish-ui/src/scss/abstracts/__all";
@import "my-theme/abstracts/__all";
@import "jellyfish-ui/src/scss/base/__all";
@import "my-theme/base/__all";
@import "jellyfish-ui/src/scss/vendors/hamburgers/hamburgers";
@import "my-theme/vendors/__all";
@import "jellyfish-ui/src/scss/layout/__all";
@import "my-theme/layout/__all";
@import "jellyfish-ui/src/scss/components/__all";
@import "my-theme/components/__all";
@import "my-theme/pages/__all";
@import "jellyfish-ui/src/scss/themes/__all";
@import "my-theme/themes/__all";
@import "jellyfish-ui/src/scss/utilities/__all";
@import "my-theme/utilities/__all";
Most settings can go in your abstracts/__all above (they're consumed later), including the $colors palette map — merge into it with the standard map-merge pattern to add your own families. One setting must be set at the very top, before the first Jellyfish @import, because the framework's own settings read it as they load:
- $token-prefix — the custom-property namespace (default jf; "" for un-prefixed --border-color names).
@charset "UTF-8";
$token-prefix: "myproject";
@import "jellyfish-ui/src/scss/abstracts/__all";
/* ā¦rest as above⦠*/
JavaScript
Include dist/js/jellyfish.min.js, or import src/js/ into your own build. It powers the navbar, modals, theme toggle, accessibility control and the helper functions.
Dark mode
On by default ($dark-mode-enabled: false to drop it). With no opt-in the page follows prefers-color-scheme. To let visitors choose — and restore it without a flash — add this to <head> before the stylesheet, then use any [data-theme-toggle] control. Full detail on Theme Colours.
Declaring a default
data-default-theme on <html> sets the site's own default, used when the visitor hasn't chosen. dark and light ignore the OS entirely — only the toggle moves off them. system (or leaving the attribute off) follows prefers-color-scheme.
This is resolved in CSS, so it holds before first paint and works with JavaScript disabled — the attribute alone is enough, no snippet required for it. Precedence is: the visitor's stored choice, then this attribute, then the OS.
| Stored choice | data-default-theme | Result |
|---|---|---|
| none | system / absent | Follows the OS |
| none | light / dark | That one, OS ignored |
| light / dark | anything | The visitor's choice |
| system | anything | Follows the OS — an explicit "use my OS" outranks the site default |
[data-theme-set="system"] is what stores that last state, so a visitor can always get back to following their OS even on a site that declares a default.
Sticky headers and deep links
If your site has a sticky or fixed header, set --jf-scroll-offset to its height so #fragment links (and the accordion deep-link) don't land underneath it. Jellyfish applies it via scroll-padding on <html>.
:root { --jf-scroll-offset: 5rem; /* or calc(var(--header-height) + 1rem) */ }