I looked at the CSS for the first codepen example, and it looks like gibberish to me.
Should we really have a mini animations programming language in the styling system? This seems like a bit much. More than a bit much.
Can't this be done with Javascript? I get that a lot of people have a knee-jerk negative reaction to using JS for everything, but it's a programming language... this is kinda its job.
I don't understand this sentiment. If you are not a web developer, and in particular not a frontend web developer, then you probably aren't building html elements with these fancy effects. And if so, then why does it matter what advanced things CSS is capable of?
> Can't this be done with Javascript?
You can totally do this with javascript. You can plop in a canvas, and use webgl to program this effect on the GPU, like a real graphics programmer. You would have to recreate all accessibility features of the html button on your own. Is it going to be easier? I doubt it. But you certainly can.
With web development, I've always thought that there is an element missing for many devs: design acumen and appreciation (I need better terms.) Just look at the site linked from this post and you see an attractive personal site. Most devs struggle with these aesthetic elements.
Desktop development is fairly constrained. As an example, devs can make good or bad decisions around use of the toolkit, but it's less of an open canvas than the web. A lot of the expanded scope of CSS can be more easily exploited if you appreciate the design aspects or have designers creating some target design for you. Putting these capabilities in front of devs without those elements doesn't lead to much success which is another factor driving sentiment.
JS should just do the same in the browser instead of relying on an arcane language not designed for this
"Arcane language" not only is CSS one of the core languages of the web, but also if you find this arcane I wonder what you think of the "native" code that react native is generating for the animations.
CSS as an animation engine is completely acceptable, and it's limitations (like the one in TFA) are slowly being pushed back.
>"Arcane language"
>"native" code that react native is generating for the animations.
>CSS as an animation engine is completely acceptable, and it's limitation
>TFA
No way that pun is intended, but CSS is kinda a Tunable/Timed Finite Automaton; but being of a lower class of technically-capable expression than Javacscript, which is of a higher set of class of automata.But, if I* have to write this same animation in two years and @property is widely available, I'll reach up for that first.
*To be honest, it will be 100% an LLM that writes it for me.
I welcome opportunities to avoid javascript in my sites, even if it's more work for me. It makes life easy for visitors who prefer to disable javascript, thereby avoiding many of the exploits, trackers, etc. that plague the web today.
By the same token, I appreciate sites that do not require javascript.
See:
- CSS keylogger, 2018: https://github.com/maxchehab/CSS-Keylogging
- OWASP cites CSS injection as a mechanism for XSS and data exfiltration: https://owasp.org/www-project-web-security-testing-guide/sta...
Luckily we haven’t seen new classes of attacks here, but being concerned about attack surface of any browser technology is valid and reasonable.
They try to sandbox it.
There are more clever ways now. Like... everything you interact with is a binary search into a projection of your (2^n-interaction) "guess"-ed/history.
If you interact with it, then it is assumed that you can see it.
Even detecting if the room is generally lit or not via the Ambient Light API can be paired with bright and dark elements to ping flashes off your face, in a dark room, to read whether or not elements were of that certain color.
But lets scrap :Visited and use arcane browser implementations and user behaviors; even something as innocuous as zooming slightly in or out is a session-persistent signal. The browsers explicit and even _inferred_ zoom level can be leveraged. A few irrational numbers and difference in spec implementations and your zoom level on Compromised_Site_A can identify you exactly from Compromised_Site_B even without Javascript.
But let's reset zoom between domains. Easy? sure.
But something still has to get painted to the page, like images, that could be cached....depending on how long they have been visited, and from what domain, and from what order. And the timing between all those are almost certainly unique to few, and sensitive to all.
If you load a thumbnail from Bad_site_a within 100ms in a country that blocked the original resource....thats a paddlin.
Those are just the first few, I could go on.
CSS is never going to be able to, on its own, read and exfiltrate the data necessary.
CSS knows a lot, and it can send it back via image requests, triggered in states through animations, 'lazier'-loading, unqie font-choosing, etc.https://blog.sheddow.xyz/css-timing-attack/
You're relying on things like access logs at that point.
Well, yes. The timing and unique request path make identifying possible. And CSS can be dropped in context by other users, crafted to refer to a different domain, so CSS worms can definitely ex-filtrate data without the webmaster being evil.https://portswigger.net/research/ublock-i-exfiltrate-exploit...
IMHO, I see all those bells & whistles more related to scripting than to styling. I'd prefer to be able to navigate with Javascript disabled and not having to suffer some superfluous animations, but maintain the styles.
Original idea puts it under the authors control to add @prefers-reduced-motion media queries.
Might be that some browsers do this anyway, otherwise it would be easy with a user script or user style sheet.
This article argues for the spirit of the spec:
https://css-tricks.com/nuking-motion-with-prefers-reduced-mo...
> “animation isn’t unnecessary.”
It has a point, intrusive animation's main bastions are not CSS-based anyway.
For example, there seems to be a continuous (JS- and HTML-based) cat-and-mouse game that makes me require an ad blocker to disable autoplay videos on news sites, regardless of browser preferences.
This part is like the DNT header all over again, incentives don't align.
And the lesson should be that CSS is the most benign battle site for this issue, because it is customizable and not yet locked down behind anti-debugging and obfuscation techniques.
The reasoning: some hosting platforms allow you to personalize your personal page changing the HTML and CSS bits, but not the JS - for security reason, obviously. Itch.io is an exmaple of that, where you can personalize your game and profile. By using CSS animations I can create cool effects without any of the security concern that allowing access to JS gives me. It makes sense and it's nice to be able to do so.
You and I are NOT designers if I may be so bold. In 1996 I was one of about 100 people on new and MAJOR website/application build. From scratch. My role: Billing Lead. As a "full stack dev" only my eCommerce insights were needed from me. It is called FOCUS.
As a StartupBus alumnus of three treks the model was brilliant: Build teams from three skill sets: Devs, Designers, and BizDevs. Focus.
I love that the examples will not be gibberish to the designers of our day.
My understanding of CSS animations is that they are particularly optimized to run more efficiently and it’s also helpful that it runs outside of the JS runtime, which frees it from any errors in the JS or it adding to the CPU load that may already be chugging along on the page.
Additionally (and this is old info so it may be outdated), using things like `translate3D()` instead of just `translate()` in your CSS will engage the GPU to handle whatever your instructions are, making everything smoother and further unburdening the CPU. This is from my own memory of things I read more than 10 years ago, so it’s possible that even more CSS functions use the GPU at this point, but I’ve not looked it up since.
Anyway, tl;dr: there are performance benefits to using CSS instead of JS for animations.
Moving work from JS to the browser’s native, polished, tested implementation with optimized performance is the right thing to do.
Of course, not disagreeing with that. It is just done in a way that is complex and cumbersome IMO. CSS is often handled by people with very little programming experience as well. I have worked for companies which gave me HTML templates, and CSS files, and my job as the developer was basically do add dynamic behavior by fetching stuff from their DB and looping over some data here and there to fill out lists/tables with actual content. To me that was very pleasant; but the guy handing me the CSS and HTML templates, had zero programming experience.
I think webdesign already is a copy-n-paste bonanza, where people find something they like, and copy it; if it gets very complicated as well. Developers are often last resort in terms of finding out why something does not work, and I fear complicated CSS after a few rounds of copy-n-paste is going painful to unwrap.
I'll have to play around with @property myself to get a sense of how it works - knowing esoteric CSS features is a superpower if you've got a complex UI to implement but wanna minimize JS dependencies.
Isn't that literally just css variables?
werent they cascading too, so the variable could be "overwritten" via classes etc? Isn't that even how tailwind does bg-opacity etc?
By default CSS variables can't be animated since it has no idea what unit it's animating between
calc(var(--foo) * 2)
can have a different result than: calc((var(--foo)) * 2)
Since they're basically just strings, there's no way for the animation system to interpolate between different values. `@property` fixes this allowing the immediate evaluation of the value into a concrete value that _can_ be interpolated.Some privacy-conscious users disable JS, or use NoScript to selectively enable JS. My understanding is that this is (1) because JS engines are often themselves a source of vulnerabilities, (2) untrusted code execution might be risky in the face of speculation execution/access attacks.
Do such users need to worry about either, or both, with such advanced, compute-y CSS primitives?
But as lelandfe points out, CSS can do that, too, for form and mouse/touch inputs at least. So the main difference is that JS tracking is ubiquitous, and CSS tracking is very rare afaik.
(This isn't a response to the question about whether speculative execution attacks are possible, sorry.)
I don't see these new CSS features opening up privacy issues, though.
To do this, you can add or remove rules, or change the values of variables.
Something that might be a source of confusion for you is that CSS isn't an imperative language, it's a declarative language.
If you're not aware of the distinction:
- Declarative languages describe what they want the output to be but doesn't go through every single step on how to create the output. (e.g. html, css, regex, sql, nix, etc...)
- Imperative languages describe every single step on how to create an output, but not what the output actually is. (e.g. js/ts, php, go, c++, rust, etc...)
Since CSS is declarative, it doesn't have imperative steps on how to draw things (e.g. calculate a bunch of co-ords, then loop through all pixels between the co-ords while setting their pixel values to #0000FF). Instead we describe what we want (.box { background-color: blue }) and leave it up to the browser to decide how to do it.
This has several advantages from a web browsing perspective:
If someone figures out a better way to draw a blue box then every website developer doesn't need to go back and change their box drawing code. Instead, the browser developers change their box drawing code and now every website is automatically upgraded at the same time.
A browser might also make decisions on which way to draw a box. It might loop through each pixel one-at-a-time on a cheap cpu-only device, whereas it might pass some info to the GPU and have its shaders draw the blue box, or it might use some clever heuristics to determine that the blue box is above a large box that already has the same blue so there's no need to draw over the same space a second time.
There are other advantages to declarative languages too. Typically around being able to specify constraints to eliminate certain problems in the design of the language itself (e.g. race conditions, side-effects, indeterminate states, halting problem, etc...).
In the end, you want to use the language paradigm that makes the most sense for the situation at hand.
For scripting: you want imperative languages.
For information and presentation: you want declarative languages.
It is often not clear to me why something is off by 3 pixels or something.
Maybe it is the cascading nature of CSS hat makes it complicated. Or maybe it is the fact that I am also using JavaScript to dynamically alter the CSS. Or maybe CSS is just getting very complicated because of its evolving nature yet having to remain backwards compatible.
Following standard practice in regards to layout will help you here:
1. Use `box-sizing` everywhere (should be defined in your css reset file, example: https://piccalil.li/blog/a-more-modern-css-reset/)
2. If you can do something in css or js, do it in css.
3. Don't use pixel values anywhere (this avoid a lot of off-by-x errors when either the math is wrong or a previous assumption is violated by new code somewhere else). Two exceptions: a) The base font size on the root (usually the <html>) element. b) A 1px border, since the box-sizing in step 1 will allow you to take it from the element's block and inline size.
---------------------------------
Also, if you're trying to position text, or an icon inside a button and it seems off, you don't want to be trying to fine-tune the positioning with pixels.
It's always better to address the root cause.
Usually this is `line-height`, `vertical-align` and also the font itself. You can see lots of examples of the font being the issue here: https://tonsky.me/blog/centering/
If you run into this issue, you can look at the font's internal metrics (shown in the link above) to get the exact values you need (Browsers will be able to do this in 2-3 years automatically with `text-box-trim`). Or you could simply switch to a better font that already has the correct values.
Since there are lots of ways to do this kind of thing, pseudo selectors, attr function etc. the ability to do dynamic and complex things from CSS, or with just CSS and HTML combined is pretty big, but as a general rule if you want to do this kind of thing statefully it is probably best to do it in JS - maintaining what variable values are in play on a particular element by setting it that way.
Imagine trying to get someone to use Git without explaining the problems it's supposed to tackle. Who could come away from that conversation thinking "this is tool I must use" and not "that was confusing"?
From the MDN article, it sounds like it's basically the same as plain old CSS variables but scoped to specific elements and/or children with some additional constraints so that it has some awareness of CSS units like angles, percentages, etc...
I probably won't be using it though. Such slight benefits don't justify added complexity and compatibility tradeoffs. I try to avoid using unnecessary new fancy syntax. I kind of stopped caring about new additions to CSS after CSS variables.
I'm sure it's very difficult and stressful to be a surgeon, but once you receive that big paycheck at the end of the week/month while sitting comfortably in your expensive home with a view, scrolling through your stock portfolio on your phone, thinking about what shares/companies you will buy next and where your next holiday will be, it can't be that hard to recover!
Ha, thought it was just me.
This strikes me as very strange. I'm not sure what the benefits are over just using CSS transforms.
He has touched on exact feature a few times, here’s a video he uploaded a week ago that shows one useful feature that registered properties enables: https://youtu.be/U8NykwZNbGs
There’s also this article that breaks down registered properties with an easy-to-follow example: https://moderncss.dev/providing-type-definitions-for-css-wit...
But IE devs were unhinged. You could build JS code as a module and attach it to elements using CSS.
Finally we're getting those kind of unhinged features again.
https://css-tricks.com/exploring-property-and-its-animating-...
You will particularly like the Airport number/timer flip display type example.
From what I gather, this new feature lets you write:
from var(--gradient-angle)
Instead of just a raw value, like: 360deg
And the former effectively gets replaced with the latter, sourcing the value from where you defined it in a `@property --gradient-angle {...}` block.Plus there's the `inherits: false;` bit. I'm not sure what to make of that. What it does is clear enough but I don't understand why. CSS selectors already let you control inheritance. Now you can control it from a second place? I don't follow...
Also, why do I have to define the type in the @property block? I don't have to define types anywhere else in CSS. The browser can see where the @property is used, why can't it infer the type from that?
`inherits: false` lets you control how the property is inherited. For example, in normal css, the property `color: red` is inherited. If you set it on a div, all elements in the div will have `color:red` unless they specifically override it. But, say the property `display: flex` does not behave this way. If I set it on the div, only the div becomes display flex. This is exposing the ability to control how your custom property is inherited -- like `color` (`inherits: true`) or like `display` (`inherits: false`).
I believe the type is there so that it can at static time know what to animate. Since a css variable can be anything, unlike a css property. E.g. `from { color: red } to {color: blue}` it knows the types because of the properties. With css variables, it needs to be told what the types are.
Added fun fact: the type syntax is actually the same syntax you'll see on like mdn! https://developer.mozilla.org/en-US/docs/Web/CSS/color#forma... . So it's like exposing the internals of CSS as an API any developer can use :)
This new feature, @property, allows you to define your property ahead of time, what "type" (syntax) it should accept (percentage, angle, color, etc), whether or not the property should inherits values from parents, and give it a default value (initial-value).
This means that if a property is declared as an angle type, and an element says "--my-prop: 5px" it will be ignored. Previously, this would be valid and depending on where you used it it might have unintentional side effects. It also means you can specify something like "--my-prop: initial" and it will use the default value (initial-value), without needing to know what it is exactly.
I've always loved noodling with CSS. After a decade+ of web dev and through making a career of web stuff I learned how much people seem to hate CSS.
I can pour countless hours into exploring and tinkering with hand rolled HTML+CSS. Deploying it just to see how it feels for real on my phone. And 99% of it all never going anywhere.
I guess for most people that's called a waste of time. Well this site sure does make my day =)
It’s great to see new features coming to html/css that reduce or eliminate the need for JavaScript.
The more that can be done with declarative interfaces with the browser assuming the optimization and complexity instead of hand coding in JavaScript, the better.
This hindered adoption.
Then over the years the overall complexity of the web stack (and its' Javascript-based "derivatives") grew, and suddenly CSS is no longer so complex - in comparison.
The people who are vocal about hating CSS are mostly just people who don't understand CSS.
That's perfectly OK. I don't understand APEX, or AP/L, or the framework-of-the-day. But I do understand CSS, and because of that I enjoy it quite a bit.
For some people it clicks, and for other people it doesn't.
The rub comes when someone for whom CSS doesn't click is required by their job to do things in CSS. Naturally, they hate it. I'd hate it if my job made me maintain an Active Directory installation. Not my thing. But CSS isn't inherently bad.
CSS is so much better than it used to be. Many people will remember positioning things with float and display: table-cell. Every time I use modern CSS I’m like a kid in a candy store.
Coming from also writing frontends pretty much entirely with JSX (in prod, especially), my understanding of the query logic has generally improved by a lot ever since I happened into a separate rabbit hole on Web scraping.
My related hot take is that the query logic wouldn't be nearly as much of a pain if professional settings used semantic elements more. (Never mind how much bare HTML has defined behaviors you don't then have to maintain, like modals.)
Yeah because as soon as you're not tinkering with only your particular combination of device/screen/browser/browser version/OS/OS version but have to implement something reasonably widely supported all the subtle "we're not following the specs" get really annoying to deal with.
Microsoft used to be the most notorious specs violator, today it's Apple.
Apply some deadline pressure, and the constraints of an existing complex frontend project, and all of a sudden the estimate you pulled out of your ass for a pixel-perfect design doesn't look so achievable; ergo, CSS sucks for some people.
Really hope this aesthetic doesn't catch on.
These sorts of things scream marketing and manipulation. Let me read your site and decide what I want to do. Don't try to distract me by annoyingly drawing my attention to the thing that will make you money.
but this isn't realistic — the places most people spend their time online are in native apps, if the web doesn't at least pretend to keep pace this will only get worse
this is like saying usenet is all the social media we need... it might be aspirational, and it might be right, but it's not reality
The extremely vast majority of web app developers don't need 99% of what CSS can offer. But it's neat to know it's there.
whole alien domain
so foreign to most developers
doesn't help.
it's so powerful, incredibly powerful,
most browsers, extremely efficient.
That is because CSS is a different Chomsky Grammar than HTML and EMCA - intentionally not Turing complete, nor-self referential - why the "has(" puedo property was so problematic.That also relates to sibling comments about the awkwardness of the pairing to Javscript, which is of a higher grammar, and Turing Complete*.
It also relates to the "awesomeness" of the "fire-and-forget" nature of CSS - unless very specifically hooked, it can be hardware-accelerated nearly care-free because it isn't per frame to the DOM, which Javascript is (meaning HTML, it's own Chomsky Grammar!)
It is what it is, the epitome of an optimized amalgamation of technical debt we call the modern web specification.
It will be a nitpicky comment, and I’m sure you mean it this way, but it wasn’t clear to me: a language’s syntax being in one type of grammar class is irrelevant to its execution semantics corresponding to a recognizing automaton. So you can have a language with a regular syntax that is Turing complete just fine.
In fact, most languages’ syntaxes are context-free (sometimes with some escape hatches), but are semantically Turing-complete.
nitpicky comment,
I even put an asterisk! Oh wait, not the usual "unlimited tape finite universe"I was unclear. It is intentionally not Turing Complete, by way of avoiding self-references, as self-references would make it a higher-order grammar, and Turing-complete because it then it can innately loop, making it impossible to flatten to a lower, Labeled Push down automaton.
Although they are mutually exclusive, I implied causality.
Its the implicit loop and requirement of a heap/stack of variables self-referencing requires that is Turing-Complete itself.
CSS has been Turing complete for many years.
You can simulate Turing machines with pure HTML+CSS, e.g. https://github.com/yrd/tm2css
"Rule 110" which implies Turing-completeness has also been implemented in CSS, e.g. http://eli.fox-epste.in/rule110/
I would had had, had - "has" not been had, expected sooner, but atlas.
But the aforementioned ":has": : The :has() pseudo-class cannot be nested within another :has(). This is because many pseudo-elements exist conditionally based on the styling of their ancestors and allowing these to be queried by :has() can introduce cyclic querying.
Pseudo-elements are also not valid selectors within :has() and pseudo-elements are not valid anchors for :has().
Note the two limits, "cyclic querying" and self-referential parameters.The former is required for a basic computational model, the latter for one that supports recursive-ness and thus some optimizations .
"Rule 110"
This is just lambada calculus and has no tape movement - requires checkin boxes, still, and thinking about whether or not to halt - which actually kinda is its own asterisk (not the usual 'infinite tape' kind). Turing Machines would halt on some input; your calculator goes until the actual computer, you, halts, or stops actually checking(computing) the state for a HALT/desired state.You'd think someone woulda parasol'd the checkboxes and at least attempted to use :onHover with grid to require minimal mouse movement to trigger input instead.
Or, a bounding box input state driven hack - like when your cursor is "in between" elements, changing every frame.
pure HTML+CSS, e.g. https://github.com/yrd/tm2css
seems cool, actually. SASS repeats CSS exhaustively through HTML-encoded steps until a valid one is painted - that valid one being the HALT/output. You do have to specify the number of steps, though. You would have to know whether or not it halts, the answer, and how many steps it took to compute to functionally (heavy-lifting in this context) use it - or else it would have to reference itself....which would make it a higher grammar.But it can't: https://www.w3.org/TR/css-variables/#cycles
This can create cyclic dependencies where a custom property uses a var() referring to itself, or two or more custom properties each attempt to refer to each other....If there is a cycle in the dependency graph, all the custom properties in the cycle are invalid at computed-value time.
Very close. But you must beg the question (ie. know the answer) in both step count and thus the answer, else you'd have an infinite HTML page. Which is fine in math (HTML is a Type 2, can be infinite, no self-reference, no self-children, nor orphans), but not really much of a simulation/emulation though - if it can only produce valid machines at (essentially) compile time.The disambiguation between levels (grammars) of syntax is what the above poster was both lamenting and heralding - possibly unaware of it's technical and mathematical necessity.
https://en.wikipedia.org/wiki/Ambiguous_grammar#Trivial_lang...
If they could just decide on the name[1] for the CSS "masonry" feature so we could finally have that without scripting, I'd be very happy.
They aren't written down, set in stone, spec'd in any way, but for example:
* the idea of a hero image with a headline and a sub headline followed by a call to action is common on many SaaS product websites. * news websites all look very coherent, so they've adopted some sort of typographical rhythm just like they would in a print publication * the multitude of component libraries means advanced UI can be programmed with some readymade parts, diminishing the need to write custom CSS for something like an image carousel (for a trivial example)
Copy what the next-bigger tech company is doing, and call it "best practices."
What you can do in modern HTML+CSS+JS is incredible. Too bad people bury it down under millions of layers of frameworks and code transformers.
Lots of factors got us into this framework and transformer hellscape, and the 'people' that made is happen are right here. I'm not without some blame within my own organization for sure.
That said, I’m always shocked when I’m interviewing a front-end candidate and they don’t know CSS. Too many rookies out there that haven’t used anything outside of styled components and tailwind.
Unfortunately, I believe for "custom jobs" like this you'd need to explicitly state that you don't want it to occur because it won't happen by default, unlike some other stuff that's more standard in the browser.
So ultimately, you apply the view to the page and the page conforms to your ingestion preference.
I should carry my own 'css' and be able to just pluck any URL and let me speak to my filter on how to display it.
And it will provide a new way to interact with my browsing history - allowing me to recall how that thing from HN from 3 months ago can tie into this thing, and augment my understanding when I can view them next to eachother... and I can categorize them into tags of the same ilk and have a mental rolodex that lets me re-view my browsing history in the UX lens of my choosing.
/edible.
I don't think this is the case here. For a CTA button (literally "Call to Action"), I think it's perfectly acceptable to add an animation to it.
When I switch from this HN tab to the article page, Firefox's CPU usage goes from 2% to 26%.
The internet is a cesspool of ad-plastered pulsating garbage. Please don’t litter more on the garbage pile.
> Cascading Style Sheets (CSS) is a simple mechanism for adding style (e.g., fonts, colors, spacing) to Web documents.
I think somewhere "simple" got lost unfortunately.
Seems pretty gibberish. Theres already CSS vars and a bazillion less/sass/css-in-js preprocessors.
Who really needs this? Why make the spec so complex?
This must be the mentality of new CS students.
i wonder if we start to see the "css engineer" job posts sooner or later
We just haven't needed a lot of pure CSS in the modern era. A lot is abstracted away in frameworks where you can simply set variables to customize the look and feel.
All websites also kind of look the same now, which isn't the worst thing, but it definitely means less need to mess with CSS.
Preferably a blocker that allows a sane subset of CSS so that normal formatting isn't impacted.
You E2E test it, and you visual regression test it.
You can see them in the specs.
You might have a variable that has the type: A|D, or maybe even A&D.
And you might have a case where a rule can interpolate values of type A, B, or C, but not D.
The @property syntax allows you to say: This variable will only ever have a type of A, so now it can be animated.
TLDR: you didn't actually need @property to do any of this magic.
Certain types are continuous between two values which allow them to be smoothly interpolated in an animation. For example, an animation from 10px to 20px would be 15px in the middle.
Certain types are discrete, so they cannot be smoothly interpolated. For example: flex to grid. There's no half flex half grid value. An animation would just hard switch to the other value.
Variables can be assigned continuous typed values, discrete typed values, or values that can be continuous or discrete.
If you're animating over a value where you don't know if the animation is continuous or discrete, you have to treat it as discrete to avoid nonsense values.
This is why @property at-rule exists. It allows you to specify "this variable" is of a continuous type, and it can not be overridden by a discrete type in the future, which among other things, allows a variable to be animated smoothly when it otherwise couldn't be without the chance of encountering a nonsense value.