Journal
Sets in JavaScript
I don’t often store things in a Set
in JavaScript, but maybe I should. The fact it will only store unique values makes it pretty handy.
One place I do currently use a Set
is for the TagList
in my 11ty-based personal website. I start by defining TagList
as a new, empty Set
. I then need to assemble all possible tags so iterate blog posts and for each add its associated tags to TagList
. This means I can be sure that all duplicates will be removed automatically.
As you would imagine, Set
has built-in methods for adding, deleting and iterating items. But if you need to do something beyond that, you can easily turn it into an array, for example by:
const myArray = [...mySet];
Also, browser support is pretty good. So although to date I’ve been safely confining my use to Node scripts for building my static site, I could probably be using it client-side, too.
Docsify – a magical Documentation Website generator
docsify generates your documentation website on the fly. Unlike GitBook, it does not generate static html files. Instead, it smartly loads and parses your Markdown files and displays them as a website.
I just completed a training workshop where the course notes were provided in a website created using this software (and hosted on Netlify), and was really impressed.
The Atkinson Hyperlegible Font (Braille Institute)
Braille Institute launch a new, free typeface promising greater legibility and readability for low vision readers.
What makes it different from traditional typography design is that it focuses on letterform distinction to increase character recognition, ultimately improving readability.
via @brucel
Cheating Entropy with Native Web Technologies (on Jim Nielsen’s Weblog)
This is why, over years of building for the web, I have learned that I can significantly cut down on the entropy my future self will have to face by authoring web projects in vanilla HTML, CSS, and JS. I like to ask myself questions like:
- Could this be done with native ES modules instead of using a bundler?
- Could I do this with DOM scripting instead of using a JS framework?
- Could I author this in CSS instead of choosing a preprocessor?
Fantastic post from Jim Neilson about how your future self will thank you if you keep your technology stack simple now.
(via @adactio)
Northern Road Trip, September 2020

Note: as I type this three weeks later, we’re about to re-enter tighter Covid restrictions, so I feel grateful to have had the opportunity for a much-needed change of scenery when we did, as it wouldn’t be possible now. I’m also thankful to everywhere we stayed for their care in taking appropriate precautions for their guests and generally for keeping going under trying circumstances.
In 2020 it's been pretty difficult to holiday abroad for two reasons: firstly, the small matter of a global pandemic; and secondly, the arrival of our Border Terrier puppy, Rudy. So we decided to make the most of our beautiful homeland, Scotland, and go on a road trip.
The plan was straightforward: we’d head primarily up the west coast, taking in new places and familiar favourites; we’d enjoy some “first holiday” fun with our furry pal; and over five nights we’d eat ourselves into a seafood-induced coma.
In reality, organising this holiday was trickier than we were used to, due to it being our first time searching for pet-friendly accommodation, a challenge which was compounded by many venues running at lower capacity due to covid considerations. However with the help of some great recommendations from friends, we found a handful of suitable spots.
In the end it worked out perfectly, and was a lovely way for us to celebrate our fourth wedding anniversary. Here’s the lowdown.
Monday
Following a quick stop to collect our hire car, we set off for Connel, near Oban.
The weather was decent, and there were early signs that Rudy would be a happy traveller. In fact we needed only one brief stop during the two and a half hour drive; at lovely Luss for a breath of fresh air and some shits and giggles (mainly shits).
By mid-afternoon we had arrived at our destination, The Oyster Inn, taken a moment to admire the view over Loch Etive, then donned our Covid masks to check-in and ditch our bags.
We made the 10 minute drive into Oban then enjoyed a saunter around the shops overlooking the bay, stopping to eat scallops at the harbourside Green Shack Seafood Hut. Aside from Rudy trying to eat everything on the ground around us, this was magic.
Later that night we ate dinner in The Glue Pot, our hotel bar-restaurant – Fish Pie and a beer for me, Scampi and a glass of wine for Clair. Good pub fare all round. The holiday was off to a fine start!
Tuesday
We started the day with breakfast in the hotel and it was a good’un: Clair opted for a “full Scottish”, and I had Eggs Royal (poached eggs, salmon, spinach, hollandaise sauce). With black clouds gathering ominously outside, this was exactly the kind of tasty fuel we needed.
We headed for Ganavan Sands and on arrival it was raining pretty heavily. However every cloud has a silver lining as this gave Rudy a chance to strut his stuff in his new Hi-Vis, waterproof jacket. We played fetch for a wee while and he had his first experience of paddling in the sea.

With our drookit dug in tow, we left for local historic attraction McCaig’s Tower, although when it became apparent that the final climb would be on foot in the rain we axed that plan, like the amateur adventurers we are. Instead we parked up in Oban and began hunting for lunch, while the rain continued unabated.
Frustratingly it was slim pickings for pet-friendly eateries and we endured a couple of knock-backs. Finally, after some frozen-fingered Googling, we found Markie Dan’s, like a pooch-friendly oasis in the desert. Clair ate fish and chips (which was dynamite) while I had chicken and rice soup and a smoked haddock and mozarella fish cake, washed down with a tasty local beer. Big up Markie Dan’s for saving the day! (And shout out to their toilets for unexpected X-rated vending machine weirdness.)
Sidenote: this wee lunchtime challenge prompted me to consider restarting a side-project I’d previously put on ice. The idea is an online directory of quality child and pet-friendly bars, restaurants and accommodation which – if you give it your current location – would list the places nearest to you. That would’ve been handy that day. Maybe someday I’ll get around to it.
With happy bellies we retired to the hotel for a rest, before it was time to head to Port Appin for dinner at the Pierhouse Hotel. Our pal Fiona is General Manager there and it had been on our visit-list for ages.
Despite bringing a canine companion we were graciously accommodated (thanks, David), although as it became clear how posh our surroundings were, we secretly began praying that the tiny terrier would be on his best behaviour.
The Pierhouse is beautifully located and the restaurant certainly lived up to its reputation.
For starters and mains we had:
- smoked salmon on cripy salmon skin;
- breaded oysters with squid ink mayo;
- a seafood platter;
- lemon sole; and on the side…
- samphire; and
- chips (obvs)

For dessert, Clair had the burnt cream, while I had their signature orange chocolate cremeux with buckthorn sorbet. (NB: despite the cast of other amazing dishes I’ve still to mention, as I look back on the overall trip I’m moved to award this dessert “Dish of the Holiday” – it really was off-the-scale!)
While dining, Rudy (who was stashed away under our table) was a bit of handful. In COVID-times, Scottish venues have no background music and are sparser than usual, so we were on high alert to catch any unacceptable doggy behaviours before they happened and marked us out as “the pain in the ass couple with the dog”. Fortunately, aside from a bit of potted plant nibbling and numerous escape attempts he didn’t do anything too visibly embarassing, although keeping one hand on him while trying to eat a plate of seafood was a bit like The Krypton Factor.
As we finished our meal, Fiona arrived to greet us and ushered us into “The Snug” for a whisky to cap the night (a Balvenie Port cask, and it fairly warmed the cockles.)
Fiona and crew are doing great things at The Pierhouse. It was lovely to catch up and a brilliant night overall.
Wednesday
We had time for one more breakfast at The Oyster Inn before leaving, and once again it hit the target. Clair went for the veggie scottish breakfast, while I had scrambled eggs and smoked salmon.
Our next stop was Glenmoriston, but before leaving Oban we had important matters to address. Following last night’s challenges with Rudy we resolved to find some superior chew-chews to keep him occupied during the remaining meal-times, so stopped in at a wee Pet Shop we’d noticed in town the previous day.
Enter Dynorod (not real name) – a stick of “Himilayan Yak Milk” that would usher in a zen-like mealtime peace we had hitherto thought impossible.
Tooled up and ready, we embarked on the most amazing sunshine drive from Oban to Kentallen (stopping at the Holly Tree Hotel for a great burger and walk along the pier) then through Ballachulish to Fort William. We’d travelled this route many times before, but this time the scenery looked even more incredible (especially just around Ballachulish). It was Scotland at its bonniest.

We then climbed over 1200 feet through the hills before settling at our destination, The Cluanie Inn. I can’t over-emphasise this: this location is stunning. You are literally right in the middle of the hills, with deer roaming free around you.
Spotting trestle tables behind the hotel we decided to check-in quickly then enjoy the last of the day’s sunshine with an al fresco beer. Unfortunately by the time I had returned with said beers, Clair was engaged in a battle of wills with the wee fella, who was going stir-crazy with all the space he found himself in. By relentlessly eating deer jobbies he kinda shattered our picture-perfect “beer in the hills” moment, but still, the thought was there…
That night we enjoyed a lovely dinner: I went for South Indian Garlic Chicken (the owners are Indian, so it seemed like a good time to change tack from seafood) while Clair had a roast pork stir fry. For desert we shared a Rhubarb and Apple Crumble with ice cream. Before bed we had a whisky and a game of Connect 4 in the lounge, while Rudy munched on Dynorod. Bliss.
Thursday
Breakfast at the Cluanie was great. Clair scratched a nostalgia itch with a bowl of Coco Pops, followed by a full Scottish. I had yogurt and muesli then scrambled eggs on toast.
Our next stop was Ullapool, way up north beyond Skye. Clair was really excited about this leg of the trip because she’d be reunited with The Seafood Shack and its owners, having enjoyed visiting earlier in the year as food photographer for their forthcoming recipe book.
The drive from Glenmoriston to Ullapool was beautiful, too, and sountracked perfectly by Clair’s “Alternative 80s” mixtape (taking in Television, Echo and The Bunnymen, Cocteau Twins) followed by our friend Andy’s excellent Go mild in the country playlist. Good times!
Arriving in Ullapool we made a beeline for The Seafood Shack and on arrival ordered 2 × Haddock Wrap (which Clair had been raving about for months). They were delicious. This gave us the necessary fuel to walk the Ullapool Hill Path which on a clear day such as it was offers fantastic views over the village, Loch Broom and the mountains beyond.

Back in the village we stopped back in at The Seafood Shack for Cullen Skink and Langoustines before it was time to check in to our home for the night, The Ceilidh Place. This hotel had been recommended by three separate friends and from the warm welcome (for both us and Rudy) and the lovely, cosy vibe, we could see straight away why people love it.
After check-in we had just enough time for a drink in their beer garden and a quick rummage around their bookshop before it was a time for a nap (this holiday business is pretty tiring…)
Later we headed to the hotel bar for a lovely dinner of Venison Stew (for me) and Fish and Chips (for Clair), sharing home-made baked cheesecake with berries for dessert. We chatted about some of our all-time favourite “long tracks” – Clair offering The Doors’ Riders on the Storm (no arguments from me) while I chipped in The Temptations’ classic Papa was a Rolling Stone.
Today was our wedding anniversary, and it had been nigh-on perfect.
Friday
Following a hearty breakfast (porridge for me; cooked breakfast for Clair) we had a wander around Ullapool. This was my first time visiting and I really liked the place. It’s a lovely, picturesque harbour village and, although fairly small, has plenty of good shops, great local food and drink, and friendly people of all ages.
Although you might think that visiting The Seafood Shack for a third time within twenty hours was bordering on the ridiculous, we popped our head in yet again for a farewell lunch. Clair had spineys (squat lobster) while I had mackeral paté with oatcakes. It was fantastic, yet again. What can I say – these folks really know their fish.
After vowing to come back to Ullapool again soon, we set off for Craigellachie, the final stop on our tour.
This was another enjoyable drive, alternating between countryside and busier roads and taking in not one but two football stadia: The Tulloch Stadium, home of Inverness Caley Thistle; and Mosset Park, home of the mighty Forres Mechanics. Sean Keveney’s 6 Music show was on the radio, and by pure coincidence the Uncle Frank’s Friday Floor Fillers section featured “Papa was a Rolling Stone” – which was every bit as good (and long) as I remembered it.
As we entered Moray Speyside we were deep within Malt Whisky country, and as fans of a dram it was exciting to pass one well-known distillery after another: Aberlour, Glenlivet, Cragganmore, Balvenie, Macallan, and more.
By 4:00 pm we arrived at our destination, The Craigellachie Hotel.
This place is great! It was definitely the poshest of our trip. It’s in a beautiful countryside location, has a lovely reception area and comfortable rooms, and an amazing bar-restaurant, The Copper Dog.
That night we had probably our favourite dinner of the holiday. For starter, Clair chose scallops with cauliflower pureé while I had haggis bon-bons in a home-made brown sauce. For our mains, Clair had their fish special: cod with sweetcorn and crab, with a side of mac and cheese. I dediced to push the boat out for our last night and had a ribeye steak. Every dish was amazing and unsurprisingly we had zero room for dessert.
To wash it down I had a Spey Valley 1814 lager then a Windswept APA. Both local and great. Clair had an Edinburgh gin.
A special shout out to the staff in the Copper Dog; they were all super-friendly and great with Rudy, including director Kevin who came over to chat before finding us a wee post-dinner table at The Quaich, their upstairs whisky bar. It would have been rude not to, so we retired there for a wee dram. With over 900 whiskies from around the world on offer it was tough to choose, but with Rudy getting tired and threatening to drag the family name through the mud in such a plush environment, we made it quick and I grabbed an Aberlour 12 (which I love) while Clair had a Glenrothes. This is a room you could definitely spend some time in, though!
Saturday
It was time to head home.
After a lovely breakfast at The Craigellachie, we made a brief stop at the nearby Aberlour distillery where I nipped into the shop to pick up a bottle of the same drop I’d had the previous night, with a wee branded glass as a souvenir.
We arrived home happy. It’s great to know you can have such an amazing holiday on your doorstep.
Thanks again to all the friends who provided recommendations.
How to hide elements on a web page
In order to code modern component designs we often need to hide then reveal elements. At other times we want to provide content to one type of user but hide it from another because it’s not relevant to their mode of browsing. In all cases accessibility should be front and centre in our thoughts. Here’s my approach, heavily inspired by Scott O’Hara’s definitive guide Inclusively Hidden.
Firstly, avoid the need to hide stuff. With a bit more thought and by using existing fit-for-purpose HTML tools, we can perhaps create a single user interface and experience that works for all. That approach not only feels like a more equal experience for everyone but also removes margin for error and code maintenance overhead.
With that said, hiding is sometimes necessary and here are the most common categories:
- Hide from everyone
- Hide visually (i.e. from sighted people)
- Hide from Assistive Technologies (such as screen readers)
Hide from everyone
We usually hide an element from everyone because the hidden element forms part of a component’s interface design. Typical examples are tab panels, off-screen navigation, and modal dialogues that are initially hidden until an event occurs which should bring them into view. Initially these elements should be inaccessible to everyone but after the trigger event, they become accessible to everyone.
Implementation involves using JavaScript to toggle an HTML attribute or class on the relevant element.
For basic, non-animated show-and-hide interactions you can either:
- toggle a class which applies
display: none
in CSS; or - toggle the boolean
hidden
attribute, which has the same effect but is native to HTML5.
Both options work well but for me using the hidden
attribute feels a little simpler and more purposeful. My approach is to ensure resilience by making the content available in the first instance in case JavaScript should fail. Then, per Inclusive Components’ Tabs example, JavaScript applies both the “first hide” and all subsequent toggling.
Here’s some CSS that supports both methods. (The hidden
attribute doesn’t strictly need this but it’s handy to regard both options as high-specifity, “trump-everything-else” overrides.)
.u-hidden-from-everyone,
[hidden] {
display: none !important;
}
For cases where you are animating or sliding the hidden content into view, toggle the application of CSS visibility: hidden
because this also removes the element from the accessibility tree but unlike display
, can be animated. Note that with visibility: hidden
the physical space occupied by the element is still retained, therefore it’s best to pair it with position: absolute
or max-height: 0px; overflow: hidden
to prevent that “empty space while hidden” effect. For example:
.off-canvas-menu {
visibility: hidden;
position: absolute;
transform: translateX(-8em);
transition: 250ms ease-in;
}
[aria-expanded="true"] + off-canvas-menu {
visibility: visible;
transform: translateX(0);
transition: visibility 50ms, transform 250ms ease-out;
}
Hide visually (i.e. from sighted people)
We’ll usually want to hide something visually (only) when its purpose is solely to provide extra context to Assistive Technologies. An example would be appending additional, visually-hidden text to a “Read more” link such as “about Joe Biden” since that would be beneficial to screen reader users.
We can achieve this with a visually-hidden
class in CSS and by applying that class to our element.
.visually-hidden:not(:focus):not(:active) {
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}
Essentially this hides whatever it’s applied to unless it’s a focusable element currently being focused by screen reader controls or the tab key, in which case it is revealed.
Note that if adding to link text to make it more accessible, always append rather than inserting words into the middle of the existing text. That way, you avoid solving an accessibility for one group but creating another for another group (Dragon speech recognition software users).
Visually hidden until focused
There are other CSS approaches to hiding visually. One approach is to not only add position: absolute
(removing the element from the document flow) but also position it off-screen with left: -100vw
or similar. The use case for this approach might be when you want your visually hidden element to support being revealed and for that reveal to occur via a transition/animation from off-screen into the viewport. See Scott O’Hara’s off screen skip-links example.
Hide from Assistive Technologies (such as screen readers)
We sometimes hide visual elements from Assistive Technologies because they are decorative and have accompanying text, for example a “warning” icon with the text “warning” alongside. If we did not intervene then Assistive Technologies would read out “warning” twice which is redundant.
To achieve this we can apply aria-hidden="true"
to our element so that screen readers know to ignore it. In the following examples we hide the SVG icons within buttons and links, safe in the knowledge that the included “Search” text is providing each interactive element with its accessible name.
<button>
<svg aria-hidden="true" focusable="false"><!--...--></svg>
Search
</button>
<a href="/search">
<svg aria-hidden="true" focusable="false"><!--...--></svg>
Search
</a>
Reference: Contextually Marking up accessible images and SVGs
How I read the web
I’m currently interested in how to spend less time on social media platforms so as to be less exposed to ads, algorithms and general ill-effects. One approach I’m trialling is going back to the old school and using RSS to receive and aggregate updates from the people I follow, allowing me to read them in a central, noise-free place and not have to use social platform websites and apps.
I use the free, open source Mac and iOS app NetNewsWire on my MacBook. This is where I tend to add and organise my RSS feeds as it has a good UI, for example for arranging feeds into suitable folders.
If I want to read new items away from my Mac (on my phone, or on another computer), I use Feedbin – either the website or the iOS app. NewsNetWire and Feedbin sync pretty seemlessly so any organisation I’ve done in NetNewsWire is visible in Feedbin.
Feedbin is paid (I currently pay 5 USD per month). It has a slick UI and, since it’s a website accessible from anywhere, could be treated as your “central hub” for reading.
Feedbin also offers a few very interesting features.
- You can use it to subscribe to email newsletters, because it provides you with an email address for that purpose. This means you can have your newsletters arrive into the same central place as your RSS feeds;
- You can subscribe to Twitter accounts, and choose to filter tweets by only those with links or media attached (in theory the “more interesting” tweets);
- there’s a “Send to Feedbin” bookmarklet that essentially provides a one-click “Read later” function for use when browsing the web. This is a really handy feature because sometimes when I’m browsing I want to mark an article as “read later” rather than bookmarking it on my website, because until I’ve read it I won’t know if it’s bookmark-worthy. Having this feature destresses online life a little by stopping me leaving lots of browser tabs open at articles I “need to read”! I previously used Instapaper (and their bookmarklet) for this function, but again, it makes sense for me to bring everything into one place (Feedbin);
- You can “star” (i.e. save) items you’ve read but want to revisit, which is handy when browsing your “Unread” list on the move; and
- You can “share” items to well-known services (Twitter, Facebook etc) but interestingly also to a “custom service” by providing a URL. I could see me using this in future to bookmark an article on my own website.
I’m also currently trialling RSS.app for its ability to let me type in an Instagram user profile URL then give me back an RSS feed URL which I can add into Feedbin, and that’s working well so far, too.
Note: many thanks to Chris Coyier whose post NetNewsWire and Feedbin pointed me toward these excellent RSS clients.
A Guide To The State Of Print Stylesheets In 2018 - Smashing Magazine
Rachel Andrew explains how to write CSS for a nicely optimised printed page that uses a minimum of ink and paper and ensures that content is easy to read.
I really like the section on Workflow that compares the options of
- organising your print styles as a separate stylesheet loaded via a
<link>
in the<head>
(this is the “traditional” approach); versus - using
@media print {}
in your main styles, which opens up the opportunity to locate each component’s print styles beside its main styles.
As Rachel notes, the first option might feel tidy (and keeping print styles separate reduces the size of your main stylesheet) however on larger sites this approach can lead to print styles being “out of sight, out of mind” and poorly maintained.
I think there will always be a need for 80% global print styles, supplemented by a sprinkling of component-specific print styles (and maybe even the odd utility class). It’s just a case of how you organise this.
I had an idea that you could maybe put the global print styles in a separate sheet and locate the component styles beside components in the main stylesheet however because we tend to want global print styles to add to and override main styles you’d want the print_globals file coming after the main styles, but that then screws up the order of the component-specific print styles. When @layers
with <link>
is supported perhaps this could all work! Until then, the future of print CSS for large design systems is perhaps Option 2: colocate print styles with screen styles.
Better Alt Text
I’ve just read The A11Y Project’s page on alt
text.
As most of us know, the HTML alt
attribute is for providing “alternate text” descriptions of images to help ensure people do not miss out on information conveyed by graphics. This can help people using assistive technology such as screen readers, and in situations where images are slow or fail to load.
The article made some interesting points and even though I’ve been using the alt
attribute for years I found three common cases where I could improve how I do things.
Avoid starting with “photo of…”
Don’t begin alternative text with “photo of…” or “picture of…”. Assistive technologies already indicate the role of the element as an “image” or “graphic”. Redundancy makes for a poor user experience.
Avoid including the word “logo” in logo images
If the image is a company’s logo, the alt
should be the company’s name. Adding the word “logo” as part of the alternative text is neither necessary nor useful. (One thing I found helpful here is to think of the way I, as a sighted person, perceive Apple’s logo. I just think “Apple”, not “Apple’s logo”, so I guess the same principle applies.)
If using an image multiple times on the page, tailor the alt
text
Using an image several times in a website doesn't necessarily mean the alt attribute should be the same for each instance. For example, when using a logo in the website’s header this often doubles as a link back to the home page. In this example, the alt
would be most useful as “Apple - Homepage”. If that same logo were used in the footer of the site alongside the text “Apple, copyright 20XX”, then the logo should have an empty alt (alt="") so as to avoid creating a redundant announcement of the company’s name.
Ledger of Harms
Here’s a list of factoids describing societal harms caused by technology platforms, each supported by a citation.
Under immense pressure to prioritize engagement and growth, technology platforms have created a race for human attention that’s unleashed invisible harms to society. Here are some of the costs that aren’t showing up on their balance sheets.
(via @adactio)