[HN Gopher] Time-Based CSS Animations
       ___________________________________________________________________
        
       Time-Based CSS Animations
        
       Author : spirit23
       Score  : 211 points
       Date   : 2024-05-05 04:26 UTC (18 hours ago)
        
 (HTM) web link (yuanchuan.dev)
 (TXT) w3m dump (yuanchuan.dev)
        
       | nikisweeting wrote:
       | I also recommend using negative animation delay values if you
       | want to control the progress via JS.
       | 
       | e.g. animation-delay: -1500ms will begin the animation
       | immediately but jump to 1.5s into the animation. Controlling this
       | value with JS lets you effectively scrub through CSS animations
       | via JS, making every animation compatible with game-engine style
       | compute-update-render tick loops.
       | 
       | https://developer.mozilla.org/en-US/docs/Web/CSS/animation-d...
        
         | 9dev wrote:
         | That should also enable iOS style, scroll-offset bound
         | animations, right?
        
           | nikisweeting wrote:
           | Yeah you can do tons of interaction-dependent stuff without
           | losing the GPU-accelerated nature and declarative style of
           | CSS animations.
           | 
           | We built a high performance animation library on this
           | concept: https://github.com/Monadical-SAS/redux-time
        
           | afavour wrote:
           | Scroll linked animations are the best way to do that:
           | 
           | https://web.dev/shows/http-203/Qf5wdXOxW3E
           | 
           | Sadly no Safari support yet.
           | 
           | (attaching an active JS event listener to scroll is
           | considered bad because it means your scroll movement gets
           | tied up in the JS event loop. On a fast device it'll probably
           | be fine but on a slower one things can start getting choppy
           | pretty easily)
        
       | GalaxyNova wrote:
       | Whatever you're doing isn't working on Firefox.
       | 
       | Edit: Just read the disclaimer, whoops!
        
         | kevingadd wrote:
         | Oddly on my system, it works better in Firefox (it's not
         | animated, but all the elements are there) than it does in
         | Chromium (completely blank where the animated demo should be).
        
           | capitainenemo wrote:
           | Same here. chromium, blank, firefox animating fine.
        
       | TekMol wrote:
       | CSS now has enough Math functions supported,         particularly
       | mod(), round(), and trigonometric         functions
       | CSS can not start a timer like JavaScript does,         but
       | nowadays it's possible to define a custom         variable with
       | the CSS Houdini API to track time         in milliseconds.
       | 
       | Why do we need all this when we have JavaScript?
       | 
       | Shouldn't the drawing layer be concerned with drawing primitives?
       | Why put more and more of the higher layers into it?
        
         | toxik wrote:
         | Just wait until we have WebSockets in CSS!
         | 
         | Jokes aside, CSS is declarative and while there is overlap
         | between problems solvable by JS and CSS, I think that's only
         | natural.
         | 
         | I'm actually really excited for all the new features added to
         | CSS lately, less interpreted code is better.
        
         | joestrong wrote:
         | Don't forget that CSS animations are hardware accelerated. If
         | you're doing trig in JS for animations, you're probably also
         | manipulating the DOM to update the UI every millisecond, which
         | is very expensive
        
           | mattgperry wrote:
           | Most CSS animations aren't hardware accelerated. Only a few
           | values like opacity and transform.
           | 
           | Updating the DOM (as in innerHTML) is always expensive
           | because it triggers layout. This is true whether you're doing
           | it from JS or a CSS trick like on this page.
           | 
           | Finally this approach is using CSS custom properties. These
           | are slow - slower than JS for most things.
           | 
           | If you stop all animations on this page and profile it via
           | Chrome you can see this in effect. The root node is animating
           | a CSS variable. 117 elements have their style recalculated.
           | Every frame - yet no animations are running. There's also a
           | tiny paint triggered too, obviously there's been no changes
           | so it is tiny in this instance, but a paint is always
           | triggered when a CSS variable updates.
           | 
           | This is why animating x and y separately via CSS and a style
           | like `translate(var(--x) var(--y))` would be worse than
           | animating them via JS ala Framer Motion/GSAP.
        
             | agust wrote:
             | Just one nitpick: the DOM is not updated by CSS here, only
             | the value of the CSS variable is. (It will indeed cause
             | style recalc and paint though, and result in poor
             | performance as we can see with the demos.)
        
               | SirHound wrote:
               | Yeah true tho I'm referring to the counter being set via
               | the content style, which doesn't update the DOM as such
               | but does/can change layout
        
             | amsheehan wrote:
             | We shouldn't diminish the power of transform here. It's not
             | just one property like opacity. You can animate quite a bit
             | on the compositor with transform
        
         | tuyiown wrote:
         | > Shouldn't the drawing layer be concerned with drawing
         | primitives?
         | 
         | CSS is not a drawing layer. The drawing is driven by the DOM,
         | either setup by HTML or updated through JS. CSS only piggyback
         | on it by giving parameters to the painting engine about what to
         | do with dom, essentially overriding the defaults parameters.
         | You can add dom blocks, modify positioning behavior with
         | complex algorithms, even margins are not really trivial.
         | 
         | I don't think this is a great solution, but people started this
         | to be able to modify colors during dom rendering without having
         | to update their HTML code, probably because updating HTML code
         | was not fun at all, but I really think the wrong problem was
         | addressed. Those were the <<webmaster>> times, so there's also
         | that.
        
         | onion2k wrote:
         | Regardless of anything else, JS is a single thread (mostly,
         | there are workers of course) so anything you can do to offload
         | work somewhere else is a good thing for keeping the UI running
         | at a solid frame rate.
        
           | SirHound wrote:
           | This doesn't offload work to another thread though. And it's
           | actually more costly as it trigger style recalculations
           | throughout the tree even when it no-ops.
        
         | RunSet wrote:
         | > Why do we need all this when we have JavaScript?
         | 
         | In practice, mostly so google can still invade the privacy of
         | users after they disable javascript.
         | 
         | No _user_ ever asked for this.
        
           | shepherdjerred wrote:
           | No user ever asked for any of these APIs or technologies, but
           | that doesn't mean they can't be useful to developers.
        
           | matheusmoreira wrote:
           | How can CSS be abused to invade our privacy?
        
             | vinnymac wrote:
             | I can think of a few ways, but here is an example where CSS
             | triggers a request to track a user:
             | https://underjord.io/is-this-evil.html
        
               | matheusmoreira wrote:
               | The reason the server can track who is hovering over
               | links is the browser apparently requests the background
               | image _only_ when the interaction happens. I certainly
               | didn 't expect that!
               | 
               | This seems to be an example of browser optimization
               | leaking private information. There's an obvious way to
               | fix that: deoptimize. Instead of lazily downloading
               | resources as they are needed, request all the linked
               | resources when the page loads, and do it only once. Now
               | they can't tell whether the requests were due to user
               | interaction or just normal browser behavior.
               | 
               | I wonder if uBlock Origin can deal with this. I know it's
               | got a lot of options for blocking weird information leaks
               | like this, webfonts being an example. Firefox also has
               | fingerprinting resistance, I wonder if it resists this.
        
         | gibbitz wrote:
         | One thing that comes to mind is separation of application logic
         | and presentation. It's easier to read your fetch logic if it
         | doesn't include loader DOM element geometry progress logic
         | (calculating rotation degrees and applying inline styles etc.).
         | I know it isn't popular to keep the chocolate separate from the
         | peanut butter these days, but conventions like this draw hard
         | lines that make it easier to reason about where code will be
         | found and where to put it.
        
       | ulrischa wrote:
       | Very impressive. But somehow I think we just reached the point
       | coming close to what we were able to do with flash decades
       | before. I do not want flash back but a more user friendly tool to
       | create css animations. If somebody knows any I would be glad.
        
       | silvestrov wrote:
       | The animation at the bottom of the page is very impressive. It
       | looks very much like a <video> rather than <div> elements.
        
       | chrisjj wrote:
       | Interestingly without 'Experimental feature flags' demos before
       | mod() work, though mod() and sin() do nothing - on latest Android
       | Chrome.
        
       | rtcode_io wrote:
       | https://RTCode.io, a real-time web playground without reloads
       | (and without state resets) might greatly benefit anyone working
       | with CSS animations/transitions!
       | 
       | Demo on https://RTCode.io
       | 
       | (To import pens, simply replace the hostname with xcodepen.io in
       | your URLs.)
        
         | simple10 wrote:
         | Has anyone tried RTCode yet? Looks interesting but the homepage
         | is a bit confusing as to whether it's a CodePen replacement
         | with realtime support or can also be used for production?
        
           | rtcode_io wrote:
           | We want to be somewhere between CodePen and Vercel (but with
           | a focus on web standards): a real-time full-stack playground
           | with global hosting and in-editor-edge-deployed
           | workers(/functions).
           | 
           | RTCode is in private alpha. (Currently building Code
           | Versions: diff, rollback, A/B testing; and Code Search: full-
           | text search across all your active deployments).
           | 
           | Our playground and network have proven stable in production
           | in several large enterprises for the last year.
           | 
           | I can answer any questions via email (support@elefunc.com) or
           | chat (https://meet.elefunc.com).
        
       | keepamovin wrote:
       | I wanted this for a while so I could do a 'box-breathing' thing.
       | With the inhale-hold-exhale-hold stages all being customizable to
       | fit your body and go for the effect you wanted.
       | 
       | Could not figure out a way to do it (sans JS or insane
       | complexity) without something like what's on this page. Holy
       | stylesheets! This page has really creative demos!!! Haha :)
        
       | KRAKRISMOTT wrote:
       | Anyone want to try replicating YouTube's upvote counter fly-in
       | animation?
        
       | krebby wrote:
       | For anything more advanced than a simple easing function or some
       | basic keyframes on one or two channels you'll quickly run into
       | the limitations of this approach.
       | 
       | I've been using Theatre.js the last few years and really loving
       | it. It's a library divided into two parts; one is a studio UI
       | with a timeline for editing keyframes and bezier curves, and the
       | other is a runtime for taking those keyframes and interpolating
       | values in relation to a timeline. Try it for anything that
       | requires coordinated animations.
       | 
       | https://www.theatrejs.com/
        
       | simple10 wrote:
       | Really well written article. Chrome hasn't yet released CSS
       | support for mod() so most of the examples on the page don't
       | animate unless you're using the preview release of Chrome.
       | 
       | If you're not needing to control ticks and just want smooth CSS
       | animations in all browsers, the FLIP method is useful:
       | 
       | https://medium.com/outsystems-experts/flip-your-60-fps-anima...
        
       | simple10 wrote:
       | The article uses custom css @properties which are awesome and
       | have 88% browser support [1].
       | 
       | One thing to watch out for is differences in how browsers handle
       | setting the fallback initial-value. Chrome will use initial-value
       | if CSS variable is undefined OR set to an invalid value. Firefox
       | will only use initial-value if the variable is undefined. For
       | most projects, this won't be an issue, but for a recent project,
       | I ended up needing to use javascript to set default values in
       | Firefox to iron out the inconsistency between browser
       | implementations.
       | 
       | [1] https://caniuse.com/?search=%40property
        
         | andypants wrote:
         | If anybody wants to try the demos in firefox, go to
         | `about:config` and toggle on `layout.css.properties-and-
         | values.enabled`.
        
         | simple10 wrote:
         | Here's how to set the property value in Javascript if needed:
         | 
         | Get property value defined in :root{}:
         | 
         | getComputedStyle(document.documentElement).getPropertyValue("--
         | some-custom-css-var");
         | 
         | Set property value:
         | 
         | document.documentElement.style.setProperty("--some-custom-css-
         | var", "some value");
         | 
         | This can work as a polyfill for browsers that do not yet have
         | CSS @property support enabled.
        
       ___________________________________________________________________
       (page generated 2024-05-05 23:01 UTC)