Reading List
The most recent articles from a list of feeds I subscribe to.
Three ways to build Crouwel's Hiroshima poster in CSS
Recreating old posters, I figured there are at least two approaches to deciding how many grid tracks your component or page needs: one can make it visually perfect, the other is more flexible if content is bound to change.
In the past 1.5 year or so I spread my excitement for flexbox and Grid Layout through workshops. An assignment I used in each one, is to recreate Wim Crouwel’s iconic “Hiroshima” poster using CSS. Poster recreation in CSS is an idea, of course, popularised by Jen Simmons and her awesome Experimental Layout Lab. She has lots of poster experiments on that site, check it out if you have not.
I like having a poster recreation exercise in the workshop, as it lets people learn CSS properties, without worry over maintainability or other concerns that come in mind when doing real-world CSS coding. It also lets the participants build graphic designs that are wildly different from most websites, think outside of the box (oh wait, CSS is ALL boxes, as Hui Jing Chen explains in her Box Alignment talk).
Photos from the exhibition about Crouwel’s work at the Design Museum in London (2010), photos by Ben Terrett. On the right: the original Hiroshima poster.
One poster I like to use is Wim Crouwel’s “Hiroshima” poster. Crouwel is one of The Netherlands’ most influential graphic designers. As co-founder and designer at the influential agency Total Design, he worked on large corporate house styles. He is best known though, for the posters he designed for Dutch museums, including the Stedelijk Museum in Amsterdam. The “Hiroshima” poster was made for an exhibition in the Van Abbe Museum in Eindhoven, The Netherlands. It’s not a complicated poster, sporting the name of the exhibition, a subtitle, location and the opening times.
The letters used for the word “Hiroshima” were manually designed by Crouwel. They have inspired various typefaces, including “Shima” by Nate Navasca, which closely resembles it, and UT Morph by Oscar Cobo.
Column choices
If you look closely, you’ll find that the opening times and exhibition duration align with the stem of the second letter ‘h’. The subtitle aligns with the letter ‘o’. Presumably, this is on purpose.
A column for each stem
One way to design the columns for this poster, is to define a column for each of the stem: 17 in total. The minimal space between the letters can be the grid’s column-gap
. This leaves us closest to what we presume the poster maker intended.
We then need to decide one or more columns to each letter: one for the ‘i’ and three for the ‘m’, for instance.
A column for each letter
Another approach is to create a column for each letter, and let the columns be of auto
width. They will then grow with the letters contained in them.
The content-based choice
We could also base our track choices on the four bits of content (title, subtitle, opening times, exhibition duration). This is a more functional approach, and less precise. The bits of content will likely not fully align with the letters of the word “Hiroshima”.
Ok, show me the code!
I’ve built examples with all three approaches: 4, 9 and 17 columns.
The two extremes: 4 columns and 17 columns, visualised using Firefox’s built-in Grid Inspector.
4 columns
The 4 column has least markup and classnames related to the function of the element in the whole. With just those four columns, it does the bare minimum. Dates and opening times don’t align with the letters they’re supposed to align with. But had someone decided to change the exhibition’s name, little harm would be done.
I approximated the size of the columns by making them all 1 part of the available space:
grid-template-columns: repeat( 4, 1fr );
9 columns
My 9 column version, has each letter wrapped in a span. Only direct children of grid containers get to play in the grid game, but with display: contents
on the <h1>
, it gets skipped and its children become grid items. Warning: do not use display: contents
in production just yet, as the heading will lose its accessible role in most browsers.
In this one, the columns are of auto
size, so that they grow with their content:
grid-template-columns: repeat( 9, auto );
Note that this works because the letters are the largest things in their respective tracks. If we had put anything larger in the same column, for instance in another row, that larger thing would have made the whole column larger.
Because of display: contents
, the span
s within the h1
became grid items. With no explicit placement, they get auto-placed in a column of their own, allowing for alignment of content with the actual letters. With that in place, I then told all span
s to go to the correct row:
h1 span {
grid-row: 3;
}
17 columns
In the 17 column version, I’ve wrapped each letter in a span with a classname. I did not need to space each letter individually, but I did have to address differences in how many columns a letter should span
: the letters ‘i’ require one column, the letter ‘m’ requires three and all the others require 2. I did unique classnames for each letter, with the two h’s and i’s sharing one between them:
.hiroshima-r,
.hiroshima-o,
.hiroshima-s,
.hiroshima-h,
.hiroshima-a {
grid-column: span 2;
grid-row: 3;
}
.hiroshima-m {
grid-column: span 3;
grid-row: 3;
}
.hiroshima-i {
grid-column: span 1;
grid-row: 3;
}
Another, more abstract approach could be to have a span-1
, span-2
and span-3
classname.
What’s better?
Thanks for reading this far in a post that is just about grid columns. Basically, my point is about two approaches: visual perfection versus functional pragmatism. I’ve seen both in real world CSS. Either can be effective. Neither of the two is better, everyone can grid however they like.
I would say visual perfection makes more sense in a promotional type of website, where the site was designed just for one purpose, maybe to communicate a one off event. A conference that you already know the name of. That sort of thing.
The functional approach is ideal when working with a CMS, where content can change, or there are multiple instances of the same design work. It’s more resilient to change.
Originally posted as Three ways to build Crouwel's Hiroshima poster in CSS on Hidde's blog.
Console logging the focused element as it changes
When you build a Single Page Application, chances are that you manage some of the focus
through script. For debugging, it can be super useful to log the currently focused element to the Dev Tools Console.
Logging the focused element
The focused element is known in the DOM as document.activeElement
, so you can just console.log()
that if you want to know what the currently focused element is.
Logging it as it changes
Thanks to Eva, I recently learned a way to log the active element as it changes:
document.addEventListener('focusin', function() {
console.log('focused: ', document.activeElement)
}, true);
The focusin
event is like focus
, but it bubbles, so when any element within document
receives focus, focusin
bubbles all the way up to document
.
When I posted this on Twitter, Christian Schaefer helpfully pointed out that, although focus
does not bubble, it can be intercepted when the capturing
flag (addEventListener
’s third argument) is set to true
. Phil Walton then added that focus
fires also for non-interactive elements and when the window
receives focus. Even better!
So this is what you could use to log the active element when it changes:
document.addEventListener('focus', function() {
console.log('focused: ', document.activeElement)
}, true);
Also relevant: PPK’s Delegating the focus and blur events, over 10 years old, in which he explains that lack of bubbling in focus
makes sense, because we would not want it to bubble to window
, as the `window’ having focus means that the user has focused the entire browser window.
Originally posted as Console logging the focused element as it changes on Hidde's blog.
Linking to translations
The other day I worked on some front-end code that takes users to a version of the website in a different language. Two attributes can make such links more accessible: lang
and hreflang
. What’s the difference?
Strings in another language
The lang
attribute can expose what language a page is in, when it is added to the root tag. For example, a page in English, will likely have this as its root element:
<html lang="en">
You can also use lang
on any tag in a document, to signify a section, paragraph or word is in a different language. This is useful when you link to a translation. If the link text has a different language than the rest of the document, you can expose that.
A link with link text in Chinese, as spoken in Taiwan, one of my favourite countries:
<a href="/zh-TW">
中文
</a>
The same link, now with the language exposed:
<a href="/zh-TW" lang="zh-TW">
中文
</a>
That’s all. Note: this only means that the word within this tag is in a different language. It says nothing about the page we’re linking to.
Words marked up in an HTML element with a lang
attribute, will get read out with a voice in that language in Safari with VoiceOver and some versions of other screenreaders, depending on settings and voice availability
Links to pages in another language
If the page you’re linking to is in a different language, you can use hreflang
to signify that (hreflang in the spec).
For example:
<a href="/zh-TW" hreflang="zh-tw">
Chinese
</a>
If you link to a page in a different language and the text you use is also in a different language, both attributes can be used at the same time.
<a href="/zh-TW" hreflang="zh-tw" lang="zh-TW">
中文
</a>
To be very honest, I don’t know of an actual system using it for detection. Implementing the attribute doesn’t hurt though, if more of us do it, tools can more reliably take advantage of that. The hreflang
attribute is also used by people who want to increase their search engine rankings, in a per page setting exposed via a link
element or as a header.
Language tags: BCP 47
The format of languages used in lang
and hreflang
is specified in something called BCP47.
They consist of one or more subtags, separated by a hyphen (-). The first one is the primary language, for example en
for English and zh
for Chinese (zhōngwén means Chinese writing). Most are two characters, some are more.
There is a list of language tags on the Library of Congress website.
Summary
So, to sum up:
lang
on any HTML element describes what language is used in that elementhreflang
on a link (<a>
) describes the language of the page you’re linking to- both
lang
andhreflang
are in the format described in BCP47
Happy internationalising!
Originally posted as Linking to translations on Hidde's blog.
On the importance of testing with content blockers
I recommend everyone to browse with content blockers turned on. The goal: protection against tracking. Safari and Firefox have good tracking protection features. With more people using these features, we should test our sites with content blockers turned on.
Content blocking
In the age of surveillance capitalism, some browsers have started getting more aggressive in how they block ad trackers to protect the privacy of their users.
Firefox has had Tracking Protection since version 42. It works with a blacklist of domains. When something is blocked, it will show up in the Dev Tools Console (“The resource at X was blocked, because tracking protection is enabled”).
Safari not only can block trackers for you, it also allows third parties to define blocking behaviour. Third party blockers can match patterns in URLs and detect things like the domain a script is loaded on (same as site vs not same as site, the latter means third party). When a tracker is identified, developers can choose what to do: block it altogether, just block cookies or hide elements from the page. Users can install one or multiple content trackers. There is a “load without content blockers” feature (long press reload on iOS), but note users may be unaware of it. I know I was until very recently.
What can break
Four examples I encountered in the last few months:
- I wanted to purchase clothing on Zara’s website, to pick up in a store. On the part of the form where I had to select which store, nothing showed. I could also not go to the next step.
TypeError: X is null
was thrown in the browser Console. A Facebook tracking script was blocked by my content blocker, presumably the reason for the script to fail. - I wanted to find opening times at my local supermarket. Search did not yield results until I turned off content blockers.
- I wanted to open a hamburger menu. It did not open. (This one is very common, actually)
- A link did not work at all.
On this page, I could not select a store or press continue, because Facebook’s tracking script did not load
To understand the last example better, see Stephanie Hobson’s Google Analytics, Privacy, and Event Tracking, which shows how Google Analytics recommended tracking code breaks links for people who block the tracker.
We should not need to track to take people’s money. Or to let them find opening times, open a hamburger menu or follow a link. Metrics can be useful, but they are rarely questioned.
A working website: some strategies
I understand companies want behavioral data in order to improve their sites. But if it puts a stop to taking people’s actual money, doesn’t that defeat the purpose of why you have a website as a company? Is figuring out how many people open your hamburger menu more important than having the feature work at all?
Use no scripts
This one is easy in theory. It is hard in the reality of modern web development, because people will laugh at the suggestion. If your site does not rely on JavaScript to build features like to take people’s money, search for opening times, show a navigation on mobile or go to other pages, these features can potentially just work.
Progressive enhancement
If you manage to develop in a way that does not assume JavaScript (or CSS), you’re likely doing progressive enhancement of some sort. It means that when you build new features, you start with the very basic building blocks, like headings and lists. Simple HTML that describes the feature in a way the most basic browsers understand. You then turn it into something fancy, using web technology a modern as you like. For example, use Web Components to make it tabs, as Andy Bell described. If the fancy thing breaks, the basic building block likely still works.
Not only should progressive enhancement help make your site more robust and resilient, if your whole team can think this way, it can help setting priorities sensibly. See also Resilient Web Design, Jeremy Keith’s free book on building resilient web sites and Dear developer, a talk by Charlie Owen.
Conclusion
To build good websites, I think we should prioritise working websites above gathering potentially useful data (if doing that at all). As developers, we should keep in mind trackers could get blocked and, consequently, never rely on their availability.
Originally posted as On the importance of testing with content blockers on Hidde's blog.
Return of the blog roll
Personal blogs are making a comeback among web folks. I like this. I have even gone so far as to add a blog roll to this site, so that you can see which blogs I like to read (fwiw).
Personal blogs FTW
When I started getting interested in the web, about 15 years ago, blogs were how I learned new stuff. It was not just learning either, it was reading what interesting people were up to. This is something I heavily used RSS for: the data format that allows easy subscribing to content (or ‘syndication’). In an RSS reader, for whoever is unfamiliar with it, I was able to follow all the feeds I subscribed to in one place.
In the last 5-10 years, Twitter took over a lot of that. I stopped using an RSS reader at some point. If I discovered blog posts, it was because the authors tweeted about them, via round-ups like The Daily Nerd (it was great and is dearly missed) or via newsletters like Rachel Andrew’s CSS Layout News, David A. Kennedy’s A11y Weekly and Zoran Jambor’s CSS Weekly.
Twitter has become a little less attractive recently. They made changes so that third-party apps like Tweetbot are mostly broken. The platform’s leadership fails to deal with the abuse that happens to its users. They keep experimenting with orders that are not historic order… all this made me realise I should go back to consuming blogs directly. I have been gone back to reading blogs through an RSS reader for a couple of months now (I use Feedbin).
There seems to be a revival of RSS, Jonathan Snook noted this week:
I like that RSS seems to be making a very small comeback. I find it easier to keep track of and means I don’t have to be on constant lookout on Twitter for updates.
Sara Soueidan said reading RSS gives less noise:
My RSS reader is like a private, quiet, comfy reading room, compared to Twitter which is more like a crowded, noisy coffee shop.
RSS is a great means to take back control over the web we love from platforms like Twitter. Ben Ubois, founder of Feedbin, a service to read RSS, explicitly says so in his latest blog post, Private by default:
I want Feedbin to be the opposite of Big Social. I think people should have the right not to be tracked on the Internet and Feedbin can help facilitate that.
This is music to my ears.
Earlier this year, NetNewsWire, the 16 year old RSS reader for Mac, was returned to Brent Simmons, its original inventor. He plans to release a new reader, open source, and make it the very best.
Šime Vidas of Web Platform News recently published his list of over 600 RSS feeds, worth a scroll through.
So yes, more people are getting interested in using RSS again. And in personal sites.
This site now has a blog roll
For those who aren’t using it: this site has two RSS feeds: full articles and summaries. You can read them in whichever reader you like, or open the posts in the browser from your RSS reader. Then you’ll see my fonts of choice.
And, as of this week, this site has a blog roll. Blog rolls are lists of (personal) blogs, usually displayed in a sidebar of a website. They have disappeared from a lot of blogs in the past years (I do like Jeremy Keith’s bedroll), but I completely agreed with Marcus Herrmann, when he suggested they should make a comeback. I love blog rolls to discover more people to follow, sometimes outside my own bubble.
On this blog, the blog roll has sites of people whose stuff I like to read. The people that inspire my writing here. The blogs I can recommend. For what it’s worth. I hope more people will follow Marcus’ example.
Originally posted as Return of the blog roll on Hidde's blog.