As someone who actively goes out of my way to stick to writing vanilla HTML/CSS/JS as much as possible, it's honestly hard to explain to people who only write within frameworks how good it's gotten. Use the proper tool for the job, of course, but it sparks joy!
I've done the same for years, and it feels a little bit like the IQ bell curve meme, where on the left and right it is like "vanilla HTML/CSS/JS are all you need."
This is an earnest question but is that really true for reactivity and state management? Of course with vanilla is all things are technically possible, but I feel like last I checked this wasn’t something well supported without really knowing what you’re doing.
1. The tools available in vanilla have improved a lot recently and 2. LLMs have made niche skills/knowledge more accessible. SPAs still have their place but the average CRUD app is now really well served by vanilla or lightweight libraries like HTMX.
On the other hand, the average CRUD app doesn’t care about the traffic and rendering overhead of a reactivity library such as Vue. Looking at the boilerplate code needed for basic reactivity that your sibling comment linked to in the Mozilla docs… no, thanks. Just eat the 16kb and have some decent ergonomics.
True, though it is also true that achieving good responsiveness was not as easy in the past, say 10 or more years ago, without flex box and grid and without calc and clamp and such.
I nowadays use flex, calc, clamp, min, max, scoped variables, and even display table sometimes these days and it just works so well. Eliminates almost all hacks.
If the rest of you weren’t so stupid, our industry wouldn’t have a problem
This attitude is why we’re all still stuck writing C++ in 2026. Nobody wants to admit that they’re not hardcore enough to write in poorly designed languages so we never make the effort to improve the situation. We all seem to agree that Zig is an upgrade over C. There’s nothing inherently modern about Zig that we couldn’t have written back in 1995 - we just didn’t because nobody wanted to admit that C is frustrating and clunky, albeit fast.
Yeah, people like to talk about how cultish Rust programmers are, but C programmers are so much worse. Just a couple days ago I had one trying to explain to me that all other languages are worse because you don't understand what the machine is doing under the hood. Completely ignoring it doesn't matter because I have a computer from 2023, not 1986.
> Just a couple days ago I had one trying to explain to me that all other languages are worse because you don't understand what the machine is doing under the hood.
Point out to these people that compilers rewrite your code quite significantly so the choice of language matters a lot less than the choice of debugger, profiler, etc.
I nowadays build sites (personal websites and projects) that are much more responsive than most things I see online or on a job, just using modern CSS, a little thinking about how I structure my stylesheets, trying to use semantic HTML and not making a div soup. It works pretty well, if used correctly and given the due attention.
What's reactivity in this context? How quickly a website responds? My personal experience is that fast backends with server side rendered HTML and a bit of dynamic sections are in practice MUCH faster than SPAs, 20 years after using Gmail for the first time. Gmail then was fast, 95% of modern SPAs are slow.
Reactivity is updating the DOM whenever the underlying data is updated. That's one of the most basic reason for existence of all js frameworks. There's TC39 Signals proposal to bring that natively, but for now as said above the choice is either use a framework or recreate one. It's surprisingly easy nowadays using Proxy.
> Reactivity is updating the DOM whenever the underlying data is updated. That's one of the most basic reason for existence of all js frameworks.
Most web apps and websites do not have that much state variables (even though it may be a lot of data). So while React may offer a small dev speed boost, it’s consumed by the need to build stuff and a whole deploy pipeline to nurse.
Libraries like HTMX and Alpine can take care of most the boilerplate for old style imperative patterns. And backend frameworks like Rails, Phoenix, Laravel donhave their own implementation for data updates.
It’s always been easy to reactively update the DOM. I was doing that in vanilla JS before HTML5 had been formalised.
What the frameworks do is take this concept one step further to create a SPA (single page application) but I honestly think they’re an antipattern that needs to die.
The problems are ownership and provenance mainly, and that all DOM access is slow and requires syncing code internally.
Anyone can write code that tweaks nodes or uses templating, but doing it in a consistent way on a project with hundreds of thousands linea of code is challenging, especially if you also need performance and everyone's least favourite child: accessibility.
Sure you don't get some of this with frameworks, but they help a lot.
Well yeah, obviously frameworks are intended to provide a standard interface for projects that scale. But you’re describing a different problem to the one originally argued.
"State management" is a fancy way to say "your Javascript stores data in variables in some way, which are updated as and when needed".
"Reactivity" means "when those variables change, some generic code already exists to update the DOM instantly". As opposed to writing specific pieces of code to make those changes directly.
Unfortunately, with React, "updating the DOM automatically" generally means: you update the data; React recreates the entire DOM as a new copy in memory; React runs a diff checker to find out what changed from the real DOM; React makes each individual change in the real DOM. With React (or other virtual-DOM-centered alternatives) being used for the smallest of web projects, so many small sites do all that work when the procedure ought to be as simple as: you update the data; you update the DOM directly.
It comes down to inexperienced devs not being able to consider which tool is best for the job at hand, and just hammering nails into every web project in the same way.
I mean all you have to do is change the framework to a better one. Vue with Vapor mode, Svelte, Solid or Preact. These don't have a VDOM at all or use a super fast minimal one.
Signals are basically as fast as writing event handlers yourself but way less fragile and verbose. React is just shaping everyone's impression of all JS frameworks because it's very popular and very slow.
I click the upvote button and a number goes from 0 to 1. Somewhere else on the page a banner gets displayed saying you have upvotes.
Your javascript can target those 2 divs, ala doc.getElementById(counter).innerHtml and document.createElement.
Like that kind of works for simple stuff. But it gets more complicated fast. Reactivity is when your counter listens for change in the count and updates itself whenever that count changes.
That's why you wouldn't target those 2 divs directly, but have one dedicated place, in which you update the divs and call that place from any other place that needs to update the 2 divs.
Well, that's simplifying the situation, but as those situations become more and more in ones site, at some point one might switch to a mediator pattern, which kind of is very close to signal emit and listening for signals.
No, it's not, despite what other comments here say. Of course it's possible but you end up recreating React or another library along the way. JS is getting native signals sometime in the future but for now pure JS is not sufficient for a full, complex app.
> you end up recreating React or another library along the way
That's always the trotted-out response, most often recited by people who've read someone else saying it but not had the experience to form an opinion for themselves.
You absolutely don't end up recreating a massive, bloated, slow framework that tries to be as generic as possible to try to be everything to everyone. What you end up creating is a relatively tiny, fast, piece of code that is specific to that site's needs. The difference in size, speed and simplicity tends to be absolutely enormous.
Wrong on both counts. I've worked in companies with vanilla JS only and made parts of those frameworks they ended up building. It is absolutely not "relatively tiny, fast, piece of code that is specific to that site's needs" and once we switched to React we actually saw improvements in many parts of the sites' loading speeds. Next you're gonna No True Scotsman me by telling me the company was just bad but I've seen enough examples at other companies to see that using React or a similar framework is simply the right move.
For a large ERP-like back-office where leadership didn't want to use an existing reactive framework, I definitely ended up recreating built on top of jQuery ( at the start of the project IE still needed to be supported ).
Once you start adding dynamic forms for managing multiple items of different kinds, dashboards, error states, i18n, etc, you either end up with a homegrown framework, or with a lot of spaghetti.
There are JS libs (like Reactive Mastro [1]) that go well with writing otherwise vanilla HTML/CSS/JS, and there are libs (like React) where you're quickly sinking into a mud of abstractions and have to fight the reactivity runtime when you try to write vanilla JS.
That is an odd caveat to throw on the end. Sure, to avoid frameworks you have to know what you are doing. Is that really such an outrageous expectation?
If people knew what they were doing jQuery, Angular and React would not have existed in the first place. With devs moving companies every two years or so, being able to hit the ground running was very important and you couldn't afford to spend weeks or months learning the idiosyncrasies of your new codebase especially when it came to state management. That's the main problem frameworks and libraries were solving.
> you couldn't afford to spend weeks or months learning the idiosyncrasies of your new codebase especially when it came to state management. That's the main problem frameworks and libraries were solving.
Not really. Frameworks are usually created to avoid boilerplate and provide some nice scaffolding to support you while you’re coding the business layer. And a lot of them do smooth over accidental complexity, even though the architecture is generic and may hinder you in the future.
But the learning curve still exist, as most of what you interact with is custome codes, modules and components.
That's not quite right. jQuery was exactly the right tool for those of us who knew what we were doing. Browser inconsistencies in the early days were practically insurmountable without jQuery to provide a consistent API surface.
> is that really true for reactivity and state management?
No. Use a framework if you want those things. Everything around reactivity, state management, and components have been badly fumbled by the web platform and the various front-end frameworks are far more ergonomic.
Definitely worth keeping up with as a framework user too.
Smaller bundles, often easier to use, less bug potential. Code's a liability and being able to occasionally rip a bunch out as a feature becomes baseline is always a joy.
Y'all know React and Vue frameworks still use HTML, CSS, and JS, right? We're using the same thing, with a thin layer of helpers around mounting components and managing their lifetimes...
People who use css-as-an-object type of frameworks or tailwind don't really get to experience what writing CSS is like. styled-components or Linaria or Emotion do though ofc
As culi also touches on I think it depends on what is meant by frameworks. As someone who belives abstraction are horrible practice unless they serve a really good purpose though, I never bought the "this is easier" part of the big CSS frameworks. I fully accept that people who work on user facing web applications more than I do, which is rarely, had a much easier time using something like bootstrap/tailwind/whatever. I always found having to look up documentation on something wich was infinitely worse than the CSS documentation on developer.mozilla.org to be a a weird experience. I do fully accept that a lot of teams experiences would prove my personal opinions wrong on this.
On the flip-side I always found javascript frameworks to have a purpose. Though to be fair I don't think I've worked with user facing javascript without a framework since jquery came about. I guess you could call that a library, but still.
I don’t disagree with you and I lurve frameworks. Yes, I love react. It is so awesome.
But it is SO nice to not have any build step. All of my new projects start as a single babashka script now. You got html templating, throw in a stylesheet. Slap a datastar script tag in there for everything else. It’s just easy peasy.
"flexible divs side by side" sounds like something which can be generated in many ways, From display: inline-block, over float:left, col-columns, flex layout, to a grid based layout. Can what you desire be created in, for example, https://grid.layoutit.com/?
My rule of thumbs is: Use flexbox unless it truly is a grid or repeating rows + "I wonder if a flexbox can be used ... ah yes it can."
Flexbox is just made for responsive layouts. It is very good.
> Just do a google search for flexible divs side by side. Start with two. Then switch to five. Tell me the solutions that work well.
I did like you asked. The first search result on google is a question on stack overflow. And the first comment provides an example that looks very much like flexible divs, side by side, between two and four based on the width of the container.
OTH all the complexity ends up baked into the browser where it will be frozen forever (even the shitty/overengineered ideas, like WebAudio). At least frameworks can be discarded and replaced when something better comes along.
IMHO even HTML+CSS should be completely implemented outside the browser in the 'framework layer', but I guess that's not a very popular opinion among the more 'conservative' web devs ;)
If that means having an "HTML+CSS framework" that I could easily swap out for a "Typst framework" and publish my blog using Typst, then sign me up!
Meanwhile, there's Typst bundles [1], still experimental, that implement the same idea backwards: convergint a Typst project into a set of output files (which can be HTML).
They were too slow, people are all tailwind native now and don't know a thing about CSS. I keep seing "full stack devs" complaining about "bleed out" issue, aka C in CSS, cascading
Agreed. I think part of why it's hard to convey is that a lot of people formed their idea of CSS back when flexbox was new. These days an accordion is a few <details>, and a reading progress bar is a fixed div with animation-timeline: scroll(). You don't need JS for either.
Flexbox is still fairly new! Hmm, maybe I'm just old.
While a lot of devs love to use brand-new stuff that's only just been added to some browsers, some of us are not willing when we know it won't work for (almost) all users. The scroll() function is too new for use in production, IMO (but good to know it exists, to revisit after a while). If I have to code something else anyway, or copy-and-paste a polyfill, then why not just use a more robust option in the first place.
Wow even more fancy border styles! Infinite complexity for useless eyecandy. Date pickers are still barely working, last time i needed to build a touch optimized interface (gloves, industrial setting) with date picker, time picker, and numeric up/down style input fields it needed custom components and js...
But who needs these, when we can have bezel and whatnot...
Who needs ways to reliably trigger the display of the touch platform-native keyboard, to be notified if it is displayed and to move the input field in view so it is not obscured by the keyboard?
This is why the web is a terrible platform compared to Windows Forms for getting stuff done. Because those making the standards only work on creating gimmicks.
> Because those making the standards only work on creating gimmicks.
Totally agree, but afaik we are a very small minority. My tinfoil hat theory is that all of this is intentional to keep monopolies and making it impossible to compete in the browser space
And I believe the OP is right. Keep people busy working with changes that don’t move the needle, each of the three large platforms wants to lock in the serious use cases into their native apps.
How does Mozilla benefit from keeping it complicated? Or Microsoft, for that matter? Neither of them have a mobile App Store, so are they just playing along for the hell of it?
This is a known consequence of standards bodies: they get infested by vested corporate interests who generally, in the best case scenario, want the standard to include their entire pre existing implementation. In the worst one they just filibuster and veto proposals until they can't any more and they have to do what everyone else wants/is doing.
This is a phenomenon that dates back to IBM doing this in the 60s-70s-80s.
Making a community maintained strict subset of the WWW is the way to go if you don't want to always rely on the monopolies. The W3C people had a good vision for the web that was compatible with the soul of the web as Tim Berners-Lee intended, but also different to what those that then went and made WHATthey were thinkingWG that wanted to embrace, extend, and extinguish the WWW into their dystopia of the web of application and forcing the poor html and css into this amalgamation instead of building on a more compatible base to their ideas. But corpos only look at the possible profit and not the general consequences, they're like parasites.
Web of applications is a novel idea if executed well, but imo just download the executable and use the package manager to update it, and we still have the internet for communication, there's no need for a pseudo OS on top of the OS, if you want sandboxing and a VM do what they did with Java. The modern Web is unnecessary, everything that needs JS or frameworks is because of the retardation in the initial primitive design of the WWW and html, everything could have been implemented in a new xml markup akin to htmx, they were steering to that with their ideas in XHTML2 but never finished because of oppositions from Google et al. Other things like implementing an office suit or playing games in the browser is incompatible with the WWW, and like I said you better go and make a better platform for that.
Today it's simple to write your own OS than make a web browser, which contradicts everything about the web being decentralized and a protocol, what's the difference then if we would send propriety bytecode to this VM called the modern web instead of html et al? Sure you can still use and support a subset, and because of that I mentioned this idea as the first sentence, but this is the trick of EEE; the majority would bite the propriety extended conveniences and make it the new standard, then they would constantly extended until it becomes a game of resources which they have the higher hand in.
Some would say it's opensource and anyone can implement it, that's half the truth when it's so complex and grand that only *big* corporations can handle it, and that the WHATWG confessed that the real standard became the source code of the big 3: chromium, webkit, and gecko.
Those that believe this is some kind of "tinfoil hat bs" and there's no conspiracy are worse than those that believe everything is a conspiracy; because at least the latter would be right once, while the former are never right. I didn't mention also how the new web makes it easier for their spyware, but that's obvious. The web was about decentralization and standardization, but they skillfully made it the literal opposite.
In another world, Netscape is able to reach a deal with Sun, and the JVM gets integrated into Mozilla. New browsers just need to implement the JVM and bind it with their XHTML's rendering engine DOM API.
It would have been the application platform people ask for, with a separate namespace for application-related tags so you can just switch them up with the OS's native UI controls.
Instead of that, we got Yet Another VM, WebAssembly.
Not trying to throw shade, but I think the number of devs wishing that the web ended up with XHTML + JVM (now owned by Oracle...) may just be you.
Never mind that when Microsoft licensed Java from Sun for IE3 and IE4, Sun sued Microsoft. Sun wanted to be the only distributor of Java, just like Adobe was with Flash. So, browsers wouldn't have actually included a Java runtime out of the box without licensing/paying Sun for it. I'm sure that dependency would have only gotten even better under Oracle.
Those of us old enough to remember the web with plugins, don't miss plugins.
> Not trying to throw shade, but I think the number of devs wishing that the web ended up with XHTML + JVM
I don't necessarily like the JVM, it's just the most popular system-independent bytecode virtual machine (and historically plausible). It's a lot easier to built a bytecode interpreter than a full language. As mentioned elsethread, Scheme would have been even better, with an even smaller base.
XHTML, however, full in. Namespaces and syntax checking alone would have been worth it.
> Never mind that when Microsoft licensed Java from Sun for IE3 and IE4, Sun sued Microsoft.
Microsoft was in their peak EEE era, no wonder Sun didn't want to do anything with that.
> Those of us old enough to remember the web with plugins, don't miss plugins.
That's why I didn't mention plugins, browsers would have a JVM engine, instead of a JS one.
I'd love to see this level of customization come to date and datetime-local popups, finding a meaningful path that preserves compatibility with the design languages of various platforms. If and when that happens, it will be because of the work of standardization working groups like Open UI and Interop.
And then there's the nightmare of any interval that runs over daylight savings boundaries, and what that really means if you want not just a date-picker but date/time picker.
> date pickers are something that quickly gets overly complex and site specific.
I'd settle for a browser specific picker that works in 80-90% of use cases. Instead it took browser several years after introudcing type=date to make a datepicker that is actually usable, and not a throwaway tiny design cooked up by an underpaid intern
that's true. But even for some of the easiest cases some browsers don't support them. input[type=month] for example still has no custom UI in Firefox or Safari. And Chrome has had one for 14 years!
That's because dates are extremely complex and subject to all sorts of political and business rules.
Those business rules, daylights savings (datetimes that can never happen, or happen twice), different M/D/Y ordering, different starting day of week, different timezones (including 15 or 30 minute offset ones like India, Iran, parts of Australia, etc), etc quickly complicate it. Oh, and don't forget about making it accessible.
That's before you even get into designers who want the date picker to look the same across platforms instead of using platform specific UI widgets...
I'm pretty sure my version of hell would be implementing a date picker until all stakeholders are happy with it (eternity).
It's probably easier to standardize small CSS utils than it is for a date picker.
What would the API even look like?
One could want to select a single date, multiple dates, a date range, multiple date ranges.
Perhaps some dates should be disabled, but should they just be greyed out or should there be a message when the user tries to select them, and if so, how can it be provided?
Then there are questions about different calendars and locales.
Perhaps third-party date picker libraries are more appropriate here than trying to address this in standards.
The stuff in this article is created by the CSS Working Group. The stuff you want would not be handled by them.
> Who needs ways to reliably trigger the display of the touch platform-native keyboard, to be notified if it is displayed and to move the input field in view so it is not obscured by the keyboard?
> The mobile web contains two viewports, the layout viewport and the visual viewport. The layout viewport covers all the elements on a page and the visual viewport is what is actually visible on the screen. When the user pinch-zooms into the page, the visual viewport shrinks but the layout viewport is unchanged. User-interface features like the on-screen keyboard (OSK) can shrink the visual viewport without affecting the layout viewport.
CSS isn't useless eyecandy. Everything we currently do in javascript that can be offloaded to CSS is a performance gain. Sadly datepickers are out of scope for CSS. Expecting this group to solve datepickers is the same as expecting them to work on solving world hunger (and almost as difficult :)
Off topic: But contrary to popular belief world hunger is technically solved (as in solved on a technical level). We do produce enough food so nobody needs to be hungry, and we know how to distribute that food to anyone who needs it (outside of a handful of warzones, but even there the right organizations have a good plan that will probably work if given the funding and the political backing).
World hunger is now fully a political problem and needs to be solved politically. It may sound hard, but in this case it is only a matter of money. The right organizations just need more funding, again that might sound hard, how do you pick the right one, but in this case the right organization is almost always the UN World Food Programme. They need exactly $13B to solve world hunger. And that is not a lot of money.
Perhaps WHATWG just needs more money and then they will solve the date-picker.
Jokes aside, I never has had any major problem with `<input type="date">`. Yes there are some annoyances when translating between local time and an absolute timezone aware timestamp. Yes it is annoying that `.valueAsDate()` doesn’t work out of the box. But those are very easy to overcome with a three line utility function.
well, no, the WFP's current yearly budget is 13B, which is nowhere near enough to solve world hunger, considering world hunger still exists. They actually say they need 93B/yr until at least 2030 to solve it.
I stand corrected. Regardless it is still an easy thing to solve. 93B/y is still not a lot of money for solving world hunger. Well worth it if you ask me.
I've been away from CSS for a few years and this looks alien to me. I don't know any of this syntax except for the div declaration, and I used to think I was good at CSS with less and sass. I don't want to deal with molecules, or atoms, this is just too much.
Since I’m in before the negativity: I love CSS! For whatever reason, it’s always made sense to me. I have great respect for everyone with the tenacity to push on improvements that might take 5-10 years to be in common use, if at all.
We're pretty far past the 5-10 year timeframe now that browsers push updates so aggressively. It's pretty common to see features that were adopted just a year ago in common use
I’m part of the seeming minority that really enjoys working with CSS. And the way I use it today is so different than I did a few years back, e.g CSS modules, declaring a palette with variables then changing it for dark mode… it’s genuinely great to work with.
light-dark() is even better for that :) I also enjoy CSS, using @scope and @layer a lot with the :has() selector, it’s just so different now and I think most people are unaware.
Working with modern CSS is such a joy, and increasingly as time goes on I'm replacing huge chunks of JS with CSS which is a little boon in itself. Honestly, my only complaint is how long I have to actually wait to use new features.
Nesting and @layers make maintaining CSS drastically easier than it once was as well.
I agree. And I don't even use layers yet. I keep specificity roughly in mind and narrow my selectors using nesting properly to only affect what I want the rules to style. Do I make mistakes? Sure, but they are easy to fix. Make selectors specific enough and think about whether the rule you are writing is something general or just something for this one component on the page, and it is eeeeasy to not make a mess these days.
I love working with CSS as well. It feels like the most optimized approach to me. However, it's really hard to use CSS as much once the project involves other engineers who don't have that level of interest in CSS.
I warmed up to CSS this year. Before that it was this cryptic thing with seemingly infinite change-try cycles. What happened was that I discovered some of the new features, and was able to greatly simplify and beautify my CSS. I might end up liking it.
It has this maddening amount of features though, and as it needs to be backwards compatible, this amount can only grow going forward. But if you look at a well chosen subset of the whole thing, it actually is a quite nice language.
"Functions in CSS" - Bah! That's all we need to make CSS even more convoluted - make it compete with Javascript now ... All these feature creep is just to make sure nobody else can create another browser engine.
This. Currently, if you don't want web pages "computing", but you still want basic content, you can turn off JS. Add explicit functions to VSS makes this impossible.
As someone mentioned above, it probably would have been better if they weren't called functions. Macros, maybe.
Also the blog really doesn't help by describing it like this:
> If you’re familiar with JavaScript, this should feel pretty familiar. We define new functions with @function and specify the returned value with result.
I'm still waiting for decent tooltips that are browser native. You can sort of minimally do them with the `title` attribute but they take ages to appear, can't contain HTML or styling (like bold text or images), and you can't choose their position. To do them properly with accessibility in mind (keyboard/mouse/touch support, screen reader support, keyboard focus, it's hard!), you need way too much markup with tricky custom JavaScript, and they're difficult to get right like making sure they don't render partially off-screen.
The new CSS anchor positioning and popover attribute help but something simple and built-in that doesn't require lots of wiring would be great. It's puzzling why we don't have this basic UI feature yet?
> The new CSS anchor positioning and popover attribute help but something simple and built-in that doesn't require lots of wiring would be great. It's puzzling why we don't have this basic UI feature yet?
What's the problem with popovers and anchor positioning? They're practically made for tooltips, I use them in production for this purpose right now.
Worth keeping in mind that Josh's blog is absolutely over-engineered and I'm sure he'd admit that himself. He tried to keep parity with his rather complex course systems and his blog itself is a lot more than 'text on a page'.
offtopic here but what the heck, I am learning C from you right now! You finally made pointers click for me after failing to learn them a handful of times in the past. Legend!
I do not think functions in CSS are the original sin. Why we don’t have them, was a valid question in the 90ies already.
And you cannot emulate functions by using a preprocessor in all use cases.
But what bothers me is the governance model of CSS, the increasing complexity that leads ultimately to more framework usage, not to thoughtful engineering of accessible front ends.
Very soon CSS will be Turing complete and we can have a JavaScript-free C64 emulator. Yay.
We need basically control structures and full access to user input to achieve that.
And we can only hope the vendors get the sandboxing right this time, otherwise we will get a entire new class of CSS based browser exploits.
Functions might sound scary, but in reality they're used already in CSS processors like SASS/SCSS - and then they actually reduce complexity of the code.
The example with linear-gradient is probably the best use case for them.
He even cites the reasons for that over engineering in the post you've linked?
Also, even before reading the comments, I was pleasantly surprised that everything on that page worked and nothing bothered me. There is a good amount of attention to detail (switching of the rounding on codeblocks when switching to light mode for example, avoiding a weird corner on mobile). Nothing moves around on load etc. I know this is a low bar, but it's gotten pretty rare, even for pages linked on here.
I'm trying to say that his 100k lines might actually be spent on attention to detail and aren't just slop.
Good to see Josh writing, especially after his courses have taken such a hit. He is excellent. As an electrical engineer and also now CS grad and someone who has purchased his courses wanting to be able to work across the entire stack.. yet have also thought "thank god I don't really have to learn css" now (yes, due to increasing model performance).
On that note I may know just enough to be dangerous thanks to Josh (casting spells: e.g. shouldn't we group those in their own container and then within that container shouldn't that be a flex box?). I guess I'm here to say humans are full of contradictions.
The discussion here reminded me of one of my favorite demos, someone live coding Qt5 and QML on a first a generation Raspberry Pi, 1080p HDMI. Sort of a mashup of CSS and JavaScript for simple shaders. Fourteen years ago.
> If you’re familiar with JavaScript, this should feel pretty familiar. We define new functions with @function and specify the returned value with result.
It used to be that HTML was for content, CSS was for layout, and JS was for "code"
Now JS is for content and layout and code, HTML is for content and layout, and CSS if for layout and code
I think your definition is off. Js was never for "code". The code itself is just a means to a goal. That certain things better can be achieved without js is good.
Better analogy would be "Microwave ovens were never for injecting electromagnetic waves into food. The electromagnetic waves were just a means to heat the food".
For people who only read the titles / comments, I was expecting another silly rant about how AI is disrupting CSS or something, but this was an excellent, concise overview of new and upcoming CSS features. Very well done.
A bit strange to me how Josh beings with heralding the browsers working together and then every mentioned feature is Chrome only. They're nice previews for a potential future I suppose!
The article is specifically about the “inter-op” program where the browsers work together on specific standards to bring to all browsers. (And we get to vote on the selection!)
It's because Chrome has taken over interop. Just like they do with any other useful initiative like OpenUI [1].
It feels like Interop was created to curb Chrome's bulldozing various processes with their own internal APIs and development, and to show that there's more to the web than yet another shitty Javascript API. So a lot of Interop is decidedly everything else. See e.g. Interop 2022: https://hacks.mozilla.org/2022/03/interop-2022/
Of course Chrome bulldozed this effort as well
[1] https://open-ui.org/ Started by Microsoft, of all people. Now almost completely taken over by Chrome of course.
The new responsively-sized iframes standard is an exciting one for me not mentioned. It's finally a step beyond the original frames and framesets. It will let us design sites out of iframes as building blocks instead of needing to use web components. Websites made out of websites.
Corners and borders have been a pain since the beginning of GeoCities. I do wish fancy corners would go away---to the point that I actively make this happen with a global Stylus rule setting border-radius to 0.
Look: Three of these 10 "improvements" deal with corner shaping, and two more will inevitably need extending, as I imagine frontend devs get around to, "GPT make reading-flow responsively round only the outside corners," and, "Claude how to squircle the individual grid cell borders when using rule gap decorations."
I understand CSS wants to do all of the things and do them well, but then the eye candy gets overused on every webpage and web framework template to the point that practically no site feels different; it's all "logo, four links, giant-ass 'call to action' rounded button in the bold colored top nav, rounded corner cards in a grid layout 3 to 4 cells wide (or in a slider), gratuitous whitespace, rounded corner everything actually, maybe a gradient text or background or both, hamburger menu on mobile, all styles inlined in the HTML classes".
Going down the list of Fortune companies, three of the top 50 don't "round corner" everything: Berkshire, Exxon, Morgan Stanley. A few more would count if you permit rounded buttons only. Marathon is a weird outlier; they have hexagonally rounded elements buttons. (Also, some of these sites must be hosted on a Zune. It takes 50 full seconds to load Cencora's main page.)
I can't say that I do web dev any better, although I am disappointed by the looks of the modern internet, and I don't think more artistic flair will make it better, just as I don't think houses and cars and suits benefit from strange shapes and colors.
although maybe more choice will free us from the confines of everything looking like Tailwind? (Despite my complaints, I am grateful for progress and also am absolutely not looking forward to people misusing functions and dropping 18 errors and 11 warnings into console.log AHEM LENOVO because they can't be troubled to write good code/markup.)
That's a spot-on summary of all websites I see. It seems particularly annoying given that most landing pages seem to be identical LLM-output pages that require a lot of scrolling before you get to any "information" on the page.
I know this post isn't about vibecoding frontends, BUT...
Many of my coworkers and friends are rejoicing that they don't have to write frontends anymore. I actually think that frontends are the last thing that should be vibecoded. It's the part that faces the user. It's what helps the user form their first impression of your product. If your landing page looks like it was made in 30 seconds by Claude, they'll assume the rest of your product was too. Use AI assistance on the parts of your codebase where only raw functionality matters (eg, the backend), and put real human effort and care into the frontend that reflects the effort put into the rest of the system.
everyone is rejoicing the other part of the stack can be vibecoded.
a backend developer would tell you the backend is much more important to focus on, performance, security, data integrity etc. not losing or exposing customer data is a lot more important than what it looks like.
truth is, it's all still important, preferably no one is vibe coding any part of a serious product.
Shocking take: you shouldn't really vibecode any part of a serious application!
Definitely use coding agents to write code, but carefully and thoughtfully review any important backend or heavily user-facing components of the software you're developing.
Here's another prediction in the ocean of them we're swimming in right now: websites won't matter. When you have a general interface that can present data however you wish, being restricted by the whims of designers will seem prehistoric.
This is the type of article I really miss reading... before AI took about half of HN front page this is the type of stuff that would routinely pop up...
Because JavaScript requires… a lot. A virtual machine, script parsing, etc. Making that a requirement before you even display any content on the page would be a regression.
I can see that, but CSS already requires a lot, no? Especially as they keep adding new features to it.
To me it feels like "programming in YAML", the way a declarative language/format acquires more and more features until you're writing functions in an awkward syntax that was never designed for it.
It requires a lot… but a lot less than JS. The awkward declarative nature of it is a side effect of wanting it to parseable at speed.
At an initial look I agree with you that the functions look very awkward. But I thought the same about CSS variables until I started using them and now I think they’re great so I’ll keep an open mind. I almost wonder if they would have been better off calling them “templates”, or something. “Functions” is going to make people think it’s just like JS.
Yeah OK, I see what you mean, I may change my mind once I start using them. And having worked on interpreters and compilers, I can understand the need to keep internals simple and fast - like everything must be parsable in one pass - so the surface ugliness of syntax isn't as important in the long term.
Perhaps I should also be sympathetic to the spec authors, since they're working under tight constraints of language design. Things might look a lot more elegant if HTML/CSS/JS were designed from scratch as a coherent whole.
Oh wow I hadn't heard of CSS Painting API. At first glance it seems like a "frame buffer" you can write to directly, kind of like the web audio worklet processor but for styling.
I've always wished more of the underlying CSS functionality were exposed to the scripting side, like calculating flex/grid layouts, without necessarily tying it to performance-critical painting path. Usually more expressive power means more responsibility, but there are already web APIs that do it in a controlled way, like request animation frame. So I can appreciate the potential of the Painting API and others in a similar direction.
At the same time, I also wish there was effort in the complete opposite way, to start over "from scratch" and make it easier (or possible at all) for people to build alternative browsers with a minimal subset of CSS. Perhaps something like a modularization of web technology, where the current hugely complex system is broken down into reusable libraries for building small and large browser-like applications. I know something like that exists, like Servo etc., but much smaller and simpler building blocks.
Strongly agree. While I am a huge fan of the capabilities of native CSS and the fact that it keeps getting more capable as time passes, I have come to the conclusion that it is unfortunately a programming language trapped in an “obsolete stylesheet syntax” body, especially after the addition of calc(), variables, functions and multiple ways of conditional logic.
The worse part of working with CSS is that there is no standard static type checking tool (stylelint comes close though). A lot of programming errors should/could be caught at build time.
Sometimes wondering if a completely alternative syntax+tooling is possible that would leverage all the existing capabilities, while using a different language paradigm.
> In an alternate universe timeline, we could have had a single web language for hypertext, styles, and scripting.
That's actually something you don't necessarily want: https://www.w3.org/2001/tag/doc/leastPower.html ... then again, once you hit turing-completeness and people start relying on it, you probably also have to admit that you're already soaking in it and you may as well make it pleasant.
> T. Berners-Lee, Axioms of Web Architecture. 1998.
I love that he used the word "axioms", especially these days when mathematical logic and mainstream software development seem to be reaching toward each other through type systems, static analysis, verification and so on.
That design document about "least power" is fascinating, it's a classic tension in programming language theory about expressivity and the value of constraints.
Reading about how HTML and CSS were intentionally designed to not become a programming language, it's funny to compare with modern web dev practices like React and CSS-in-JS, which re-envision what the separation of concerns means, very different from what the language designers had in mind.
If CSS is Turing complete, that means it has a virtual machine with parsing and so forth. That means that difference between it and JavaScript is just syntax. (Same for any Turing complete language)
Not just. There’s also the issue of complexity. And JS is considerably more complex. Just think of all the APIs that are immediately available at runtime in JS, for one. It takes up far more memory and CPU cycles to initialize, the language itself is much more complex…
I am not quite sure I understand what you are getting at. Surely, we don't have to go into why syntax is extremely significant for feasibility of implementing features. I mean, we don't code in assembly much these days, do we?
I was going to complain that the W3C CSS validator is hopelessly out of date, and still doesn't handle CSS nesting for example. But there's been loads of activity in the last few weeks, including a fix for nesting.
The future of HTML/CSS and hopefully JavaScript is, that it no longer used and replaced by a new technology stack.
Especially CSS is such a miss fitting technology for what it is used today, that web frameworks actively fight it, by trying to keep its scope to components.
When looked at web tech from a distance, it is cristal clear to me that we need something new.
Instead of all the abysmal complicated rules of CSS, we would probably be much better served by something like ElmUI (a modern advanced version of the idea) + some scripting for dynamic things.
Imagine a world where we have better technology and someone looks 20 years back at an old codebase. Everybody would have a hard time to understand anything. Everything of the old web tech would look overly complex und laughable overengineered. Nobody would probably be able to understand how a piece of CSS influences a part of a web page or how all the abstractions work in the code base and why they are there in the first place.
Modern web is a mess. I wish it wasn't, but it is.
This is a monkey's paw situation, because instead of the web people are increasingly getting pushed into native apps. I'll take the janky web languages over native apps any day of the week.
I'm more insterested in the new CSS scoping feature that still not supported. HAving CSS only work on a scope of the DOM would make dealing with CSS a lot easier.
While waiting for that I decided to use Tailwind so I can basically "not do CSS", but have it locally defined in my HTML. It buys me a similar freedom to the CSS scoping feature, as the cost of having to run a bunch of tools to get my final CSS asset file for deployment.
2. website work perfectly fine without CSS functions, Bevels and squircles, Infinite possibilities with border-shape, ... only need these for make CSS educational blog
Been waiting a long time for CSS inherit() . . . although I freely admit that (and CSS Functions) open a respectable-sized can of worms. Sort of like what transclusion and conditionals do for document markup.
Anchor Positioning would be sweet and doesn't feel like it's got so much baggage.
However, I always wonder, does the browser really need to understand this syntax? (I feel `function` is too much for just stylesheet)
Ultimately, what we want to represent is a DOM tree. The format doesn't matter. So we should send a computer-friendly, pre-compiled data structure that the browser can use directly. memcpy is faster than parse.
CSS was born out of the idea that content and presentation should be separate with the former controlled by the author and the latter by the consumer.
Most of CSS's design was informed by that idea. That styling is in separate files in the first place and then all the complicated cascading stuff that is even in the name of the thing.
I've always been fond of that idea and still am but there is no denial that it utterly and completely failed and now we live in a world where all these things are just cargo cult. Sometimes I think it'd be best to finish what Tailwind started and be consequential about it which would mean going back to presential HTML alltogether.
It failed because it married selectors to the content, so the CSS rules inevitably follow the document structure. You can avoid it by either using utility css, avoiding descendant selectors or using some methodology like BEM and use only classes to style elements. There are two types of separation here, same document that can be styled differently with a different stylesheet (think zen garden), but the other one is reusing the same look&feel across different web pages. These two goals are not always compatible. The other thing to consider is that maybe HTML itself is the presentation layer, data usually lives in a database or different file formats, JSON, CSV, excel spreadsheets. A lot of the aspects of laying out the content is trapped in how you structure the HTML, and no amount of CSS can change how the document is organized.
This looks a bit like another revolution is brewing, where people relying heavily on Tailwind might one day be surprised how powerful the raw CSS has become.
I am very much excited for the future of CSS. And I love that functions are a part of it.
I spent 3 months this year testing out a reporting system for large quantities of dynamic data.
My requirement was to generate pdf reports, but didn't want any reporting tools and installations. Especially something like Microsoft Excel, which the old system was based on.
After a lot of tests and proof-of-concept apps, I finally zeroed down to simple, pure, self contained html, that I am generating from a python script.
And it's glorious.
I am generating interactive charts when the html is viewed in the browser, and hiding all of them and only printing static svg images when in print mode, using css media print queries.
I built a web app with Claude Code without reading the code it wrote. I only asked for things like "add outer margins to the menu and header, with a transparent blurred background," and it came out the way I imagined.
Give it a more charitable reading. But I think there is truth to it, CSS was never that great with just describing what you want, it was always more like arcane spells and tricks you learn to achieve a specific goal. Historically just trying to center something or achieve equal spacing would send you down a deep rabbit hole of quirks, browser support, layout modes and so on.
For small-scale projects, I use a server-side helper for an HTML page to include only certain CSS, SVG, and JS on a page. Each JS file is tiny, progressive, vanilla JS; SVGs are predefined and generate an SVG sprite that I then consume; CSS pulls in a `base.css`, the page's CSS file, and any component ones pull in their own. It's hand-rolled per project (pre-AI being decent), but I'm proud of it, and it keeps every page tiny. HTTP/2 multiplexing is pretty good and downloads the files more or less in parallel.
Thankfully, now that our machine God is here, we don't need to bother ourselves with learning new CSS features. Just feed the article to the machine as part of the spec and it will handle everything.
I hold the opinion that adding anything to CSS is a bad idea. It's already complete, you can do almost everything you'd want in it, and if you can't there's always javascript. Updating CSS forces people to update their browsers and we get that never-ending chase of compatibility. It's just breaking stuff for a little benefit
a) they keep on making CSS more and more complex. You can reason in favour of it, of course, but it is undeniable that CSS becomes more and more complex - and complicated, too. Which leads us to b)
b) "CSS Subgrid is a good example. Subgrid is a super-powerful extension to CSS Grid which enables entirely new layouts."
Well ... I wanted two flexible divs side by side. It is possible, but there are like 5 different main strategies for this, grid is one of them.
Now via a "subgrid", they acknowledge that the existing ways SUCK. So they add yet-another-component here. This reminds us of:
People can hate it, but they work really almost flawlessly. I am not saying I use them for everything, but I totally changed my mind after I saw how flexbox and other things SUCK to no ends. So I now compare all of them to HTML tables. If they suck more than HTML tables, I discard them. This is my quality metric now. And a lot of this has to do with developers making these decisions, failing hard at DESIGN. What happened to simplicity? HTML tables are simple for the most part; they are kind of like a grid already.
I wanted subgrid a few years back. Imagine you need to show 3-4 pricing cards next to each other. It can't be a table, the cards have padding, an outline, shadow, etc. Inside they have rows of features. But some of the items aren't just a single line of text, they wrap around, and you need to have the heights of those inner rows align between the cards. It's not possible without a subgrid or some custom JS code.
so funny to start the article with "Interop that all compilers unite to implement together" and then proceed to show features available only in one browser
this is like the webdev version of the c++ people who love talking about how great the modern version of their language is, ignoring the fact that all the bad stuff is still in there...
remove inheritance and cascade from css and then we'll talk. but for now ill stick to tailwind.
Less than you'd think. A lot of it is just knowing the right element exists. A slide-out menu that closes on Esc or when you click outside is a button with popovertarget, a nav with popover, and a few lines of CSS for the animation.
As someone who actively goes out of my way to stick to writing vanilla HTML/CSS/JS as much as possible, it's honestly hard to explain to people who only write within frameworks how good it's gotten. Use the proper tool for the job, of course, but it sparks joy!
Yes!
I've done the same for years, and it feels a little bit like the IQ bell curve meme, where on the left and right it is like "vanilla HTML/CSS/JS are all you need."
This is an earnest question but is that really true for reactivity and state management? Of course with vanilla is all things are technically possible, but I feel like last I checked this wasn’t something well supported without really knowing what you’re doing.
1. The tools available in vanilla have improved a lot recently and 2. LLMs have made niche skills/knowledge more accessible. SPAs still have their place but the average CRUD app is now really well served by vanilla or lightweight libraries like HTMX.
On the other hand, the average CRUD app doesn’t care about the traffic and rendering overhead of a reactivity library such as Vue. Looking at the boilerplate code needed for basic reactivity that your sibling comment linked to in the Mozilla docs… no, thanks. Just eat the 16kb and have some decent ergonomics.
CSS was always pretty accessible. You just had to actually care to learn it.
True, though it is also true that achieving good responsiveness was not as easy in the past, say 10 or more years ago, without flex box and grid and without calc and clamp and such.
I nowadays use flex, calc, clamp, min, max, scoped variables, and even display table sometimes these days and it just works so well. Eliminates almost all hacks.
I used flexbox 10 years ago for sure. Grid I think was introduced before flexbox, but didn't get proper browser implementations until around covid.
If the rest of you weren’t so stupid, our industry wouldn’t have a problem
This attitude is why we’re all still stuck writing C++ in 2026. Nobody wants to admit that they’re not hardcore enough to write in poorly designed languages so we never make the effort to improve the situation. We all seem to agree that Zig is an upgrade over C. There’s nothing inherently modern about Zig that we couldn’t have written back in 1995 - we just didn’t because nobody wanted to admit that C is frustrating and clunky, albeit fast.
Yeah, people like to talk about how cultish Rust programmers are, but C programmers are so much worse. Just a couple days ago I had one trying to explain to me that all other languages are worse because you don't understand what the machine is doing under the hood. Completely ignoring it doesn't matter because I have a computer from 2023, not 1986.
Case in point: https://news.ycombinator.com/item?id=50169201
I honestly didn't know people like this still existed, with such strong viewpoints on C.
> Just a couple days ago I had one trying to explain to me that all other languages are worse because you don't understand what the machine is doing under the hood.
Point out to these people that compilers rewrite your code quite significantly so the choice of language matters a lot less than the choice of debugger, profiler, etc.
Yep. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
I nowadays build sites (personal websites and projects) that are much more responsive than most things I see online or on a job, just using modern CSS, a little thinking about how I structure my stylesheets, trying to use semantic HTML and not making a div soup. It works pretty well, if used correctly and given the due attention.
Responsiveness has been fine for a while. Not surprising with the smartphone revolution being nearly 2 decades old by now.
GP asked about reactivity. And that still requires some frameworking, either prebuilt or a lightweight self-written one.
What's reactivity in this context? How quickly a website responds? My personal experience is that fast backends with server side rendered HTML and a bit of dynamic sections are in practice MUCH faster than SPAs, 20 years after using Gmail for the first time. Gmail then was fast, 95% of modern SPAs are slow.
Reactivity is updating the DOM whenever the underlying data is updated. That's one of the most basic reason for existence of all js frameworks. There's TC39 Signals proposal to bring that natively, but for now as said above the choice is either use a framework or recreate one. It's surprisingly easy nowadays using Proxy.
How I've done it is to use some kind of observer pattern, where you register listeners to state changes.
Whenever state is updated, the listeners are all called with the updated state and can update the UI and what not based on the new state.
I haven't profiled this and compared it to frameworks, but feels adequate for the relatively simple UIs I've done.
In a way that's where all frameworks start.
> Reactivity is updating the DOM whenever the underlying data is updated. That's one of the most basic reason for existence of all js frameworks.
Most web apps and websites do not have that much state variables (even though it may be a lot of data). So while React may offer a small dev speed boost, it’s consumed by the need to build stuff and a whole deploy pipeline to nurse.
Libraries like HTMX and Alpine can take care of most the boilerplate for old style imperative patterns. And backend frameworks like Rails, Phoenix, Laravel donhave their own implementation for data updates.
It’s always been easy to reactively update the DOM. I was doing that in vanilla JS before HTML5 had been formalised.
What the frameworks do is take this concept one step further to create a SPA (single page application) but I honestly think they’re an antipattern that needs to die.
The problems are ownership and provenance mainly, and that all DOM access is slow and requires syncing code internally.
Anyone can write code that tweaks nodes or uses templating, but doing it in a consistent way on a project with hundreds of thousands linea of code is challenging, especially if you also need performance and everyone's least favourite child: accessibility.
Sure you don't get some of this with frameworks, but they help a lot.
Well yeah, obviously frameworks are intended to provide a standard interface for projects that scale. But you’re describing a different problem to the one originally argued.
"State management" is a fancy way to say "your Javascript stores data in variables in some way, which are updated as and when needed".
"Reactivity" means "when those variables change, some generic code already exists to update the DOM instantly". As opposed to writing specific pieces of code to make those changes directly.
Unfortunately, with React, "updating the DOM automatically" generally means: you update the data; React recreates the entire DOM as a new copy in memory; React runs a diff checker to find out what changed from the real DOM; React makes each individual change in the real DOM. With React (or other virtual-DOM-centered alternatives) being used for the smallest of web projects, so many small sites do all that work when the procedure ought to be as simple as: you update the data; you update the DOM directly.
It comes down to inexperienced devs not being able to consider which tool is best for the job at hand, and just hammering nails into every web project in the same way.
I mean all you have to do is change the framework to a better one. Vue with Vapor mode, Svelte, Solid or Preact. These don't have a VDOM at all or use a super fast minimal one.
Signals are basically as fast as writing event handlers yourself but way less fragile and verbose. React is just shaping everyone's impression of all JS frameworks because it's very popular and very slow.
I used to be Reactpilled, but ever since I've tried Svelte, I haven't gone back.
I click the upvote button and a number goes from 0 to 1. Somewhere else on the page a banner gets displayed saying you have upvotes.
Your javascript can target those 2 divs, ala doc.getElementById(counter).innerHtml and document.createElement.
Like that kind of works for simple stuff. But it gets more complicated fast. Reactivity is when your counter listens for change in the count and updates itself whenever that count changes.
... But vanilla JS with the DOM already has event listeners... ?
You still have to set them up and twar them down and update the display in disconnected places.
Works well for a small bumber of things to update, quickly becomes unmanageable.
For this specifically I would have the "you have upvotes" banner in the dom already with a class display:none.
I consider it a huge advantage to have the code for both the counter and the banner in the same place. thisCounter++; thisBanner.className = "shown";
That's why you wouldn't target those 2 divs directly, but have one dedicated place, in which you update the divs and call that place from any other place that needs to update the 2 divs.
Well, that's simplifying the situation, but as those situations become more and more in ones site, at some point one might switch to a mediator pattern, which kind of is very close to signal emit and listening for signals.
Vanilla JS handles reactivity just fine with it's built-in methods.
I also do stuff wayyy more efficiently than I do on a job
But it has no utility
Compute is fine and nearly free
These are just art projects
> without really knowing what you’re doing
Really knowing what you're doing is the implicit part of the right-hand side of the bell-curve meme :-)
>This is an earnest question but is that really true for reactivity and state management?
Yes. We could do those before React and other crap too.
No, it's not, despite what other comments here say. Of course it's possible but you end up recreating React or another library along the way. JS is getting native signals sometime in the future but for now pure JS is not sufficient for a full, complex app.
> you end up recreating React or another library along the way
That's always the trotted-out response, most often recited by people who've read someone else saying it but not had the experience to form an opinion for themselves.
You absolutely don't end up recreating a massive, bloated, slow framework that tries to be as generic as possible to try to be everything to everyone. What you end up creating is a relatively tiny, fast, piece of code that is specific to that site's needs. The difference in size, speed and simplicity tends to be absolutely enormous.
Wrong on both counts. I've worked in companies with vanilla JS only and made parts of those frameworks they ended up building. It is absolutely not "relatively tiny, fast, piece of code that is specific to that site's needs" and once we switched to React we actually saw improvements in many parts of the sites' loading speeds. Next you're gonna No True Scotsman me by telling me the company was just bad but I've seen enough examples at other companies to see that using React or a similar framework is simply the right move.
For a large ERP-like back-office where leadership didn't want to use an existing reactive framework, I definitely ended up recreating built on top of jQuery ( at the start of the project IE still needed to be supported ).
Once you start adding dynamic forms for managing multiple items of different kinds, dashboards, error states, i18n, etc, you either end up with a homegrown framework, or with a lot of spaghetti.
have you played with lit.dev ? It's part of the OpenJS Foundation (formerly jQuery and Node.js Foundations)
There are JS libs (like Reactive Mastro [1]) that go well with writing otherwise vanilla HTML/CSS/JS, and there are libs (like React) where you're quickly sinking into a mud of abstractions and have to fight the reactivity runtime when you try to write vanilla JS.
[1]: https://mastrojs.github.io/reactive/
Perhaps put a disclosure that you're the one working on whatever you're linking.
> without really knowing what you’re doing.
That is an odd caveat to throw on the end. Sure, to avoid frameworks you have to know what you are doing. Is that really such an outrageous expectation?
If people knew what they were doing jQuery, Angular and React would not have existed in the first place. With devs moving companies every two years or so, being able to hit the ground running was very important and you couldn't afford to spend weeks or months learning the idiosyncrasies of your new codebase especially when it came to state management. That's the main problem frameworks and libraries were solving.
> you couldn't afford to spend weeks or months learning the idiosyncrasies of your new codebase especially when it came to state management. That's the main problem frameworks and libraries were solving.
Not really. Frameworks are usually created to avoid boilerplate and provide some nice scaffolding to support you while you’re coding the business layer. And a lot of them do smooth over accidental complexity, even though the architecture is generic and may hinder you in the future.
But the learning curve still exist, as most of what you interact with is custome codes, modules and components.
That's not quite right. jQuery was exactly the right tool for those of us who knew what we were doing. Browser inconsistencies in the early days were practically insurmountable without jQuery to provide a consistent API surface.
> is that really true for reactivity and state management?
No. Use a framework if you want those things. Everything around reactivity, state management, and components have been badly fumbled by the web platform and the various front-end frameworks are far more ergonomic.
Definitely worth keeping up with as a framework user too.
Smaller bundles, often easier to use, less bug potential. Code's a liability and being able to occasionally rip a bunch out as a feature becomes baseline is always a joy.
I feel like I'm taking crazy pills.
Y'all know React and Vue frameworks still use HTML, CSS, and JS, right? We're using the same thing, with a thin layer of helpers around mounting components and managing their lifetimes...
People who use css-as-an-object type of frameworks or tailwind don't really get to experience what writing CSS is like. styled-components or Linaria or Emotion do though ofc
I love emotion.sh with my heart. It used to be so hard to write css for me until I landed on the mental model of styled components
As culi also touches on I think it depends on what is meant by frameworks. As someone who belives abstraction are horrible practice unless they serve a really good purpose though, I never bought the "this is easier" part of the big CSS frameworks. I fully accept that people who work on user facing web applications more than I do, which is rarely, had a much easier time using something like bootstrap/tailwind/whatever. I always found having to look up documentation on something wich was infinitely worse than the CSS documentation on developer.mozilla.org to be a a weird experience. I do fully accept that a lot of teams experiences would prove my personal opinions wrong on this.
On the flip-side I always found javascript frameworks to have a purpose. Though to be fair I don't think I've worked with user facing javascript without a framework since jquery came about. I guess you could call that a library, but still.
Think layer? Like a page loading 6MB of crap to show 0.5KB of text?
OP might be referring to using React together with a UI library that comes with elements like <Grid>, instead of using just React + CSS grid.
Except that with React you usually use something like tailwind or similar that abstracts writing CSS, that do me doesn't make sense.
Of course you can still write plain CSS.
I don’t disagree with you and I lurve frameworks. Yes, I love react. It is so awesome.
But it is SO nice to not have any build step. All of my new projects start as a single babashka script now. You got html templating, throw in a stylesheet. Slap a datastar script tag in there for everything else. It’s just easy peasy.
Good how and where? That's a very uncritical take you have here.
I find it is way too complicated with regards to flexbox, grid etc...
Just do a google search for flexible divs side by side. Start with two. Then switch to five. Tell me the solutions that work well.
"flexible divs side by side" sounds like something which can be generated in many ways, From display: inline-block, over float:left, col-columns, flex layout, to a grid based layout. Can what you desire be created in, for example, https://grid.layoutit.com/?
don't search, ask an llm. Ask it to keep it as simple as possible and have it explain the tags you've forgotten.
flexible divs side by side is trivial with both flexbox and grids. Far, far, far easier than prior to flexbox.
My rule of thumbs is: Use flexbox unless it truly is a grid or repeating rows + "I wonder if a flexbox can be used ... ah yes it can." Flexbox is just made for responsive layouts. It is very good.
> Just do a google search for flexible divs side by side. Start with two. Then switch to five. Tell me the solutions that work well.
I did like you asked. The first search result on google is a question on stack overflow. And the first comment provides an example that looks very much like flexible divs, side by side, between two and four based on the width of the container.
https://stackoverflow.com/questions/60615826/two-divs-side-b...
What didn't you like about the solution in that comment?
OTH all the complexity ends up baked into the browser where it will be frozen forever (even the shitty/overengineered ideas, like WebAudio). At least frameworks can be discarded and replaced when something better comes along.
IMHO even HTML+CSS should be completely implemented outside the browser in the 'framework layer', but I guess that's not a very popular opinion among the more 'conservative' web devs ;)
If that means having an "HTML+CSS framework" that I could easily swap out for a "Typst framework" and publish my blog using Typst, then sign me up!
Meanwhile, there's Typst bundles [1], still experimental, that implement the same idea backwards: convergint a Typst project into a set of output files (which can be HTML).
[1] https://typst.app/docs/reference/bundle/
That would mean some shitty load times for even the most basic web site.
But there is probably a world where what you’re describing is possible with WASM and Canvas. Would need to solve for accessibility though.
i also found this to be even more powerful today with AI.
dont need to import libraries anymore, can just build my own.
Any good articles or post you could link to, CSS has come so far and I’m trying to gather info on what’s now possible
It's a little dated, but you'll get the idea:
https://nerdy.dev/cascading-secret-sauce
> it's honestly hard to explain to people who only write within frameworks how good it's gotten.
What exactly has gotten good?
CSS is the only area that is seeing improvement, and frameworks ... use the same CSS, so no idea what you're talking about.
Most everything outside of CSS has been and continues to be shit.
Edit: Moreover, literally all frameworks as one say: give us good browser APIs so that we don't have to do any of the things we do.
They were too slow, people are all tailwind native now and don't know a thing about CSS. I keep seing "full stack devs" complaining about "bleed out" issue, aka C in CSS, cascading
After Tailwindcss got bought by the child killers I tore Tailwindcss out of everything.
More info please
Shopify
Agreed. I think part of why it's hard to convey is that a lot of people formed their idea of CSS back when flexbox was new. These days an accordion is a few <details>, and a reading progress bar is a fixed div with animation-timeline: scroll(). You don't need JS for either.
(Full disclosure, I wrote a book on this, so I'm not exactly neutral: https://theosoti.com/you-dont-need-js/)
Flexbox is still fairly new! Hmm, maybe I'm just old.
While a lot of devs love to use brand-new stuff that's only just been added to some browsers, some of us are not willing when we know it won't work for (almost) all users. The scroll() function is too new for use in production, IMO (but good to know it exists, to revisit after a while). If I have to code something else anyway, or copy-and-paste a polyfill, then why not just use a more robust option in the first place.
Wow even more fancy border styles! Infinite complexity for useless eyecandy. Date pickers are still barely working, last time i needed to build a touch optimized interface (gloves, industrial setting) with date picker, time picker, and numeric up/down style input fields it needed custom components and js...
But who needs these, when we can have bezel and whatnot...
Who needs ways to reliably trigger the display of the touch platform-native keyboard, to be notified if it is displayed and to move the input field in view so it is not obscured by the keyboard?
This is why the web is a terrible platform compared to Windows Forms for getting stuff done. Because those making the standards only work on creating gimmicks.
Ignorance and generally a hater position
Yes, web people don't know about the outside word, and generally hate it, and its usecases.
> Windows Forms
Rage bait, don't engage
> Because those making the standards only work on creating gimmicks.
Totally agree, but afaik we are a very small minority. My tinfoil hat theory is that all of this is intentional to keep monopolies and making it impossible to compete in the browser space
A completely non-sensical non-sequitur. What are you even trying to say?
What does one (CSS tech) even have to do with the other (competition in the 'browser space')?
https://news.ycombinator.com/item?id=50177605
And I believe the OP is right. Keep people busy working with changes that don’t move the needle, each of the three large platforms wants to lock in the serious use cases into their native apps.
If web was as good as iOS native, for example, Apple wouldn’t get their cut.
What does that mean as related to 'competition in the browser space' ?
Apple has a browser. Apple sits on the CSS steering committee.
The assertion is that the major browser owners (Apple, Microsoft, Google, Mozilla) don't want competition, so they keep CSS complicated.
All four of these companies are members of the CSS Working Group. So the ability to do this is within their power.
IMHO, a sad and small minded conspiracy theory
Also very likely true.
How does Mozilla benefit from keeping it complicated? Or Microsoft, for that matter? Neither of them have a mobile App Store, so are they just playing along for the hell of it?
This is a known consequence of standards bodies: they get infested by vested corporate interests who generally, in the best case scenario, want the standard to include their entire pre existing implementation. In the worst one they just filibuster and veto proposals until they can't any more and they have to do what everyone else wants/is doing.
This is a phenomenon that dates back to IBM doing this in the 60s-70s-80s.
Making a community maintained strict subset of the WWW is the way to go if you don't want to always rely on the monopolies. The W3C people had a good vision for the web that was compatible with the soul of the web as Tim Berners-Lee intended, but also different to what those that then went and made WHATthey were thinkingWG that wanted to embrace, extend, and extinguish the WWW into their dystopia of the web of application and forcing the poor html and css into this amalgamation instead of building on a more compatible base to their ideas. But corpos only look at the possible profit and not the general consequences, they're like parasites.
Web of applications is a novel idea if executed well, but imo just download the executable and use the package manager to update it, and we still have the internet for communication, there's no need for a pseudo OS on top of the OS, if you want sandboxing and a VM do what they did with Java. The modern Web is unnecessary, everything that needs JS or frameworks is because of the retardation in the initial primitive design of the WWW and html, everything could have been implemented in a new xml markup akin to htmx, they were steering to that with their ideas in XHTML2 but never finished because of oppositions from Google et al. Other things like implementing an office suit or playing games in the browser is incompatible with the WWW, and like I said you better go and make a better platform for that.
Today it's simple to write your own OS than make a web browser, which contradicts everything about the web being decentralized and a protocol, what's the difference then if we would send propriety bytecode to this VM called the modern web instead of html et al? Sure you can still use and support a subset, and because of that I mentioned this idea as the first sentence, but this is the trick of EEE; the majority would bite the propriety extended conveniences and make it the new standard, then they would constantly extended until it becomes a game of resources which they have the higher hand in.
Some would say it's opensource and anyone can implement it, that's half the truth when it's so complex and grand that only *big* corporations can handle it, and that the WHATWG confessed that the real standard became the source code of the big 3: chromium, webkit, and gecko.
Those that believe this is some kind of "tinfoil hat bs" and there's no conspiracy are worse than those that believe everything is a conspiracy; because at least the latter would be right once, while the former are never right. I didn't mention also how the new web makes it easier for their spyware, but that's obvious. The web was about decentralization and standardization, but they skillfully made it the literal opposite.
In another world, Netscape is able to reach a deal with Sun, and the JVM gets integrated into Mozilla. New browsers just need to implement the JVM and bind it with their XHTML's rendering engine DOM API.
It would have been the application platform people ask for, with a separate namespace for application-related tags so you can just switch them up with the OS's native UI controls.
Instead of that, we got Yet Another VM, WebAssembly.
Not trying to throw shade, but I think the number of devs wishing that the web ended up with XHTML + JVM (now owned by Oracle...) may just be you.
Never mind that when Microsoft licensed Java from Sun for IE3 and IE4, Sun sued Microsoft. Sun wanted to be the only distributor of Java, just like Adobe was with Flash. So, browsers wouldn't have actually included a Java runtime out of the box without licensing/paying Sun for it. I'm sure that dependency would have only gotten even better under Oracle.
Those of us old enough to remember the web with plugins, don't miss plugins.
> Not trying to throw shade, but I think the number of devs wishing that the web ended up with XHTML + JVM
I don't necessarily like the JVM, it's just the most popular system-independent bytecode virtual machine (and historically plausible). It's a lot easier to built a bytecode interpreter than a full language. As mentioned elsethread, Scheme would have been even better, with an even smaller base.
XHTML, however, full in. Namespaces and syntax checking alone would have been worth it.
> Never mind that when Microsoft licensed Java from Sun for IE3 and IE4, Sun sued Microsoft.
Microsoft was in their peak EEE era, no wonder Sun didn't want to do anything with that.
> Those of us old enough to remember the web with plugins, don't miss plugins.
That's why I didn't mention plugins, browsers would have a JVM engine, instead of a JS one.
One small glimmer of hope is that customizable selects are indeed being worked on: see https://open-ui.org/components/customizable-select.explainer... and the broader work of the Open UI group at W3C.
I'd love to see this level of customization come to date and datetime-local popups, finding a meaningful path that preserves compatibility with the design languages of various platforms. If and when that happens, it will be because of the work of standardization working groups like Open UI and Interop.
date pickers are something that quickly gets overly complex and site specific.
They are only simple when you have no restrictions on which dates that can be selected.
But a date picker for a hotel, airplane travel, restaurant, ... might have to show some days as disabled or some days that are "cheap offer" dates.
To this add anything that needs to select an interval, like an airplane return ticket.
And then there's the nightmare of any interval that runs over daylight savings boundaries, and what that really means if you want not just a date-picker but date/time picker.
> date pickers are something that quickly gets overly complex and site specific.
I'd settle for a browser specific picker that works in 80-90% of use cases. Instead it took browser several years after introudcing type=date to make a datepicker that is actually usable, and not a throwaway tiny design cooked up by an underpaid intern
that's true. But even for some of the easiest cases some browsers don't support them. input[type=month] for example still has no custom UI in Firefox or Safari. And Chrome has had one for 14 years!
That's because dates are extremely complex and subject to all sorts of political and business rules.
Those business rules, daylights savings (datetimes that can never happen, or happen twice), different M/D/Y ordering, different starting day of week, different timezones (including 15 or 30 minute offset ones like India, Iran, parts of Australia, etc), etc quickly complicate it. Oh, and don't forget about making it accessible.
That's before you even get into designers who want the date picker to look the same across platforms instead of using platform specific UI widgets...
I'm pretty sure my version of hell would be implementing a date picker until all stakeholders are happy with it (eternity).
It's probably easier to standardize small CSS utils than it is for a date picker.
What would the API even look like?
One could want to select a single date, multiple dates, a date range, multiple date ranges.
Perhaps some dates should be disabled, but should they just be greyed out or should there be a message when the user tries to select them, and if so, how can it be provided?
Then there are questions about different calendars and locales.
Perhaps third-party date picker libraries are more appropriate here than trying to address this in standards.
The stuff in this article is created by the CSS Working Group. The stuff you want would not be handled by them.
> Who needs ways to reliably trigger the display of the touch platform-native keyboard, to be notified if it is displayed and to move the input field in view so it is not obscured by the keyboard?
Sounds like you need window.visualViewport: https://developer.mozilla.org/en-US/docs/Web/API/VisualViewp...
> The mobile web contains two viewports, the layout viewport and the visual viewport. The layout viewport covers all the elements on a page and the visual viewport is what is actually visible on the screen. When the user pinch-zooms into the page, the visual viewport shrinks but the layout viewport is unchanged. User-interface features like the on-screen keyboard (OSK) can shrink the visual viewport without affecting the layout viewport.
CSS isn't useless eyecandy. Everything we currently do in javascript that can be offloaded to CSS is a performance gain. Sadly datepickers are out of scope for CSS. Expecting this group to solve datepickers is the same as expecting them to work on solving world hunger (and almost as difficult :)
Off topic: But contrary to popular belief world hunger is technically solved (as in solved on a technical level). We do produce enough food so nobody needs to be hungry, and we know how to distribute that food to anyone who needs it (outside of a handful of warzones, but even there the right organizations have a good plan that will probably work if given the funding and the political backing).
World hunger is now fully a political problem and needs to be solved politically. It may sound hard, but in this case it is only a matter of money. The right organizations just need more funding, again that might sound hard, how do you pick the right one, but in this case the right organization is almost always the UN World Food Programme. They need exactly $13B to solve world hunger. And that is not a lot of money.
You're right. Our CSS committee will get right to it :)
Perhaps WHATWG just needs more money and then they will solve the date-picker.
Jokes aside, I never has had any major problem with `<input type="date">`. Yes there are some annoyances when translating between local time and an absolute timezone aware timestamp. Yes it is annoying that `.valueAsDate()` doesn’t work out of the box. But those are very easy to overcome with a three line utility function.
well, no, the WFP's current yearly budget is 13B, which is nowhere near enough to solve world hunger, considering world hunger still exists. They actually say they need 93B/yr until at least 2030 to solve it.
https://news.un.org/en/story/2025/11/1166397
I stand corrected. Regardless it is still an easy thing to solve. 93B/y is still not a lot of money for solving world hunger. Well worth it if you ask me.
> CSS isn't useless eyecandy.
Did I claim CSS being useless eyecandy? Nope. Bezels and squircles? Yes.
But it's just too complex, more and more stuff. What is this even (from another comment):
<div class="container"></div> .container { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-template-rows: 1fr 1fr 1fr; gap: 0px 0px; grid-auto-flow: row; grid-template-areas: ". . ." ". . ." ". . ."; }
I've been away from CSS for a few years and this looks alien to me. I don't know any of this syntax except for the div declaration, and I used to think I was good at CSS with less and sass. I don't want to deal with molecules, or atoms, this is just too much.
Date pickers are on the OS vendors to implement properly, at least learn who to direct your ire toward.
Since I’m in before the negativity: I love CSS! For whatever reason, it’s always made sense to me. I have great respect for everyone with the tenacity to push on improvements that might take 5-10 years to be in common use, if at all.
We're pretty far past the 5-10 year timeframe now that browsers push updates so aggressively. It's pretty common to see features that were adopted just a year ago in common use
I started to love CSS even more after I had the fatal ambition to style a table in LaTeX.
Yup and I hate CSS when I want a page to print properly.
There is a "W3C Editor's Draft" (no idea what that means) on CSS for paged media: https://drafts.csswg.org/css-page/
Try tabularray.
I’m part of the seeming minority that really enjoys working with CSS. And the way I use it today is so different than I did a few years back, e.g CSS modules, declaring a palette with variables then changing it for dark mode… it’s genuinely great to work with.
light-dark() is even better for that :) I also enjoy CSS, using @scope and @layer a lot with the :has() selector, it’s just so different now and I think most people are unaware.
Working with modern CSS is such a joy, and increasingly as time goes on I'm replacing huge chunks of JS with CSS which is a little boon in itself. Honestly, my only complaint is how long I have to actually wait to use new features.
Nesting and @layers make maintaining CSS drastically easier than it once was as well.
I agree. And I don't even use layers yet. I keep specificity roughly in mind and narrow my selectors using nesting properly to only affect what I want the rules to style. Do I make mistakes? Sure, but they are easy to fix. Make selectors specific enough and think about whether the rule you are writing is something general or just something for this one component on the page, and it is eeeeasy to not make a mess these days.
How is that? I also like CSS, but when I looked at the @layers spec I didn't see any immediate use case.
Also, grids and flexbox solve so many previously tricky layout problems. Animations obviate a bunch of small JS.
I sometimes wish that CSS were reduced to the "good parts" and made simpler through it, but I realize that it's infeasible.
Yeah with flexbox and fit-content/max-content is pretty fine now.
I love working with CSS as well. It feels like the most optimized approach to me. However, it's really hard to use CSS as much once the project involves other engineers who don't have that level of interest in CSS.
I warmed up to CSS this year. Before that it was this cryptic thing with seemingly infinite change-try cycles. What happened was that I discovered some of the new features, and was able to greatly simplify and beautify my CSS. I might end up liking it.
It has this maddening amount of features though, and as it needs to be backwards compatible, this amount can only grow going forward. But if you look at a well chosen subset of the whole thing, it actually is a quite nice language.
"Functions in CSS" - Bah! That's all we need to make CSS even more convoluted - make it compete with Javascript now ... All these feature creep is just to make sure nobody else can create another browser engine.
This. Currently, if you don't want web pages "computing", but you still want basic content, you can turn off JS. Add explicit functions to VSS makes this impossible.
How niche would a website have to be to target the less than 1% of users who have disabled JS?
OP is saying disabling javascript may no longer work as desired if CSS is enhanced with JS features ...
But it isn’t? The functions discussed in the article are not connected to JS at all.
As someone mentioned above, it probably would have been better if they weren't called functions. Macros, maybe.
Also the blog really doesn't help by describing it like this:
> If you’re familiar with JavaScript, this should feel pretty familiar. We define new functions with @function and specify the returned value with result.
So this is a semantics complaint? Man, developers are so anal about everything.
They're less functions and more akin to templates or hygienic macros, iiuc from the specs/docs
Part of me feels like naming them functions was a mistake. The other part things screw it, the haters are going to complain no matter what you do.
Things incoming when this goes live
- “I made doom run with only css functions!”
- “CSS function vulnerability exposes api keys in NextJs server side rendering”
- “css function used for fingerprinting violates EU laws”
- “Facebook/Meta caught tracking users using CSS function exploit”
I’m being facetious, mostly.
CSS is not at all convoluted. As far as complicated technology goes it is refreshingly simple.
Style and keep an eye out for the cascade.
Simplicity itself.
I'm still waiting for decent tooltips that are browser native. You can sort of minimally do them with the `title` attribute but they take ages to appear, can't contain HTML or styling (like bold text or images), and you can't choose their position. To do them properly with accessibility in mind (keyboard/mouse/touch support, screen reader support, keyboard focus, it's hard!), you need way too much markup with tricky custom JavaScript, and they're difficult to get right like making sure they don't render partially off-screen.
The new CSS anchor positioning and popover attribute help but something simple and built-in that doesn't require lots of wiring would be great. It's puzzling why we don't have this basic UI feature yet?
At one point the native tooltips should appear, on top of popovers: https://open-ui.org/components/popover-hint.research.explain...
> The new CSS anchor positioning and popover attribute help but something simple and built-in that doesn't require lots of wiring would be great. It's puzzling why we don't have this basic UI feature yet?
What's the problem with popovers and anchor positioning? They're practically made for tooltips, I use them in production for this purpose right now.
Maybe I’m alone, but all of those suggestions seem to make CSS needlessly complex (or more like JS).
Especially functions.
Makes me think of a previous post from the author, who wrote 100k lines-of-code to power their blog.
https://www.joshwcomeau.com/blog/how-i-built-my-blog-v2/
Yeah it looks to me like we're scraping the bottom of the barrel, if this is what's left.
Worth keeping in mind that Josh's blog is absolutely over-engineered and I'm sure he'd admit that himself. He tried to keep parity with his rather complex course systems and his blog itself is a lot more than 'text on a page'.
At last I can realize my dream of writing a JS interpreter in CSS! ;)
offtopic here but what the heck, I am learning C from you right now! You finally made pointers click for me after failing to learn them a handful of times in the past. Legend!
i dont think functions belong there at all. i'd actually be pretty disappointed if they added them.
I do not think functions in CSS are the original sin. Why we don’t have them, was a valid question in the 90ies already.
And you cannot emulate functions by using a preprocessor in all use cases.
But what bothers me is the governance model of CSS, the increasing complexity that leads ultimately to more framework usage, not to thoughtful engineering of accessible front ends.
Very soon CSS will be Turing complete and we can have a JavaScript-free C64 emulator. Yay.
We need basically control structures and full access to user input to achieve that.
And we can only hope the vendors get the sandboxing right this time, otherwise we will get a entire new class of CSS based browser exploits.
For some reason CSS wants to have all the useful things from SASS without actually making them useful like SASS.
Functions might sound scary, but in reality they're used already in CSS processors like SASS/SCSS - and then they actually reduce complexity of the code.
The example with linear-gradient is probably the best use case for them.
He even cites the reasons for that over engineering in the post you've linked?
Also, even before reading the comments, I was pleasantly surprised that everything on that page worked and nothing bothered me. There is a good amount of attention to detail (switching of the rounding on codeblocks when switching to light mode for example, avoiding a weird corner on mobile). Nothing moves around on load etc. I know this is a low bar, but it's gotten pretty rare, even for pages linked on here.
I'm trying to say that his 100k lines might actually be spent on attention to detail and aren't just slop.
Good to see Josh writing, especially after his courses have taken such a hit. He is excellent. As an electrical engineer and also now CS grad and someone who has purchased his courses wanting to be able to work across the entire stack.. yet have also thought "thank god I don't really have to learn css" now (yes, due to increasing model performance).
On that note I may know just enough to be dangerous thanks to Josh (casting spells: e.g. shouldn't we group those in their own container and then within that container shouldn't that be a flex box?). I guess I'm here to say humans are full of contradictions.
The discussion here reminded me of one of my favorite demos, someone live coding Qt5 and QML on a first a generation Raspberry Pi, 1080p HDMI. Sort of a mashup of CSS and JavaScript for simple shaders. Fourteen years ago.
https://youtu.be/0j-Wakm5B84?is=7dU_EvFyk_nQNwjO
It's like a peek into a CSS future from a different timeline. Something we could have had.
> If you’re familiar with JavaScript, this should feel pretty familiar. We define new functions with @function and specify the returned value with result.
It used to be that HTML was for content, CSS was for layout, and JS was for "code"
Now JS is for content and layout and code, HTML is for content and layout, and CSS if for layout and code
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/P...
To be fair, the `content` property rarely gets used for anything more than a label or icon, or perhaps a tooltip
I think your definition is off. Js was never for "code". The code itself is just a means to a goal. That certain things better can be achieved without js is good.
Microwave ovens were never for heating food. The warming is just a means to a dinner.
Better analogy would be "Microwave ovens were never for injecting electromagnetic waves into food. The electromagnetic waves were just a means to heat the food".
JS was for "interactivity". CSS function is just a simple abstraction for user reusable logic.
CSS is for styling and layout, but there is no conceptual reason this couldn’t be defined through functions.
“Code” is not a concern like semantic vs style.
For people who only read the titles / comments, I was expecting another silly rant about how AI is disrupting CSS or something, but this was an excellent, concise overview of new and upcoming CSS features. Very well done.
A bit strange to me how Josh beings with heralding the browsers working together and then every mentioned feature is Chrome only. They're nice previews for a potential future I suppose!
The article is specifically about the “inter-op” program where the browsers work together on specific standards to bring to all browsers. (And we get to vote on the selection!)
It's because Chrome has taken over interop. Just like they do with any other useful initiative like OpenUI [1].
It feels like Interop was created to curb Chrome's bulldozing various processes with their own internal APIs and development, and to show that there's more to the web than yet another shitty Javascript API. So a lot of Interop is decidedly everything else. See e.g. Interop 2022: https://hacks.mozilla.org/2022/03/interop-2022/
Of course Chrome bulldozed this effort as well
[1] https://open-ui.org/ Started by Microsoft, of all people. Now almost completely taken over by Chrome of course.
The new responsively-sized iframes standard is an exciting one for me not mentioned. It's finally a step beyond the original frames and framesets. It will let us design sites out of iframes as building blocks instead of needing to use web components. Websites made out of websites.
Corners and borders have been a pain since the beginning of GeoCities. I do wish fancy corners would go away---to the point that I actively make this happen with a global Stylus rule setting border-radius to 0.
Look: Three of these 10 "improvements" deal with corner shaping, and two more will inevitably need extending, as I imagine frontend devs get around to, "GPT make reading-flow responsively round only the outside corners," and, "Claude how to squircle the individual grid cell borders when using rule gap decorations."
I understand CSS wants to do all of the things and do them well, but then the eye candy gets overused on every webpage and web framework template to the point that practically no site feels different; it's all "logo, four links, giant-ass 'call to action' rounded button in the bold colored top nav, rounded corner cards in a grid layout 3 to 4 cells wide (or in a slider), gratuitous whitespace, rounded corner everything actually, maybe a gradient text or background or both, hamburger menu on mobile, all styles inlined in the HTML classes".
Going down the list of Fortune companies, three of the top 50 don't "round corner" everything: Berkshire, Exxon, Morgan Stanley. A few more would count if you permit rounded buttons only. Marathon is a weird outlier; they have hexagonally rounded elements buttons. (Also, some of these sites must be hosted on a Zune. It takes 50 full seconds to load Cencora's main page.)
I can't say that I do web dev any better, although I am disappointed by the looks of the modern internet, and I don't think more artistic flair will make it better, just as I don't think houses and cars and suits benefit from strange shapes and colors.
although maybe more choice will free us from the confines of everything looking like Tailwind? (Despite my complaints, I am grateful for progress and also am absolutely not looking forward to people misusing functions and dropping 18 errors and 11 warnings into console.log AHEM LENOVO because they can't be troubled to write good code/markup.)
That's a spot-on summary of all websites I see. It seems particularly annoying given that most landing pages seem to be identical LLM-output pages that require a lot of scrolling before you get to any "information" on the page.
I know this post isn't about vibecoding frontends, BUT...
Many of my coworkers and friends are rejoicing that they don't have to write frontends anymore. I actually think that frontends are the last thing that should be vibecoded. It's the part that faces the user. It's what helps the user form their first impression of your product. If your landing page looks like it was made in 30 seconds by Claude, they'll assume the rest of your product was too. Use AI assistance on the parts of your codebase where only raw functionality matters (eg, the backend), and put real human effort and care into the frontend that reflects the effort put into the rest of the system.
Haha, until you figure out the entire frontend is one large dump of esoteric jQuery, with 15 years of accumulated terrible decisions
I gave your resume to the B-9 HR bot and it said you should be escorted off the premises. "DANGER DANGER!"
everyone is rejoicing the other part of the stack can be vibecoded.
a backend developer would tell you the backend is much more important to focus on, performance, security, data integrity etc. not losing or exposing customer data is a lot more important than what it looks like.
truth is, it's all still important, preferably no one is vibe coding any part of a serious product.
Fwiw I am a "backend" developer and have never in my professional career written a frontend except for internal tooling.
Shocking take: you shouldn't really vibecode any part of a serious application!
Definitely use coding agents to write code, but carefully and thoughtfully review any important backend or heavily user-facing components of the software you're developing.
you can&should use AI to help you with frontend (css,js).
doesnt mean you tell it: make it look nice.
i find it is great if you want to apply your creativity and ideas.
how to add borders, gradients, animations, positioning, etc.
its a great time for everyone to build things, just how they want/imagine them.
> It's the part that faces the user. It's what helps the user form their first impression of your product.
Same for the README on a GitHub project. Alas, plenty of those are now just voluminous AI spew.
Truth be told, marketing is the only truly non-fungible function we have.
Here's another prediction in the ocean of them we're swimming in right now: websites won't matter. When you have a general interface that can present data however you wish, being restricted by the whims of designers will seem prehistoric.
>if your landing page looks like it was made in 30 seconds by Claude ....
This is very true, I 'walked' away from a material coating website just yesterday because it looked too Claude.
This is the type of article I really miss reading... before AI took about half of HN front page this is the type of stuff that would routinely pop up...
Do we really want functions in CSS? I guess that ship has sailed a while ago, since CSS reached Turing completeness.
Why not provide better integration with JavaScript, to make this kind of acrobatics unnecessary.
Because JavaScript requires… a lot. A virtual machine, script parsing, etc. Making that a requirement before you even display any content on the page would be a regression.
I can see that, but CSS already requires a lot, no? Especially as they keep adding new features to it.
To me it feels like "programming in YAML", the way a declarative language/format acquires more and more features until you're writing functions in an awkward syntax that was never designed for it.
It requires a lot… but a lot less than JS. The awkward declarative nature of it is a side effect of wanting it to parseable at speed.
At an initial look I agree with you that the functions look very awkward. But I thought the same about CSS variables until I started using them and now I think they’re great so I’ll keep an open mind. I almost wonder if they would have been better off calling them “templates”, or something. “Functions” is going to make people think it’s just like JS.
Yeah OK, I see what you mean, I may change my mind once I start using them. And having worked on interpreters and compilers, I can understand the need to keep internals simple and fast - like everything must be parsable in one pass - so the surface ugliness of syntax isn't as important in the long term.
Perhaps I should also be sympathetic to the spec authors, since they're working under tight constraints of language design. Things might look a lot more elegant if HTML/CSS/JS were designed from scratch as a coherent whole.
It’s worth noting that the CSS Painting API exists and allows you to use JS functions:
https://developer.mozilla.org/en-US/docs/Web/API/CSS_Paintin...
It’s Chrome only though.
Oh wow I hadn't heard of CSS Painting API. At first glance it seems like a "frame buffer" you can write to directly, kind of like the web audio worklet processor but for styling.
I've always wished more of the underlying CSS functionality were exposed to the scripting side, like calculating flex/grid layouts, without necessarily tying it to performance-critical painting path. Usually more expressive power means more responsibility, but there are already web APIs that do it in a controlled way, like request animation frame. So I can appreciate the potential of the Painting API and others in a similar direction.
At the same time, I also wish there was effort in the complete opposite way, to start over "from scratch" and make it easier (or possible at all) for people to build alternative browsers with a minimal subset of CSS. Perhaps something like a modularization of web technology, where the current hugely complex system is broken down into reusable libraries for building small and large browser-like applications. I know something like that exists, like Servo etc., but much smaller and simpler building blocks.
Strongly agree. While I am a huge fan of the capabilities of native CSS and the fact that it keeps getting more capable as time passes, I have come to the conclusion that it is unfortunately a programming language trapped in an “obsolete stylesheet syntax” body, especially after the addition of calc(), variables, functions and multiple ways of conditional logic.
The worse part of working with CSS is that there is no standard static type checking tool (stylelint comes close though). A lot of programming errors should/could be caught at build time.
Sometimes wondering if a completely alternative syntax+tooling is possible that would leverage all the existing capabilities, while using a different language paradigm.
The ironic thing is that the old-school ancestor to CSS already was a programming language: DSSSL was a dialect of scheme.
That DSSSL syntax looks a lot better subjectively.
In an alternate universe timeline, we could have had a single web language for hypertext, styles, and scripting.
Wow - looks so good in LISP syntax. They could have probably also introduced compute restrictions (Execution Time Cap) by limiting nesting.
> In an alternate universe timeline, we could have had a single web language for hypertext, styles, and scripting.
That's actually something you don't necessarily want: https://www.w3.org/2001/tag/doc/leastPower.html ... then again, once you hit turing-completeness and people start relying on it, you probably also have to admit that you're already soaking in it and you may as well make it pleasant.
> T. Berners-Lee, Axioms of Web Architecture. 1998.
I love that he used the word "axioms", especially these days when mathematical logic and mainstream software development seem to be reaching toward each other through type systems, static analysis, verification and so on.
That design document about "least power" is fascinating, it's a classic tension in programming language theory about expressivity and the value of constraints.
Reading about how HTML and CSS were intentionally designed to not become a programming language, it's funny to compare with modern web dev practices like React and CSS-in-JS, which re-envision what the separation of concerns means, very different from what the language designers had in mind.
If CSS is Turing complete, that means it has a virtual machine with parsing and so forth. That means that difference between it and JavaScript is just syntax. (Same for any Turing complete language)
Well, kinda... https://cssdoom.wtf/
Not just. There’s also the issue of complexity. And JS is considerably more complex. Just think of all the APIs that are immediately available at runtime in JS, for one. It takes up far more memory and CPU cycles to initialize, the language itself is much more complex…
CS theory-wise, yes. Practically, no.
I am not quite sure I understand what you are getting at. Surely, we don't have to go into why syntax is extremely significant for feasibility of implementing features. I mean, we don't code in assembly much these days, do we?
We had that. It was called XSLT.
Google said they weren't smart enough to implement it, or pay anyone to fix the one they forked a decade ago.
Because that CSS can be evaluated with lower latency than the equivalent js
Probably. Trade-offs is engineering
I was going to complain that the W3C CSS validator is hopelessly out of date, and still doesn't handle CSS nesting for example. But there's been loads of activity in the last few weeks, including a fix for nesting.
Thank you "sideshowbarker", whoever you are.
CSS shouldn't have logic it. But layout needs logic. The next step should be to ditch CSS altogether and implement it as a DSL in JavaScript.
The future of HTML/CSS and hopefully JavaScript is, that it no longer used and replaced by a new technology stack.
Especially CSS is such a miss fitting technology for what it is used today, that web frameworks actively fight it, by trying to keep its scope to components.
When looked at web tech from a distance, it is cristal clear to me that we need something new.
Instead of all the abysmal complicated rules of CSS, we would probably be much better served by something like ElmUI (a modern advanced version of the idea) + some scripting for dynamic things.
"Some scripting for dynamic things" will never satisfy the "everything must be an SPA" crowd, unfortunately.
CSS has warts, true, but you are not forced to use them. Modern CSS can be brief and clean.
Imagine a world where we have better technology and someone looks 20 years back at an old codebase. Everybody would have a hard time to understand anything. Everything of the old web tech would look overly complex und laughable overengineered. Nobody would probably be able to understand how a piece of CSS influences a part of a web page or how all the abstractions work in the code base and why they are there in the first place.
Modern web is a mess. I wish it wasn't, but it is.
This is a monkey's paw situation, because instead of the web people are increasingly getting pushed into native apps. I'll take the janky web languages over native apps any day of the week.
I'm more insterested in the new CSS scoping feature that still not supported. HAving CSS only work on a scope of the DOM would make dealing with CSS a lot easier.
While waiting for that I decided to use Tailwind so I can basically "not do CSS", but have it locally defined in my HTML. It buys me a similar freedom to the CSS scoping feature, as the cost of having to run a bunch of tools to get my final CSS asset file for deployment.
Is there any implementation proposal which exists that makes relative corners automatic?
If you want them now, you have to do sort of verbose and clunky calculations to get outer corner radius.
[Outer Radius = Inner Radius + Padding](https://www.reddit.com/r/Design/s/oal9fZclJS)
This seems like something standard enough to be a built-in feature.
1. "cascade" is mistake and "separation of concern" is mistake https://adamwathan.me/css-utility-classes-and-separation-of-...
2. website work perfectly fine without CSS functions, Bevels and squircles, Infinite possibilities with border-shape, ... only need these for make CSS educational blog
3. future of CSS is DeepSeek
You're wrong. I can't wait for these to land in CSS.
Baseline 2031 let's goooooo!
Seriously though. Safari will take 2 years to implement and the releases to work their way out in MacOS/iOS updates.
Some internal Mozilla employee that disagrees with a spec will let that be known by slow rolling implementation for 4 years.
Hah;
> The Anchor Positioning API allows us to anchor one element to another.
Hello CSS, Welcome to 1996 Delphi :-/
Been waiting a long time for CSS inherit() . . . although I freely admit that (and CSS Functions) open a respectable-sized can of worms. Sort of like what transclusion and conditionals do for document markup.
Anchor Positioning would be sweet and doesn't feel like it's got so much baggage.
https://caniuse.com/css-anchor-positioning
All browsers at least have partial support. I've been using it.
However, I always wonder, does the browser really need to understand this syntax? (I feel `function` is too much for just stylesheet)
Ultimately, what we want to represent is a DOM tree. The format doesn't matter. So we should send a computer-friendly, pre-compiled data structure that the browser can use directly. memcpy is faster than parse.
Memcpy of what? I'm fairly sure Firefox's internal representation is different from Chrome's, so you just replaced parsing from X with parsing from Y.
CSS was born out of the idea that content and presentation should be separate with the former controlled by the author and the latter by the consumer.
Most of CSS's design was informed by that idea. That styling is in separate files in the first place and then all the complicated cascading stuff that is even in the name of the thing.
I've always been fond of that idea and still am but there is no denial that it utterly and completely failed and now we live in a world where all these things are just cargo cult. Sometimes I think it'd be best to finish what Tailwind started and be consequential about it which would mean going back to presential HTML alltogether.
It failed because it married selectors to the content, so the CSS rules inevitably follow the document structure. You can avoid it by either using utility css, avoiding descendant selectors or using some methodology like BEM and use only classes to style elements. There are two types of separation here, same document that can be styled differently with a different stylesheet (think zen garden), but the other one is reusing the same look&feel across different web pages. These two goals are not always compatible. The other thing to consider is that maybe HTML itself is the presentation layer, data usually lives in a database or different file formats, JSON, CSV, excel spreadsheets. A lot of the aspects of laying out the content is trapped in how you structure the HTML, and no amount of CSS can change how the document is organized.
What a beautiful blog and post. Highly appreciated, especially in the current times. :-)
This looks a bit like another revolution is brewing, where people relying heavily on Tailwind might one day be surprised how powerful the raw CSS has become.
I don't use Tailwind becuase raw CSS wasn't powerful, but becuase it makes it easier to use.
I don't have to think about a class name, in what element to put that class, doing media queries or pseudo states and having separate the CSS files.
Also Tailwind IntelliSense helps a lot because you can see what styling is being applied to the element in the same place.
This is just a list of Chrome-only CSS extensions.
Read the article again and really focus every time the word “interop” appears.
I am very much excited for the future of CSS. And I love that functions are a part of it.
I spent 3 months this year testing out a reporting system for large quantities of dynamic data.
My requirement was to generate pdf reports, but didn't want any reporting tools and installations. Especially something like Microsoft Excel, which the old system was based on.
After a lot of tests and proof-of-concept apps, I finally zeroed down to simple, pure, self contained html, that I am generating from a python script.
And it's glorious.
I am generating interactive charts when the html is viewed in the browser, and hiding all of them and only printing static svg images when in print mode, using css media print queries.
And there is so much more.
The format is awesome for ingestion by ai models.
in the times before LLM working with CSS manually was kinda fun actually. Sad thing it is too time-consuming nowadays
I forgot about functions!
I always thought that everything from Sass was pretty much ported over by now.
> It was implemented in Firefox back in 2019, but there wasn’t much movement with other browsers for years
Just call it like it was: Chrome. It was Chrome that didn't move. We can all see the graph :P
I built a web app with Claude Code without reading the code it wrote. I only asked for things like "add outer margins to the menu and header, with a transparent blurred background," and it came out the way I imagined.
You do realize "Claude" actually wrote CSS for you and thus you need that language to strive ?
Such an uninsightful comment.
Give it a more charitable reading. But I think there is truth to it, CSS was never that great with just describing what you want, it was always more like arcane spells and tricks you learn to achieve a specific goal. Historically just trying to center something or achieve equal spacing would send you down a deep rabbit hole of quirks, browser support, layout modes and so on.
Congrats
Like Rust, CSS is a great language if you never ever have to actually look at it.
Still can't tree shake. It's what makes my old css files grow into monsters. I feel like everyone has given up on this.
CSS modules ought to make it possible. But it’s more or less impossible with regular CSS, you have no idea when a class/ID might be used.
For small-scale projects, I use a server-side helper for an HTML page to include only certain CSS, SVG, and JS on a page. Each JS file is tiny, progressive, vanilla JS; SVGs are predefined and generate an SVG sprite that I then consume; CSS pulls in a `base.css`, the page's CSS file, and any component ones pull in their own. It's hand-rolled per project (pre-AI being decent), but I'm proud of it, and it keeps every page tiny. HTTP/2 multiplexing is pretty good and downloads the files more or less in parallel.
Why do you not do any refactoring of styles?
Great Atricle
Thankfully, now that our machine God is here, we don't need to bother ourselves with learning new CSS features. Just feed the article to the machine as part of the spec and it will handle everything.
I hold the opinion that adding anything to CSS is a bad idea. It's already complete, you can do almost everything you'd want in it, and if you can't there's always javascript. Updating CSS forces people to update their browsers and we get that never-ending chase of compatibility. It's just breaking stuff for a little benefit
At what point is CCS just another programming language? It's getting there, no?
In general I like CSS, but ...
a) they keep on making CSS more and more complex. You can reason in favour of it, of course, but it is undeniable that CSS becomes more and more complex - and complicated, too. Which leads us to b)
b) "CSS Subgrid is a good example. Subgrid is a super-powerful extension to CSS Grid which enables entirely new layouts."
Well ... I wanted two flexible divs side by side. It is possible, but there are like 5 different main strategies for this, grid is one of them.
Now via a "subgrid", they acknowledge that the existing ways SUCK. So they add yet-another-component here. This reminds us of:
https://xkcd.com/927/
I started to go back to oldschool - HTML tables.
People can hate it, but they work really almost flawlessly. I am not saying I use them for everything, but I totally changed my mind after I saw how flexbox and other things SUCK to no ends. So I now compare all of them to HTML tables. If they suck more than HTML tables, I discard them. This is my quality metric now. And a lot of this has to do with developers making these decisions, failing hard at DESIGN. What happened to simplicity? HTML tables are simple for the most part; they are kind of like a grid already.
Aren’t HTML tables accessibility nightmares?
For data? There are some foot guns but they do intended job well. For page layout? Accessibility nightmare.
Did you know you can make tables in CSS now ... ; )
I wanted subgrid a few years back. Imagine you need to show 3-4 pricing cards next to each other. It can't be a table, the cards have padding, an outline, shadow, etc. Inside they have rows of features. But some of the items aren't just a single line of text, they wrap around, and you need to have the heights of those inner rows align between the cards. It's not possible without a subgrid or some custom JS code.
so funny to start the article with "Interop that all compilers unite to implement together" and then proceed to show features available only in one browser
see here: https://news.ycombinator.com/item?id=50176056
this is like the webdev version of the c++ people who love talking about how great the modern version of their language is, ignoring the fact that all the bad stuff is still in there...
remove inheritance and cascade from css and then we'll talk. but for now ill stick to tailwind.
CSS was done a long time ago. Stop changing it.
interpolate-size: allow-keywords holy shit, didn't know I'd see the day...
cool stuff
you need to be a pro to build fancy shit with vanilla css xD
Less than you'd think. A lot of it is just knowing the right element exists. A slide-out menu that closes on Esc or when you click outside is a button with popovertarget, a nav with popover, and a few lines of CSS for the animation.
(I'm biased, I ended up writing a book about this kind of stuff: https://theosoti.com/you-dont-need-js/)
Say it with me:
Broad support for new CSS features is GOOD.
Making BASIC SITE FUNCTIONALITY depend upon new CSS features is bad.
HTML and CSS are like bash, no one would use them if it wasn't for the fact that it is everywhere.
Why would you pick something that isn’t ubiquitous? Being everywhere is the probably the most important feature for the vast majority of cases.
Because ubiquitous has nothing to do with any other quality like correctness, ease of use and ergonomics, good taste, robustness, and so on.