Latest Posts (15 found)
David Bushell 4 weeks ago

Better Alt Text

It’s been a rare week where I was able to (mostly) ignore client comms and do whatever I wanted! That means perusing my “todo” list, scoffing at past me for believing I’d ever do half of it, and plucking out a gem. One of those gems was a link to “Developing an alt text button for images on [James’ Coffee Blog]” . I like this feature. I want it on my blog! My blog wraps images and videos in a element with an optional caption. Reduced markup example below. How to add visible alt text? I decided to use declarative popover . I used popover for my glossary web component but that implementation required JavaScript. This new feature can be done script-free! Below is an example of the end result. Click the “ALT” button to reveal the text popover (unless you’re in RSS land, in which case visit the example , and if you’re not in Chrome, see below). To implement this I appended an extra and element with the declarative popover attributes after the image. I generate unique popover and anchor names in my build script. I can’t define them as inline custom properties because of my locked down content security policy . Instead I use the attribute function in CSS. Anchor positioning allows me to place these elements over the image. I could have used absolute positioning inside the if not for the caption extending the parent block. Sadly using means only one thing… My visible alt text feature is Chrome-only! I’ll pray for Interop 2026 salvation and call it progressive enhancement for now. To position the popover I first tried but that sits the popover around/outside the image. Instead I need to sit inside/above the image. The allows that. The button is positioned in a similar way. Aside from being Chrome-only I think this is a cool feature. Last time I tried to use anchor positioning I almost cried in frustration… so this was a success! It will force me to write better alt text. How do I write alt text good? Advice is welcome. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

1 views
David Bushell 1 months ago

Croissant Favicons and Tauri Troubles

Croissant v0.4 is out! I fixed a few minor bugs and added favicons. I’ve had a surprising amount of feedback. I wasn’t expecting anyone to care about an app I designed for myself. Thanks to all who managed to navigate my contact form . Croissant’s design philosophy is vague because I’m just making it up as I go along. Essentially it’s an experiment in keeping it simple. Not “MVP” because MVP is nonsense — and not “minimalism” because that does not mean good. Croissant is just basic and unbloated. The three most requested features have been: Folders is never going to happen, sorry! That would literally double the codebase for a feature I’d never use myself but have to maintain. Bookmarks is possible. Croissant is just a reader not an organisation tool but I see the value of “read later”. Not sure how this will work yet. I do not want to build a bookmark manager. Favicons has happened! When I declared “no icons” I was talking about the craze of UI icons everywhere . Icons without labels! Meaningless béziers from self-important designers that leave the rest of us saying “WTF does this button do?” Favicons actually serve a purpose and improve the design. Favicons are a simple feature but were not easy to implement. Tauri is causing me headaches. I’m starting to rethink if I should continue the native app wrapper or focus solely on the PWA . The web platform always wins. How many cautionary tales must I read before I accept the truth! Why am I wasting time debugging Tauri and Apple’s webview for issues that don’t even exist in Safari? Wasted time and energy. I’m accruing non-transferable knowledge in my (very) limited brain capacity. Croissant v0.4 might be the last native macOS version. It only exists because the PWA requires a server proxy (CORS) that has privacy concerns . Maybe I can add a “bring your own proxy” feature? Podcast feeds include an image tag but basic RSS does not. There are standardised ways to provide an image/icon with and web manifests . These both require parsing the website’s HTML to discover. I’m relying on “known” root locations; namely: These locations aren’t required for either icon but browsers check there by default so it’s a good place to guess. For the 200-ish blogs I subscribe to I get a ~65% success rate. Not ideal but good enough for now. I really want to avoid HTML spelunking but I may have to. Expect an improvement in the next update. For now a croissant emoji is used for missing icons. I’m using the Offscreen Canvas API to generate a standard image size to cache locally. Favicons are currently cached for a week before refreshing. First I tried using a service worker to cache. Tauri was not happy. Second I tried using OPFS with the File System API. Tauri was not happy. I dumped Base64 into local storage and Tauri was OK with that but I wasn’t because that’s horrible. Finally I went back to IndexedDB which is perfectly happy storing binary blobs. So you can see why Tauri is on thin ice! I don’t want tech choices dictating what parts of the web platform I can use without jumping through non-standard hurdles. That’s all for now. I hope to have another update this year! Visit CroissantRSS.com to download or install Croissant as a progressive web app. Oh yeah… and I kinda messed up deployment of the PWA service worker so you may need to backup, remove, and reinstall… sorry! Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
David Bushell 1 months ago

RSS Club #004: Ghost of Autumn

The summer solstice has long past which means it’s Christmas soon if the local supermarkets are to be believed. I refuse to eat a mince pie before November at the earliest. Daylight savings time will come to an end (impossible to know exactly when). For the UK that means dark mornings, dark evenings, and grey skies around noon. It’s time to hibernate! I can recommend a bit of entertainment to wile away the winter. Imperium by Robert Harris is the first book of the Cicero trilogy. Although fiction, this novel is based upon real events at the end of the Roman Republic. The series follows the political career of Marcus Tullius Cicero . A fascinating era of human history. Move over Wordle, Connections is the new daily brain teaser. New to me anyway. If puzzle numbers are to go by it’s been around for years. Presumably inspired by the Connecting Wall you must make 4 groups from 16 words. Green is supposed to be the most obvious but I keep finding the blue group first. I’ve just finished playing Ghost of Yōtei the spiritual sequel to Ghost of Tsushima . If I rated Tsushima 5 stars I’d give Yōtei 4 stars. I achieved the platinum trophy for 100% completion in both games. The game is beautifully designed and fun to explore. Fair warning: moderate spoilers ahead. Yōtei is a great game but the story doesn’t hit the same emotional level as Tsushima. The ending fell flat for me and overstayed its welcome. The antagonists progressively lost their mystique until they became boring. Their repeated escapes were eye-rolling. It made Atsu look dumb and the Matsumae clan comically inept. Plot points are forced and pacing is criminally ruined by bad open world design. They front-load the starting area with the most side activities and then almost immediately move the main quest elsewhere. Ignore content, or ignore story? You can fast travel back and forth of course but it ruins the immersion. I played 20 hours and only saw two cutscenes. Most side characters are relegated to vendor NPC level which was disappointing. I’m left confused as to what purpose the wolf served? Despite these issues it was an experience worthy of the hours invested. As we know the true game is finding the tengai hat and fundoshi armour and terrifying the local samurai. I’m afraid I did not dare witness the final cutscene in this attire. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
David Bushell 1 months ago

What is a Linux?

Do you build websites like me? Maybe you’re an Apple user, by fandom, or the fact that macOS is not Windows. You’ve probably heard about this Linux thing. But what is it? In this post I try to explain what is a Linux and how Linux does what it be. ⚠️ This will be a blog post where the minutest of details is well actually-ied by orange site dwelling vultures. I’ll do my best to remain factual. At a high level Linux is best described as an OS (operating system) like Windows or macOS. Where Linux differs is that its components are all open source. Open source refers to the source code. Linux code is freely available. “Free” can mean gratis ; without payment. But open source licenses like GPL and MIT explicitly allow the sale of software. “Free” can also mean libre ; unrestricted, allowing users to modify and redistribute the code. Linux software is typically both free and free. You may see acronyms like OSS (open source software), and FOSS/FLOSS (free/libre and open source software), emphasising a more liberal ideology. Some believe that non-free JavaScript is nothing short of malware forced upon users. Think about the sins you’ve committed with JavaScript and ask yourself: are they wrong? Linux and OSS is a wonderful can of worms with polarising opinions. We can break down Linux usage into three categories. Linux can be “headless” meaning there is no desktop GUI. Headless systems are operated via the command line and keyboard (except for the occasional web control panel). This is the backbone of the Internet. The vast majority of web servers are headless Linux. “Desktop Linux” refers to the less nerdy experience of using a GUI with a mouse. Linux has never done well in this category. Depending on whom you ask, Windows (with a capital W) dominates. Steam survey puts Windows at 95% for gaming. Other sources are more favourable towards macOS reporting upwards of 15%. Linux is niche for desktop. Some will claim success for Linux in the guise of Android OS . Although technically based on Linux much of Android and Google’s success is antithetical to FOSS principles. SteamOS from Valve is a gaming Linux distro making moves in this category. Embedded systems are things like factory robots, orbital satellites, smart fridges, fast food kiosks, etc. There’s a good chance these devices run Linux. If it’s Windows you’ll know by the blue screen and horrendous input latency. That was four categories, sorry. Linux is not one operating system but many serving different requirements. If Bill Gates created Windows and Steve Jobs oversaw macOS, who’s the Linux mastermind? Linux is named after Linus Torvalds who is still the lead developer of the Linux kernel. But there is no Microsoft or Apple of Linux. Due to its open source nature, Linux is more like a collection of interchangeable pieces working together. There is no default Linux install. You must choose a distribution like a starter Pokémon. Linux distros differ in their choice of core pieces like: The Linux kernel includes the low-level services common to all Linux systems. The kernel also has drivers for hardware and file systems. Each distro typically compiles its own kernel which means hardware support can vary out of the box. It’s possible to recompile the kernel to include modules specific to your needs. Linux distros can exist for niche and specialised use cases. OpenWrt is a distro for network devices like wireless routers. DietPi is a lightweight choice for single board computers (a favourite of mine). Distros exist for seasoned nerds. Gentoo Linux is compiled from source with highly specific optimisation flags. NixOS provides an immutable base with declarative builds. If no distro meets your requirements, why not build Linux from scratch? You can find all sorts of weird and wonderful distros on Distro Watch . If you consult the distro timeline on Wikipedia you can see an extensive hierarchy. It’s overwhelming! Know that most are hobbyist projects not maintained for long. They’re nothing more than pre-installed software, opinionated settings, and a wallpaper. Distros like Debian and Arch Linux offer a more generalised OS. They provide the base for most commonly used distros. RHEL (Red Hat Enterprise Linux) also exists for the corporate world. From Debian comes Ubuntu and Raspberry Pi OS . Ubuntu desktop is by far the most popular distro for day-to-day use. Ubuntu makes significant changes to Debian and provides its own downstream package repository. Where should you start? You’ll get some crazy bad answers. Just try Ubuntu. It has the “network effect” and you’re more likely to find support online. This advice is likely to elicit the most comments! Desktop Linux can look wildly different across distros. There is no universal desktop GUI like you’d find on Windows or macOS. KDE offers the classic Windows-like experience. Gnome is more akin to macOS. XFCE is a lightweight option. Hyprland strips back the GUI using a tiled window presentation. There is a shortage of design and accessibility expertise within FOSS. Linux can be ugly and inaccessible at times. If you like design perfection Linux can make your eye twitch. On the plus side, you’re not stuck with a vendor-locked experience. Desktop environments provide hundreds of dials to customise their appearance. Want a start menu? You can add one! Hate the dock? Remove it! Some parts of Linux are even styled and scripted with CSS and JavaScript. Distros come with a package manager (think NPM). This is the main source of system updates and software. On Debian-based systems you’ll find commands. Arch-based systems use . Distros may include a custom GUI and auto-update feature for those scared of the command line. Linux has multiple upstream package repositories. If you run on Debian you’ll get an old version (politely referred to as: “stable”). In comparison, running on Arch gives you the cutting edge, likely compiled from Github last night. Remember that almost everything around Linux is open source. You’re free to compile and install software from anywhere. Software maintainers often provide an install script. See Node.js for example: To download and immediately execute a script from the Internet is insanely insecure! You’re suppose to vet the code first but nobody does. Every Linux system is different so software support can be tricky. Containerised software has become a popular distribution method to solve compatibility issues. Flatpak is the leading choice and Flathub is a bountiful app store. AppImage is a similar project. Ubuntu is trying to make Snaps happen in this space. Hopefully I’ve explained what Linux is! But is it for you? Linux can be a great OS if you’re a web developer writing code. All the familar tools should be available. If you like to tinker, Linux will be a never-ending source of weekend projects . Linux has unrivalled backwards compatibility and avoids the comparable bloat of Windows and macOS. Older hardware can feel surprisingly fresh under Linux. If you require access to proprietary design software like the Adobe suite you’re out of luck. This is why I’m stuck on macOS for my day job. Clients love to deliver vendor lock-in with their designs. There are often 3rd-party workarounds for apps like Figma. Unofficial apps are always buggy and prone to breakage. Both the best and worse parts about Linux is too much choice. Everything can be modified, replaced, improved, and broken. I’ll end before this turns into a book. Let me know if you found this informative! Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. The Linux kernel A package manager A boot and init system Network utilities Desktop experience

1 views
David Bushell 1 months ago

Email: The Final Form

I’m taking one last stab at my contact form before it’s binned forever. Back in May I came up with a “progressive dehancement” technique to validate form submissions. For non-JavaScript ‘users’ I took the drastic measure of blocking all @gmail and @outlook addresses. Along with problem phrases like “SEO” and entire unicode ranges. Despite my best effort to maintain a JavaScript-free form I failed. Bots have ruined the web! I’ve done the unthinkable and added a CAPTCHA thing. I chose the invisible Cloudflare Turnstile . It seems to be accessible and the least intrusive. I’m using to add the three worst words in web development. At least it’s not “Please use Chrome”. That’s worse I suppose. Cloudflare is a controversial choice not least because some employees sponsor unsavoury projects . Is it time to deflare? I degoogled years ago. I degithubed a few months ago. I mostly deflared moving to Bunny CDN but my contact form remains on Cloudflare. Why is it so difficult to find reputable services? Just don’t be a bad guy! I considered rolling my own invisible CAPTCHA thing. It’s security by obscurity when you think about it. Over summer I had a go at building Anubis at home . The “proof of work” is really just “proof of JavaScript” in practice. I don’t want JavaScript gatekeeping my entire website. Cloudflare’s secret sauce will be some combination of browser detection and heuristics. If this fails I’m tapping out and you can email me directly. It’s weird that my address is unobscured yet I get more spam via the contact form! Update: Note for October 11th Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
David Bushell 1 months ago

Not My Cup of Tea

As blog topics go, last week’s Next.js clownshow was a freebie. A bit of front-end dev and a middle finger to fascism. I had it drafted before my tea went cold. I wasn’t expecting round two to hit harder. This week I momentarily lost the will to blog. Ok, I’m being very dramatic. It wasn’t writer’s block or imposter syndrome. Not the usual suspects. I was just stun-locked for a couple of days. Like any self-respecting person with an ounce of sanity, I’ve been off Twitter X since it got all fashy. Nevertheless, it’s impossible to avoid the crazy stuff. And this week’s crazy was another level. Enjoyed my discussion with PM Netanyahu on how AI education and literacy will keep our free societies ahead. We spoke about AI empowering everyone to build software and the importance of ensuring it serves quality and progress. Optimistic for peace, safety, and greatness for Israel and its neighbors. @rauchg Sep 29, 2025 (xcancel) - Guillermo Rauch On seeing this I noted in anger followed by a hastily worded social post: I wonder if @svelte.dev is onboard with this? The obvious answer is: ‘no’. Everything I already know suggests the Svelte maintainers are antithetical to Rauch. My words were clumsy not malicious. I was merely wondering what on earth does Svelte do? WTF does anyone do when a major funding source does… that? A quick catch-up for those unaware: In the wake of this mess some people were keen to remind everyone of Svelte’s independence. Rich Harris and others were lost for words. Can you blame them? I called out Svelte specifically because it’s the one project with ties to Vercel I care about. Svelte is a shining light in a rather bleak JavaScript ecosystem . I try to avoid political discussion online. I’m a little ham-fisted in questioning the ethics of my tech stack. Some argue that taking Vercel’s money has moral baggage. That it makes the recipient complicit in brand-washing. Personally I’m not sure what to think. To cut ties with Vercel would be morally courageous. Then what? There’s no easy alternative to keep the lights on. The day after Rauch’s infamous selfie Vercel announced $300M in series F funding . The “F” stands for “f*ck you” I’m told. Vercel’s pivot to AI banked them one third of a billy in a world where profit doesn’t matter . Until the “AI” bubble bursts Vercel are untouchable. Is it wrong to siphon off a little cheddar for better use? Let’s be honest, who else is funding open source software? Few users are willing to pay for it, developers included. The world revolves around load-bearing Nebraskans . So what can projects like Svelte do? Does it matter? Nothing matters anymore. You can just say things these days. Make up your own truths. Re-roll the chatbot until it agrees. And if your own chatbot continues to fact-check you just rewrite history . We live in a reality where you can spew white supremacy fan fiction for the boys on X and Cloudflare will sponsor your side hustle a week later. Moral bankruptcy is a desirable trait in this economy. Is it any wonder open source maintainers with a backbone are shell-shocked? I’ll leave Svelte to figure out how to navigate impossible waters. Let’s hope that open governance remains intact, lest it go off the rails . For the rest of us: Taking action and Doing The Right Thing is often difficult, always exhausting, but it is what we must do, together. We all deserve better. The world deserves better. It’ll take a little work to get there, but there is hope. We all have a choice - Salma Alam-Naylor Amen to that. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Guillermo Rauch is CEO of Vercel Netanyahu is a wanted war criminal Vercel funds Svelte and employs creator Rich Harris Svelte remains open governance; not owned by Vercel Cut ties and take the moral victory for a day and then be amazed by the magical vanishing act of an entire dev community when asked for spare change tomorrow? Continue discarding skeets until the drama blows over? Pivot to “AI”?

0 views
David Bushell 2 months ago

RSS Club #003: Silksong

This is an “RSS-only” post where I discuss topics tangentially related to my usual web design and development feed. Ignore or enjoy! Before I delve into the dark corners of Pharloom I’d like to discuss one related topic. Silksong is a hard game that offers no affordances. There is no “easy mode”. There are no granular controls to tailor the experience to your individual ability or preference. Silksong is in stark contrast to games like Star Wars Outlaws by Ubisoft. Modern Ubisoft games take accessibility seriously. Outlaws has a huge list of accessibility options covering visuals, audio, controls, menus, and gameplay. Outlaws is a masterpiece of development that is unfortunately undone by being a rather boring game. The Silksong meme is “get good” and it’s a great game if your able to “get good”. But I strongly disagree with the notion that it has to be that way. Any argument for single-player games not providing “difficulty” settings is inherently exclusionist. If a game offers one mode, that does not mean all players experience the same challenge. An abled twenty year old memer is playing an easier game than anyone with a disadvantage. Be that any disability or distraction. How others experience a game should have absolutely no bearing on your own enjoyment. That’s just pathetic. Online discussion tends to fall into shallow gate-keeping. Providing more accessibility options would help ensure players get a comparable experience. Such options allow more players to find fun in a game. There’s a grey area between artistic choice and discrimination. I believe hard games should be allowed to exist in the same way comedians should be allowed to tell edgy jokes. The difference is games can have options, so why add self-imposed limits to exclude players? In 2007 game devs Team Cherry published a five star game, Hollow Knight . I never played it on release. I picked up the Voidheart Edition some years later and completed almost every challenge (can’t remember how far I got in the Pantheons). Silksong is the long awaited sequel. Hornet is the playable character replacing John Hollow Knight as Silksong’s protagonist. Hornet’s movement and play style is faster and more aggressive. If Hollow Knight was five stars I’d give Silksong three stars. A good game but nothing special and let down by lessons unlearned. Fair warning: spoilers galore below! Nothing is off limits. After 18 days and 52 in-game hours I rolled credits on Silksong. I immediately jumped back in for another week to tie up loose ends. After 68 hours, my Silksong adventure is over! I played the first Hollow Knight and shamelessly followed a walkthrough verbatim. Silksong was an amazing experience to explore blind and discover for myself. I followed every path and found every upgrade to make the main quest easier. I enjoyed the fast paced combat. That said, I can’t be bothered to 100% Silksong. I’ve seen two endings and I’ve watched the rest on YouTube. I’m in Act 3 and I joined the Flea Festival and I’m happy here! I’ve absolutely no desire to see more. A shame because there are cool boss fights I’m missing. But boss fights are what let this game down. Before I discuss the bad these are my top five in fight order: These were great fights I beat clean without spamming tools. Sadly, fun bosses were few and far between in Silksong. Too many bosses were giant amorphous blobs where contact damage from their fat-ass movement was more deadly than the attacks. Boring; forgettable. That’s my main criticism of Silksong; underwhelming boss fights and an over-reliance on harder gauntlet battles. The High Halls gauntlet would have felt more rewarding had I not been fatigued already. Most bosses I beat within a dozen tries. For me Silksong lacked a Soul Master moment where hours of practice and progress felt like a real achievement. First Sinner came close but as an optional hidden boss — I never got captured and had to break into The Slab — it didn’t feel like a major victory. I’m actually complaining about lack of — or the wrong kind of — difficulty in boss fights. Difficulty in a fun way where I learn to overcome a challenge. Not difficulty where I repeat the same madness until I get lucky and not caught in the air between fat bouncy blob, randomly spawning blob, and heat-seeking acid spew blob. Lazy game design is not fun. I know quite a lot of potentially cool bosses are in Act 3 along with possibly 20–30 hours of extra content. I wish I cared. It just feels like a chore to progress any further. Backloading the endgame is just bad design in my opinion. You might say I never finished the game and quit before the final act. Whatever, I got my money’s worth! Personally I think Silksong was comparably easier than I remembered Hollow Knight. Regardless, I found the difficulty in this game unfair. Deaths in Hollow Knight always felt preventable. Many deaths in Silksong came from gambling with flying enemies designed to punish no matter how you moved or attacked. Like many players I discovered poisoned Cogflys to be very effective against pesky flies. This made areas like Bilewater bearable. If everyone is using the same overpowered tactic that suggests poor game balance. Platforming challenges were fun once I mastered the 45° degree pogo. Longclaw made that easier. Climbing Mount Fay to unlock the double jump was a pleasant change of pace. I would have preferred a Path of Pain over Bilewater’s gimmick. The economic balance of rosaries and shards sucked and dissuaded me from experimenting. Many tools felt unnecessary and my load-out rarely changed. The Architect Crest looked interesting but farming shards was bad enough. I went 80% Hunter and 20% Reaper when I required longer attacks. I found Weavenest early which also locked in my choice. Silksong is a fantastic game overshadowed by the relative perfection that was the original Hollow Knight. In comparison I found Silksong a little too unfair and at times unrewarding. I don’t feel like I could play Silksong again but I could give Hollow Knight another run. Unlocking every skill in Hollow Knight felt like a big milestone. Silksong missed that mark. For me Silksong is a solid three stars that took risks but failed to improve on the original. I’ll be playing Ghost of Yōtei next! Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. First Sinner

0 views
David Bushell 2 months ago

How Much Does Freedom Cost?

Trump’s National Design Studio has an executive order to “modernize the interfaces that serve everyday citizens” . That means rich/white people (but not the ‘disabled’ kind). The US government had digital service agencies that cared about a performant and accessible web until they got the DOGE treatment . The NDS’ latest website trumpcard.gov is a Next.js disasterclass . Vercel’s CEO Guillermo Rauch thinks an endorsement by a friend of Epstein is… a good thing? Anyway, Trump invites you to “Submit Your Appl 🦅 tion”. This side-eying American Bald Eagle is a 579 frame animation. Each frame is a 1671×1300 pixel PNG weighing on average 30 KB each. Frames 261 through 320, where the eagle is looking straight forward, are replaced by frame 320 to save bandwidth. Despite this valiant effort the total size of these PNG files is 16.7 megabytes . PNG frames are requested by a Web Worker and saved using the CacheStorage API. The worker returns URLs for each frame. The React hook is used ( very carefully ) to trigger to update an elements source. And that is how you get 16.7 MBs of freedom. Alternate text is seemingly used as a comment for developers. Eagle-eyed readers will have noticed the eagle’s body is a static image. The PNG frames only contain the head which is no larger than 400×400 in the centre. A quick crop and squoosh suggests a 20% saving with no quality loss. Using a lossy codec like AVIF would allow for anywhere between 50–80% smaller images with little perceptual quality loss. I’m guessing the animation trickery is done to superimpose the eagle over the text “Submit Your Application”. Is it worth the cost? No. Just use a video! You could just make the entire thing a video including the text (like my screen recording above). This would limit the responsive design and the initial text transition but would be much smaller than 16.7 MB. To retain separation of elements a video codec with alpha transparency can be used (see CSS-Tricks , Jake Archibald ). WebM/VP9 works in Chrome and Firefox and HEVC works for Safari/iOS. A quick test returns 500–800 KB depending on codec and quality. Using the HTML attribute allows to work in most browsers. These are rough numbers but suffice it to say a PNG based animation is expensive . Then again, if you’re in the market for a $1 million dollar card you can probably afford this too. Decapitating America’s “national bird” is not the only sin committed by the National Design Studio. Trump’s gold card website is a treasure trove of bad development. View source and see what fun you can find. And remember, for facist-friendly hosting™, think Vercel. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
David Bushell 2 months ago

Let’s see Paul Allen’s CSS Reset

CSS “resets” are boilerplate code designed to remove or normalize browser defaults. They provide solid foundation to build bespoke CSS upon. When utilised correctly they should be unobtrusive. Any quirks being ones of personal taste and flair. These quirks are why CSS programmers obsess over their reset stylesheets like the infamous business card scene (YouTube) † . † ⚠️ beyond the satirical quotes, American Psycho is a brutal movie with extreme violence. Heed warning before watching, there are no further parallels to the comfort of web development! CSS resets have matured along with the CSS spec(s). They’ve gotten complicated. Some incorporate choices that can have big consequences if not used with care. Perhaps a good reason to roll your own CSS reset; you must understand every line. Here are a few notable recent examples to learn from: And saving the best for last: I won’t copy & paste it all because my CSS reset is a “living standard” like the HTML spec. You can find 👉 my CSS reset here 👈 You’ll have noticed I wrap all selectors in to zero out specificity, just in case. I will also typically import my CSS reset into the lowest cascade layer. If you don’t bikeshed those layer names in the comments I’ll be disappointed. I define my layers alongside top-level imports rather than wrapping large blocks of code. The only thing that gets imported earlier are declarations. Another “just in case”. Does this allow the browser to fetch fonts faster? No idea lol (ask Harry ). I will preload critical fonts in the anyway. I just like putting fonts up top in CSS; they’re special. This combo of selector and cascade layers make specificity a non-issue. I’ve been on the logical properties everywhere train for years. This practice allows for almost free right-to-left support. For nuances see RTL Styling 101 by Ahmad Shadeed. You’re missing out on that free RTL styling if you forget the class. The class is added by Google Translate. Google doesn’t alter the attribute so it won’t naturally flip without help. Kagi Translate does add — one of a thousand reasons to stop using Google. I prefix the naked tag name for clarity. Does that matter? Nope! My properties are ordered alphabetically because I’ve worked with Stu Robson . My haphazard aesthetic ragged edge ordering did not vibe with Stu’s sensible design system. I’ve been an alphabetical convert ever since. As an almost 40 year-old that still sings the alphabet to place letters, this is not easy for me. Siri, delete that last paragraph. Okay, what’s all that about? I once had a client that resized the browser below 300px and complained. The is more interesting. This enables a full viewport “hero”, depending how you go about it. It also allows you to push the footer to the bottom on shorter pages. Nothing weirder than seeing a floating footer in the middle. Why ? The viewport height on iOS Safari is dynamic (maybe Android browsers too, I forget). Anything sized to it causes janky layout thrashing on scroll. This BBC profile on Armand Duplantis using is a good example of that issue. The initial size before scrolling is usually the smallest. This fits my use case. I don’t actually reset stuff like the default heading margin. I always style those later. When arrives I may add: Just out of respect for the glorious new pseudo-class. I add to paragraphs and it does something in Safari . I don’t headings as some resetters do by default. I find that too opinionated. Only specific design patterns suit balanced headings. I love a bit of hanging punctuation so I yolo’d it. Then I learned from Jeremy Keith (as one does) this practice has unwanted side effects. So I reset it back to on form elements. A reset within a reset, is that code smell? I may or may not have secretly patched half a dozen client websites. Speaking of fancy pants typography, please show support for Richard Rutter’s Interop 2026 . Prioritise long-standing bugs first Big Browser 🙏 For a long time I refused to use “font smoothing”. I was staunchly a “please don’t mess with text rendering” person. That was until I did a deep dive on: What’s the deal with WebKit Font Smoothing? — I’m not happy with that post, it’s confusing, but the takeaway is I now add the style to my reset. So that’s my CSS reset . It has and will change over time. Let’s see yours! Do you keep it lean, or prefer a chonky reset? P.S. did I just big blog twice in one day? Is that allowed? Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Chris Coyier (Sep 2025) UA+ (Apr 2025) Piccalilli (Sep 2023) Josh W. Comeau (2021–2025) Elad Shechter (Oct 2021)

0 views
David Bushell 2 months ago

I Shut The Emails Out

Last week I let the emails in by self-hosting an unencrypted SMTP server on port 25. That was a “fun” challenge but left me feeling exposed. I could host elsewhere but most reputable hosting providers block SMTP ports. I found another answer. I know. Bleh! Sellout to Big Tech why don’t I? I don’t see you opening ports into your home. Anyway, Cloudflare has this thing called Email Routing and Email Workers . Cloudflare handles the SMTP and verification of incoming emails. Emails can be forwarded elsewhere or handled by a worker. Catch-all can be configured so it’s wise to do your own address validation. My worker takes the following actions: I’m locked in to Cloudflare now for this side project. Might as well use the full suite. The basic worker script is simple. There is one issue I found. claims to be type: And claims to take type: — amongst others. In reality the email API does not play nicely with the storage API. My worker timed out after 5 minutes with an error. “Provided readable stream must have a known length (request/response body or readable half of FixedLengthStream)” That is why I’m using which I yoinked from @std/streams . I’d rather stream directly but this was a quick fix. Since I have a one megabyte limit it’s not a problem. My original idea was to generate an RSS feed for my Croissant web app à la Kill the Newsletter (which I could just use instead of reinventing…) HTML emails though are a special class of disaster. Semantics and accessibility, anyone? No? Table layouts from the ’90s? Oh, okay… that’s another blog post. Actually hold up. Do we just lose all respect for accessibility when coding HTML emails? Apparently so. I built an HTML email once early in my career and I refused to do it ever again. Here’s a screenshot of the web UI I was already working on to read emails. I’m employing similar tricks I learnt when sanitising RSS feeds . This time I allow inline styles. I remove scripts and images (no thanks). Content security policy is very effective at blocking any tracking attempts that might sneak through. I have a second proxy worker that receives a URL and resolves any HTTP redirects to return the real URL. For good measure, tracking params like are removed at every step. Email truly is the cesspit of the internet. Dreadful code. Ruthless tracking. Why am I doing this again? Most of these newsletters have an RSS and web version available. I can’t believe I let this stuff into my home! Come to think of it, maybe I can pass the plain text versions through a Markdown parser? Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. validate address reject emails larger than to an R2 Storage bucket with metadata

0 views
David Bushell 2 months ago

Trillion Dollar Elephants

I was hesitant to post this because the WHATWG & friends war party is strong on the defence! I’d ask for parley but this is going to get spicy so I won’t feign friendship. I want my web career to survive. I want the web to be better. I want to address the trillion dollar elephants in the room. Quick heads-up: I do believe most individuals involved are good people trying to do a good job. I’m just venting frustration (and torturing a metaphor). Browser teams at trillion dollar companies Apple , Google , and Microsoft , are asking for Interop 2026 proposals . Along with other web platform contributors like Igalia and Mozilla — well some Mozilla employees; I can’t find an official blog. I’ve noted before I’m skeptical of Interop but I decided to play their game this year. I submitted a proposal for XSLT 3.0 . Seems like a good candidate? Well specced with what looks like a test suite . I expect my proposal to be ignored or disqualified. Regardless, this blog post isn’t about XSLT drama. That’s just a symptom. I just didn’t want the lack of proposal to be more ammunition for the inevitable firing squad. I’m not as cynical as some regarding Interop. I believe there is genuine attempt to engage with web developers here. I just wish they’d finish what they start before marching on. With Interop comes Baseline . Baseline gives you clear information about which web platform features are ready to use in your projects today. When reading an article, or choosing a library for your project, if the features used are all part of Baseline, you can trust the level of browser compatibility. Baseline (web.dev) (emphasis mine) That quote would be accurate… if “clear” and “trust” were replaced by “confusing” and “doubt”. My opinions on Baseline are summed up in one image I shitposted back in June. That’s obviously a joke, but I build a lot of websites and the reality is not as rosy as what Devrel PR wants you to believe. I wonder though, how can this process improve? Before you say: “please report bugs” let me get to my serious point. Let’s put the white guy surveys down and ask the real questions. Browser engine teams are custodians of the web platform and open web standards. That’s a big responsibility. Most are employed by trillion dollar companies . Those companies consider the web and its users a product and themselves the owner. It’s an awkward juxtaposition. Are we just going to keep ignoring it? They ask for bug reports with no compensation. The last bug I reported cost me over $1000 † to isolate, reproduce, and write-up. Why should I work for free? Sure, I get to improve the web, but why shouldn’t I profit when those companies do? † approximate USD equivalent for my time (and my rate is cheap for a white guy ) Any mention of “trillion dollar company” is immediately shot down; browser teams have a small budget. Not their fault. But if Google et al. refuse to invest appropriate funds into an open web, why should I be silent? That’s kind of a major problem. Who is in a better position to fix that? A loudmouth blogger, or employees who work there? Don’t get upset when I point out the trillion dollar elephant over your shoulder. Don’t act like I’m the problem. You’re employed by the problem. And if you’re not, why on earth would you defend this status quo? Just to be absolutely clear, am I saying browser vendors should pay developers who are solicited for their professional expertise? Yes I am. If their work is accepted under an agreed criteria. How is such a system structured? Not my problem. Let’s stop pretending we’re on equal footing, in this together for the betterment of a free and open web. Whilst there are trillion dollar elephants in the room these are my terms: Sorry, is that such a radical idea? I think every professional web developer should be saying the same thing. If you want me to change my tune: change the situation. I’d prefer if you echoed my call for more funding. Maybe there are internal efforts? Fantastic! Telling me I’m wrong and that I should allow my time and expertise to be exploited is another option, I guess. P.S. “trillion dollar” applies to market cap not cash on hand. That means share price × number of shares . It’s fiction. The stock market is a casino. Like any shitcoin if too many shares are sold the price plummets. Apple , Google , and Microsoft each have between $50–100 billion in the bank. Mozilla is not publicly traded but their 2023 financial position lists $263 million in “cash and cash equivalents” . P.P.S. my terms also apply to VC-funded companies that open source a few products and exploit “the community” for free labour. I’ve fallen for that trick. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. If you want professional consultation: pay me If you want professional bug reports: pay me If you want professional testing: pay me

0 views
David Bushell 2 months ago

I Let The Emails In

They say never operate your own email server. It’s all fine and dandy until Google et al. arbitrarily ban your IP address. Doesn’t matter if you configure DMARC, DKIM, and SPF — straight to jail. But that only applies to sending email . I think. I’m testing that theory. How easy is it to receive emails? Turns out it’s almost too easy. I coded an SMTP server in TypeScript. I added a couple of DNS records on a spare domain (redacted for obvious reasons). I rawdogged port 25 on my public IP address. I sent myself a test email from Gmail and it worked! Join me on the adventure of how I got this far. I’m using Deno flavoured TypeScript and below is the basic wrapper. I’ve simplified the example code below to illustrate specific concepts. Open the TCP server and pass off connections to an async function. The handler immediately responds in plain text. Wikipedia has a good example of a full message exchange. Only the number codes really matter. Then it reads buffered data until the connection closes. Commands are ASCII ending with the carriage return, line feed combo. I get a little fancy with the so that it throws an error on malformed text. Later I decided that giving unbridled to a 3rd-party was not a smart move. I added a couple of protections: By the way, this exact code never throws because the main thread is blocked. The abort signal task is never executed. Replacing the placeholder comment with an to read data unblocks the event loop. Handling commands is easy if you’re careless. I don’t even bother to parse commands properly. (Note to self: do a proper job.) If there is any command I don’t recognise I close the connection immediately. It was at this stage in my journey that I learnt of the command. The STARTTLS keyword is used to tell the SMTP client that the SMTP server is currently able to negotiate the use of TLS. It takes no parameters. This is supposed to be included as part of the response to . It’s worth noting at this point I’ve tested nothing in the wild. Had I tested I would have saved myself days of work. I found Deno’s function which looked ideal. But no, this only works from the client’s perspective ( issue #18451 ). One does not simply code the TLS handshake. (Some time later I found Mat’s @typemail/smtp — this looks much easier in Node!) It’s possible for an SMTP server to listen securely on port 465 with TLS by default. Deno has to replace . Say no more! Side quest: code an ACME library Side quest status: success! So after that 48 hour side quest I now have a TLS certificate. Which is useless because mail servers deliver to each other on port 25 unencrypted before upgrading with and I’m still blocked there. It’s confusing. Clients can connect directly over TLS to post emails (I think). Whatever, the only way to know for sure is to test in production. And this brings me back to the screenshot above. I opened the firewall on my router and let the emails in. And guess that? Google et al. don’t give a hoot about privacy! Even my beloved Proton will happily send unencrypted plain text emails. Barely compliant and poorly configured server held together by statements and a dream? Take the email! My server is suspect af and yet they handoff emails no sweat. Not their problem. If I tried to send email that’d be another story. For my project I’m just collecting email newsletter; did I mention that? We’ll see if they continue to deliver. If you have a port open on a public IP address you will be found . Especially if it’s a known port like 25. There are bots that literally scan every port of every IP. I log all messages in and out of my SMTP server. I use the free IPinfo.io service to do my own snooping. Here is an example of Google stopping by for a cup of tea. I decided it was best to block all connections from outside NA and EU. For my purposes those would be very unlikely. This one looked interesting: Sorry for the lack of hospitality :( When it’s running, my SMTP server is inside a container on a dedicated machine that is fire-walled off from the LAN. I won’t provide exact schematics because that would only highlight weaknesses in my setup. I’d prefer not to be hacked into oblivion. My server validates SPF and DKIM signatures of any email it receives. RFC 6376 was a formidable foe that had me close to tears. I know I don’t need to code all this myself, but where’s the fun in that? I’m throwing away emails that have malformed encoding. In this case parsing Quoted-Printable and MIME Words formats myself did not look fun. I found Mat’s lettercoder package that does a perfect job. I added a concurrent connection and rate limiter too. @ me if I’m missing another trick. The plan is to keep the SMTP server live and collect sample data. I want to know how feasible it is to run. I’m collecting email newsletters with the idea of designing a dedicated reader. I dislike newsletters in my inbox. This may be integrated into my Croissant RSS app. Of course, Kill the Newsletter! can do that job already. If it proves to be too much hassle I’ll slam the door on port 25. Does anybody know a hosting provided that allows port 25? I was going to use a Digital Ocean droplet for this task but that’s blocked. Update: one week later… I shut the emails out! Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. A generous 30 second timeout A maximum 1 MB message size

0 views
David Bushell 3 months ago

Croissant RSS Beta is Live!

and it has been for a couple of weeks . I’m bad at launching stuff but the important thing is that Croissant is live! I’ll tell you what you need to know. After this screenshot. Maybe try reading this post in Croissant! Croissant is an RSS reader I designed for myself. It might not be for you, but you’re welcome to try it and provide feedback. There are a few ways to use Croissant: Croissant is “beta” which means use the export feature regularly because I test in production. I’m half-joking, the code is stable now. Don’t ask me what “stable” means. Croissant was designed to be as light on features as possible. I hate software bloat so I experimented with the opposite idea. What features can I remove and still make a functional app? I have a few ideas I’d like to add (favicons is one) but updates will be slow and focused on bug fixes and accessibility improvements. Croissant was designed as a desktop app. It’s a responsive website, naturally, but my focus wasn’t on the mobile experience. That’s another excuse for bugs. Please @ me screenshots if anything looks bad on your flip phone. There is no auto-sync you must click the “Sync” button manually. Why? Check back later, I have a note to retrofit a cool philosophical reason for that choice. I subscribe to ~200 feeds that typically publish weekly or monthly. Croissant has no organisation. If you follow feeds that publish 10 times a day you might struggle. There is a single “Mark All as Read” button. It’s okay to accept defeat! I’ve added plenty of polish over the last two months. I’m happy with how it works but there is more to hone. I would like to add colour and typographic theme choices. Just for fun, but I reckon that’d make it more accessible for others. The annoying banner that appears on launch will be removed eventually! Croissant is “source available” not open source. You can review the code and compile for personal/non-commercial use. I chose this model because I have: The first point may change in future. I had considered selling Croissant in some fashion. There’s the whole ordeal with support etc I’m too busy to deal with right now. It should go without saying, but please do not redistribute the code on GitHub . I’ve written at length about the no build/no framework architecture, how I use web components and style them , the Tauri app , and an experimental feature: text to speech synthesis . I have a long series of notes starting July 3rd chronicling this journey. You can follow Croissant development by following my RSS feeds! They’re linked below. I won’t be offended if you don’t use Croissant to subscribe. That’s the awesome thing about RSS. It’s an open standard that has no gatekeeper. If you missed the link: CroissantRSS.com Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Install CroissantRSS.com as a PWA Download the macOS app build from source (for personal use) no time for the burden of open source no desire to hand-feed the slop factories

0 views
David Bushell 3 months ago

RSS Club #002: Dino Edition

As the VC-funded web continues to ensloppify , it’s important to remember that we don’t need to play their games . Despite billion dollar efforts the web remains decentralised. We can hyperlink right past the wannabe gatekeepers. Like this hyperlink to the Animal Photo Reference Repository . “AI” animal approximations ain’t got nothing on the real deal. Did you know there’s a Reddit page for Defending AI Art . Absolutely bizarre. In my first “RSS-only” post I discussed my favourite whale books. Thank you for the reminders of Hitchhiker’s Guide , which after deliberation I’m tentatively qualifying as whale fiction. There is sadly no photo reference for many extinct animals, but we do have other non-AI artistic depictions. I’ve watched all the Jurassic Park movies which basically makes me a palaeontologist now. I’m here today to present my top five scariest dinosaurs. ⚠️ Spoiler warning. ⚠️ …from the the Jurassic “Cinematic Universe”, which plays fast and loose with its definition and depiction of dinosaurs across seven movies. Yeah seven; they rebooted it this year with Scarlett Johansson and Mahershala Ali . It’s passable. The Jurassic movies cover many genres including comedy, outright horror, and Jeff Goldblum . I love these movies because no matter how dreadful the plot becomes a good dino spook never gets old. This is not a paid sponsor I just think dinosaurs are awesome. In reverse order. Jurassic World: Dominion (2022) is an absolute travesty. They brought back the original cast and squandered it. The movie lost sight of what made the franchise great. The Therizinosaurus also lost sight but it was never explained how it was blinded. This long-fingered feathered psycho could have been the main villain. The swamp scene (YouTube) where Therizinosaurus stalks Bryce Dallas Howard , who silently escapes underwater before rising for air, was channeling Apocalypse Now energy. Unfortunately the rest of the movie removed all suspense and danger. Jurassic Park III (2001) is an underrated movie in the franchise. They’d done Raptors twice. They upped the ante with two T-rex and baby T-rex in The Lost World (1997) . What could they do next, three T-rex? That’d be as ludicrous as four naans . The new big bad Spinosaurus was vicious and fast with a terrific intro (YouTube) . Having the Spinosaurus swallow the satellite phone and using the ringtone to announce its presence was a masterful plot device rivalling any horror movie. Number three might be a controversial choice. Jurassic World (2015) is in many ways a retelling of the original movie, except they invented a fake dinosaur. Indominus Rex’s paddock escape (YouTube) is a thrilling introduction. I-Rex on the loose as the park panics to lockdown adds a permanent tension to the movie. Before the franchise shit the bed with raptor-whispering, Raptors sent a shiver down the spine. First appearing in Jurassic Park (1993) , they’re one of four dinosaur species † to appear in all seven movies. An unseen raptor gets the first kill in the movies opening sequence. The early feeding scene (YouTube) is frightening and we still don’t see the raptors. Once they appear around an hour in their reputation is defined. It’s edge of the seat stuff for the rest of the movie. Nowadays they’d have their own TikTok account before the movie even hit cinemas. † Parasaurolophus, Triceratops, and Tyrannosaurus are the rest ( apparently ). The other confirmed species to appear in all seven movies is, of course, Human. And aren’t we the real dinosaurs? An easy and obvious top spot for the T-rex. Peak Spielberg cinema. The original movie was well paced and truly terrifying at times. Notice how the night scene in T-rex’s escape (YouTube) is lit. It feels dark yet you can actually see the action. A lost art in modern cinematography. T-rex really pops off in the 2nd movie. Again, the night scene rescuing baby T-rex (YouTube) is a Spielberg masterclass. T-rex is done dirty in the 3rd movie, but get’s revenge in the 4th. The standout scene in Jurassic World: Rebirth (2025) is a T-rex cameo battling a yellow rubber dinghy. This pays homage to the original novel by Michael Crichton . Although the Pteranodons are a threat in multiple movies, they lack the scare factor for my list. They get a bigger role in the latest movie but it’s all so lacklustre. Jurassic World: Fallen Kingdom (2018) ; the Indoraptor feigning sleep to escape it’s cage is a great scene (YouTube) . It promises so much only to be thwarted by plot armour and well polished hardwood floors. And I can’t have two phonies on my list. The Mosasaurus , a massive aquatic reptile, first appeared as a sideshow in Jurassic World . Its lurking cameo (YouTube) in Fallen Kingdom has Jaws-like vibes. Sadly we don’t see it again until Rebirth which again is a weak effort. Shoutout to those who dare criticise the original T-rex scene because of a supposed plot hole. Where exactly does the cliff suddenly come from? To be fair, it’s a good question and I like a low stakes conspiracy theory, but also shut up and enjoy the best movie ever made. And read the two Michael Crichton novels the movies miss a lot of action. BTW, I stealth launched my Croissant RSS reader app! It can be used as a PWA (experimental) and macOS app. Croissant is “source available” not open source at this time. I’m still considering the best open source approach as I develop it. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
David Bushell 3 months ago

RSS Club #001

Welcome to RSS Club! The first rule of RSS Club is: you tell everyone about RSS Club. RSS is the best way to follow weblogs. I’ve used NetNewsWire for years and I’m now building Croissant RSS to control my own reading experience. Croissant will be available in September as kind of a “beta” release. You’ll have no doubt heard at least one web-adjacent “content creator” embarrass themselves by saying “RSS is dead”. They left the open web behind to build their fragile empire on a platform of proprietary sand. They became slaves to an algorithm. Now that algorithm is starting to reject them in favour of AI slop. Big Tech has invested billions; they’re peddling slop whether anyone wants it or not. Open standards like RSS are a panacea for “the algorithm” — AI or otherwise; always has been. RSS broadcasts, shares, notifies, collates, and aggregates. All without a middleman. RSS bypasses the tech bro nonsense and they can’t do anything to stop it! The broligarchy love to talk about “democratising” tech. That is code, not very subtle code, for you “participating” under their control. The web doesn’t need false governance. The web is decentralised and RSS strengthens the web. But you know this, so remind others about RSS! To be honest I’ve not really thought this through. I’ve seen other bloggers do RSS-only posts. I like the idea of bonus content. My RSS Club posts will have real public URLs. You’re welcome to bookmark and share those pages. They won’t be listed in my blog index or sitemap. My RSS feed will be the only way to discover them. I’ll publish to RSS Club infrequently. Monthly, at most. Maybe not even monthly. Maybe never again! RSS Club will be the only place where you’ll find my list of… I’ve not completed the list yet, obviously, but I’m currently reading (and listening) to Whalefall , which I heard was being adapted into a motion picture. Believe it or not I’ve read Moby Dick twice. All (both) books in my list centre around the mighty Sperm Whale . Sperm whales are, in my opinion, the most interesting whale. Yes their name literally refers to semen. Their bulbous heads are filled with Spermaceti . The substance was initially believed to be whale semen, due to its appearance when fresh. Sperm whales dive to incredible depths to eat Giant and even Colossal Squid . There is almost no footage of such squid alive in their natural habitat; they are the mythical Kraken . And a sperm whale’s supper. The bigger Blue Whale is estimated to be the largest animal ever . More massive than even Sauropods. Blue whales feed on krill , not squid. Pathetic. You cannot unsubscribe from whale facts, by the way. There is contention within the emoji world as to which species of whale should be illustrated. There are currently two unicode points: The abstract nature of the designs makes it impossible to classify most emoji but a few have unmistakable characteristics of a sperm whale. Anyway, please help me complete my top ten whale books. If you’re familiar with whale fiction please get in touch and recommend. Space Whales qualify. End of transmission. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Moby-Dick; or, The Whale, by Herman Melville Whalefall, by Daniel Kraus Whale U+1F40B Spouting Whale U+1F433

0 views