Posts in Web (20 found)
Unsung 1 weeks ago

Asana’s fascinating Tab shortcuts

If you’re a professional web app, your key shortcut situation is not to be envied. Once the operating system grabs the ⌘ shortcuts it requires (⌘M to minimize, ⌘H to hide, ⌘Q to quit, etc.), the browser has its turn, claiming everything from ⌘R, T, N, L, W for tab operation, to ⌘F, P, O, and S for other things. And then, some input controls inside the browser also need to listen to ⌘Z and XCV, and maybe even A (select all), B (bold), and I (italic). At this point things feel barren, and some web apps start reaching instead for less common modifier keys (⇧, ⌥, ⌘⇧), and others go straight to no modifier zone, or override those of the above shortcuts that they can. Each approach, of course, has its own set of challenges . It’s perhaps not a surprise that someone got fed up, and that someone was people working on the project management tool Asana, which did something relatively unique: it promoted Tab to be a modifier key. The video shows me using Tab+K to like tasks, Tab+Return to open a sidebar, Tab+Q to add a quick task, and Tab+H to return home. Here’s the entire official shortcut list, with Tab shortcuts emphasized: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/asanas-fascinating-tab-shortcuts/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/asanas-fascinating-tab-shortcuts/2.1600w.avif" type="image/avif"> What’s fascinating about choosing Tab is that the key already has so much to do: On top of that, repurposing a key to be a modifier key – especially one that already has a job or two – will also have a long tail of strange consequences. And, Tab is only on one side, which could wreak havoc with the ergonomics of keyboard use. (You are, technically, always supposed to use the modifier key with the opposite hand to the hand you’re pressing the main key with.) I am not ready to hate it quite yet. Tab is not the worst key to use in this context, as it’s really the only available big key other than Caps Lock, which is impossible to mess with on the web. The other big keys – the spacebar, Return, and Backspace – would be radioactive for this purpose. The asymmetry issue? Anecdotally, I understand that both right-handed and left-handed people most often use the pointing device (mouse or trackpad) with their right hand, and consequently often prioritize left modifier keys anyway. Here is how Asana solves some other challenges: What’s interesting and I bet the main reason Asana approached it this way, is that Tab is a separate little island, far away from other modifier keys – and thus not just without any preexisting conflicts, but also impossible to confuse with other modifier keys. Asana could have kept all the shortcuts above but substituted Tab with Ctrl on a Mac and Alt on a PC, but those would then be packed among many other similar-feeling keys . (There is a price for this isolation, as Tab backfires the moment you have to combine it with other modifier keys. Asana doesn’t do it very often – I have only seen Tab+Shift+D, G, and F – but I wish they didn’t do it at all.) Overall, I’m surprised how positively I feel about it. If you use Asana a lot, I’d be curious how Tab-based shortcuts feel to you. If you work at Asana, I would love to know if you consider these a success. The only thing that seems to be missing is an option to go back to regular shortcuts if needed, for people who might want it for motor control reasons. (It is possible to achieve that with tools like Karabiner Elements, but that tool is really unpleasant to use.) Oh, also. Tab+B does this, because, well, “tabby.” Cute. #easter eggs #ergonomics #keyboard #web it moves focus to the next UI control, it indents a bullet point or even just text, it accepts an autosuggestion or a placeholder (and similar things ). When you press Tab to move focus around, the action can now only take place on key up, not key down, so tabbing (or, indentation of bullet points) feels slower . When you hold a regular modifier key and then change your mind and simply release it, no action occurs. But Tab already has a job as a regular key (tabbing or indentation, depending on context), so if you change your mind, something will still happen. This might be annoying. (You can press Tab+Esc or Tab+Space for a safe cancel, but that doesn’t seem very intuitive, especially in a moment of panic .) An action only on key up also means there can be no repeat when holding Tab. I am not sure how important this is, especially in the context of accessibility.

0 views
Unsung 1 weeks ago

You only get one chance to make a zeroth impression

Contra the previous post , just spotted this “Same settings, new look!” callout in Firefox, on a page I have never visited before, talking about a feature I have never used: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/you-only-get-one-chance-to-make-a-zeroth-impression/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/you-only-get-one-chance-to-make-a-zeroth-impression/1.1600w.avif" type="image/avif"> I mentioned this once – when you get someplace new, everything is new. This redesign announcement’s conditions were engineered poorly, because they didn’t even consider people who didn’t use the feature before the redesign. I keep thinking of the very old computers from the 1940s, 1950s, and even 1960s, where the challenge wasn’t what to do with the computer, but with keeping the computer running. There was a machine called JOHNNIAC which gained a nickname “pneumoniac” because it refused to work on a warm day. On many other computers, there was a daily ritual of finding which of the vacuum tubes blew up and had to be replaced. Some teams had a literal downtime tax; they knew and communicated in advance that 40% of the days the machine would not be up to the task, consumed by tweaks and repairs to bring it just to the state of being ready to do work . When I look at those kinds of pop-ups and callouts, I think how we’re unwillingly recreating the very same conditions. I deeply believe people are exhausted not just by changes in software , but also constant questions, pop-ups, unnecessary notifications, “STOP 2 END,” emails to unsubscribe from, unsubscribes that don’t work the first time, and so on. Software should not require the user to occasionally click on buttons just to keep it running. #attention #onboarding

0 views
Unsung 1 weeks ago

In between the lines

Over the years, I acquired this weird collection of almost-invisible, but important signifiers of when I know a product really focuses on craft and thinks about its users. I thought about one recently. Here’s what happens when you try to copy a long block of text from YouTube’s (otherwise very useful) text transcript pane: And here’s an analogous example from GitHub: GitHub’s arrives ready to go. YouTube’s throws in a lot of messy things in between the lines. Why does it matter? Because these both feel like places you’ll be copying a lot from, and dealing with a messy paste can feel so, so unpleasant. You have probably seen this chart before, from xkcd : = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/in-between-the-lines/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/in-between-the-lines/3.1600w.avif" type="image/avif"> This is the fabled automation trade-off, or the high fixed cost vs. low variable cost dilemma. Yeah, if you’re doing a lot of copy/​paste, you might invest in creating some sort of a clean-up step, or even going through a programming text editor which has multiple cursors or other casual automation . But what if you don’t do that often, or if you don’t even know how much time it’d take you to automate it? Then the investment seems scary or insurmountable, and you’re stuck doing something like this, time and again: And it’s really nice to encounter a place like GitHub, where the team was thoughtful enough to save you all this trouble. There is also an asymmetry that’s worth pointing out. I believe making this good doesn’t have to be a lot of work for people putting these surfaces together. Here’s me fixing the YouTube situation with two simple lines of CSS with : I don’t know if it’d be as easy for all big text block situations, but I think it’s good practice to look around a bit and think about what are tiny things that you can do on your side that will save your users minutes or hours of tedium (see also: recents and paste and even more recents ). #copy paste #selection #text editing

0 views
Farid Zakaria 2 weeks ago

Small site changes and new design

I have been wanting to refresh my site for a while now. I have even posted a few times on LinkedIn and X offering to pay if somoene was interested in taking a stab at it. I am sure this will put people off from reading my blog just stating this, but I decided to take a stab at some design changes with AI and some minor site improvements that I have always wanted to do. If you think the site looks much worse, please let me know . Some small improvements and quality-of-life enhacements: Look at me! I’m sidebar content I will undoubtedly abuse. I continued to try and give it my personal flair to avoid it looking like AI-slop but 🤷 A small entry in the footer to showcase the site is built with Nix. A Jekyll plugin that automatically creates source-sets for the images I use in my blog posts. A Jekyll plugin to create a short content hash for the stylesheets to avoid the browsers caching stale CSS. A Jekyll plugin that generates a little curved line for the masthead that is the of the page. Redesigned the layout to allow side-bar content.

0 views
Unsung 3 weeks ago

“Maze of pages, redirects, and confirmation emails”

Nikita Prokopov on his fun Tumblr-like site Grumpy Website that collects UI transgressions with light commentary: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/maze-of-pages-redirects-and-confirmation-emails/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/maze-of-pages-redirects-and-confirmation-emails/1.1600w.avif" type="image/avif"> Why log in when you have to, when you can instead experience the same Kafkaesque maze of pages, redirects, confirmation emails, copying codes, and searching for a second device—all a week in advance? I agree with authentication experiences being absolutely horrible, especially in the corporate context. But I think the “your login expires in 5 days” callout is actually positive. Your reauthentication will happen anyway according to the security regimen. Instead of it potentially surprising you at a wrong moment – for example just before, or in the middle of the presentation in front of a boss – you could get ahead on that process during the next moment of downtime, and have some peace of mind. I know Slack has a similar warning, although I don’t happen to have a screenshot handy; I imagine a few other places do, too. (However, that gesture doesn’t give apps permission to handle expiring credentials badly. There should be no excuse for losing anything the user is doing – for example writing a long comment – just because the reauthentication kicks in in the middle of them doing that. Even the app losing its mind for a while just as its separate parts are waking up to the reality of reauthentication at their own pace and throwing strange errors, but the login screen hasn’t reappeared yet, can be really confusing.) #attention #nikita prokopov #security

0 views
Julia Evans 3 weeks ago

Learning a few things about running SQLite

Hello! I’ve been working on a Django site recently, and I decided to use SQLite as the database. When I was getting started with using SQLite as database for a website I read a bunch of blog posts about how it is totally fine to use SQLite in production for a small site and I think it is totally fine, but what I did not fully appreciate is that SQLite is still a database, databases are complicated, and I do not know a lot about operating databases. So here are a couple of small things I’ve been learning about running SQLite. This is the 4th website I’ve used SQLite for, and I think this one is harder because with the power of the Django ORM I’ve been making the database do more work than I was previously without Django. I started by turning on WAL mode like all the blog posts said to do and hoping for the best. Today I was running a query (using SQLite’s FTS5 for full-text search) on a table with 4000 rows and it took 5 seconds. That seemed wrong to me: computers are fast! It turned out that what I needed to do was to run ! Immediately the problem query went from taking 5 seconds to like 0.05 seconds (or some other number small enough that I didn’t care to investigate further). I still don’t know exactly what went wrong in the query plan, but my best guess is that it was some sort of accidentally quadratic thing. generates “statistics” (I guess about the number of rows in each table? and presumably other things?) so that the query planner can make better choices. Maybe one day I’ll learn to read a query plan. Occasionally I’ve run into situations where I accidentally put a bunch of rows in my database that I don’t want to be there (for example completed tasks from django-tasks-db ), and I want to clean them up. What’s happened to me a few times in this case is: My approach so far has been to just do these cleanup operations in small batches so that I don’t need to do database queries that take more than 5 seconds to run. This whole experience has given me more of an appreciation for why someone might want to use a “real” database like Postgres which can have more than one writer at the same time though. Maybe in the future I’ll just take the site down for scheduled maintenance instead when I need to do this kind of thing, but I haven’t figured out a workflow for that yet. So far I’ve been using Django’s ORM to make any query I want without paying any attention at all to query performance and it’s mostly been going okay other than the thing. The database is pretty small (maybe 10000 rows?) and I expect it to stay pretty small forever, so I’m hoping that that plan will keep working. I’ve done SQLite backups a couple of ways. I don’t think I’ve actually tested restoring from my backups but I do usually try to monitor them with a dead man’s switch. way 1: restic way 2: litestream I started trying out Litestream recently because I felt like doing incremental backups might be more efficient: my restic backups were sometimes getting OOM killed, and I was a bit tired of it. Basically I just write a config file and run: I set in my config file in an attempt to retain some amount of history of the database but I have no idea if it works. I’ve been backing up to AWS, which is always a pain because it’s annoying to navigate the AWS console to generate credentials. Maybe one day I’ll move away to some other S3-compatible alternative. My current project only has one database, but one trick I used with Mess with DNS was to split the tables into three separate database files because I didn’t actually need my tables to be in the same db. I think it was helpful. Mess with DNS has been running on SQLite for 4 years now (since 2022) and it’s been great, I think the move from Postgres was a great choice for that project. It’s always kind of fun to see how long it takes me to learn sort of basic things about the technologies I’m using. I think I used SQLite for a web project for the first time in 2022 and I only learned that existed today! I imagine in a year or two I’ll be learning about some other very basic feature. Some blog posts I’ve looked at, other than the official docs: I run some kind of command to clean up the rows The command takes more than 5 seconds, since there are a lot of rows (though I still have some questions about why these DELETE statements are so slow honestly, maybe there’s a bunch of Python code running inside a transaction, I’m not sure) One of the other workers tries to write the database while this is happening, and times out after 5 seconds (I have a timeout of 5 seconds set) The worker crashes because it couldn’t write to the database and the VM shuts down The definitive guide to using Django with SQLite in production a gist on sqlite performance tuning

0 views
Unsung 3 weeks ago

“If HEIC has no haters I’m dead.”

Over on Bluesky, Melanie Walsh asks : Favorite and least favorite file formats? I’ll start. Favorite: TXT Least favorite: HEIC The answers – both replies and quote posts – are really interesting because most of the time they’re not about inherent capabilities of each format, but: Of course, Walsh put a finger on the scale with her initial example, but HEIC stands out as a favorite least favorite. I understand this is mostly out of its limited support, raising a question whether Apple spent the right amount of time socializing and incentivizing its adoption – even on a Mac, you can’t escape blank stares the moment you drag it into many websites/web apps: HEIC on the other hand, Apple’s way of making photos smaller and everything else more complicated than it needs to be. By the way HEIC is when you drag a picture from your Notes app into your email, and then it laughs in your face and is like sorry, girl, I’m HEIC!! I don’t do things like that!! I didn’t know I had a least favorite file format but yeah HEIC can fuck right off Sweet fucking hell fuck heic into the sun Reading the replies here makes me feel like I live in an oddly privileged bubble in an inverse of the usual meaning of privilege for being a poor Android-using mfer who has never seen a HEIC in their life and had to actually look that sh*t up. Least favorite is a toss up between HEIC (WHICH NOBODY ASKED FOR, APPLE) and WEBP Controversial but I hope everyone involved with HEIC only tastes soap instead of cilantro forever I agree with this person that WebP is much better supported than it used to, but it sometimes takes one link in the chain – cough Google Docs cough – for you to avoid a format forever. And, those are always lagging indicators. If a format didn’t work once in an important flow, it might take many years before you come back: all the people saying “webp” in the quotes might as well be fighting WW2 still. look for another grievance. please Some other fun answers: IF IT’S CALLED [C]OMMA [S]EPARATED [V]ALUES WHY DO I HAVE TO OPEN A WINDOW AND CHANGE THE DEFAULT DELIMITER OPTION FROM TAB TO COMMA ??!?!?! Favorite: MP3 (invented piracy, patents all expired, doesn’t need an FPU) Least favorite: DICOM (nightmarish metadata, too many possible image encodings, when it wants a 3D volume the solution is just “a bunch of files in a folder”, also IT IS A NETWORK PROTOCOL >:( ) Least fave: .R01, .R02, etc... – nothing needs to be split into multiple rar files! Please stop! The world has moved beyond this. Least favorite: can I count those awful pointer doc types Google uses, like .gdoc and .gsheet favorite: transparent PNG least favorite: transparent PNG that is not really transparent but just a fuckin checkered background I forgot about this meme: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/if-heic-has-no-haters-im-dead/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/if-heic-has-no-haters-im-dead/1.1600w.avif" type="image/avif"> For least fav I voted for GIF, having not only spent countless hours trying to make good-looking animated gifs that do not weigh tens of megabytes, look horrible, and cause performance issues… but also having worked on two different products (Medium and Figma) that had to swallow gifs made by others, and seeing engineers lose their minds peeking into their insides and how messy they were . To be fair, GIF comes from the late 1980s, and simply outlived its purpose. It’s a fascinating format that literally deserves a book written about it: the messy patent wars, the pronunciation, the technical format and many surprises hiding inside , even the word “gifs” transcending the format itself to mean “short animated memes.” To go back to the thread, a small pattern that I also encountered from time to time: Least favorite: .md, specifically when it’s used for Sega Genesis game roms. There’s already a type of text file type called .md, so Windows tries to open them in notepad. Just call it .gen instead, nerd. Favorite: TS, the one that opens in my IDE Least Favorite: TS, the one that opens in Quicktime Lastly, because of course someone had to do it: Favorite: Gaylord Archival® Reinforced Acid Free Manilla Least favorite: Office Depot Vertical Hanging Folders #encoding #graphics #software evolution how well supported it is in the general ecosystem? how painful it was last time I used it? who’s using it and for what? if there is one app I use it with, do I like this app? (interesting in the context of PDFs which some people love, and others hate)

0 views
Unsung 3 weeks ago

More absolutely strange Google shortcuts

I’m endlessly confounded (as a user) and fascinated (as a designer) when it comes the shortcut conventions in Google’s professional web apps. They seem… bad, but bad in a strange, inexplicable, enthralling way. Previously , we encountered this: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/more-absolutely-strange-google-shortcuts/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/more-absolutely-strange-google-shortcuts/1.1600w.avif" type="image/avif"> The lessons there were, primarily: don’t… do this, and also maybe don’t show it like this. Today’s entrant, from Google Drive, offers a different lesson: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/more-absolutely-strange-google-shortcuts/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/more-absolutely-strange-google-shortcuts/2.1600w.avif" type="image/avif"> Immediately, I have so many questions. Why a sequenced shortcut instead of something simpler, in a space where there aren’t that many shortcuts? Why Control of all things? On a Mac? Why is it so different than Google Docs in every way – don’t you all talk to each other? And why not a proper typographical symbol for Control (^ is not ⌃)? But there is also a mechanical lesson here. I’d encourage you to actually press any of these three shortcuts, and watch your fingers doing that. I bet you will observe one of two ways: Turns out, people are messy when it comes to modifier keys. That messiness was even encouraged from the very first day we breathed life into the very first modifier key. Most of 20th century typewriters had a full stop and a comma on both shifted and unshifted positions – pressing Shift was heavy early on, and this helped when punctuating all-caps sentences or preparing for a capital letter starting the next sentence. (Also, Shift Lock wasn’t as smart as Caps Lock is.) = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/more-absolutely-strange-google-shortcuts/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/more-absolutely-strange-google-shortcuts/3.1600w.avif" type="image/avif"> But even without that encouragement there are still two legitimately valid ways to understand “^C then F” – you release ⌃ before the second key, or after – but Google Drive only listens to the first one. Couple this with giving you zero feedback after ⌃C, and I won’t be surprised if many people try this sequence once, and give up assuming it’s just not working. So, it feels it’d be good to think about being extra forgiving here, the same way it’s good to think about “coyote time.” As always, please let me know if you see the method in this alleged madness . After all, the goal for this blog is not to blindly ridicule things, but to learn together through thick and thin. #google #keyboard ⌃ down, C down, C up, ⌃ up, F down, F up ⌃ down, C down, C up, F down, F up, ⌃ up

0 views
Unsung 4 weeks ago

My one (1) Medium secret

When I was at Medium, over a decade ago, I really enjoyed going deep on typography. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/1.1600w.avif" type="image/avif"> People seemed to generally enjoy what we did. Writers really loved automatic em dashes and range dashes, discovered the beauty of hanging punctuation, and as funny as it might sound today, the smart quotes were a huge hit, too. I was proud of the tight drop caps, the underlines brought me some notoriety, and we even supported ligatures at a time when not only this wasn’t the default, but it also had some mildly scary performance consequences. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/4.1600w.avif" type="image/avif"> But for every two things that worked well, there was also something that in retrospect proved to be me trying too hard, and had to be quickly undone. I was really excited about resurrecting pilcrows , but many users saw them as rendering or escaping errors. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/6.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/6.1600w.avif" type="image/avif"> I briefly added vulgar fractions to all the places where Medium rounded numbers, but that made those numbers confusing and weird in practice. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/7.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/7.1600w.avif" type="image/avif"> (And I already mentioned the strange, rare bug with system fonts , although I suppose there are always bugs.) = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/8.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/8.1600w.avif" type="image/avif"> It was an interesting calibration process. And somewhere in between successes and failures was one thing that I have never mentioned before, and one nobody ever brought up. I recently shared the story of 2015’s typographical redesign of Medium. As we were exploring the candidate typefaces, we fell in love with one in particular: Charter , a font designed by the industry legend Matthew Carter – and no, this is not a bug, Google Search switches to using Carter’s own Verdana to honor him. Charter had this perfect balance of “casual” and “refined” we wanted for Medium at the time. Unsurprisingly, it also came with a bunch of typographical niceties – among them lowercase (old-style) digits, which I really wanted: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/9.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/9.1600w.avif" type="image/avif"> But there was a problem. Those lowercase numerals came with a “medieval 1,” a particular style of a lowercase digit 1 that resembled an uppercase I. People hated it and were confused by it, thinking indeed that a bug caused a letter I to make its way to the numbers. No amount of pleading would get us to push that digit through. The backup plan was going with uppercase numerals, but I hated the idea; those digits felt so ugly and pedestrian to me – they were not just uppercase, but also monospace! It was a frustrating situation, being so close and yet separated from a warm Charter embrace by one glyph that it didn’t happen to have. And so… I drew one. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/10.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/10.1600w.avif" type="image/avif"> I, someone who has never ever designed a typeface, decided to vandalize Matthew “ The Most Widely Read Man In The World ” Carter’s typeface and plop in a new digit 1 of my own creation. = 3x)" srcset="https://unsung.aresluna.org/_media/my-one-1-medium-secret/11-framed.1600w.avif" type="image/avif"> The internal complaints stopped. Weeks later, we launched the new fonts, Charter front and center, my fresh non-medieval 1 attached. I don’t remember the exact details, but we found a way to do this that was compatible with the font’s licensing – and yet I never talked about it because… well, I think you can understand why. I believe my rogue 1 lasted until a subsequent redesign in 2022, long after I left the company. A decade in, I still don’t know how to feel about it. Did I save Charter as a candidate for Medium by mutilating it a bit, am I writing this post just to launder my own ego, or is this the equivalent of a perp coming back to the scene of the crime? Was I ambitious (laudatory) or ambitious (derogatory)? Maybe you can tell me. But I hope either way it makes for a fun story. #above and beyond #craft #hacks #marcin wichary #typography

0 views
Jim Nielsen 4 weeks ago

What’s an Icon in 2026?

As icons continue to change across Apple’s platforms, I have thoughts. They mainly revolve around two perspectives: Let’s see if I can articulate my thoughts. In “Create icons with Icon Composer” from WWDC 2025, Lyan Bewry from Apple’s Design Team gives the rationale for why developers should use Apple’s new Icon Composer: Icon design is moving from a past of simply static images, to a future of expressive, multi-layered artworks that respond to user input and adapt between appearances. They’ve become a much richer and more integrated experience on-device. Catch that? Icons are moving from a “static” past to an “expressive, multi-layered […] much richer” future. You may have noticed this in some of Apple’s latest OS releases, how lighting effects, customizations, etc., can all affect what an icon looks like at any given moment within the operating system. So what are these files made by Icon Composer? In the Accidental Tech Podcast episode 699 “Not the Correct Squircle” John Siracusa talks about some of the technical details and differences between app icons in macOS 26 (Tahoe) and 27 (Golden Gate): These files, this format that Apple came up with, it’s a bunch of resources and a recipe. So it’s like bitmaps, vector images, layers, recipes and effects. That’s what it is. And these icons are assembled on the fly by the operating system. It doesn’t burn up bitmaps of them. I take your ingredients, I assembled them, I composite them, I apply your layer effects, and then eventually it renders a bitmap that it keeps in memory somewhere. Who is thinking about backwards compatibility in their icons? Tahoe’s effects are different than 27’s effects […] And also, 27 has effects that 26 doesn’t support. And 26 won't even read the files from 27, which makes everything complicated. Complicated indeed. As noted, the days of a single, static image for icons are over. An app icon is no longer a PNG file. It’s a bit of a Schrödinger’s icon if you will. There’s no longer a universal answer for “What does your app icon look like?” An icon is simultaneously light, dark, glass, tinted, etc.. Only once it is “observed” — that is rendered at runtime on a device with settings applied (user preferences, device angle, etc.) — can you really know what it looks like. An icon now has a runtime. I don’t know. Icons are effective because of their ability to be quickly recognizable and memorable. Visual simplicity and consistency support that. Making something more “expressive” and “richer”, to me, means conveying more. But icons are meant, to a degree, to convey less. Only the essential. That’s what makes them effective. There’s definitely a point where, the more they convey, the less effective they are at their purpose. The more you move away from a singular, visual representation, the more room there is for confusion and greater cognitive effort for discernment. Take, for example, Apple’s Phone app. What’s the icon for it? Can you picture it in your head? It’s a green icon with a white phone glyph. That’s what it was in the original iPhone keynote (and it’s what the Phone app will always be to me). Iconic! But wait! Now it’s also a black icon with a green phone glyph if you’re in dark mode. And there’s more! It’s a clear glass icon with a phone glyph if you’re in clear mode. And! It’s [insert color here] with a phone glyph if you’ve tinted it. Consistent color is a strong ingredient in aiding memorability and recognizability. Look at Coke: Simplicity matters. It aids recognizability and memorability. If you start making it more complicated and more varied, you lose what made it simple, recognizable, and memorable to begin with. And what are app icons but visual tools for immediate recognizability? Anyway, now that app icons have a runtime and will increasingly vary in their appearance, I’m not sure how to archive them anymore. This story is still developing… Reply via: Email · Mastodon · Bluesky What I think of icons as a long-time user of Apple’s platforms. What I think of icons as a digital collector and physical archivist of icons. Red can? Coke Black can? Coke Zero Silver can? Diet Coke

0 views

Establishing an Identity

If you’ve followed me on RSS for any amount of time, first off, thank you so much! Second, you may not have noticed how often this site changes. RSS protects you from the near-monthly changes that my mad scientist side makes to this site. This year alone, ThatAlexGuy.dev has been powered by 11ty, Hugo, plain HTML, Bear, Micro.blog , and Pure Blog. My files have sat on OpenBSD Amsterdam, DigitalOcean, and a Laravel Forge VPS. I’ve written new articles and lost old articles in migrations. My site has switched appearance more frequently than a Bian Lian (变脸) performer! I’ve come to realize I’ve been seeking both an identity and a voice. I want an outlet that reflects my interests, my background, and my day-to-day, but that’s more than what I could accomplish on something like Mastodon. All that brings us here, iteration 4 (or 8, or 15, or 16, I can’t remember). There are a few key differences and intentional choices that reflect where I want ThatAlexGuy to go. Building a new experience that will stick and satisfy the goals in my head won’t be easy, but here are the guiding pillars that are to shape what’s coming next. I have a desire to create in-depth, well-researched, and potentially interactive content. Many of my current posts come with a “1-minute read” tag. I want to change that. I’ll be digging into topics with greater detail, cross-referencing multiple sources, and (hopefully) interviewing others. As a result, I’ll be posting less frequently, but my new goal is quality over quantity. Regulars on my site will be aware of my “Photo Journal” series in which I posted a set of photos around a theme (macro, nature, Gameboy Camera ). I want to continue building my photography skills through the incorporation of high-quality photos in my articles. While text sets the tone, visuals set the atmosphere in an article. Here’s the big tomato, as they say (nobody says that): defining what this site represents. That means setting the tone and defining how topics string together to form a consistent narrative. I’ll be figuring this out for a while, but I want to leverage my interests such as indie technology, vintage computing, time away from the screen, photography, and Chinese culture. So what’s changed so far? Quite a bit! First, ThatAlexGuy.dev is now run by Ghost.org . For myself, this means less time in the technical weeds and more focus on writing. For readers, it opens the doors to a wider audience. Email newsletters are a more accessible way to stay up-to-date on new articles. Don’t worry though, RSS isn’t going anywhere! In fact, I managed to fix the broken RSS feed URLs from previous migrations (hopefully)! I’ve started to define the personality of the new site. I pulled background and accent colors from one of my favorite atmospheres in a game (Sprout Tower in Pokémon Gold). Using my iPad, I’ll be creating article images that give a calligraphy + hand-painted vibe. I’ve also brought in my Chinese name for the logo(小艾 - Little Alex). I’m working on my first longer-form article. It probably won’t be great, but first attempts never are. From there, I hope to refine my writing, researching, and supporting photography.

0 views

Wiki, Wittgenstein, and Wits

Read on the website: So I was considering starting a wiki. But it seems there are some unsurmountable value mismatches with me and wikis. So here’s a small reflection piece engaging Wittgenstein, literary theory, and a straw man idea of wikis.

0 views
David Dodda 1 months ago

Why Don’t Websites Put All Their Images Into One Giant JPEG? (Nerd-Sniped by My Brain)

I had a simple question: Why do websites load lots of individual images instead of stitching them into one giant image and cropping out the pieces they need? At first glance, an image atlas sounds great. Instead of this: You create this: Then each UI tile crops a specific region from the atlas. That would mean: fewer network requests images arrive together no staggered popping maybe better perceived loading maybe less request overhead Not a new idea by any means. Games and UI libraries have used sprite sheets and texture atlases forever. The question is: why isn’t this the default for websites? I compared three approaches: Individual optimized images 14 separate optimized JPG files rendered as normal elements Canvas atlas one stitched atlas JPG each tile rendered by cropping from the atlas into CSS background atlas one stitched atlas JPG each tile rendered with , , and The atlas was regenerated from the same optimized images, so the comparison was more fair. NOTE: I ran the experiment by hosting it locally. so all the number you see are when you have the application served using a python server running locally. If you want to poke at it yourself, the experiment is live here: https://daviddodda.com/experiments/img-atlas/ note: make sure you disable cache. try each version a couple of times. I focused on three headline metrics. How many bytes were downloaded? When did the last required image resource finish downloading? When was the image grid actually ready to see? This last one matters because network completion is not the full story. The browser still has to decode images, rasterize, paint, composite, and show pixels. On a remote machine running Chromium, all files hosted locally, 10 runs each: The surprising result: The CSS background atlas was the fastest to visible. The atlas had a clear network advantage: Well, one larger request has less overhead than many smaller requests. This effect is especially visible when the server/browser are using less optimal connection behavior. In my test, Chromium reported for the local server, so request overhead was more obvious than it would be under HTTP/2 or HTTP/3. With modern HTTP/2 and HTTP/3, many individual image requests are less painful because requests can be multiplexed over one connection. But request overhead still exists. The individual images transferred: The regenerated atlas transferred: Because an atlas is a rectangle. Real images have different aspect ratios. When you pack them into one big rectangular sheet, you often create empty space. In my case: That is about 31% extra pixel area. So even though the atlas used one request, it transferred more data and required the browser to decode a bigger image surface. The canvas atlas looked like it should be fast (thought modern hardware was fast enough). It loaded one atlas image, then cropped each tile into a canvas. But the results were poor: The breakdown showed: The actual JavaScript canvas drawing was not expensive. The expensive part was making all those canvas results visible. That means the bottleneck was not: It was the browser’s later paint/composite work. The CSS background atlas used normal DOM elements: This was much faster: The breakdown: The decode cost was still there. But paint/composite was dramatically better than the canvas version. So if you are going to do image atlasing in normal web UI, CSS backgrounds may be much better than drawing many cropped canvases. They are great for: emoji sheets game textures small repeated UI assets known fixed-size tile sets maps or tile-like interfaces cases where all assets are needed immediately They are less great for: photo galleries blog images user-generated content responsive images content-heavy websites long scrolling pages frequently changing assets now, don't go getting any ideas about rewriting your website's image pipeline to use image atlas. here are some reason why it's a really bad idea. With individual images, the browser can load only what is needed: With a giant atlas, loading one image means loading everything in that atlas. That is great if you need everything immediately. It is terrible if the user only sees 5% of the images. The web has powerful responsive image tools: The browser can choose the right image for the device, viewport, DPR, and network. With a giant atlas, this becomes much harder. You may need multiple atlases: The combinatorial complexity gets ugly quickly. Atlases require packing. Packing creates waste. If the images have different shapes, the atlas may contain a lot of empty or unused area. Even a good packing algorithm cannot always avoid this. In my test, the atlas had about 31% more pixel area than the individual images. With individual images: Only that image needs a new URL/cache entry. With an atlas: The whole atlas cache is invalidated. That is bad for websites where content changes often. Browsers are good at prioritizing resources. The hero image can be high priority. Below-the-fold images can be lazy. Tiny thumbnails can wait. With a giant atlas, everything has one priority. You cannot easily say: The atlas is all-or-nothing. A compressed JPG might be 2 MB on the network, but decoded pixels are much larger. Decoded RGBA memory is roughly: A large atlas can become a huge decoded surface. In my first broken atlas attempt, the atlas was: That is around: Even if the file downloads quickly, that is a lot for the browser to decode, rasterize, and paint. An has natural semantics: A CSS background image is decorative by default. If the image is meaningful content, you need to rebuild semantics with ARIA or hidden text. That is doable, but it is extra work and easier to get wrong. Browsers have spent decades optimizing: If you use an atlas, you bypass some of that machinery and take on more responsibility yourself. Sometimes that is worth it. Often it is not. Every approach has its niche use case (shocker). My brain nerd-sniped me into exploring and writing about this. It was fun seeing the cute animals load in though. fewer network requests images arrive together no staggered popping maybe better perceived loading maybe less request overhead Individual optimized images 14 separate optimized JPG files rendered as normal elements Canvas atlas one stitched atlas JPG each tile rendered by cropping from the atlas into CSS background atlas one stitched atlas JPG each tile rendered with , , and emoji sheets game textures small repeated UI assets known fixed-size tile sets maps or tile-like interfaces cases where all assets are needed immediately photo galleries blog images user-generated content responsive images content-heavy websites long scrolling pages frequently changing assets

0 views
Unsung 1 months ago

Frozen in time

A few readers wrote in response to me sharing Panic’s blog to say that they witnessed online publications doing the same. Here’s a 1993 essay by William Langewiesche from The Atlantic Online (sic!) that’s still on the web – which, by the way, you should read because it’s really great writing – juxtaposed with a screenshot of a 2026 Atlantic essay on the same machine: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/1.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/2.1600w.avif" type="image/avif"> Likewise, here is a BBC News article from 1997 , and another one just from today : = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/3.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/frozen-in-time/4.1600w.avif" type="image/avif"> I do see those as something different, though. The old essays here are basically preserved as they were, which you can tell by the tiny images, pixel fonts, narrow widths, and so on. They’re likely the output of contemporaneous CMS frozen in time, functionally equivalent to a “Save As…” command. This is better than those articles disappearing altogether, and better still than them being carelessly converted in bulk to a more modern CMS, resulting in formatting mistakes, broken images, and missing context. But what I appreciated about Panic’s approach is that it felt unified with the rest of the blog. In a way, it was less like preservation “as is” and more like “remastering” – ask any Star Wars fan about the difference – with slight updates to fonts, more thorough integration, and thinking about readability on smartphones that didn’t exist in the 1990s. Of course, compounding the difficulty of online preservation, “as is” in the computer realm doesn’t really exist; even The Atlantic Online’s 33-year-old HTML is served using modern fonts via crisp and tiny pixels 1993 would die for – but even if it’s increasingly more and more possible, you also probably wouldn’t want to emulate an old, flickering CRT and Internet Explorer 3 to read it. On the web, just like elsewhere in computing , you truly can’t go home again. Thanks to Phil Gyford for a few examples. #emulation #history #web

0 views
Kev Quirk 1 months ago

📝 2026-06-23 12:58: Create one of those Uses pages. Still a work in progress, but there's a good...

Create one of those Uses pages. Still a work in progress, but there's a good chunk of the stuff I use on there now. https://kevquirk.com/uses Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
Unsung 1 months ago

“Don’t entangle emulators in infringement events that are visible from space.”

A funny and occasionally spicy 15-minute video by Nerrel from October 2024 about some of the nuances and legal fights surrounding Nintendo’s fight with community-made Nintendo emulators: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/dont-entangle-emulators-in-infringement-events-that-are-visible-from-space/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/dont-entangle-emulators-in-infringement-events-that-are-visible-from-space/yt1-play.1600w.avif" type="image/avif"> The video paints Nintendo in the harsh light, highlighting their double standards and willingness to throw their corporate legal weight around just to squash the challenges before they go to court, despite court precedents ruling against them. The video also talks about software preservation – this is the part that feels very important to me – and I also learned things about piracy, DCMA, and modern video game encryption. Just to highlight the versatile value of emulation, in another corner of the emulation universe, I found this fascinating project: a web page called Yes we scan , made by George MacKerron, that promises scanning directly from the browser – for example if you have an old scanner unsupported by your modern OS. And… it actually works! It combines WebUSB with an interesting technique: Your web browser emulates a whole PC running Linux with open-source scanning software (SANE). It connects that to your scanner via WebUSB. If you are interested, the details page has more… well, details . MacKerron also wrote Printervertion that allows you to print directly from web, too, even if your operating system abandoned your vintage printer. The way I understand this, both efforts basically invite an alternative operating system that might be more supportive to take a stab at scanning or printing, and do it in a friendly and sleek way through emulation. It’s kind of incredible this is even possible. #emulation #games #hacks #hardware #youtube

0 views
Xe Iaso 1 months ago

I hate compilers

Anubis is about to get WebAssembly-based proof of work checks so that administrators can use a non-SHA256 proof of work method to protect their websites. Part of the implementation goals of this work is that the check logic is defined in one place on both client and server. The client and server will then hook into the WebAssembly in order to make sure they're running in lockstep. However, one small problem comes up. What do you do when the client has WebAssembly disabled? I really don't want to de-facto lock people out of websites. Anubis exists in an impossible balance of user experience, administrator experience, and developer experience and any change to any of these factors disrupts the balance for other factors. To work around this and also fulfill the goal of having check logic defined once , I decided to take inspiration from the legendary talk The Birth and Death of JavaScript and just recompile the WebAssembly to JavaScript. Sure, the resulting JavaScript will be slower than the equivalent WebAssembly (even more so because disabling WASM usually disables the JavaScript JIT, the thing that makes JavaScript fast), but it will finish eventually . Hopefully it will be more efficient than the existing JavaScript is on lower end hardware, but research is required. Luckily enough, the tool I need ( from the binaryen project ) is packaged in Linux distributions. The bad news is that distributions ship ancient versions of it that don't get the same output as the version on my development machine's copy from Homebrew . In order to really make sure that the output of this is deterministic (essential for reproducible builds), I need to bundle a copy of . So I did that by building a version of compiled to WebAssembly with wasi-sdk . The rest of the article is the tale of reproducibility woe that lead to the implementation I ended up with. Buckle up and enjoy the ride! Back up a sec, this doesn't make sense to me. If you have the same bytes of input to a compiler, you should get the same bytes of output assuming that the compiler flags, target, and other platform details are controlled for right? A compiler is just a deterministic function of input source code becomes output bytecode, right? lol you'd think, but no, it's not. In theory it is (and for small scale compilers it definitely is), but in practice compilers are strange and complicated beasts containing multitudes that no mere mortal can fully comprehend on their own. There are a shocking number of ways to accidentally create nondeterministic output when doing C/C++ development. One of the easiest is to use the builtin and macros to stamp a build with the time the compiler was executed at: Building and running it once gets me this: Another time it gets me this: Even though the source code had the same bytes , the output of the compiler was wildly different. In order for users and packagers to trust the binaries of I'm committing to the Anubis repo, I need to make sure that you can build the same version I built, down to the same bytes . For an added bonus, you should be able to build this on your machine and get the same bytes I got. That sure does sound like a great ideal, it would be horrible if something unforeseen came up to ruin it! Among other tools like , binaryen has a bunch of other useful tools such as . optimizes WebAssembly compiler output to let you eke out more performance. This doesn't work in every circumstance, but when it does work it makes a huge difference. As such, clang shells out to when doing builds. This normally makes sense, but in this case it caused builds to fail on my DGX Spark because its version of is too old: Compared to my workstation which installs from Homebrew : Turns out that wasi-sdk and binaryen rely on the WebAssembly Exceptions extension . This is a reasonable thing to assume given that wasi-sdk mostly assumes you're building things for web browsers and 93.86% of browser users have a browser engine new enough to support it. C++ is also one of the main places where exceptions are used, so I guess WebAssembly-native exception handling removes a lot of boilerplate here. Both wasmtime and wazero require you to flag into exception support. This is fine; we can just pass to wasmtime and use a custom runner harness for wazero. The annoying part is what happens when my arm machine's anemic build of wasm-opt sees exception handling instructions, causing it to exit. This made the build fail. The solution was to pass at the linking step. This removed one angle of irreproducibility. I guess in the future we could make it use the version of it just built to optimize the output, but that may be a premature optimization for now. The version of clang that I use to compile has some address-sensitive code generation hiding in its exception handling path. Raw pointer values leak into the order a handful of blocks come out in. This surfaces as every build differing from the next by about 29 bytes: To make this easier to spot, here's a partial disassembly: The computation is nearly identical, but the byte order is just different enough to also make the catch references differ. This also fires when you build this pinned version of wasm2js on arm64 machines because its pointer iteration order is different from it is on my workstation. To work around this, I took two steps: I also made a CI job ensure this: To be extra sure, we have this job run on both x86_64 and arm64 hosts. I'd really love to have this be reproducible across hosts, but that's an upstream LLVM bug that I am not powerful enough to tackle. If you work on LLVM and are reading this, it would be nice to set a seed of some kind to ensure that this iteration order is fixed across architectures. At the very least builds are deterministic within architectures. This may have to be good enough for now. Disable address-space randomization for this build using . Create known good sha256 checksums for both x86_64 and arm64 via building this program on machines I trust.

0 views
Unsung 1 months ago

Fontificator

I thought about this the other day, and I thought it’d be fun to share this internal tool I made over a decade ago to aid with exploring options for Medium’s typographical redesign. It’s called Fontificator. You can play with Fontificator here (desktop browsers only), or watch the likely confusing video below: The motivation for building Fontificator came from two observations: With Fontificator, I was aiming at this Doug Engelbart-esque notion of one hand on the keyboard + one hand on the mouse, and the UI where it was only necessary to point to an element, and the keys under your other hand would start working immediately – no clicking needed: This way, we could move really, really fast. To accommodate that, Fontificator always tried to keep the current item under the cursor by counter-adjusting scroll position as needed. On top of it all, a few more shortcuts: You can also edit any text if you are so inclined, and also drag in any font file from your computer onto a paragraph – then that font becomes part of the F/G stack. (Bernino Sans and Freight Text were the starting fonts before the redesign.) On the left, you can also see a naïve mobile preview – there was also more sophisticated on-smartphone preview, but I removed it from this restored version. Fontificator was literally made for an audience of 2–3 designers (and perhaps 1–2 stakeholders in read-only mode), and it was surprising to me how quickly one could master this strange tool, have fun with it, and feel the entire typography on the page becoming much more malleable. We also put up a more “traditional” list of contenders on the wall… = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/fontificator/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/fontificator/2.1600w.avif" type="image/avif"> …but it was in Fontificator where we learned the most. I love internal UIs because they allow you to go very wild and very tactical. If you have one you’d be willing to share (maybe it, too, is on the other side of the statute of limitations?), or one you already wrote about or spotted someone else doing so, please let me know! #internal ui #typography font previews on type foundry sites were generally too limited to get a real sense of how a certain typeface feels, and it was best to see a font in situ, often an extremely tiny nuance – like adding some letter spacing, or messing with line height – was what separated something that was promising from something that seemed very far from working. F and G to change the font, – and + for font size, ← and → for letter spacing, ↑ and ↓ for line height, < and > for opacity (for all the above you can hold Shift for bigger moves), and, there are a few more shortcuts you can see at the top. ⇥ and ⇧⇥ move very quickly between different types of stories so you can preview that, Space compares to the original/​current version, 1–9 allow you to switch to different “slots” so you can have various presets ready to compare, Esc hides the toolbar for maximum immersion,

0 views
iDiallo 2 months ago

Please, use a link!

This is a rant. It didn't start today, but I think I've reached the end of the line. The straw that broke the camel's back, so to say. I used an internal tool for the first time. I logged in and navigated through the web app, making some updates here and there. All was well. But then I made the mistake of wanting to go back to the initial dashboard. I clicked the back button, and instead of returning to the previous page, I saw Chrome's default tab page staring right back at me. How is it possible? I had navigated through at least a dozen pages, yet one back button click and the web app was completely gone. If you've ever experienced something similar, it's probably because you were using a single-page app. Nothing wrong with single-page apps, of course, but over the years I've concluded that people who only know how to build single-page apps don't know what a link is. So let's start with examples of what a link isn't. Not a link. It's a div with an event handler. You can style it all you want, but it's not a link. This may be a button, but it is not a link. With the advent of React, this has become so common. Because it's called a button, learners naturally gravitate toward it to link different pages. But there is worse. This almost feels intentional. As if the developer is teasing me. Why would you use an anchor tag but then omit its most important attribute? Here is what a link is supposed to look like: That's it. Simple. You don't have to add any configuration for the browser to support it. You don't even have to style it. All user agents have sensible default styling for the different states of a link: unvisited, visited, and active. It works well with browser history. On desktop, when you hover over it, you get a preview of the destination URL in the bottom-left corner of your screen. On mobile, you can press and hold to get several options on how to open it. You don't even have to worry about accessibility. It just works. But when a developer is deep in their React app thinking about functionality, they might say, "When you click this button, go to the home page." They will naturally think of as an event. And since it's a single-page app, they're thinking about state, not a page. They might write something like this: This is already bad enough. But depending on how the function is implemented, it can make or break the entire browser history. In the internal tool I was using, was essentially replacing the current URL with the new one using . You can avoid all of these issues by just using an anchor tag. If you need it to play nicely with your React app, React Router has a component. Please, just use a native link and you won't have to worry about anything else.

0 views
Kev Quirk 2 months ago

It's Just Broken: Oh WordPress

by Pup On Tech In a recent post, the Pup ON Tech perfectly captures the absolute nightmare that is building a self-hosted WordPress site. What starts as a simple VPS setup quickly devolves into a bloated mess of heavy themes, dozens of conflicting plugins, and rigid page builders. By the time you’ve fought with broken caching layers and terrible performance, you realise that fixing the bloat defeats the entire purpose of using WordPress. Read post ➡ WordPress really is a nightmare, and this post by Pup On Tech really capsulated that! Should have just used a flat-file system or an SSG from the start. 🙃 Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views