This is a terrrific presentation by Chris, going through some practical implementations of modern CSS: logical properties, viewport units, grid, subgrid, container queries, cascade layers, new colour spaces, and view transitions.
Sunday, June 11th, 2023
Saturday, November 19th, 2022
I appreciate Hidde’s reluctance to participate in anything that looks like a pile-on, but in this case, it’s important to call out the bad behaviour so it doesn’t happen again.
The specific issues I’ve put in this post cross the line between honest mistakes and bad behaviour. They cross the line, because they consistute fraud (the livestream) and because they impact attendees, sponsors and speakers. The front-end community doesn’t deserve this, and I’m worried for people new to the industry, who get may assume this is normal or ok. It’s not normal.
Friday, November 18th, 2022
I’ve heard from multiple people about how much of a shitshow this event was. Worth remembering in case they try to pull the same shit again.
Tuesday, November 15th, 2022
A lovely fansite dedicated to the life and work of Paul Rand.
Sunday, November 28th, 2021
I like this high-level view of the state of CSS today. There are two main takeaways:
- Custom properties, flexbox, and grid are game-changers.
- Pre- and post-processers are becoming less and less necessary.
This is exactly the direction we should be going in! More and more power from the native web technologies (while still remaining learnable), with less and less reliance on tooling. For CSS, the tools have been like polyfills that we can now start to remove.
They could learn a thing or two from the trajectory of CSS: treat your frameworks as cattle, not pets.
Thursday, March 11th, 2021
It’s official. The extremely niche browser behaviour I documented is a bug.
When service workers met framesets
Oh boy, do I have some obscure browser behaviour for you!
To set the scene…
I’ve been writing here in my online journal for almost twenty years. The official anniversary will be on September 30th. But this website has been even online longer than that, just in a very different form.
Here’s the first version of adactio.com.
Like a tour guide taking you around the ruins of some lost ancient civilisation, let me point out some interesting features:
- Observe the
.shtmlfile extension. That means it was once using Apache’s server-side includes, a simple way of repeating chunks of markup across pages. Scientists have been trying to reproduce the wisdom of the ancients using modern technology ever since.
- See how the layout is
100vh? Well, this was long before viewport units existed. In fact there is no CSS at all on that page. It’s one big
tableelement with 100% width and 100% height.
- So if there’s no CSS, where is the
border-radiuscoming from? Let me introduce you to an old friend—the non-animated GIF. It’s got just enough transparency (though not proper alpha transparency) to fake rounded corners between two solid colours.
if (navigator.appName == "Netscape")
Note that these are not iframes, they are frames. Different thing. You could create single page apps long before Ajax was a twinkle in Jesse James Garrett’s eye.
If you view source, you’ll see a React-like component system. Each
frameset component contains
frame components that are isolated from one another. They’re like web components. Each frame has its own (non-shadow) DOM. That’s because each frame is actually a separate web page. If you right-click on any of the frames, your browser should give the option to view the framed document in its own tab or window.
Now for the part where modern and ancient technologies collide…
If you’re looking at the frameset URL in Firefox or Safari, everything displays as it should in all its ancient glory. But if you’re looking in Google Chrome and you’ve visited adactio.com before, something very odd happens.
Each frame of the frameset displays my custom offline page. The only way that could be served up is through my service worker script. You can verify this by opening the framest URL in an incognito window—everything works fine when no service worker has been registered.
I have no idea why this is happening. My service worker logic is saying “if there’s a request for a web page, try fetching it from the network, otherwise look in the cache, otherwise show an offline page.” But if those page requests are initiated by a
frame element, it goes straight to showing the offline page.
Is this a bug? Or perhaps this is the correct behaviour for some security reason? I have no idea.
I wonder if anyone has ever come across this before. It’s a very strange combination of factors:
- a domain served over HTTPS,
- that registers a service worker,
- but also uses framesets and frames.
I could submit a bug report about this but I fear I would be laughed out of the bug tracker.
Still …the World Wide Web is remarkable for its backward compatibility. This behaviour is unusual because browser makers are at pains to support existing content and never break the web.
Technically a modern website (one that registers a service worker) shouldn’t be using deprecated technology like frames. But browsers still need to be able support those old technologies in order to render old websites.
This situation has only arisen because the same domain—adactio.com—is host to a modern website and a really old one.
Maybe Chrome is behaving strangely because I’ve built my online home on ancient burial ground.
It’s all to do with navigation preloads and the value of
event.preloadResponse, which I believe is only supported in Chrome which would explain the differences between browsers.
According to this post by Jake:
event.preloadResponse is a promise that resolves with a response, if:
- Navigation preload is enabled.
- The request is a GET request.
- The request is a navigation request (which browsers generate when they’re loading pages, including iframes).
event.preloadResponseis still there, but it resolves with
Notice that iframes are mentioned, but not frames.
My code was assuming that if
event.preloadRepsonse exists in my block of code for responding to page requests, then there’d be a response. But if the request was initiated from a frameset, it is a request for a page and
event.preloadRepsonse does exist …but it’s undefined.
I’ve updated my code now to check this assumption (and fall back to
This may technically still be a bug though. Shouldn’t a page loaded from a frameset count as a navigation request?
Friday, December 24th, 2010
A gorgeous sci-fi short film with some fine interface porn.
Monday, March 2nd, 2009
This is beautiful. Really beautiful.
Tuesday, November 15th, 2005
What if the Force isn't a plot device... what if the Force is the plot?