Mat has written this free course for you all about images on the web. Covering image formats, responsive images, and workflows, this is one to keep on speed dial.
Thursday, February 2nd, 2023
A person seeking help in a time of crisis does not care about TypeScript, tree shaking, hot module replacement, A/B tests, burndown charts, NPS, OKRs, KPIs, or other startup jargon. Developer experience does not count for shit if the person using the thing they built can’t actually get what they need.
Wednesday, February 1st, 2023
Imagine the web is a storefront, React is a hot dog car, and here’s Create React App dressed as a hot dog:
HTML is the cornerstone of the web — so why does creating a “React app” produce an empty HTML file? Why are we not taking advantage of the most basic feature of the web—the ability to see content quickly before all the interactive code loads? Why do we wait to start loading the data until after all the client-side code has finished loading?
So much ink spilled supposedly explaining what “the web platform” is …when the truth is you can just swap in the “the web” every time that phrase is used here or anywhere else.
Anyway, the gist of this piece is: the web is good, actually.
Saturday, January 28th, 2023
I feel like we need a name for this era, when CSS started getting real good.
I think this is what I’ve been calling declarative design.
Tuesday, January 24th, 2023
I quite like this change of terminology when it comes to making fast websites. After all, performance can sound like a process of addition, whereas efficiency can be a process of subtraction.
The term ‘performance’ brings to mind exotic super-cars suitable only for impractical demonstrations (or ‘performances’). ‘Efficiency’ brings to mind an electric car (or even better, a bicycle), making effective use of limited resources.
Sunday, January 22nd, 2023
Culture and style
Ever get the urge to style a good document?
No? Just me, then.
Well, the urge came over me recently so I started styling this single-page site:
I’ve followed this document across multiple locations over the years. It started life as a newsgroup post on rec.arts.sf.written in 1994. Ken McLeod published it there on Iain M Banks’s behalf.
The post complements the epic series of space opera books that Iain M Banks set in the anarcho-utopian society of The Culture. It’s a fascinating piece of world building, as well as an insight into the author’s mind.
I first became aware of it many few years later, after a copy had been posted to the web. That URL died, but Adrian Hon kept a copy on his site. Lots of copies keep stuff safe, so after contemplating linkrot, I made a copy on this site too.
But I recently thought that maybe it deserved a bit of art direction, so I rolled up my sleeves and started messing around, designing in the browser and following happy little accidents.
The finished result is still fairly sparse. It’s still entirely text, except for a background image that shows up if your screen is wide enough. That image of a planet originally started as an infra-red snapshot of Jupiter by the James Webb Space Telescope that I worked over until it was unrecognisable.
The text itself is the main focus of the design though. I knew I wanted to play around with a variable font. Mona Sans from Github was one of the first ones I tried and I found it instantly suitable. I had a lot of fun playing with different weights and widths.
After a bit of messing around, I realised that the heading styles were reminding me of some later reissues of The Culture novels, so I leant into that, deliberately styling the byline to resemble the treatment of the author’s name on those book covers.
There isn’t all that much CSS. I’ve embedded it in the head of the HTML rather than linking to a separate style sheet, so feel free to view source and poke around in there. You’ll see that I’m making liberal use of custom properties, the clamp function, and logical properties.
Originally I had a light mode and dark mode but I found that the dark mode was much more effective so I ditched the lighter option.
I did make sure to include some judicious styles for print, so if you fancy reading on paper, it should print out nicely.
Oh, and of course it’s a progressive web app that works offline.
I didn’t want to mess with the original document other than making some typographic tweaks to punctuation, but I wanted to break up the single wall of text. I wasn’t about to start using pull quotes on the web so in the end I decided to introduce some headings that weren’t in the original document:
- Legal System
I’m pretty pleased with how this little project turned out. It was certainly fun to experiment with fluid type and a nice variable font.
I can add this to my little collection of single-page websites I’ve whittled over the years:
Friday, January 20th, 2023
I’ve personally never really seen frontend as an assembly job. Lego is admittedly awesome, but for me the mental model of assembling Lego bricks in the required order until a Jira ticket can be marked as “done” feels too linear and too rigid for how I like to work. And that’s not to mention the pain that comes when you have to partially dismantle your bricks to correct some earlier misstep.
I like the pottery analogy.
Thursday, January 19th, 2023
Three attributes for better web forms
Forms on the web are an opportunity to make big improvements to the user experience with very little effort. The effort can be as little as sprinkling in a smattering of humble HTML attributes. But the result can be a turbo-charged experience for the user, allowing them to sail through their task.
If you’re using the right
input type value, you’re most of the way there. Browsers on mobile devices can use this value to infer which version of the virtual keyboard is best. So think beyond the plain
text value, and use
number when they’re appropriate.
But you can offer more hints to those browsers. Here are three attributes you can add to
input elements. All three are enumerated values, which means they have a constrained vocabulary. You don’t need to have these vocabularies memorised. You can look them when you need to.
inputmode attribute is the most direct hint you can give about the virtual keyboard you want. Some of the values are redundant if you’re already using an
input type of
But there might be occasions where you want a keyboard optimised for numbers but the input should also accept other characters. In that case you can use an
input type of
text with an
inputmode value of
numeric. This also means you don’t get the spinner controls on desktop browsers that you’d normally get with an
input type of
number. It can be quite useful to supress the spinner controls for numbers that aren’t meant to be incremented.
If you combine
pattern="[0-9]", you’ll get a numeric keypad with no other characters.
The list of possible values for
inputmode attribute provides a hint about which virtual keyboard to show, the
enterkeyhint attribute provides an additional hint about one specific key on that virtual keyboard: the enter key.
For search forms, you’ve got an
enterkeyhint option of
search, and for contact forms, you’ve got
enterkeyhint only changes the labelling of the enter key. On some browsers that label is text. On others it’s an icon. But the attribute by itself doesn’t change the functionality. Even though there are
enterkeyhint values of
next, by default the enter key will still submit the form. So those two values are less useful on long forms where the user is going from field to field, and more suitable for a series of short forms.
The list of possible values is
autocomplete attribute doesn’t have anything to do with the virtual keyboard. Instead it provides a hint to the browser about values that could pre-filled from the user’s browser profile.
Most browsers try to guess when they can they do this, but they don’t always get it right, which can be annoying. If you explicitly provide an
autocomplete hint, browsers can confidently prefill the appropriate value.
Just think about how much time this can save your users!
name value you can use to get full names pre-filled. But if you have form fields for different parts of names—which I wouldn’t recommend—you’ve also got:
You might be tempted to use the
nickname field for usernames, but no need; there’s a separate
As with names, there’s a single
tel value for telephone numbers, but also an array of sub-values if you’ve split telephone numbers up into separate fields:
There’s a whole host of address-related values too:
address-line3, but also
If you have an international audience, addresses can get very messy if you’re trying to split them into separate parts like this.
postal-code (that’s a ZIP code for Americans), but again, if you have an international audience, please don’t make this a required field. Not every country has postal codes.
Speaking of countries, you’ve got a
country-name value, but also a
country value for the country’s ISO code.
autocomplete value is specifically for the details of the current user. If someone is filling in their own address, use
autocomplete. But if someone has specified that, say, a billing address and a shipping address are different, that shipping address might not be the address associated with that person.
On the subject of billing, if your form accepts credit card details, definitely use
autocomplete. The values you’ll probably need are:
cc-namefor the cardholder,
cc-numberfor the credit card number itself,
cc-expfor the expiry date, and
cc-cscfor the security again.
Again, some of these values can be broken down further if you need them:
cc-exp-year for the month and year of the expiry date, for example.
autocomplete attribute is really handy for log-in forms. Definitely use the values of
username as appropriate.
If you’re using two-factor authentication, be sure to add an
autocomplete value of
one-time-code to your form field. That way, the browser can offer to prefill a value from a text message. That saves the user a lot of fiddly copying and pasting. Phil Nash has more details on the Twilio blog.
Not every mobile browser offers this functionality, but that’s okay. This is classic progressive enhancement. Adding an
autocomplete value won’t do any harm to a browser that doesn’t yet understand the value.
autocomplete value of
current-password for password fields in log-in forms. This is especially useful for password managers.
But if a user has logged in and is editing their profile to change their password, use a value of
new-password. This will prevent the browser from pre-filling that field with the existing password.
That goes for sign-up forms too: use
new-password. With this hint, password managers can offer to automatically generate a secure password.
There you have it. Three little HTML attributes that can help users interact with your forms. All you have to do was type a few more characters in your
input elements, and users automatically get a better experience.
This is a classic example of letting the browser do the hard work for you. As Andy puts it, be the browser’s mentor, not its micromanager:
Give the browser some solid rules and hints, then let it make the right decisions for the people that visit it, based on their device, connection quality and capabilities.
Tuesday, January 17th, 2023
Over the past 10 years or so, we’ve slowly but very surely transitioned to a state where frameworks are the norm, and I think it’s a problem.
Chain of tools
I shared this link in Slack with my co-workers today:
Cultivating depth and stillness in research by Andy Matuschak.
I wasn’t sure whether it belonged in the
#research or the
#design channel. While it’s ostensibly about research, I think it applies to design more broadly. Heck, it probably applies to most fields. I should have put it in the Slack channel I created called
The article is all about that feeling of frustration when things aren’t progressing quickly, even when you know intellectually that not everything should always progress quickly.
The article is filled with advice for battling this feeling, including this observation on curiosity:
Curiosity can also totally change my relationship to setbacks. Say I’ve run an experiment, collected the data, done the analysis, and now I’m writing an essay about what I’ve found. Except, halfway through, I notice that one column of the data really doesn’t support the conclusion I’d drawn. Oops. It’s tempting to treat this development as a frustrating impediment—something to be overcome expediently. Of course, that’s exactly the wrong approach, both emotionally and epistemically. Everything becomes much better when I react from curiosity instead: “Oh, wait, wow! Fascinating! What is happening here? What can this teach me? How might this change what I try next?”
But what really resonated with me was this footnote attached to that paragraph:
I feel seen.
I know I’m not alone. I know people who were driven out of front-end development because they felt the unspoken ultimatum was to either become a “full stack” developer or see yourself out.
The question I keep asking though: is the divide borne from a healthy specialization of skills or a symptom of unnecessary tooling complexity?
Mostly I feel sad about the talented people we’ve lost because they felt their front-of-the-front-end work wasn’t valued.
But wait! Can I turn my frown upside down? Can I take Andy Matuschak’s advice and say, “Oh, wait, wow! Fascinating! What is happening here? What can this teach me?”
Here’s one way of squinting at the situation…
There’s an opportunity here. If many people—myself included—feel disheartened and ground down by the amount of time they need to spend dealing with toolchains and build systems, what kind of system would allow us to get on with making websites without having to deal with that stuff?
I’m not proposing that we get rid of these complex toolchains, but I am wondering if there’s a way to make it someone else’s job.
I guess this job is DevOps. In theory it’s a specialised field. In practice everyone adding anything to a codebase partakes in continual partial DevOps because they must understand the toolchains and build processes in order to change one line of HTML.
I’m not saying “Don’t Make Me Think” when it comes to the tooling. I totally get that some working knowledge is probably required. But the ratio has gotten out of whack. You need a lot of working knowledge of the toolchains and build processes.
That doesn’t seem right. We should change it.
The whole article is great, and really charmingly written, with some golden nuggets embedded within, like:
- You’ll find that spending more time getting HTML right reveals or even anticipates and evades accessibility issues. It’s just easier to write accessible code if it’s got semantic foundations.
- In my experience, you will almost always spend more time overriding frameworks or compromising your design to fit the opinions of a framework.
- Always style from the absolute smallest screen your content will be rendered on first, and use
@media (min-width)queries to break to layouts that allow for more real estate as it becomes available.
- Always progressively enhance your apps, especially when you’re fucking with something as browser-critical as page routing.
I think some tools are a good idea. But as few as possible, and the easier they are to stop using, the better.
Now Michelle asks:
Suppose we want to stop using Tailwind one day?
So whenever possible, the safest, and most future-proof bet is to use the native features of the web platform.
Myself, I think some tools are a good idea. But as few as possible, and the easier they are to stop using, the better.
To paraphrase Michael Pollan:
Write CSS, not too much, mostly vanilla.
Monday, January 16th, 2023
There’s a broader point here about declarative design:
Setting very specific values may feel like you’re in more control, but you’re actually rescinding control by introducing fragility in the form of overly-specific CSS.
Wednesday, January 11th, 2023
I like to think of CSS as a conditional design language.
Yes! This is exactly what I’m talking about with declarative design!
Read on for some fantastic examples. And also, Ahmad makes a comparison between CSS and Figma, pointing out that the conditional, declarative possibilities currently aren’t available in graphic design tools.
Thursday, January 5th, 2023
I did not know about
box-decoration-break—sounds like a game-changer for text effects that wrap onto multiple lines.
Wednesday, January 4th, 2023
Styling a list of nested
details elements to create a beautiful lokking tree view, all in CSS, all nicely accessible.
Saturday, December 24th, 2022
All twelve are out, and all twelve are excellent deep dives into exciting web technologies landing in browsers now.
Wednesday, December 21st, 2022
Strong—and true—words from Alex.
Frontend’s failure to deliver in today’s mostly-mobile, mostly-Android world is shocking, if only for the durability of the myths that sustain the indefensible. We can’t keep doing this.
If you disagree, I encourage you to dive into the data that Alex shares.