13 ms·
HTML and CSS techniques to reduce your JavaScript
- nattaylor 5y agoI was vaguely aware of several of these, but hadn't thought to use them in the ways the author proposes. The gallery with horizontal snap scrolling, the use of smooth scrolling to jump between anchors and even clamp are all quite cool. I also had no idea that's how sticky worked!
- deleted 5y ago[deleted]
- armchairhacker 5y agoI'm currently trying to do as much as possible (without crazy hacks) in HTML / CSS alone, just because it's easier. Things like "position: sticky" are easier than anything JS could do.
- SilverRed 5y agoNot only easier, but more performant. You don't end up with one element lagging behind as you scroll.
- brundolf 5y agoIt’s also easier to debug, because state is so minimal and visible
- Dylan16807 5y agoSometimes. Is there any good way to see why an element is a certain size? I often end up digging back and forth through children and parents and wanting to tear my hair out.
- brundolf 5y agoIt's easy to see computed CSS properties and which selectors they come from (and what the order of specificity is that caused those properties to take effect) Given the properties, I personally find sizes to be pretty predictable based on the rules of block or flex sizing
- Dylan16807 5y agoI'm talking about sizes that aren't coming from properties in that specific element. I can see that it's height 20 and I can see that it's not set directly, but how do I know if it's coming from the parent element or a child element, and for the latter how do I know which children/grandchildren/greatgrandchildren are causing it to be that size? And every one of those elements has 100 rules applied because it's a mess I didn't create, so brute force searching is a giant pain.
- brundolf 5y agoI'm also talking about sizes that aren't hardcoded. I don't really know what to tell you except that in my experience the rules governing the sizing of CSS elements don't tend to be very complicated. If you're in a default (block/inline) context, and no width or height is set, then if it's display: block it will be the full width of its parent and its height will be determined by its content. If it's inline or inline-block, its width will also be determined by its content. Flex contexts have their own rules that are a bit more complicated but remain very predictable once you learn them. Etc. Generally, nearly every element's size comes down to some combination of: 1) Explicit width/height properties (and padding/margin) 2) Special layout mechanisms like filebox or grid 3) The element's contents 4) Its direct parent's dimensions That's pretty much it. There's really no case I can think of where a grandparent directly drives an element's size (it may drive the parent's size which drives the child's size, but the reach at each individual stage remains short)
- Dylan16807 5y agoI tried to recreate my original full set of grievances, but firefox has changed the CSS around too much. But I can still go with this: I inspect the tab toolbar. I pick a tab and look at the contents of the div. Just inside the actual tab div is a "stack" element, whose width is being set to the size of its contents right now. The stack is size 50.5x44, and it's display:grid. It has two visible children. Both of them are 50.5x44, and are display: -moz-box. I can tell from deep inspection and trial and error that one of those children is setting the size, and the other child is inheriting the size. But if I don't want to dig around every single sub-div, what can I do to figure out which one is which? They look the same in the layout inspector, and neither of them has any computed properties relative to width. For bonus difficulty: If the parent div of the "stack" element tries to grow wider than the stack, the stack will grow to match its width, and the child divs of the stack will also grow to match it. All without any computed properties changing, or the layout inspector noting that anything is different. So the size of the "stack" element could be set by either its parent or one of its children and I have no idea how to figure out which one except by experimentation. This is not a very pleasant experience. Ideally, I could get a list of every element competing to set the width of a div, and which one(s) are winning. Less ideally, I could see just which element(s) are currently responsible for the size of a div. But as far as I can tell there's nothing, and I have to blindly search every other related element that has a suspiciously similar size.
- recursivedoubts 5y agoif I may recommend my own library: https://htmx.org https://htmx.org it extends the expressive power of HTML as a hypertext and allows you to do quite a bit more within the hypertext paradigm.
- speg 5y agoLike the parent I am trying to DIY most things on my personal projects. Standard library for everything except the database driver and… htmx ;) Thank you!
- leephillips 5y agohtmx is great. Thank you for making it.
- k1rcher 5y agoWow, this looks bloody brilliant. I’ve only recently begun feeling more “comfortable” writing JS on the fly for frontend development (previous roles were nearly all backend-centric), but one big issue I’m facing is managing the ever-growing ecosystem in a way to minimize complexities in a timely and efficient manner. HTMX seems as though it will catalyze those efforts.
- pjerem 5y agoWow, that's impressively cool ! Well done
- armchairhacker 5y agoWow thanks! I am definitely checking this out. HTMX + TailwindCSS, so almost everything client-side is in HTML. And I use FreeMarker macros to generate the HTML components.
- sillyquiet 5y agoThe repeated "All browsers except Internet Explorer" with regard to support is exactly why a lot of these solutions are in javascript still for a lot of sites.
- netr0ute 5y agoIs Internet Explorer still that popular to require extra support?
- mod 5y ago3.37% (3rd most popular) https://gs.statcounter.com/browser-market-share https://gs.statcounter.com/browser-market-share
- mumblemumble 5y agoI see Edge at 3.37% and IE at 0.62% in that chart.
- sillyquiet 5y agoSome industries (government, hospitality, health care, some travel) have proportionally more IE users unfortunately than the general population
- deleted 5y ago[deleted]
- blacktriangle 5y agoDepending on your market, it's not about the raw popularity. If you are selling to business, many of them are running ERP systems that depend on IE11 and will never be updated. However the knowledge that IE sucks is well established outside of developers at this point. We sell into business and only officially support Chrome and Safari. When people run into common issues we tell them to switch from IE to Chrome, and 90% of the time they respond as if they screwed up not us, and that they should have thought to try in the non-sucky browser.
- 5y ago
- eyelidlessness 5y agoI’m not surprised but a little disappointed that most of the older techniques aren’t mentioned: - checkbox/radio inputs can be used to toggle state with `:checked ~ .foo` selectors - `:focus` (and now `:focus-within`, and `:active` though it’s less useful) can be used similarly, but also allow child selection [Edit to add: `tabindex="-1"` makes anything focusable with a pointer input, but doesn’t capture keyboard tab or iteration with assistive tools] - `:target` can be used similarly, paired with fragment links [Edit to add: but beware history entries, this can be a poor UX] - `<label>` can be used to not only set those states but also trigger scrolls (including within `scroll-snap` parents) without creating navigation history entries - the `attr()` function can be used to reference server-dynamic HTML data for display with `content` in pseudo-elements - I have to assume CSS animations are adopted widely enough that people aren’t using JS for that where it isn’t needed; but you can also use declarative, even interactive, animations in SVG - speaking of which, inline SVG (even `<use>` references) are part of the CSS cascade, and you can change any CSS-addressable property with `currentColor` - and you can nest HTML in SVG with `<foreignObject>` if you want to use SVG techniques in HTML - probably not worth mentioning but in case you don’t know... if you miss table layouts, you can use them with `display` on basically anything; if you want table semantics without tabular rendering you can override `display` as well Alllllll of that being said, if you use these techniques check your stuff with assistive technologies!
- eyelidlessness 5y agoAlso: almost all of these are actively in use on my personal site, they’re not just stuff I mention academically. They’re great for places you might progressively enhance with JS but want to provide reasonable no-JS fallbacks.
- decremental 5y agoI'm new to getting my designs working well with assistive tools. What do you use for testing and what are the prominent tools that should be targeted?
- eyelidlessness 5y agoAdmittedly I have a better track record saying than doing. So I’ll double down on that and repeat what all of the a11y advocates I follow say: - you want to at least test with JAWS, NVDA and VoiceOver - automated tooling isn’t great and you probably need to manually verify things - axe does help spot problems just don’t rely on it completely
- mdoms 5y agoPretty embarrassing how slow this website is too load, considering the dude's core competency.
- SilverRed 5y agoIt wasn't slow for me and also the page is on the front of HN right now which often hammers web servers.
- marvindanig 5y agoA gentle reminder to anyone dismissing this theme of making websites work with less javascript: Amazon.com works great with NO javascript. Seamlessly.
- asddubs 5y agoalthough i recently found out you can't cancel prime without javascript. took me ages to figure that one out since the site usually works for the most part
- TheAceOfHearts 5y agoYou can use Facebook without JS as well: mbasic.facebook.com I'm not sure if it's completely JS-free but Gmail also has a Basic HTML view, although you must enable JS in order to login to your Google Account. However, this seems like a weird comment. Should it be surprising that some of the world's largest tech companies with effectively infinite resources are able to provide a JS-free version of certain services?
- asddubs 5y agoare able? not surprising. that they do, is nice though. twitter got rid of their no-js site, so it's not a given, even for huge websites. amazon does stand out in that their main site still gracefully degrades well, not some alternate version that's stowed away somewhere. I am grateful for the gmail html version though. ever since they redesigned gmail I've been using that, since it still has the old interface. and it does have optional javascript based enhancements here and there, as you say (e.g. suggesting people from your contacts when typing in a recipient)
- rammy1234 5y agoa basic question - why there is no multi threaded browser ?
- pg_bot 5y agoFlow is attempting to do just that. https://www.ekioh.com/flow-browser/ https://www.ekioh.com/flow-browser/
- rammy1234 5y agoNice ! thanks that's an interesting read. All this javascript is single threaded in browser is all so limiting.
- livre 5y agoSaying that JavaScript is single threaded isn't accurate anymore. Even the article we just read mentions that you can run multiple threads with WebWorkers. The problem with JavaScript is that the main thread may* block the UI. * Why may? The older APIs such as document.write and synchronous XHR do but modern browsers already warn against that. And the modern APIs don't block the UI because they are asynchronous and work with callbacks or promises. Bad JavaScript code can make the UI sluggish though, people should be performing complex tasks on a WebWorker but that's not as easy or as obvious as the default of performing them on the UI thread. The same problems can happen in native Windows programming for the same reason, the UI thread being the main thread. This is a bad design decision from decades ago that will likely haunt us for many more decades in the desktop OS and on the web.
- dmitriid 5y ago> Saying that JavaScript is single threaded isn't accurate anymore. Even the article we just read mentions that you can run multiple threads with WebWorkers This doesn't make Javascript multithreaded. It means you run single-threaded programs in separate containers and pass messages between them.
- markdog12 5y agoIronically it took 20 seconds to load this site.
- onion2k 5y agoThat's obviously not the JS though, because it takes a while to connect and download the first request rather than taking a long time to render. It's likely that the server is just struggling under an unusual amount of traffic right now. So no, its not ironic.
- robbrown451 5y agoNot to downplay the potential usefulness of some of these, but some of the reasoning for them that is presented is making some assumptions about how the Javascript is done, and those assumptions might not be true. JavaScript can load just as fast as CSS etc if done carefully. If you really want to, you can put some JS right in the HTML file, immediately following the elements it is going to operate upon, changing the display of the elements before they are even rendered to the screen. Users will experience no delay (or flashing) at all. Whether or not that is considered good practice is another matter, but it most certainly is possible to eliminate the delay that is discussed in the article without abandoning JavaScript approaches. The problem is when people require a big framework be loaded just to do simple things. Or, I guess they write JavaScript that is so complicated that it causes a noticeable delay simply due to loading the massive code. But that is an awful lot of code. The examples given would never need more than tiny amount of JS code. There are other reasons, of course (people who turn off JS still exist, I'm told), but as someone who simply knows JS well but doesn't know nearly as much about CSS (which has far too many surprises and special cases for my liking), I tend to be of the "if all you've got is a hammer, everything looks like a nail" mindset. So I'm unlikely to figure out how to do something in HTML/CSS if I can do it instantly in JavaScript. (obviously I do regular styling in CSS.... I'm talking about the more advanced stuff as per the article) That's just my reality, right or wrong.
- strogonoff 5y ago> If you really want to, you can put some JS right in the HTML file, immediately following the elements it is going to operate upon, changing the display of the elements before they are even rendered to the screen. This is indeed a cool trick I have seen in use in the wild. Can it work with CSP, however?
- PinkPigeon 5y agoThat would have been my first question as well. It can work, if you specifically add the hash of that bit of JS to script-src or use the nonce based approach (I never figured that one out). Otherwise it's unsafe-inline, at which point you may aswell not bother ;)
- RheingoldRiver 5y agoThere's a limitation to `position:sticky;` though, which is that it will not work inside of ANY parent that's `overflow:auto` or `overflow:hidden`. I hope this gets addressed in a future version of the spec one day. Gtihub issue: https://github.com/w3c/csswg-drafts/issues/865 https://github.com/w3c/csswg-drafts/issues/865 The biggest issue that happens to me is that I'll have a large data table where I want `overflow-x:auto` with a sticky header, and this is just impossible without Javascript. Of course, the UX of such a table is not ideal, but sometimes nothing will substitute for a large data table when you have a lot of data that goes into a table and people want to see it.
- chadlavi 5y agoThe thead isn't a child of tbody anyway; you can just make tbody scrollable for this, no? Edit oh I missed the "x" there, I see.
- Cthulhu_ 5y agoI've inherited a pretty bad codebase written in PHP and JS, mostly Dojo. Its UX is based around a lot of dialog windows. Some dialog windows' contents are too big, so that a scroll bar would appear. One issue they had before I came in was that in those cases, the save and close buttons in a bar at the bottom of the dialog would also end up at the bottom, so they had to scroll all the way down. This issue had been open for years. IDK if the previous developer had a look at it, but the interim guy - some PHP consultant - spent a few days trying to fix it. I added `position:sticky` to it and fixed it in minutes, everywhere. Not to boast or anything, but that's all it took. Okay fine I am boasting that my google-fu was slightly better than the other guys. Didn't know about the `loading=lazy` attribute on images yet, mentally I was still thinking of plugins and JS libraries that take care of it for you.
- specialist 5y agoPretty cool. Nothing beats reading the docs, being curious. Weird notion: Is there a FindBugs for HTML, CSS, JavaScript? Such a tool might have to analyze the live DOM, with the actual behavior, to infer what's actually happening, to better suggest refactorings. https://en.wikipedia.org/wiki/FindBugs https://en.wikipedia.org/wiki/FindBugs
- tobyhinloopen 5y agoI like the snap scrolling feature, i didn’t know that one
- martyalain 5y agoSame thing using a language unifying HTML, CSS and JS http://lambdaway.free.fr/lambdawalks/?view=scroll_snap http://lambdaway.free.fr/lambdawalks/?view=scroll_snap To be improved for non squared pictures
- Narretz 5y agoThe -webkit-clamp-line feature would be super cool if it didn't require you to use `display: -webkit-box` and `-webkit-box-orient: vertical` to achieve it: https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-lin....
- smusamashah 5y agoAn unrelated javascript technique I learned on HN sometime ago. `document.getElementById("id")` can be replaced by `window["id"]`.
- onion2k 5y agoThat seems like a dangerous idea to me. If you decided to have an element with an ID of, say, "print" you'd end up getting the window.print method instead of the DOM element you're expecting.
- c-smile 5y agoJust in case, in Sciter (https://sciter.com https://sciter.com) you can declare div { behavior:check; } div:checked { color:red; } and all divs will behave as checkboxes - will toggle :checked flag on clicks. Same way: div { behavior:radio; } div:checked { color:red; } Or even : table > tbody { /* scrollable table body, behaves as <select>*/ behavior:select; overflow-y: auto; } table > tbody > tr:current { /*current "option" */ color:red; } Also you can put this in your markup: <frameset cols="120px,*"> <div>left</div> <div>right</div> </frameset> to have split view. No script is required for all these.