Getting started
Install
Import jellyfy.css for every control, or import the component files you use. startJellyfy() runs the press and the loading lights, and it keeps the range fill in step with the input.
Install the package
npm install jellyfyThe whole library
One file. It imports the material, the motion, and every component. Put it after Tailwind. A utility such as px-4 still sets that padding. The press stays.
@import "tailwindcss";
@import "jellyfy/jellyfy.css";Without Tailwind, link that file or import it from a bundler.
<link rel="stylesheet" href="./node_modules/jellyfy/jellyfy.css" />import "jellyfy/jellyfy.css";One component
Import the material, the motion, and the components you use. A component file that is not imported is not in the build. Do not also import jellyfy.css. That file already contains these.
@import "tailwindcss";
@import "jellyfy/material.css";
@import "jellyfy/motion.css";
@import "jellyfy/button.css";
@import "jellyfy/input.css";Without Tailwind, drop the Tailwind line. The same files work from a link tag or a bundler.
material.cssis required. It holds the grain, the blur, and the colors.motion.cssis required. It holds the press.button.cssisbtn.icon-button.cssisbtn-icon.bump-button.cssisbtn-bump.input.css,textarea.css,select.css,checkbox.css,radio.css,toggle.css,range.css,alert.css,badge.css,card.css,modal.css, andmessage.cssmatch those class names. The switch istoggle.css. The range slider isrange.css. The dialog ismodal.css.
Call it once
Call startJellyfy() once, after the controls are on the page. A pointer press squashes the control under the pointer. Controls that appear later, including after a page change, are included. A later call is ignored. The full pages are in examples.
Plain HTML
<script type="module">
import { startJellyfy } from "./node_modules/jellyfy/index.js";
startJellyfy();
</script>Vue
Import the CSS in the entry. Use jellyfy/jellyfy.css for the whole library, or the material, the motion, and the component files. Call the function when the app is mounted.
import { createApp } from "vue";
import App from "./App.vue";
import "jellyfy/jellyfy.css";
createApp(App).mount("#app");<script setup>
import { startJellyfy } from "jellyfy";
import { onMounted } from "vue";
onMounted(() => {
startJellyfy();
});
</script>React
Import the CSS after Tailwind. Use jellyfy/jellyfy.css, or the component files. Call the function once from the root component.
import "jellyfy/jellyfy.css";
import { startJellyfy } from "jellyfy";
import { useEffect } from "react";
export default function App() {
useEffect(() => {
startJellyfy();
}, []);
}Press any element
Add squish to give any element the same press. On a Jellyfy control it uses the face that control already has. Add it to a card when the card should press. A disabled control does not squish.
<article class="card squish">Notes</article>Your own element
The thickness classes paint the jelly on an element that is not a Jellyfy component. They need the material file, which the whole library already includes.
<div class="thickness-surface">A surface</div>
<div class="thickness-field">A field</div>
<div class="thickness-control">A control</div>
<div class="thickness-mark">A mark</div>Add noise for the grain alone. Put it on your own element the way you put squish on it for the press, or a thickness class on it for the edge.
<div class="noise">Grain only</div>Browser support
Chrome and Edge 123+, Firefox 120+, and Safari / iOS Safari 17.5+. Jellyfy uses native light-dark() for theme-aware colors and material lighting.