Things you don't need JavaScript for
lexoral.com
lexoral.com
You can make links or forms submit but not cause browser navigation by having your server respond with a 204 No Content.
I feel like this is a completely forgotten technique, but we used this a ton pre-AJAX for little one off things to shoot a message to the server without interruption.
How do you handle reflecting the new state in the UI though? Do you just use JavaScript anyway?
I have a form which looks like a toggle, and interacting with the toggle initiates a POST request. If the server responds with a 204, the UI doesn't actually update to reflect the new toggled state. I'm not sure how to work around this.
Furthermore, according to this article[0], the `:target` approach is viable when it's acceptable to change the browser history, whereas in my case that is exactly what I'm trying to avoid.
I've never heard this turn of phrase before, but I really like it.
We also did just use some JS to for instance hide the button. Our goal wasn't to avoid JS perse, just AJAX wasn't really a thing yet.
To be fair, on the second point, on an error, you can not return a 204, and take them somewhere telling them what went wrong.
I mean the status code can be looked up easily, but where would we have read about the "submit but don't cause nav" feature?
https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.5
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204
It used to use HTTP 204's, but submitting the 204 made Firefox stop steaming the motion jpeg!? When I showed it off on HN in 2020, a PR was submitted that switched it to your iframe method which works smoothly in all browsers without JS.
What happens with a 40x or 50x? I guess with 40x there's potential to bring the user to a sign in page if that's the problem, but if there's a server error then it seems like the user may lose their form data and end up on a useless error page.
Using 204 seems like a good default, though, because it means I can still use forms with JS turned off but I can choose for the site to be progressively enhanced by JS if I turn it on.
As rough as the experience of being taken to an error page is, I think it's often both more obvious (for users) and easier to get right without thinking too hard about it (for developers).
Why would I have any interest in making requests for "No Content". Perhaps this is why web developers use Javascript to trigger them, without any input from the user. How many users knowingly make such requests for no content, or otherwise send data, while expecting no visual acknowledgment/feedback that data is being or has been sent to a server.
There could be legitimate uses for this perhaps but the uses to "avoid detection by the user" outweigh the benefit of allowing it.
However once a 204 response is discovered in the logs the domain or URL can be blocked going forward.
I generally do not use a Javascript-capable browser nor enable Javascript when I am using a popular browser so JS-triggered requests for no content fail on account of no JS engine available. In cases outside the browser, e.g., checks to detect captive portals, I block them with a proxy.
Other users may operate the computer using popular software running under default settings where, e.g., visiting a website automatically runs a number of Javascripts unseen by the user and the user implicitly trusts that, whatever these scripts are doing, it is necessary and for the user's benefit. We know that is not always true. (This blog post shows us a number of instances where JS is used unncessarily.)
There could certainly be legitimate uses for the non-JS 204 no content data sending technique. If I was using a website where this was useful, of course I would not block it. I am not yet aware of any such website among the ones I visit. Every use of requests for no content I have seen has been unnecessary. Usually it is some form of telemetry, sending data about user behaviour to a server without any prior user consent or affirmative action. I suffer no loss of benefits by not making or blocking these requests. For me, this is the most sensible approach. YMMV.
There is often a privacy benefit, too, if the request are being used to send data to an entity that supports online advertising. In some cases, not making these requests avoids supporting the practice of unconsented user data collection, telemetry and online advertising.
There are thousands of reasons things would return a 204. Blocking that is just being obtuse.
There are lots of requests that return a 200 with no body as well. Do you block all AJAX requests? The user doesn't see those happening, but it's not abuse.
I do not block all AJAX-triggered HTTP requests. For the ones I might need to make in order to retrieve content, I make them without using Javasscript, outside the browser.
Being called names without repercussion always proves that HN policies do not apply to everyone. It also indicates there is no cogent counter argument to make. More name-calling please. :)
If HN commenters want to protest over when and how one user uses her own computers and her own network, I welcome the entertainment. I'm bored today so foolishly responding to every comment, no matter how stupid.
For a light-mode/dark-mode toggle that doesn't use JS, I would suggest using radio buttons. It's really a situation that calls for 3 distinct states: follow the system preferences, override to force light mode, and override to force dark mode.
---
I totally agree though that JS should be used to augment, especially to save the state across page loads. At best, Firefox will autofill radio buttons across page reloads within a session, but that's not sufficient enough.
I was recently considering the approach of keeping this transient state in the URL somehow: the only place that makes sense (for CSS to access it) is in the fragment. Rather than toggling a checkbox or radio group, link to a fragment of the page. This gets tricky with multiple pieces of state though; you have to permute all of the state on the page into increasingly long (or unreadable) fragments (eg. `example.com/my-page.html#color-scheme-override-dark-and-sort-by-title-asc`). However on the plus side, you get state for free _and_ can share your set of state with other people (which makes sense for page state like sorting and filtering, but not so much color scheme overrides).
Historically it was also rather buggy in most browsers, though hopefully that’s sorted out now. (A decade ago, Firefox was fine, but IE and Chromium both had significant bugs, might have been to do with back/forward not recalculating :target or something like that. When I last seriously used :target in 2016 or so, on a multipage-in-one-document résumé, I think they were down to fairly minor bugs.)
Accordions make most sense as a table of contents, although they are often used in FAQs. But in FAQs, you can't use the browser's search on page to find collapsed words. So you trade better scrollability for searching on the page. Not sure how many people use "search on page" on mobile devices though.
1 + 3 are great though.
I'm glad that you enjoyed 1 and 3 though - it's been really interesting seeing each person take something different away
Aside from that, something very weird is going on with the page. There’s a huge blank area to the right of the screen that you can easily scroll to accidentally. This also happens on Safari on macOS, where for some reason it doesn’t let you scroll back left (and persists the scroll position on page refresh?!).
I definitely agree with the blog post in general though - we should try to use HTML and CSS instead of always resorting to JavaScript.
Collapsable objects can be expanded by default as well, so not sure how relevant that is. I'd much rather a site use native techniques than load 100 JS frameworks in my browser to do something simple.
The thing the article seems to be missing is an explanation about when not to use CSS. In my experience there's a lot of scenarios which could be solved with pure CSS in theory but in the end will be implemented in javascript.
The first reason is browser compatibility. If older browsers need to be supported (unfortunately IE is not completely dead yet), many CSS based solutions are just not possible.
The second reason is changing requirements and future-proofing. Often only the simplest requirements can be fulfilled with a pure CSS solution. When more requirements are added or the feature needs to be extended in any way, the only possible solution is to just completely scrap the CSS solution and re-implement it in javascript. I feel this happens so often that most web developers just prefer implementing the feature in javascript straight away because they know it will be easier to change later if needed.
This is a great point. "how am I going to maintain this?" or "how will someone else maintain this?" are often the most important questions and are often overlooked.
I joined this company that has a 10 year old Dojo application as their UI. Before I joined they had a guy come over once a week for some maintenance work. They spent several days trying to solve an issue where a bar with a 'save / close' action would show up at the bottom of a dialog, making users scroll down. This was a complaint that users had for literal years.
I added position: sticky and had to figure out how it worked, but the issue was resolved with about ten minutes of work. Not to pat my own shoulder too much, but that was pretty cool. Plus it works gracefully, in that if the browser doesn't support it yet, it falls back to (or, should) to the old behaviour.
Showing up at the bottom?
I know jQuery isn't cool these days, but if you have a site that uses it, sticky-kit is the way to go. It's very fast and handles a lot of corner cases (pun intended).
<script>
const button_close = document.querySelector('#menu-button-
close');
const button_open = document.querySelector('#menu-button-
open');
const menu = document.querySelector('#menu'); // Menu
button_close.addEventListener('click', () => {
menu.classList.toggle('hidden');
});
button_open.addEventListener('click', () => {
menu.classList.toggle('hidden');
});
</script>[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/de...
As with most things, the ideal is somewhere in the middle - use these techniques to get a baseline, then embrace progressive enhancement and round off the rough edges with JavaScript
The remnant who absolutely refuse to run javascript under any circumstance aren't worth worrying about unless you want to appeal to them, specifically, as a demographic.
Sure, in the year of 2010 maybe... With https on almost every website this is hardly an issue now. We need more valid critism, not these outdated incidents to scare people
I use this theme, because I disable js myself.
I think the true progressive enhancement route would be to render the menu either visibly on the page (maybe at the bottom?) or on a separate page entirely. Your burger menu icon is a link (either an anchor to bring the menu into view or to the dedicated menu page) and if JS is supported, you hijack the link using code similar to the parent comment and add a class to bring the menu element into view from there.
In doing so, your page can work just as HTML, not even CSS required, and if JS is supported then you have real state management to control the visibility of your menu (although accessibility concerns still potentially exist if you're not careful!).
JS has its uses. The majority of UI elements should not involve JS though. Unfortunately, UI also provides low-hanging fruit for beginner-level JS developers to tangle with.
https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pref...
That doesn't make any sense.
While it does lack in many other areas, Safari on MacOS has a wonderful interface for per-site default behavior for: automatically using reader-mode, allowing permissions (microphone, etc), setting page zoom, etc. This would be the perfect place for per-site overrides of the system light/dark mode.
Problem is, this doesn't always work;
https://forum.manjaro.org/t/google-chrome-not-in-dark-mode/8... https://forum.manjaro.org/t/why-media-query-always-choosing-...
Editing config or .desktop files to work around such issues may be an option for experienced user, but even speaking from such a users perspective, I would much prefer a webpage to offer me a simple button or checkbox.
The first is a complaint about a browser context menu not the web page and the second is about a GNOME theme which obviously has no affect on CSS in browsers.
Instead of a shitty div hell to construct a slide toggle, which becomes super laggy if you have to have a scrollable list of 1000 of them.
[0]: https://developer.mozilla.org/en-US/docs/Web/CSS/:indetermin...
Slide toggles would be completely bizarre on a survey, for example. "ah yes I'll just turn on 'member of the armed forces'"
<input type="checkbox" ...>
<input type="slide_toggle" ...>
<input type="range" min="0" max="1000" step="5">
<input type="color">
....
You can have whatever you want, just saying, make modern UI native components accessible via HTML without some CPU-intensive div-react-polyfill-javascript fluff. It's ridiculous that if you need to implement a slide toggle, which is available as a native component, that you try to emulate the shit out of it with some images and CSS and javascript and more div hell for the sliding animation and then even more div hell for the little radiating animation instead of just dropping in the native widget which will do all of that and at way better fps than your emulated version.[X] Mute notifications
[X] Large fonts
Whereas with slide toggles the on-off semantics are much more obvious and design patterns tend to get forced to a better, simplified pattern:
[o--] Notifications
[--o] Large fonts
(where the toggle is clearly lit up for the "on" state of course)
Checkboxes may be ugly but pretty clear.
Here's an HTML and CSS snippet to implement smooth scrolling:
""
That's it. An empty string. In other words, nothing. It's already implemented in the browser! Wasn't that easy?
Now stop wasting time on an JS-based implementation of smooth scrolling that breaks in at least 1 browser.
For example, you can make an accordion menu with plain HTML, but should you? Accordions are horrible. They just hide information. 20 years ago an accordion was a design pattern that made a bit of sense - scrolling meant moving the mouse to the scrollbar or pressing Page Down which took you out of the reading flow on the page. Not to mention screens were tiny so a long page didn't work very well. Today though, users can scroll easily with a mouse wheel or a swipe, and screen are much bigger. Just show the text and let the user scroll past it.
CSS-derived dark mode is another example of "Yeah, you can, but it's a bit rubbish." The site won't retain the user's choice if you use plain CSS which is pretty horrible. Either use JS, or use your build step to bake two versions and serve them on different URLs like "/dark/page-1" and "/weird-bright-mode-wtf/page-1".
The off-canvas menu and sticky bar are quite nice, but again it does feel like developing something that could be better without any clever CSS or JS through sensible design choices.
I love outliners such as Workflowy and Dynalist. I'd like most textual content to look more like them. It's really great being able to expand/collapse/zoom into entire sections, link from one section to another, etc. You can expand everything with a single command and you should also be able to flatten the tree and read it like a normal page if that's how you like it.
Regular pages with accordions are just a poorer version of this. I'd like it to go all the way in that direction.
There's nothing much to it, it's just collapsible nested lists. And to be clear, I think most people would be weirded out by a blog post that looked like that. I think making the "flat" view the default one but adding a toggle for a hierarchical view would be the ideal UX for me, but I bet this is a very niche preference and it wouldn't be worth it for a larger audience.
(sunglasses)
We're in one right now?
Correct, that's why the suggested solution here is just as bad.
"Plain CSS" dark mode just follows your device’s setting via `prefers-color-scheme` @media query. Anything else is just unnecessary and should be suppressed. Just set your whole system once and be done.
That "Plain CSS" works perfectly and indeed does not need any JS nor different URLs (wut? who does that.)
Scroll wheels were a thing 20 years ago too :)
I've been building websites as well as surfing the web for nearly 30 years now and I can honestly say I've never once found the scrollbar or using the arrow keys (which I favored over the Page Down) as jarring to the reading experience like you said it is. Generally you'd just keep one hand hovered over the keyboard button or the mouse cursor on the scrollbar, much like you might keep your finger on the scroll wheel now.
If anything, I find swiping on a mobile screen more jarring since it means I have to use both hands (since I'd be holding the phone with one hand), or do some "phone gymnastics" where I try to shift the phone position in my hand enough to slide the screen with my thumb while still holding the phone, and do so without dropping the phone. Which often results in scrolling either too far or not far enough.
> Not to mention screens were tiny so a long page didn't work very well.
Mobile screens display a lot less text than a webpage did on a 90's 800x600 PC screen. Remember that modern screens will have a higher DPI to make things look smoother. On older screens we just accepted that stuff would look pixelated because that was the state of the art.
Incidentally, the biggest mistake the web 'committee' did was to make a web-components spec that mandatorily requires javascript even for a basic 'hello world' label. That made it strictly a no-go for many domains where HTML/CSS generation/rendering is accepted but JS is not.
I am in hard-favour of approaches towards UX components without JS.
The trick is, people want less-simple things now.
<a href="/some/path">Place</a>
They will do something like <a href="#" onclick="window.location.href='/some/path'">Place</a>
(or whatever the current equivalent is in framework du jour) Making it impossible to right click the link and open a new tab. Yo, I need to be able to reference data from multiple areas of the application and your javascript is making that really hard to do! I know that you can do this properly in javascript, but it would appear that at least some people have not gotten the memo. So I'm going to say - you don't need javascript for navigation.Keeping `<a href="/some/path">Place</a>` but adding an event listener to capture your click and run some JS instead fixes that particular issue but opens a whole other can of shit.
BTW, https://remix.run is a sweet new framework that properly embraces progressive enhancement, ie almost everything works with JS disabled.
Like a news site?
I've seen a few sites requiring javascript that can only be explained by it.
In general I like the concept of not using js unless you have to, but it’s important to consider mobile.
As for the sticky example, I'm really not sure what's going on there. It certainly seems to be supported. https://caniuse.com/css-sticky
They might know tailwind or bootstrap, but I doubt they even know what kind of HTML their react component library is producing, let alone have the capability to style it.
Never had an interview question about styling before - but some places ask you about inverting binary trees than never have you do anything that involves inverting a binary tree, so that wouldn't tell me much.
I have dabbled periodically in modern front end development, but it depresses me hugely. All the mistakes that gave us PHP dominating back ends (another sad story) being repeated in a modern context.
Learn CSS? I did. Feel like I wore out MDN but I agree it is awesome. An adequate solution to a very difficult problem.
My experience in the last few years has been "no", in general. It is a rare, elite few who bother to learn it. Most devs don't want to put in the effort, and so think it's hard, or think there is a better, easier solution out there.
As a freelancer, I've seen many teams prefer to reach for React components that do layout, or for other libraries like MaterialUI which take just as much effort to learn as CSS, but then they are unequipped to troubleshoot the inevitable unexpected consequences.
CSS is a pretty amazing system for laying things out responsively. I've not seen anything better.
Is super easy for someone to screw things up and cause a 25% CPU usage and not notice it on his dev machine.
After this incident my rule is to always triple check in code reviews any animation that has "infinite" in it (though I am mostly a backend dev)
=> If you use sticky headers/footers, lay out the other content so that it isn’t overlaid by those headers/footers.
Anyway, it doesn’t matter much what would be the better solution as long as browsers don’t implement it.
but the slowness of new features is definitely frustrating, even if understandable.
Yes but javascript can enhance a sticky top nav by watching the scroll position and updating the nav with whatever is intended by design, relative to the scroll position or direction. Such as hiding/showing or doing something else in response.
Even though it might still function as a basic nav without js, if I made a movie and found out people were watching it with "special effects turned off" it wouldn't be fun to learn that about the audience.
> "1. Animating SVGs"
Cool, but the more interesting animation possibilities are javascript driven. Like when using timing, waiting, chaining multiple animations, and responding to user interaction or other events. Need javascript for dynamic animation.
Also for animation it depends on the use-case. Complicated animations are better suited for JS than CSS https://developers.google.com/web/fundamentals/design-and-ux...
I recall trying out a complicated SVG animation and it used a decent chunk of CPU time
If not, then I'd be interested in the device you're using, to try and debug the animation.
You're correct though, SVG animations can be resource-intensive. There's an interesting discussion elsewhere in the comments about how best to use the developer tools to debug poor performance in animations, but it can be a struggle.
Javascript offers ways to do everything only in Javascript. That's wonderful.
But, all that are not things this article is about. They just name five specific things you meet regularly in web design and that don't need JS anymore. And in that case it's valid as the browser will generally do things better than you do yourself, be more accessible and integrate better into different platforms / OSes.
As an example: https://github.com/stevenwaterman/Lexoral/blob/stage/fronten...
I wonder if we could also have a .restricted TLD that doesn't support javascript, the more invasive of these CSS hacks, transclusions of any sort except from the same domain, or cookies persisting longer than the browser session. That would make it a lot easier to have reasonable security assurance about pages with private contents, at the expense (or rather, the added benefit) of not being able to have blingy javascript effects on the page.
That is, imagine I have two `select` dropdown with a set of numbers in each, and a `submit` button. I thought there was a way to construct a target url based on the values of `select` without using JS. So you might select '2' and '5' from the dropdowns and hitting submit would send you to 'mysite.com/2/5'. As far as I can tell, I was wrong. Anyone disagree?
<form method="get" action="foo.php">
<select name="item" mutiple>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<button>go</button>
</form>
If you select option 1 and option 3 it will submit to foo.php?item[]=1&item[]=3So in general <form method="get"> will append a query string to the action url composed of the form field values. But it is not possible to specify an url template to control the exact structure of the url. If you want that you have to implement a server side redirect.
One thing I did not know until recently myself: form submit buttons can specify their own formaction and formmethod attributes that override that ones specified by the form. So you can have multiple buttons inside on form the submit to different locations.
It pays of to check for new HTML and CSS tags/functions once in a while. Have been a (web)developer for some years now, and it's only since recently that I found all these things. The amount of JS that I could ditch was astounding to me. Just liberating.
Aside from the typical complaints that you should be using prefers-color-scheme instead… This doesn’t work for me. Is it supposed to leverage autocomplete or something?
Only the accordion is working.
I’d recommend more testing before using. Though the details element is great.
Maybe for killing the user's battery?
The left side of the paragraphs, somehow, is cut off.
I cannot scroll sideways.
Edit - It should be fixed now. GitHub Actions seems to be having some issues so it took a long time to deploy
You don't owe us an excuse
so many people I know have amazing projects and work they're afraid to post here because they don't want a massive audience of highly technical people picking at the bugs
The reason it was broken was because when writing the toy examples, I went in with the mindset of creating an example rather than production code, and set them all to a static `width: 25em` - forgetting that these toy examples were going to be inlined into the page. Silly mistake, should be checking each post before publishing, learnt my lesson now!
From time to time though, "Fuck everyone, you're all wrong!" is also still kind of fun.
I'd suggest finding a bright side: if all a massive audience of highly technical people can find wrong is presentation nitpicks, then there your project/idea/content can't be too terrible.
Though to be fair to the nitpickers, if you are criticising design matters you should probably make sure your own design is solid enough.
Of course, all that would be avoided by just running a web server locally!
The main text column has the right size now but I can scroll 50 vw out to the side.
> overdoses on css instead