This lib runs a a RAF animation loop every 8ms across every component on the page that causes the entire document to repaint.
The comment above appears of the AI generated sort: // One shared animation frame: step every live component, park when idle. // The delta is capped so a background-tab pause never becomes one giant step.
The "JellyEngine" instead of just calculating the jelly animation on pointer events is recalculating for every active component on the page every frame.
This is the kind of thing usually a human notices and says 'dont do that, that is kind of crazy'.
Agreed the comments look a bit slop-ish but I don't see anything obviously wrong with its approach, and the core loop is running in microseconds for me when nothing is happening.
Cursor idle, viewport on the button examples. 3ms repaint every 8-11ms. Animation frame points to the code i mentioned.
The problem isn't doing work on a website, its if you have an idle task that is taking up a significant portion of the frame budget then its easy to have frame drops when you do significant work like clicking, scrolling, browsing.
Idle work showing up in flamecharts is usually the thing to be cautious of.
It's not crazy. That is literally what 99.99% of video games do. They repaint everything constantly, only limited by either your vsync rate or hardware.
If I click and hold then move the mouse away to release, I assume an element should not register that as a click. As-is, this is inconsistent: the button registers a click, the checkbox does not.
Neave was a personal hero of mine back then... hope you're well if you're reading this!
By contrast, most of the other controls do seem to stick to the cursor, such as jelly-resizable.
Also, the "Placeholder" control seems to fail to actually make the placeholder disappear when clicked in.
opacity: 0.5 for disabled elements is a crime.
pointer-events: none on disabled elements and claiming WCAG AA compliance? Ew.
EDIT: It's also WILDLY inconsistent. Click and drag on a button and the shape doesn't change. Click and drag on an on/off and the deformation follows the mouse. Merely click an on/off and the deformation does not follow the the little circle thingy, or bear any relation to the action of the button.
Some of the things are inoffensive, spinner dots, progress bars, accordion menus. But basically anything that deforms on click related to where you click are nonsense.
EDIT 2: The buttons in the demo area apparently do have distortion that follows the mouse, but on the left side they don't? For me this is just a lot of bafflingly inconsistent gloss that makes me wonder what's going on or why one thing behaves differently than others, and what that means for actual functionality. Rather than just interacting with the UI.
Heads up: the "See it live in the showcase → " links in the API documentation do not go back to the showcase - they just reload the same current API section.
Question: maybe I've missed it, but what exists here wrt distribution / packaging / bundling / source availability? I see MIT listed, but no repo. I see src="https://jelly-ui.com/package.js" as a sourcing import, but obviously I'm not going to bundle foreign assets into my app.
This is a security nightmare.
Shape "square": still rounded
-----
It's visually creative. At the same time, the reactive animations would bother me (to the point of deeming it unusable) in any production app or website. I'm glad it respects "reduced motion" preferences.
Also, some Jelly buttons animate correctly when you move your mouse over them mid-click, while some remain stuck in the original position when you clicked them.
Ordinarily I wouldn't comment on this (eg: for the plethora of React-using sites that haven't tested without it yet work fine when manually bypassed) but in this case it's intended as a drop-in UI.
Wow, you just unlocked a memory. Good times.
It's poorly implemented and looks crude and unpolished.
There might be an idea there, for limited applications, but this isn't it.
- i can see it changes size on clicking and dragging
- so what is the author actually doing?
[deleted]
Also, the buttons on those spinboxes are way too small.
—⁂—
It requires JS to work, which could have been avoided at some arguable ergonomic cost. Personally I’d disqualify it from being considered “native HTML form controls”—it’d need to be just an enhancement to qualify in my mind.
—⁂—
Your sets of chips like mode auto/dark/light should be marked up and behave as radio buttons: when one is checked, it should be the only one in the tab order, and arrow keys and such cycle through them. <jelly-segmented> gets this right.
—⁂—
The demos show a “click” toast on buttons even if you move out of the button before releasing, which should cancel it. Either the event handler is linked to something other than activation (which should be fixed), or activation behaviour is wrong (which should be fixed).
—⁂—
> <jelly-checkbox indeterminate>
Oh how I wish <input type=checkbox> had an indeterminate attribute and a way of telling it to cycle through indeterminate when clicking. As it is, it’s purely a property, not attainable in serialised HTML.
—⁂—
> <jelly-otp>
I hate it. Do not under any circumstances use a sequence of single-character inputs for OTPs. It behaves really nastily. Sure, you made the simple paste case work, but all kinds of other normal interactions are busted. You must use one input. If you want to style it in a way that shows the intended length and puts characters in those boxes, you can still do it. Use `font-variant: tabular-nums` or `font-family: monospace`, then rely on the ch unit and probably add some letter-spacing (one of the very few legitimate cases for letter-spacing), and draw behind. Or, if you want more control… contenteditable is available.
—⁂—
> <jelly-range>
I thought we were talking “native HTML form controls”? There ain’t no such thing in HTML. (It becomes apparent the further I go that it’s not intended to be limited to what HTML has.)
—⁂—
> <jelly-switch>
There’s a gap in the hit target between the switch and the label. This needs to never happen. It didn’t seem to with checkboxes or radio buttons.
—⁂—
> <jelly-textarea>
Hold down a letter until it gives up expanding, and I found text and scrollbar drawn on top of the jelly border.
—⁂—
> <jelly-alert dismissable>
The × hit target is much too small.
—⁂—
> <jelly-pagination>
Not pleasant to use. Bad hit targets (too small, gaps between), poor choice of pages to offer (‹ 1 … prev self next … last ›: you want 2 instead of … if prev is 3, and you want more than one prev/next), and if it’s ever going to be interactive, the layout changes far too much.
—⁂—
> <jelly-tabs>
Ugh. Ugh. Unpleasant appearance, presenting tab bar and panel as unrelated widgets. Bad cross-fade (opacity drops below 1).
—⁂—
> <jelly-dialog>, <jelly-drawer>
Opening it in dark mode was very jarring: no transition, and the backdrop lightens (should darken; that may require changes to the dialog background colour).
—⁂—
> <jelly-menu>
You reused a <select> dropdown, and it shows. Interactions are all wrong. It also says “typeahead keyboard support” but I see no such thing.
With that said, I hope no one ever uses it, it's terrible.
Scroll-snap is a really risky feature, very niche in its reasonable applications. This is definitely not a suitable place to use it.
can you give an example of why/how? I thought it was well done and enjoyable. Regular fast scroll was still as expected, and then the slower interactions felt like slide changes.
[dead]
[dead]
[dead]
That's exactly what I was saying. Rendering a few widgets shouldn't pin your CPU or GPU because it's so little work.
This page, however, has an animated SVG and moving DOM elements in the header which consume far more resources than the widgets it is trying to showcase. Compare usage before and after deleting the header element (`section.hero`) in the inspector to see for yourself.
> That's exactly what I was saying. Rendering a few widgets shouldn't pin your CPU or GPU because it's so little work.
Your comment doesn't say this at all:
> > This is the kind of thing usually a human notices and says 'dont do that, that is kind of crazy'.
> It's not crazy. That is literally what 99.99% of video games do. They repaint everything constantly, only limited by either your vsync rate or hardware.
Am I missing something? Are you referring to some other part of the thread?
[deleted]
He's right - the DOM also has observers.
The difference is what is rendered, not that observers are involved and the concept of looping.
Millions use React - you want to talk about performance?
Anyway, something like this only needs to paint when states change or animations are running. That's an easy optimization to make here if it doesn't do it already. And games don't even bother with it, they repaint all UI even if it doesn't change.
Point being: your comment made me sad and I needed to lighten myself up a bit.
To be clear, I'm not saying it's fine to constantly render when you know nothing changed. I'm saying the load from this should be very small. Most of the performance issues from this page are actually from the header animation, which you can delete in the inspector to see a significant drop in usage (mine went from ~35 to ~6.6 CPU).
A videogame is expensive to render because of several MB models, constantly moving camera, and other things.
The concept of observing elements is not even new.
These downvoters act like native JS doesn't do the exact same thing with event listening and observing the DOM. So does React and other FE frameworks.
Philip J Fry is either being disingenuous or genuinely doesn't know that game rendering has often several MB models, is often raycasting, maintaining camera calculus, and a lot more.
But many smaht people out there don't know that.
For instance, the mouse cursor is composited on the GPU during scanout. That means simply moving your cursor requires zero rendering.
Another example: When typing only the newly typed character and caret are rendered. The rest of your entire screen is reused.
You're right that they avoid unnecessary painting but it is not this granular anymore. It used to be but rendering is so much faster these days where it is cheaper to just render a bit more than tracking dirty regions. It's easily visible on Android where you can enable "Show view updates" and see the entire textbox view updates when the cursor flashes. The docs say the same thing.
https://developer.android.com/reference/android/view/View#in...
They already do exactly this. The commenter wants a switch to force animations anyway, so he can check the demo without changing system settings.
These cool demos come up now and again and it always takes me a minute to remember I have reduced motion. But for that minute I was disappointedly clicking around thinking "Whats the big deal?"
defaults write com.apple.universalaccess reduceMotion -int 1 && killall DockBut for a single like button, an effect slider, or magic search bar? It would be be a lovely touch.
I think now that llms make it super easy to add anything that its important not to add everything.
------------------
Original:
How does that make anything about this "physics-based"? I'm not being snarky, I'm genuinely trying to figure out what part of this is completely going over my head. I don't see any "soft-body physics" interactions, but maybe I don't understand what to look for.
I don't see any deformation or elastic collision physics, and those are usually the most obvious things that I associate with "soft bodies" in engineering/physics.
You sure about that? “Turn on Reduce Motion” was a common bit of advice for people who were looking for ways to make Liquid Glass livable.
1. The AI they used called it "physics-based" as a hallucination (probably due to the popular "JellyCar" game), and they went with it because they don't know better.
2. They don't know better, so they asked the AI for a "physics based" system, and the AI was too sycophantic to correct them.
Either way, it's slop.
You've built something really great here, your grasp of web components is incredibly strong, and the way you use TypeScript is very light handed in a way that made the code just a delight to read through, in a way I've not had in many years. It's been a while since I looked at a new library's codebase and learned something new, so thank you for that!
This may sound silly, but I think you've laid the foundation here for the next Bootstrap / MUI. It just needs more expandability and distribution options.
> Here are 5,338 public repositories matching this topic...
Thanks for the link--I didn't know you could search Github by topic.
Why would you say this? These buttons recognize every click I do on them and I find it very nice that the deformation is different for different click areas. The button still works like a normal button but is nice to look at, or have I misunderstood you?
very important to filter out and choose who you engage with
It's buried at the bottom. Had to click on the "sponsoring" link, and then select the package.
Feels like they should make the repository more prominent.
It's the kind of UI that works if you scroll a specific way. A lot of people probably do. But if you don't, it's all very tedious. I consider that to be poor design.
The scroll is delayed significantly from when I scroll to when it actually scrolls.
The amount scrolled is inconsistent, sometimes it scrolls a very slowly a tiny amount because the page doesn't fit on the screen by an unknown tiny fraction, but if I scroll again because it is scrolling both slowly and with delay it now scrolls an entire page.
If I want to scroll past one of the demos I have to wait
If I drag the scroll bar on the side slightly it often snaps backwards.
It feels like I'm interacting with a phone/tablet screen on a computer, there's a reason why windows 8 failed.
It would be like if my shoes suddenly made me take steps at perfect widths, and no matter how/where I tried to step on my own, they forcibly move my foot to the spot they think is best. Like, okay, I see the good intentions here. But I have no trouble walking on my own. I don't need help. So I'm not sure what problem this solves. And this would obviously feel jarring and awkward, and would take a lot of getting used to until it didn't.
Except at least my shoes go with me, so presumably if I had a pair of auto-stepping shoes I would get used to them over time. But this website is a one-off, I'm going to visit once and never again, so it's just going to be weird and jarring, and then I'll leave.
I am only being literal when I say this, but as someone who is actively keeping an eye out for this sort of thing (CSS frameworks, UI kits), I lost interest pretty immediately when I saw that and closed the tab immediately. Assuming the people who made this page also made the UI kit, it tells me their web design values run contrary to mine.
I don't even fall into one of the exceptional cases, and this was a very bad using-a-website experience for me.
There is therefore an intrinsic physical link between the actions of my fingers, and the motion on the web page. My finger moves, and an immediate, proportional response is observed. This is an utterly base level of how most humans interact with the world. It is why using a mouse or trackpad came quite easy to many people (and why some can flick a mouse in a shooter, turn a precise 274.9 degrees, move up 14.2 degrees, and click on the head of an enemy player in fractions of a second with pinpoint accuracy). It is also why even a toddler can use a touchscreen; direct manipulation is inherently understandable to even a baby.
When I am turning in a screw by hand with a screwdriver, the feeling of the screws threads through the handle into my fingers, the immediate force feedback, the observable, feelable progress of the screw in or out of its screwhole, forms this same interface. Where human and tool meet, latency and unexpected behavior, especially if divorced from the input force, are undesirable qualities of a tool.
Scroll jacking is to a trackpad or a fine scroll wheel as turning a screwdriver handle by twisting a bungee cord is to using a screwdriver. It unhooks the immediate, direct feedback from the motion of my hand; its jarring, unpleasant, frustrating. On this page, I immediately put two fingers on the trackpad and moved them less than a centimeter, and didnt let go, and the entire screen cycled its view, as if I pressed a button "move to next item". Except I didn't (and why would I want that in the first place???), I just moved my fingers less than a centimeter. Nothing in the real world moves like that except for things less than a centimeter away from falling out of balance. And it feels the same. Precarious. A common human reaction to things moving out of proportion to our body is nausea!
I think a better question is, can you give an example of "why/how" this solves any actual problem someone would have had scrolling this website had it not used scroll snapping? Would the top comment have been "Boy I wish this site had used scroll snapping, it would have been more well done and enjoyable that way"?
It doesn't look like there's anything custom going on here either, it's all just standard scroll-snap-* CSS properties. if you have an issue with the way your browser is handling the scroll-snap CSS properties, I recommend you take that up with your browser? After all, you should be using a user agent that works for you, not against you.
The change was so sudden and stark that I thought some sort of error had occurred and I was looking at a broken render of whatever I should be seeing.
Might be slightly better if the background didn't change color as soon as you move off the first "slide". Then it might not feel like you left the site or got dumped to an error page.
[deleted]
Do you know that regular HTML and CSS use GPU all the time?
That's what this thread is about, I thought.
All this work to replicate the animated blobbiness of Liquid Glass. I thought everyone hated it! So, then, why is this a thing?
It does in my mind. I fully expect visiting any of reddit.com, github.com, notion.so, or meet.google.com to have the chance to pin a cpu core at 100% for as long as the site is open.
At this point, I expect the average webpage to use more CPU than any of the video games I play. The only reason I had to upgrade to my current machine is because a 2021 CPU (intel gen 11) wasn't capable of running notion.so or google meet anymore, it still ran all the video games I care about just fine.
CPU bound games examples: Chess, Go, Final Fantasy XIV, Elite Dangerous, and any competent Civilization / 4X or turn-based strategy game. Yes, you can dial up the graphics on these to force them to be GPU bound, but they’re each CPU bound in their own unique ways. Perhaps none such games appeal to you, but as with above, extrapolating from personal preferences is a non-starter.
Non-tech people teach each other to force-quit apps to stop their battery drain. Websites aren’t apps, so their phone ‘randomly’ gets hot sometimes and they either have no idea why or just try closing all tabs in a vague hope that it works. Sometimes a webpage uses up all their data for the month downloading ads and so they stop using the web over cellular at all.
This is the baseline level of competence that improving the web must be aiming for — not ‘web developers will understand that the tab is using lots of battery and must be closed’. Making the web better is not about making the web significantly more battery-hungry, no matter how pretty it might seem. No visual advancement in radio button UX is worth a continuous repaint in JavaScript.
Chrome on desktop has an option for flashing whenever it paints and it only highlights the line of text you're typing on. So clearly chrome still tracks dirty rects properly.
It's likely the same on iOS. You'd have to try implementing it to really see why it isn't practical.
Consider you were implementing drawing a button. Your UI framework calls your draw method with some interface to draw with and gives you a rectangle specifying the region to draw. Your button is probably some form of rounded rectangle which will be complicated to draw a subsection of if the rectangle intersects a corner. If it intersects the button's text then you probably need to figure out which characters intersect the text and only render those. It's a non-trivial amount of work to cull the draw commands to an arbitrary region. Also, if you stop passing dirty regions around then the widget drawing method is closer to being a pure function meaning the UI framework can cache the draw instructions instead of calling it over and over for different regions.
> Chrome on desktop has an option for flashing whenever it paints and it only highlights the line of text you're typing on. So clearly chrome still tracks dirty rects properly.
Looks like it but it doesn't show any renders for the cursor flashing so I don't fully trust it.
The way this is done everywhere is to invalidate the entire area of the button. Buttons usually change background on hover/click anyway, so it just doesn't make sense to do more. Text input is special because these widgets can be very large, sometimes spanning the whole screen, so you want fine-grained dirty regions.
> Also, if you stop passing dirty regions around then the widget drawing method is closer to being a pure function meaning the UI framework can cache the draw instructions instead of calling it over and over for different regions.
I've never heard of anyone adding a general Widget-Level cache, considering that most UI elements don't change position that would be quite expensive. In any case the rendering is still a "pure" function regardless of whether you're using dirty regions or not, so not sure what you're trying to say here.
> Looks like it but it doesn't show any renders for the cursor flashing so I don't fully trust it.
That is definitely weird, but it still clearly shows that the regions are being tracked.
The DOM does this. React does this.
Did you know CSS even invokes the GPU for certain tasks?
You guys really need more experience. I can't believe how many people apparently know nothing at all about web dev and computers.
The processes don't stop, no, but they do pause and go idle, waiting for the next event to come in. Not sure what that has to do with this.
> The DOM does this. React does this.
What does react have to do with any of this discussion, and what do you mean by "this"?
> Did you know CSS even invokes the GPU for certain tasks?
Whether the GPU or CPU does work is unrelated to how frequently and how much of the screen is rendered. Damage regions work just fine for GPU-based rendering.
> You guys really need more experience. I can't believe how many people apparently know nothing at all about web dev and computers.
Part of my job is maintaining a retained mode UI library. I've literally written some of the parts that handle damage regions, as well as the GPU-based rendering. But do go on about how I don't know how any of this works.
e.g. I have "reduced motion" turned on because the workspace switching animation (and some of the other animations) on macOS is unbearably slow, and that flag is the only way to get rid of it.
I can break basic user interaction with one line of CSS, does that mean I should?
The websites I mentioned use more cpu and memory than most games in Civilization the series, which are largely competently developed. My previous laptop could play civ 5 at a higher framerate than it could scroll github diffs or notion pages. Civ 5 handled full-speed keyboard input, while notion doesn't let me input text at my roughly 100 wpm typing speed.
I agree that we shouldn't be expecting users to figure out how to close the right tab, however I'm reporting the way things currently are, which is that webpages are poorly optimized messes.