Hacker News new | past | comments | ask | show | jobs | submit

CSS @property and the new style

https://ryanmulligan.dev/blog/css-property-new-style/
I'm not a web developer, but I've built toy websites (without frameworks) and can do basic things in a few web frameworks. I remember when CSS was "invented". After a small amount of time, I could reasonably fit all of it in my head without needing to look anything up.

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.

loading story #41454599
loading story #41451012
loading story #41452290
Needing a full feature programming language for things purely related to the page aesthetic is not a great idea.

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.

loading story #41456127
loading story #41456328
loading story #41465054
loading story #41456393
loading story #41457599
loading story #41456283
loading story #41453853
Wow, reading this, I can _feel_ my brain resist an unfamiliar concept. I recommend people read the MDN article linked to in the first sentence before moving onto the examples in the blog.

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.

After reading through the mdn article I'm hopelessly confused.

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?

loading story #41449861
What's particularly interesting about @property is that you can associate custom rendering code. I think this website does a pretty good job showing the powers: https://houdini.how/
I have no idea how naive this question is... but here goes.

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?

Imo, those are security reasons to disable JS. The main privacy reason (again, imo) to disable JS is simply that JS can just send each and every one of your inputs to the server.

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.)

loading story #41452817
loading story #41453372
loading story #41453912
What's absolutely amazing about that is how far people go to do everything in pure CSS, without Javascript, that they put Javascript inside their CSS.
CSS is becoming ever more like a programming language. But you cannot debug it. So why not use a programming language instead where you can do that, and can do pretty much anything you want.
CSS is absolutely debuggable, every browser has dev tools just for this very thing.

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.

Good points about declarative languages. I use CSS all the time. Have to. It is the best tool for the job. But I don't find the browsers' CSS dev-tools very useful. Maybe I'm not just using them right.

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.

The off-by-x-pixels problem usually only happens when you take the unwise path somewhere.

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.

loading story #41453917
loading story #41452003
loading story #41453122
loading story #41449947
loading story #41452364
loading story #41453384
loading story #41450434
loading story #41451850
loading story #41458366
loading story #41451249
loading story #41451838
loading story #41452534
loading story #41450654
loading story #41449190
loading story #41449699
loading story #41449248
loading story #41449755
loading story #41451339
loading story #41450041
loading story #41451395
loading story #41451128
loading story #41451003
loading story #41453150
loading story #41456530
loading story #41456441
loading story #41452450
loading story #41452323
loading story #41456566
loading story #41455959
loading story #41449467
loading story #41454945
loading story #41454011
loading story #41450248
loading story #41452522
loading story #41453215
loading story #41452990
loading story #41509982
loading story #41451662
loading story #41452605
How do we unit test such code in CSS?
You don't unit test CSS.

You E2E test it, and you visual regression test it.

What the hell, CSS has types now?
Always has.

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.

Just so everyone understands what this is... they've added typed variables to CSS that can be passed down to children, so CSS is just converging even more to SCSS and friends. The button is flashy, but not really relevant.

TLDR: you didn't actually need @property to do any of this magic.

You need @property for the interpolations between values for the animations
Isn't that what @keyframes is for?
@keyframes specifies what the values should be at specific moments in a timeline, but not what values they can be between those moments.

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.

loading story #41453898
loading story #41449508
loading story #41451768
loading story #41451746
loading story #41451631
loading story #41449778
loading story #41478060
loading story #41449536