2024-02-28 08:00:00
In the last couple of years I have developed a complicated relationship with my phone. Whether it's scrolling past an endless wall of hate on Twitter or feeling my mood buckle under the weight of every TikTok or Reel that I push skywards, the tiny computer in my pocket has started to feel a bit like that box from Dune – there's nothing but pain in there.
Increasingly though, it's not just "in there" that's the problem. Over-reliance on my phone has often left me feeling like I'm not being forced to remember things as much as I'd like and the addictive nature of notifications means that I'm less present when my pocket starts to buzz. My hobbies have taken a hit too. Whilst I've always been keen on travel photography, I've noticed that on my recent trips I've been taking fewer and fewer photos with my camera. At the same time, I've taken hundreds of mediocre smartphone photos. The convenience of the phone in my pocket has started to outweigh the joy that I get from composing and shooting with the camera in my bag. Honestly, it's made me sad for all of the missed opportunities.
As much as I joke about disconnecting and running off to a cabin in the woods though, I'm still quite realistic that I do need a phone for modern life and work. There are many fantastic and necessary things that I love about having a smartphone to hand, I'd just like to use it a little less compulsively.
When my Samsung S21 literally and unceremoniously fell apart back in January of this year, I was confronted with the reality that I was going to have buy a new phone. But what do you buy when you want to use something capable, but much less frequently? Well, it turns out that there is a UK-based company called Nothing who pitch exactly that. As a "midrange" device the Nothing Phone 2 isn't as powerful as the latest iPhone or Samsung devices, but something that came up time and time again in reviews was that Nothing aim to help people to make more intentional use of their phones. That claim, along with the industrial design, sufficiently piqued my interest. After finding a great deal on the 512gb model, I decided to take a punt on it.
Tech has a real issue with chasing statistics and I'm always aware that, working in the industry, there can be a pressure to always have the latest and greatest device. After four weeks of use, I thought I'd share a few thoughts on taking a side-step.
Nothing's "use your phone less" ethos was undeniably appealing in choosing their device, but it remains questionable when a company is ultimately still in the market of selling phones. With that in mind, I'm pleasantly surprised that the Nothing Phone 2's OS actually makes good on some of the company's claims about minimising distractions.
Nothing OS is a light-touch skin over stock Android that adds just enough personality without reinventing the wheel. No emphasis on AI-driven nonsense and no pre-installed app bloatware; just a dot-matrix font and icons, some smart app-grouping options and a few useful widgets, all tied together with custom UI animations. Amusingly, those animations and transitions have a decent heft and easing to them which, despite the supposedly inferior chipset powering this phone, leaves the phone feeling snappy or, dare I say it, blazingly fast. It's all very refreshing to use.
The most important change for me though, is the focus on minimalism baked into the OS. You'll find a few accent colours dotted here and there, but my homescreen is now sparse to the point of being almost-monochrome. This design choice isn't just for the vibe though - instead of a multi-coloured wall of app icons and notifications bubbles just waiting to distract me, I now have a list of discreet black and white icons. Where a dedicated app icon isn't available, the OS applies a contrasty greyscale filter that, so far, hits more than it misses (check out the Elk icon in the photo above).
In practice, removing the colour from the icons means that the list of apps is harder to scan and the net result is that I'm spending less time compulsively hopping between apps. When the UI forces me to stop and read, my usage starts to feel more intentional. Chuck in a screen-time widget on the always-on display and I am genuinely finding that I'm unlocking my phone less frequently. Admittedly these are all subtle tweaks to the software but, given how much I've struggled to use my phone less, they come together to feel like a win.
So, a win for the software. But what about the hardware?
In my opinion, Android phone designs in 2024 are wholly uninspiring. For a company that once released a phone in Thanos-chic purple and gold, Samsung's latest phones have been reduced to characterless monotone slabs. Then there's the latest Pixel phones from Google which look like a from-memory sketch of Daft Punk and are equally loaded with enough AI intrusions to make them seem Human After All.
The Phone 2 stuck out to me as doing things a little differently. With its sharp screen, uniform bezel and hole-punched camera the front looks a lot like an iPhone 15, but flip it over and the back is a different story.
The back of the Nothing Phone 2 is a glass panel that shows through to a design that hints at the interior components without actually showing them. The end result is a finish that is shiny and smooth yet, at the same time, the components underneath create a surprising amount of texture (something that made more sense when I learned that Teenage Engineering had a hand in Nothing's design language). The whole thing is surrounded by matte metal rails and yet remains surprisingly lightweight, given how solid the materials feel.
Then there are also the lights – sorry, the "Glyph".
The back glass of the phone is home to an excessive number of white LED lights that etch out a pattern which looks like it could have been part of some glitchy Channel 4 ident from 2001. Coincidentally, that's exactly what it sounds like too as the phone's sound design (by Swedish House Mafia) is straight out of the 56k modem school of music. Think: lots of glitchy pops, buzzes, cracks and clicks.
Look, I'll be real: these lights are an absolute gimmick and I'm so unconvinced by their actual utility as "distraction free" notification lights that I swiftly disabled them in the settings. At the same time though, I'm really glad they're here.
You see, comparing stats like chip speed, resolution and screen brightness will only get you so far but there's another side to any design that is much more unquantifiable - how the thing makes you feel. It's entirely subjective, but one of things that drew me to this phone is that the design reminds me of a very specific era of consumer electronics when hardware could be fun and wasn't so beholden to market expectations. I'm talking about the transparent Gameboy Color or the smoke-grey N64; Apple's first iMac and the legendary G4 Cube; Sony's burgundy-lacquered MZ-E620 MiniDisc Walkman and the aqua-camouflage Neo Geo Pocket; The goddamn WonderSwan.
The back of this device is leaning into the early-2000s transparent aesthetic and, to be honest, I'm here for it. Hardware design used to be weird, creative and exciting to me and the Nothing Phone taps back into that long-dormant part of my brain quite nicely. The first time I saw the back of my phone light up like a football pitch, I just had to smile at the absurdity. Somehow, it feels good.
So, should you buy this phone if you were already planning on getting the latest iPhone or Samsung? Probably not. I got this phone after deciding that it was right for my needs. If it seems like it might be right for you too then go for it.
I want to be realistic and step away from any brand Kool-aid though: This phone is far from perfect and the design won't speak to everyone. The back glass is slightly pillowed which makes it feel a lot thicker in the hand than it actually is. With a 6.7" screen, the phone sadly remains the size of a small horse. The camera (as every review quite fairly warned) has the distinction of being bang average in anything other than good light. And lastly, let's not forget that Nothing themselves are such a new company that there's no guarantee they'll still be around in 5-10 years.
One month in, though, and I'm really happy with my move to Nothing Phone 2. For my needs, the hardware has just enough charm that I'm feeling happy to reach for my phone again and, at the same time, the thought that has gone into the software is helping me to break my phone addiction. Despite the industry's obsession with comparable stats, I haven't personally noticed any lack of power either. In fact, when I look at the reasons for upgrading my previous phones it has always been because of battery degradation or running out of storage and never because of a lack of power. In that regard – with 2 days on a single charge and 4 times the storage of my last phone – the Nothing Phone has actually been something of an upgrade.
The jury is out on whether or not my usage will creep back up over time, or if the battery-life will stay steady, but I'm already feeling less negativity about my phone. I'm also happy to report that the lacklustre camera is making sure that my Fujifilm isn't staying in its bag anymore. So far, at least, I'm pleased I went with Nothing.
2024-02-22 08:00:00
The web industry is full to the brim with tales of side-projects that grew into successful businesses and, like many of us, I'll often find myself tinkering away on an idea or three after I've finished with my day-job. Whilst it's definitely an enticing prospect, working on a side-project is not always sunshine and Lambos though – sometimes they just don't work out. If you're reading this, there's a chance that you might have recently abandoned (or are considering abandoning) a side-project. Many of us have been there. Hell, the neglected side-project has become something of a developer-meme at this point.
That said, I often get emails from beginner developers looking for advice and one of the growing themes I've noticed recently is concern that they they aren't shipping their side-projects as quickly or numerously as they would like. That anxiousness is totally understandable. When the prevailing wisdom of developer hustle-culture is "always be shipping" and tech-interviewers will routinely measure candidates by the output of their extra-curricular coding, those abandoned side-projects might not feel so funny anymore. That doesn't sit right with me. We hear about all the side-project success stories, but what if we talked more openly about the ones that tanked? Many of us do retrospectives at work, but personal projects don't get the same treatment. Instead, why don't we shine a light on all the time we spent on projects that didn't go anywhere? The seemed-like-a-good-idea-at-the-time abandonware; the graveyard of node_modules
folders still haunting our development environments.
I'd like to talk about a side-project I worked on a while ago; one that I abandoned the same day it was deployed.
My partner is Latvian and, a few years back, I set out to learn her language. Being from a small country, detailed learning resources for the Latvian language are a bit sparse but I made decent progress regardless. That was, until I discovered that Latvian has grammatical cases. If you've never encountered a "case" before, here's a little primer:
A language like English uses word order and prepositions such as "for", "to" or "in" to add meaning to each word in a sentence. If the order is wrong, or you miss a preposition, the sentence might no longer makes sense. For example, "Tom gives the book to Anna" sounds natural whereas, "Tom the book to Anna gives" doesn't. Cases change this up a bit. Instead of relying on word order and helper words, the end of each word itself changes to show what it is doing within the sentence. To return to the same example sentences in Latvian, "Toms dod grāmatu Annai" (emphasis added to highlight the functional endings). Literally translated back to English, this sentence would be something like "Tom-subject gives book-object Anna-towards".
Linguistically, cases are a pretty cool system because you no longer need to care about word order. As a learner though, this is a problem because you do need to care about all of the various endings for each word you learn. Latvian has seven cases in total, two grammatical genders (each with three separate conjugation patterns), and nouns can be singular and plural. The TL;DR is that's something like 84 possible endings to memorize.
So, cases can be a lot for a first-language English speaker. Thankfully though, I'm also a developer and therefore I'm hardwired to think that I can solve everything with code. What if I could build a quiz app to help me learn noun endings? This smelled like a side-project 🚀
I wanted to keep my app simple. Whilst I had a lot of other grammar to learn, I was only focusing on noun conjugations and that would help me whittle the initial concept down to an MVP. The quiz mechanism would present a series of Latvian nouns and the user would be required to conjugate the noun to the appropriate ending. To keep things interesting, the quiz would allow the user to make three mistakes before ending and I'd throw in a simple high-score system to keep track of how I'd performed in past quizzes.
The tech stack would be simple too. At the time of planning, Svelte 3.0 was the new shiny so I decided to use it for my UI. I knew that I wanted to host everything on Netlify, so for the backend I'd write a couple serverless functions to present the questions and check the answers. The main list of nouns could be served from a static JSON file and, as I'd be the only user, I could safely persist previous quiz results and a high-score to local storage. I wouldn't need a database right now.
As for how I would actually check answers, that would take a bit of research. After extensively reading about the conjugation patterns and how the various types of nouns are classified, I decided that my simplest option would be to build a system that leaned heavily on Regex to strip noun stems and append the appropriate suffixes.
With a decent plan in place, I started to code.
After a full week of evenings working on the project, I put the finishing touches to the MVP. I deployed everything to Netlify and started my initial testing.
The UI was simple but passable and worked well on mobile devices. Quiz questions progressed smoothly and the session would end after three wrong answers, as designed. In between quizzes, the dashboard was correctly displaying stats for hits and misses on each word and the overall high-score was persisting between sessions. Happy that everything was working as planned, I cracked a beer and started training word endings.
It quickly became clear that my app had a really big problem that I hadn't anticipated. The quiz was far too easy. Worse still, if I didn't make 3 mistakes, the quiz would keep going indefinitely. It just wasn't fun to use.
I racked my brain for possible ways to make the quiz more fun but, eventually, the penny dropped: The issue couldn't actually be solved in code. It turns out that, in devising and coding all of the logic needed to test the various noun endings, I had passively learned the rules needed to form them.
Over the last week I had worked long evenings to research and build an app – with a target audience of one person – and I didn't really need to use it anymore. Oops.
Out of all of my abandoned side-projects, this was the one that made me think differently. Even if I would never actually use the end 'deliverable', working on the project still indirectly achieved what I'd set out to do. That led me to an important realisation: we talk a lot about abandoned side-projects as "failed", but their success is really a matter of perspective.
Despite what some tech recruiters might have you believe, the success of a side-project doesn't need to be defined by a beautiful, shipped product. We work in a practical medium and any build experience, good, bad or abandoned, is still valid experience. If you are able to remove the pressure to ship and instead approach them like throwaway prototypes, side-projects become a great scratch pad for experimentation. As I found when building my Latvian app, even the act of writing code itself can be a successful tool for solving problems.
This is not all to say that we should dismiss the reasons these projects get abandoned – introspection is still important – but I find that focusing on the progress made can feel more constructive in the long-term. After abandoning my Latvian project, I dipped back into some of the other stalled side-projects languishing on my laptop. Where I'd previously grumbled over a string of failures and wasted time, I could now refocus on what had gone well. On one project, I could see where I'd first learned how to make an API in Go. Elsewhere I was impressed at how I had figured out how to work with GIS map data in Postgres. In another derelict directory, I saw not much more than a broken animation - one that I would later revisit and evolve into this website.
I still regularly work on side-projects but my perspective and motivations are different now. My advice to a beginner dev struggling with their side-projects would be to always make sure that you're doing them for yourself, and for the right reasons. Instead of approaching your first project purely as a means to make it big or to impress recruiters, see it firstly as a means to learn and explore what's possible. Once you've built up enough experience (i.e. abandoned a few projects) the rest usually follows. Side-projects should be creative and fun. If you find that shipping your project is starting to cause you stress or, worse yet, leaving you feeling burned out, then don't hesitate to cut it loose. Chances are that, if you look close enough, it has already brought you plenty of value.
2023-12-31 08:00:00
For the past few years I've tried to do a little retrospective post on the year that was. This year, inspired by the endless "such-and-such wrapped" tracking-data-as-entertainment emails that I've been getting, I'm going to mix up the format a bit and throw in an extra rundown of some of the media I enjoyed this year.
So, let's go. Here's my 2023 Wrapped (replete with overly-excitable subheadings)
I had a really varied year of freelancing in 2023 - I've worked on a bunch of brochure sites, a full design system, an app dashboard, I refactored part of a project written in Elm, I built a PWA with lots of time and timezone-dependent features and so much more that I struggle to recall.
2023 also marked the milestone of being five-years-freelance and I worked extra hard this year. If I'm honest, I worked too hard and burnout is once again knocking at my door. I still love the flexibility of the freelance life, but I'm starting to get the itch to do my own thing. I'm not sure what "my own thing" will be yet, but in 2024 I'm going to take time out of client work to try my hand at a few personal projects.
Every year I try to blog more and, whilst my drafts folder is still pretty well stocked, this year I published a tiny bit more than I did in previous years. This year I also challenged myself to write a little less technically and a little more conceptually. I think I just-about pulled it off.
Here's a quick rundown of links:
In 2023 I did a hell of a lot of work with Nuxt and Vue. Moreso than any other framework or programming language. I really enjoy using Nuxt and will continue to do so, but this year the fragmentation of Nuxt 2/3 compatibility has caused me quite a few serious headaches. In fact (and this is absolutely not intended as a slight on the work of the Nuxt team) this year I started questioning the use of frameworks altogether.
But then, I did a couple of projects with Astro.
Over the years I've slowly come to the realisation that the thing I like most about front-end frameworks is not encapsulating JavaScript or declarative code or any of the usual DX suspects. I like the componentisation of reusable HTML. Simply, I like not having to copy-paste a bunch of template code like we did in the old days. Because of that, Astro has been a great fit for me - Astro components allow me to assemble chunks of HTML and CSS and opt-in to all the benefits of a framework like React or Vue if and when I need them. No client-side JS by default? That's pretty damn cool and I'm looking forward to more Astro projects in 2024.
For someone who loves to travel, I haven't been out of the UK since I returned from Japan in March of 2020. To be frank, it has been an absolute slog. Thankfully, this summer, I was finally able to break the streak (and the Great British Depression that came with it).
My partner is Latvian and every five years Latvia holds a huge cultural celebration of traditional songs, dancing and costume – Dziesmu un deju svētki. In July we flew out for two weeks of seeing her family and friends, eating great food and listening to fantastic musical performances.
The highlight for me was the final concert, deep in a forest park and featuring a choir of 16,000 people. Add to that the crowd and you have close to 40,000 people singing long into the night. The next event is in 2028 and I can't recommend it enough. Just look at the size of this stage; you don't so much hear the songs as feel them in your chest. Magic.
It's hard to understate the positive effect that travel has on my mental health, so I'm really looking forward to travelling more in 2024.
My extreme burnout from the endless Marvel content-machine peaked this year (Hi-and-bye, Quantumania) but thankfully there has been a wealth of decent alternatives this year. Here are my top film & tv picks from the last year:
The Bear: season 2 - I loved the first season and tbh, the ending of season one was so well handled that I'd have been happy if it was a one-and-done show. Against my initials fears though, season two was better in almost every way (and not least because I'm an absolute sucker for a redemption arc). My standout episodes were Honeydew and, of course, Forks.
Past Lives - Beautifully acted, absolutely gorgeous to look at, and with an ambiguous and nuanced plot. When it finished, my partner and I sat and discussed our interpretations for quite a while afterwards. I still can't get over how this was director Celine Song's first movie. Phenomenal talent.
Godzilla Minus One - This one slipped into my list right before Christmas. Some people grow up with Star Wars or Lord of the Rings or whatever, but for my brother and I we had the Godzilla movies. The recent US-made 'zilla flicks have been of diminishing quality but they still provide me some small amount of satisfaction for the lizard-brain. Minus One is a very different and very character-driven movie. Normally I'd be rooting for the big lad, but here he was so intimidating and the characters so well drawn that I was cheering them on instead.
Even if you're not a fan of kaiju movies, I'd recommend giving this one a watch. It's a brilliant anti-war allegory and absolutely the best Godzilla has been since the 1954 original. On a personal level, hearing the original Godzilla theme blasting out in a cinema was a real treat too.
I thought I played a lot of games this year, but statistics don't lie. As I wrote on Mastodon:
Of all the "isn't how we track you fun!!" Wrapped things this year, I enjoyed the Xbox Gamepass one the most because it showed that my girlfriend has basically worked a second job playing Age of Empires II
That said, I did fit a couple of gems in the gaps between AOE2:
Zelda: Tears of the Kingdom – I've been a Zelda fanboy since the LttP days so, if that means anything to you, I probably don't need to elabourate much more on why I loved this game. I'm completely in awe of how Nintendo managed to reuse so much of the game world from Breath of the Wild and still make it feel fresh and innovative. The level of creativity and fore-planning in this game is genuinely inspiring (web industry take note).
Also, the music. OMG the music.
Alan Wake II - This was a curveball; the sequel I never knew I wanted. I played the original game back when it came out and I was honestly lukewarm about it. When AWII launched around Halloween, I knew very little about it, but decided to take a punt on it. Oh damn, is it good. It has a pulpy and totally overblown story, parts of it are genuinely scary and its blending of game and live-action looks phenomenal even if it creaks a little bit on my Xbox Series S. Seriously, the game crashes very frequently on Series S and yet I couldn't even be mad at it. I needed to see what fresh madness would happen next.
So that was my 2023. If I'm entirely honest, it feels a little bit like I only just wrote one of these posts. This year has absolutely flown by for me, but I'm feeling ready for the changes that the new year will bring.
Cheers for reading this far, and here's to a happy and healthy new year in 2024! 🍻
2023-12-20 08:00:00
It's finally happened – with the release of Firefox 121.0 :has()
has landed in all browsers (though writing ":has()
has" is sadly no less awkward). In celebration, I thought it a good time to share one of my favourite practical uses of :has()
so far – scroll locks.
Imagine that you need to open a modal window, or flyout menu. To prevent from losing the user's place in the page whilst that modal is open – particularly on mobile devices – it's good practice to prevent the page behind it from scrolling. That's a scroll lock.
Let's take a look at how we might implement one.
Probably the simplest way to lock the user from scrolling a document is to add overflow: hidden
to the document body.
body.lock-scroll {
overflow: hidden;
}
This class will totally disable scrolling, so we can't just leave it in our HTML. It will need to be conditionally added and removed whenever a modal, flyout or scroll-locking element is active within the page.
One way to solve this might be to adjust the body class when opening or closing the scroll-locking element:
const openModal = () => {
// ...some code to open the modal
// then lock the scroll
document.body.classList.add('lock-scroll');
}
const closeModal = () => {
// ...some code to close the modal
// then unlock the scroll
document.body.classList.remove('lock-scroll');
}
This method is generally fine, but there are some complications.
What happens if you have multiple screen locks at the same time, for example? Let's say that our user clicks a hamburger menu to open a flyout whilst a modal is already open; both UI elements will lock the scrolling but, using the approach above, closing either the modal or the flyout would remove the .lock-scroll
class from the body and unlock the scrolling whilst the other element is still active.
Similarly, if you're in a framework with clientside routing then navigating to a different page won't automatically remove the body class. Unfortunately, that means the scroll will still locked when the new page is loaded in.
None of this is insurmountable by any means, but managing the body class to cope with edge-cases takes a bit of effort. CSS can make things simpler.
:has()
Because :has()
lets us modify a parent element based on its contents, handling scroll locks becomes a breeze. We can tweak the CSS declaration on our body element to use :has()
:
body:has(.lock-scroll) {
overflow: hidden;
}
Now, rather than managing state directly on the body by toggling a .lock-scroll
class with Javascript, we can now manage it on the markup of any element that needs to lock the page scroll:
<dialog class="lock-scroll">
<!-- some wonderful modal content -->
</dialog>
Instead of the lock being hinged on JS state-management, we've tied it to the contents of the DOM itself. As long an element with .lock-scroll
is in the DOM, the scroll we be locked.
Need to unlock the scroll? remove the element from the DOM. If there are multiple instances of .lock-scroll
, then the scroll will remain locked until all of them are gone. The same goes for route changes - if there's no .lock-scroll
class present in the new page then the scrolling will be automatically unlocked.
...and that's kinda all there is to it. Lush.
The above is a very simple example, but it's one that I've found useful. With support for :has()
now across all browsers, it's also one that is increasingly viable. The nature of CSS means it's pretty simple to expand the example to more elabourate use-cases too. You might, for example, wish to bind the scroll lock as a side-effect to changes in data or aria attributes:
body:has(.some-class[aria-expanded="true"]) {
overflow: hidden;
}
Whatever your application, :has()
looks to be a really handy tool and I'm stoked to see it finally get full support.
2023-11-16 08:00:00
Recently, as I started getting back into photography I read something that stuck with me (though sadly the source didn't). To paraphrase:
If you were able to take a great photo on a camera from 1979 then that same camera can still take a great photo today. New and shiny tech may make certain things easier, but a good photo is a good photo. Ultimately, the viewer won't give a shit which camera you used
As a frontend developer, I think about this a lot.