I love Henry’s guide: How to Make a Website.

There is precious little recent instructional material on how you can build a website, a perfectly great website, using just the raw materials of the web. Raw HTML & CSS, as it were. But that’s not all that Henry’s guide is about. It’s full of holistic advice going well beyond web design:

Be kind and curious and humble when you’re working with folks, and be extra forgiving of their mistakes, so when the time inevitably comes that you make your own, there’s perhaps some goodwill in the vault for you.


I do suspect if it’s not just lack of awareness that you can build a website with just hand-written raw HTML and CSS, but more of a then what? situation. Of course, we’re hoping CodePen is a place where that is a good option and are working to make that better every day. But there are plenty of options for getting that locally crafted HTML website to a real website, like Vercel, Netlify, GitHub pages, etc, which all make it pretty decently easy. It would be unfortunate if the DevOps knowledge for getting websites to production is just as much knowledge as actually making websites.

Oh hey this makes me think of a great term thrown out by Robb Owen: Hand-thrown frontends. He compares the website-making process to the ceramics process of making a bowl out of clay.

So, for me, the frontend bowl-making process is a cyclical, non-linear one. On a surface-level it probably doesn’t seem like it’s as efficient as assembling Lego bricks to order, but over time you’ll make more bowls and each phase of iteration will gradually shorten as your skill increases towards mastery.

I’m a sucker for a good ceramics analogy as that’s what my Bachelor of Arts was focused on in college.

Oh! And speaking of Ceramics, have you seen Charlotte Dann’s Ceramics project? It’s probably my favorite generative art project I’ve ever seen. This surface is totally code-generated:

Might as well be a photograph of real carved, glazed clay.

Oooooo tricky CSS challenge! Skewed Highlights. Vadim Makeev did up good:

You’d think transform: skew() would be involved somehow, but there isn’t a great opportunity for that, especially with arbitrary line breaks and such. Instead, the backgrounds are created with multiple gradient backgrounds (super clever) and fortunately box-decoration-break: clone; makes it look reasonable across lines.

Musing about slight alterations in CSS selector structure and how it affects selections? Sign me up for that party! Bramus compares:

.a .b .c { }
/* Versus! */
.a :is(.b .c) { }

They do look and behave similarly, but the former enforces that “c is a child of b is a child of a” situation solidly, while the latter allows for a situation where c is a child of a which is a child of b. That’s way too hard to understand in words, so here’s an image:

Admittedly I don’t reach for :is() all that much, but I suspect usage might go up a bit now that native CSS nesting is here and that all nested selectors must start with a symbol. So a quick way around wanting to nest element selector is wanking it in an :is():

header {
  h1 { } /* nope */

header {
  :is(h1) { } /* yup */

Let’s end with a little collection of developers looking forward to upcoming tech trends. This is, of course, popular in January and it’s March now but gimme a break I’m a little slow sometimes.