Tags: worldwideweb
64
Wednesday, October 30th, 2024
Saturday, October 12th, 2024
It turns out I’m still excited about the web
While I’ve grown more cynical about much of tech, movements like the Indieweb and the Fediverse remind me that the ideals I once loved, and that spirit of the early web, aren’t lost. They’re evolving, just like everything else.
Monday, August 5th, 2024
The next decade of the web | James’ Coffee Blog
After the last decade, where platforms have emerged as a core constituent of the web on which many rely, it may feel like things cannot change. That the giants are so big that there is no other way. Yet, to give into this feeling – that things can’t change – is not necessary. It is the way it is is not true on the web. We can make change. It’s your web.
Tuesday, May 7th, 2024
Declarative Design
A presentation given at the final An Event Apart in San Francisco, as well as at Pixel Pioneers in Bristol, Web Summer Camp in Croatia, and Wey Wey Web in Spain.
- Download the slides
- Watch the video
I want to talk to you today about declarative design. But before I get to that I want to talk to you about music.
I want to talk about two different approaches to musical composition. I want to compare and contrast.
Classical
On the one hand, I’ll take this man as an example. This is Wolfgang Amadeus Mozart, a classical composer. He’s got this amazing music in his head and he can get that down onto sheet music which is very specific, very accurate. You can note down what notes to play, how long to play each note for each instrument, even some instructions on how to play the music.
So very accurate, very specific. That’s one approach to to musical composition.
Jazz
The other approach is very different and I’m going to use this man as an example. This is Miles Davis, from the jazz side of things. And his approach to composition was very different to Mozart.
Take something like his classic album, Kind Of Blue. He comes into the studio with sketches, with maybe some scales and no rehearsal for the musicians. And what resulted was absolutely amazing!
Like So What?, the opening track. That’s where the instructions were literally “Let’s do 16 bars in D Dorian then another eight bars and D flat Dorian and go back to D Dorian eight bars.” That’s as much structure as there is. And what comes out is absolutely amazing.
So these are two different approaches to musical composition: the classical and the jazz approach. Very different styles.
I think there’s a corresponding kind of split that you can see in the world of programming. You can divide programming into two different categories as well.
Imperative programming
On the one hand you’ve got imperative programming. Most programming languages are imperative programming languages. This is where you describe step-by-step what the computer should do. You give it clear instructions. Very specific. This makes it very powerful. It makes it general purpose. Maybe hard to learn because there’s a lot you have to understand before you can write those instructions.
Classic pseudo-code for an imperative language would be something like this. These step-by-step instructions:
- create an array of stuff,
- loop through each item,
- check to see if a condition is true,
- return the result.
You’ve got arrays and loops and ifs and else’s and returns: all the classic bits that go into general purpose imperative programming languages.
Declarative programming
The other category of programming language is declarative programming. This is where you don’t give step-by-step instructions to the computer. Instead you describe the outcome you want and you leave the implementation details to the to the language. You don’t describe the specific steps.
These are often domain-specific. They’re usually not general purpose languages and they’re probably less powerful than imperative languages. But on the other hand they may be easier to learn because you don’t have to get into all the the nitty-gritty that you do with an imperative programming language.
A classic example of a declarative programming language would be something like Structured Query Language or SQL. You describe what you want. You leave the details to the database. So you write something practically in English here:
select items from table where condition is true
Now it might be that under the hood the programming language is going to create an array of items, loop through each one, check if the condition is true and return the result but you don’t need to care about that. You don’t have to write those specific instructions. You describe the outcome you want.
Those are the two categories of programming language: imperative and declarative.
With that in mind let’s turn our attention to the medium where I work and I’m sure a lot of you do as well, which is the World Wide Web.
The World Wide Web
Let’s go back to the the birth of the World Wide Web, which is thanks to this gentleman. This is Sir Tim Berners-Lee working at CERN in the 1980s. He’s trying to solve the problem that there’s just so much information and how to manage it. So he writes this memo, this proposal. Information Management: A Proposal.
Terrible title, riddled with typos, incomprehensible diagrams and yet his supervisor Mike Sendall must have seen some some promise in it because he scrolled across the top:
vague but exciting.
This was March 1989. Tim Berners-Lee gets to go ahead to do that information management project which turns into the World Wide Web.
Now Tim Berners-Lee had some ideas about how to approach programming in general but also information management. He’s got design principles.
The principle of least power
For example, one of the principles he wants to adhere to is the principle of least power. The principle of least power states that:
for any given purpose, choose the least powerful language
…which sounds really counterintuitive. Why on Earth would I choose a less powerful language to accomplish what I want to do?
But this goes back to the declarative/imperative split, because the less powerful language may also be easier to learn, maybe more robust, less fragile.
HTML
He certainly puts that into practice when he creates HTML which is very much a declarative language. The classic case of a declarative language. It’s domain-specific. It’s for the web only.
Interestingly it’s fault-tolerant. By that I mean if you write some HTML and you make a mistake or you just type out an element that doesn’t even exist, the browser doesn’t throw an error . It doesn’t refuse to render any of the HTML that comes after that mistake. It just ignores what it doesn’t understand and carries on.
That actually turns out to be very powerful and I think maybe it’s only possible because HTML is a is a declarative language.
CSS
A couple of years later we get the next language on the web which is CSS. This is also a declarative language. It is also fault tolerant. If you’re writing CSS and you give the browser something it doesn’t understand it doesn’t choke on it. It just ignores it and carries on processing the style sheet. Again that’s very powerful.
But you might be thinking, “Hang on— CSS? Declarative? No no no, surely when I’m writing CSS I’m telling the computer exactly what to do? I’m telling the computer exactly how to style things.”
No. You’re not. It’s worth remembering with CSS you’re not telling the browser to do anything you’re making suggestions. Eric Meyer once said that every line of CSS is a suggestion to the browser. I think that’s worth bearing in mind.
Cascading HTML Style Sheets
Now CSS did not come from Tim Berners-Lee. The original proposal came from Håkon Wium Lie in an email in 1994. The original proposal was called Cascading HTML Style Sheets and he puts forward some ideas for how this could look.
h1.font.size = 24pt 100%
h2.font.size = 20pt 40%
This isn’t what we ended up with. You can see the syntax isn’t like the CSS today but you can kind of make sense of it. You can kind of understand what’s going on. I see this is setting the font size of all the H1s to 24 points and all the H2s to 20 points.
But hang on. What’s going on here with these percentages? 100? 40?
Well, what the percentages indicate is this early idea called influence in CSS where you as the author would basically specify how much do you care about this particular style. Like 100, I really want the H1s to be 24 points. But 40, I don’t care so much.
Influence
The idea was that that there were these competing concerns. There’s you, the author of the style sheet, the person making the website. There’s the browser itself which will have opinions in the user agent style sheets about how things should be styled. And really importantly, the user. The user should also have a say.
And this was the default in early browsers. You would have user style sheets—not user agent style sheets—user style sheets so the user could specify how they wanted things.
The idea with influence was that the browser would somehow hand-wavingly figure out exactly the right number to come up with. It obviously didn’t work. And we don’t have user style sheets anymore in any of the major browsers, which is a real shame. You can install browser extensions to do the same thing so it’s a bit of a power user feature, although if anyone’s played around with The Arc browser they’ve kind of got a similar thing. They call it boosts but it’s basically like user style sheets.
Preference queries
I do see almost a little bit of resurgence of this idea of influence though coming back into CSS. I see it in media queries level five where we have the so-called preference queries, where now the user can at least specify their preference, usually at the operating system level. Like I prefer reduced motion. I prefer reduced data. I prefer a dark color scheme.
Now it’s not quite the same as influence because it’s it’s up to us as developers to honor those preferences. But I like it because it’s again getting back to not thinking of CSS about giving precise instructions but it turns it into more of a dialogue with the user. Instead of the designer dictating their wishes upon all the users, it’s more like a conversation.
“What do you want? What do you care about?”
“Well, here’s what I care about. Let’s come to some kind of agreement.”
I like that. I think that’s good. I want to see more of that kind of dialogue happen on the web rather than just us dictating to users.
JavaScript
There’s one final language on the web. That’s JavaScript. That came along a few years later.
This is not a declarative language. This is an imperative language which makes it more powerful. You can do a lot more with JavaScript.
But JavaScript is not fault tolerant. In other words if you do make a mistake in your JavaScript or give the browser something it doesn’t understand it will stop at that point it will not parse any further. So it’s less resilient than HTML or CSS.
So this is what we have on the front end of the web. These three languages: HTML, CSS ,and JavaScript. Two declarative and fault-tolerant languages. One imperative language that isn’t fault tolerant.
Fault tolerance
I fell into a trap of thinking for a while “Oh, all declarative languages are fault-tolerant.” I guess I was seeing causation where there’s just correlation. That’s not true. You can absolutely make a declarative language that is not fault-tolerant.
In fact XML is a perfect example. The parsing instructions for XML say “if you see a mistake, stop: do not render anything; just quit right then.”
So not all declarative languages are fault tolerant. But I think we’re lucky on the web that the two we have are fault tolerant. I think that makes the web more accessible to people.
I think it would be very hard to make a fault-tolerant imperative language. It would be impossible to debug an imperative language if it just ignored what it didn’t understand and carried on.
This is kind of how I like to approach building on the web, in this order:
- the foundations of HTML for the structure,
- I’ll layer on my suggestions for styling with CSS and then, if I need to,
- I’ll reach for JavaScript to do the more powerful behavioral stuff.
Mindset
So in programming we’ve got these two approaches, these two categories of programming languages: imperative and declarative. But I think more importantly what we have is two different mindsets, two ways of approaching how you solve a problem: an imperative way and a declarative way. And the kind of mindset you have will probably influence the kind of languages you prefer, the kind of languages you gravitate towards.
Let’s take a a problem we’re trying to solve on on the web where we want to make a component, a button component.
How will we go about making this button component? Because a nice thing on the web is there’s no one way of doing things. You can do things however you like.
One approach would be a very imperative way. We reach straight for JavaScript. We’d have the bare minimum HTML, just a div
or something. Throw in a bunch of event handlers to handle those clicks. Don’t forget you got to handle keyboard support as well. Got to make sure it’s accessible too so you’ll need to put in some ARIA roles and all that stuff.
So that’s one way to do it.
Or just use a freaking button
element.
This would be the declarative approach.
So which approach would you go for?
Now I know what I would do. Mostly because I’m just lazy. I don’t want to have to do all this when I can do this. I’m absolutely going to reach for the declarative approach, which kind of reflects my general approach with client-side JavaScript on the web which is:
JavaScript should only do what only JavaScript can do.
That means if there’s a way of doing it in HTML or CSS, do it in HTML or CSS. Only reach for JavaScript when you when you absolutely need to.
(This is client-side Javascript I’m talking about here. When you’re doing something on a server do what you want. It’s a different environment. I’m talking about in the browser on the World Wide Web.)
Okay, so I know how I would do it. But I’m trying to understand why would anybody do this? Why would anybody reach for JavaScript immediately and do the over-engineered version?
I don’t want to just think “Oh, they don’t know what they’re doing!” That doesn’t feel right. I want to understand the mindset that’s going on.
I’m going to reach for a button
element because I get so much for free. I get some styling for free but I can change it. I get interactivity for free. I get the keyboard support for free. It’s accessible by default. So if the browser gives you all the styling and behavior for free, why would you invent everything from scratch and reject that?
I think it’s about control.
Control
This goes back to that mindset. I think if you have this imperative mindset then control is probably a priority. You want to understand exactly how things work in precise step-by-step instructions. I feel like people with this imperative mindset, they’re probably coming from a computer science background where you’re used to specifying everything very precisely. And if that’s your attitude then those free stylings and behavior you get from the browser, those aren’t features— they’re bugs.
Because, well, what if there’s some unintended side effects? If you haven’t written it yourself how do you know how it’s going to behave in every situation? You don’t. Whereas if you invent everything from scratch it feels like you’ve got total control.
Declarative approaches can feel like giving up control: I’m going to leave the details to the web browser, I’m going to trust that the web browser handles the keyboard support and accessibility.
But I feel like this control comes at a cost. I’m not sure you really gain control. I think you get the feeling of control. But it always involves making assumptions, whereas a declarative mindset is about avoiding assumptions.
Assumptions
Let me illustrate what I mean. To illustrate this I’m going to use a declarative language but show you how the mindset could still be imperative.
Let’s say we’ve got a button and we want to style it so we’re going to use CSS, a declarative language. I might write some CSS like this:
button {
font-size: 16px;
padding-left: 16px;
}
Absolutely nothing wrong with the CSS. Font size 16 pixels, padding left 16 pixels, on a button. That’s fine.
But is that what I really mean?
When I say font-size: 16px
do I really mean the default browser font size? (which is 16 pixels most of the time)
I could be more intentional about this. When I say 16 pixels what I mean is the default browser font size: one rem.
button {
font-size: 1rem;
padding-left: 1rem;
}
Now if the user changes their default font size my button will change accordingly. I’ve removed that assumption that the default browser font size is always going to be 16 pixels.
Actually when I say padding-left
is one rem, do I really mean padding -*left*
? Or do I mean the padding at the start of the text?
If that’s what I mean then I can say that. I can say padding-inline-start
is one rem.
button {
font-size: 1rem;
padding-inline-start: 1rem;
}
Now inline-start is the same as left if it’s a left-to-right language like English. But I’m making an assumption that it’s going to be presented in a left-to-right language like English when I use padding-left
.
This is again removing that assumption. I might not have any plans to translate my website myself, but users can translate my website. It’s more of that that two-way conversation with the user. If they want to do that, let’s allow them to do that. So again I’ve removed an assumption there.
But if I want to really get into a conversation with the user and how they come to me to look at this website I could start to adjust the font size to be relative to their browser width by using the the viewport width unit here: vw
.
button {
font-size: calc(0.5rem + 0.666vw);
padding-inline-start: 1rem;
}
I throw it into a calc
with a bit of rem
. The reason I’m doing this is that if you just use viewport width then the font size can’t respond to changing. So mixing it up with a relative unit like this keeps it accessible; people can change their their font size.
But the point here is that the text in the button now could change depending on the browser width. I could do that with media queries but then you’d be jumping at these different break points. This keeps it fluid the whole time.
But maybe I’ve gone too far here. Because maybe at small sizes it’s going to get way too small and at large screen sizes is going to get way too big. That’s okay. I can put guard rails in place.
button {
font-size: clamp(
1rem,
0.5rem + 0.666vw,
1.5rem
);
padding-inline-start: 1rem;
}
We’ve got this clamp
function in CSS. In the middle I’ve got the same declaration I had before( but I don’t even need to use calc
when I use clamp
) but what I’ve got on either side is like a minimum and a maximum: don’t ever go below one rem and don’t ever go above 1.5 rems. Let it flow in between those.
Now the truth is I probably wouldn’t do this on a button
element. I’d probably want my whole interface to to respond like this. So I’d probably do it on the body
and say let the font size adjust. It’s going to be relative to the the viewport but it’s never going to be lower than that it’s never going to be higher than that. And then you end up with an interface that just scales fluidly with font size.
Now I’ve kind of given up a lot of control here. Because if you were to ask me “What is the font size when the screen width is 1024 pixels wide?”my answer would be “I don’t know …but I know it’ll look good.”
I know that everything will be in proportion and I know it will never get too small and it’ll never get too big.
In a way I’m giving up control so that I can have more of that dialogue with the user, more of that conversation.
Utopia
This idea of fluid typography—and fluid spacing as well—is what’s at the heart of a project called Utopia I highly encourage you to check out utopia.fyi
Full disclosure: Utopia started life at Clearleft, the agency I work at. It’s the work of Trys Mudford and James Gilyead.
It’s kind of like clamp
on steroids. You set the boundary conditions. In this case it’s what type scale you want to use. And that type scale is probably going to be different for small screens than large screens. So you might say for small screens I want my type scale to be 1.2. That’s the the ratio. But on the large screen I want a larger type scale: 1.3.
So you specify those those edges and then you let the browser figure it out. It does the calculations. Figures it out for you.
I like this diagram that James put together for it where it shows I designed the minimum and the maximum and then maths figured out the in-between. Handing over those controls.
I think it’s this great use of machines and humans working together, doing what they’re best at. Because you got the human defining the boundary conditions, doing the design. And then handing over to the machine to do the calculations, to do the maths, which is what machines are good at.
You know when Steve Jobs described computers as a bicycle for the mind? I wonder can CSS be a bicycle for design? Where it’s amplifying design. You set the boundary conditions and then the browser does all the in-between.
Because CSS now is full of these functions that that work like this, where you give it the edges, you give it the boundary conditions and then it figures out the specifics. It does the calculations. It does the maths for you.
calc()
clamp()
min() and max()
fit-content
min-content and max-content
repeat()
minmax()
Intrinsic web design
This all opens up whole new ways of designing for the web that some people have been exploring. Jen Simmons in particular. She calls this intrinsic web design. She’s got a YouTube channel called Layout Land. It’s well worth checking out.
Watching her talks on this but I feel like it’s kind of got the same mindset that the Utopia project has: defined boundary conditions; let the browser figure out the specifics.
Be the browser’s mentor, not its micromanager
Every-Layout.dev is a project from Heydon Pickering and Andy Bell. It’s a book with various designs you can you can implement. Well worth checking out. I feel like the same mindset is there as well.
Even if you don’t buy the book it’s worth going to the website and reading the thinking behind it. If you go to the axioms there’s a quote there that says:
Instead of thinking of designing for the web as creating visual artifacts, think of it as writing programs for generating visual artifacts.
Declarative programs I would say.
Andy Bell,one of the guys behind that,he also built this website for a conference talk that’s called Build Excellent Websites. The talk was called “Be the browser’s mentor, not its micromanager”. Chef’s kiss! I think that is exactly what I’m trying to get at here:
Give the browser some solid rules and hints then let it make the right decisions for the people that visit it.
That’s exactly what I’m getting at!
Declarative design
So I feel like there’s something here. There’s this kind of declarative approach to design I’m trying to put my finger on and feel like they all share a mindset, a declarative mindset.
Now am I then saying that the the declarative approach is inherently better than the imperative approach?
The answer to that question is …it depends
…which is a bullshit answer. Anytime someone gives you this answer to a question you must follow up with the question, “it depends on what?”
Culture
In this case, whether the declarative approach is inherently better than an imperative approach depends on …culture, for one thing. The culture of the organization that’s producing the website, the culture of the organization that’s shipping.
Companies have different cultures which manifest in different ways, like management: how a company does management.
I think you could you could divide management into two categories like you can do with programming languages. There is a very imperative school of management where it’s all about measurements, it’s all about those performance reports, it’s all about metrics, time tracking. Maybe they install software on your machine to track how long you’ve been working. It’s all about measuring those outputs.
That’s one approach to management. Then there’s a more declarative approach, where you just care about the work getting done and you don’t care how people do it. So if they want to work from home, let them work from home. If they want to work strange hours, let them work strange hours. What do you care as long as the work gets done? This is more about giving people autonomy and trust
Now I know which approach I prefer and I would say at Clearleft we’ve definitely got a declarative approach. We give people lots of autonomy and trust.
That’s not always necessarily a good thing. If someone’s coming from an imperative background and on the first day of work is told “hey you’re a designer, you solve the problem; we’re not going to tell you what to do” people can really flounder if they’re not used to that level of autonomy and trust.
So again I’m not saying one is is right or wrong. I know which place I’d rather work at but I’m not saying one is is right and the other is wrong.
So companies have different cultures. There’s no one-size-fits-all way of thinking that will work for all company cultures.
Culture is one of those things that’s usually implicit and it’s unspoken. It’s rarely made explicit. It can be made explicit and one of the ways I think you can make a company culture explicit is through design systems.
Design systems
I know when normally we think of design systems we’re thinking of component libraries. We’re thinking of interface elements gathered together. To me that’s not what the design system is. My favorite definition of design systems comes from Jina Anne who knows a lot about design systems and she said that design systems are “the way we do things around here.”
I think focusing on those those components is maybe focusing on the the artifacts.
It will come as no surprise to you that I think you can kind of divide design systems into two categories. What are those categories? Imperative and declarative.
Before I look at how we divide design systems into imperative and declarative design systems I’m going to take a step back and talk about how we think about thinking.
I’m going to get meta here. And I don’t mean just on the web I mean how we approach problem solving as human beings.
Analytical thinking
I think there are two different ways historically to approach thinking and problem solving. One is analytical thinking. This isn’t new. This goes back centuries. This is what Emmanuel Kant was talking about in his critique of pure reason.
With analytical thinking you understand how something works by breaking it down into its constituent parts. This is what underpins the scientific method. It’s really, really useful for things that work exactly the same way everywhere in the universe: chemistry and physics and mathematics. I would say it’s probably not so great when you’re dealing with messy unpredictable things like human beings but analytical thinking has served us very, very well in our civilization.
Sytems thinking
On the other hand you’ve got systems thinking, which is almost the opposite of analytical thinking, where you understand the parts by looking at how they all work together as a whole.
To be very crude about it, analytical thinking is about zooming in and systems thinking is about zooming out.
So with that in mind let’s look at design systems.
Well the word “system” is right there in the title so surely what we’re talking about here is systems thinking, right?
Surprisingly most design systems to me seem to exhibit very analytical thinking: breaking things down into their constituent parts. Maybe you do an interface inventory; break things down into components, atoms, molecules.
It doesn’t have to be that way.
Let’s go back to our friend the button. Let’s say we’ve got our design system with a bunch of different button styles and you want to document this. That’ss what a design system for, right? Documenting the different styles you have.
You can see these buttons have different background colours and different borders and one approach would be to document those colours. You put those in the design system. Maybe there’s nice tokens, right? And then when someone needs that information they go to the design system and they pluck out the colours. Done.
That’s one way of doing it. That’s a very imperative, very precise way of doing it.
The other way is to pull back and say “what’s the commonality across all these buttons?” And then you could come up with that rule, that boundary condition. which would be:
the border colour should be 10% lighter than the background colour.
You could convert this to CSS now using custom properties. We’re even gonna have a color-mix
function in CSS.
But you see how this is a very different approach to just specifying what the final colours are.
So am I saying that when it comes to design systems a declarative approach is always better than an imperative approach?
I’m saying it depends.
“It depends on what?” you ask.
It depends on your team. It depends on their background and their mindset.
Teams
In a way it doesn’t matter whether you have a declarative or imperative mindset. What matters is what’s the mindset of the team working on this? That should dictate the approach you take.
When I hear someone say “design systems stifle creativity” what I’m hearing is “I’m a declarative designer and the design system is being very imperative, it’s fencing me in.”
But if you’re from an imperative background, “I need to know the color of the border for this button!” And if the design system says “well, you should make the border 10% lighter than the background,” that’s not useful—“Just give me the colors!” That’s the mindset I’ve got: “don’t make me think; just give me the data!”
I was I was talking about composers and I was comparing Mozart and Miles Davis. But let’s also compare their teams.
Classical musicians, they’re trying to sight read. It’s like a superpower they have. Whereas jazz musicians are trained to improvise. That’s their superpower.
With classical musicians, they could play a whole new piece of music without ever having heard it just from sight, which is absolutely amazing. But if Miles Davis had tried to record Kind Of Blue with a bunch of classical musicians I think it would have turned out very, very differently.
And then there’s the process, the design process.
The design process
I struggle with the design process on the web. I assume everyone does.
Jason Grigby has been blogging about this on the Cloud Four blog. The very first post in the series is Traditional Website process is Fundamentally Broken. I think we’d share that frustration.
He shows the traditional sort of very waterfall-y process that happens a lot, where particularly you’ve got this handover stage. The design all happens on this side of the handover and the development all happens on that side of the handover.
I think we can all agree that’s not good. That’s not going to lead to a great result.
He proposes something more like this, that goes backwards and forwards in time and also intertwingling design and development. And that’s that’s clearly better.
I still think there’s an issue here. Right here in the middle. Static mock-ups. Very precise, high-fidelity pictures of how something should look before you start actually building the thing.
Tools
Our tools tools influence us. They can’t help but do that.
We shape our tools and then our tools shape us.
Look at the tools we use for designing on the web. It used to be Photoshop and then it was Sketch. Now it’s Figma. Whatever it is, they’re very precise high-fidelity pixel-perfect tools. They’re very imperative. So we take imperative approach and then we try to translate it into a declarative language like CSS which is supposed to be about setting boundary conditions, leaving the browser to figure out the details.
There’s a mismatch there. So what’s the alternative?
We could jump straight to CSS, designing in the browser. Is that the answer? I’m not sure.
I like I like the phrase that Dan Mall uses which isn’t designing in the browser but deciding in the browser. He’s kind of talking about sign off . Instead of having something done in a mock-up and that’s what gets signed off, that’s the ideal we want and then you go to the browser. Instead do as much as you want in the in the design tool but that’s not the sign-off. You get it into the browser and at some point in the browser you go “Yes, that’s what we want” Sign off on that.
Now it’s already been translated into the the language of the browser so there isn’t going to be that disappointment with the traditional design process: the designer is disappointed because the end result doesn’t look like what they designed; the developer is disappointed because the designer did all this without consulting them; the client is disappointed; everybody is disappointed.
So I like the idea of deciding in the browser. But your approach to taking things into the browser sooner—maybe even designing in the browser—will depend entirely on your attitude to CSS.
If you’re from an imperative mindset you might think:
CSS is broken and I want my tools to work around the way that CSS has been designed.
Which is fair enough if you’re coming from that imperative mindset. I totally understand why you’d think that way. And there are tools to help you. This is pretty much what Tailwind does. Or CSS-in-JS. Treat the C in CSS as a bug and and work around. In that situation maybe you do want to stick to designing as much as possible in an imperative tool like Figma.
But if your mindset is more declarative you may think:
CSS is awesome and I want my tools to amplify the way that CSS has been designed.
Then, yeah, go check out Utopia, go check out those other websites I was talking about. Because that’s what they do. They go with the flow of CSS.
I’ve been saying “it depends”. It depends on your team. It depends on the culture of your company. You have to choose the approach that works best foryou and and your team. But to finish I want to point out one more thing that it depends on.
The medium
Choosing a declarative or an imperative approach to design also depends on the medium. The medium that you’re working in.
Now if you’re working in a medium that’s very precise like print or native apps, mobile or operating system specific apps for desktop, then you do actually have a lot of control. So an imperative approach might make a lot more sense. Those assumptions are maybe justified because you’ve got such a tightly controlled environment. So in that situation, yeah, go for it— be like Mozart; take the imperative approach.
But I don’t think that maps very well to the World Wide Web.
I think on the World Wide Web you want to be more Miles. You want to be more declarative.
We’ve tried them the past on the World Wide Web to shoehorn in an imperative mindset, to say “Well, let’s say things are really defined—let’s make assumptions about, you know, how wide everybody’s screen is.”
I’m showing my age here but when I started making websites, the assumption was everybody’s screen is 640 pixels wide. Later on it was 800 pixels wide. 1024.
Then mobile phones came along and everybody shat the bed because they didn’t know what they were supposed to do.
You understand why designers were doing this. It was to try and feel that sense of control. But it was always an illusion of control. It was a consensual hallucination to say “Yes, everybody’s screen is 800 pixels wide.” It doesn’t match with the reality, the messy beautiful reality of the World Wide Web.
To paraphrase the senator from Alderaan:
The more you tighten your grip, the more the World Wide Web slips through your fingers.
People have been talking about this for a long time. There’s an article called A Dao of Web Design by John Alsopp. It was published in 2000. 23 years ago it still holds up today. I recommend going back and reading it.
It was all about rejecting assumptions. Assumptions about devices. Assumptions about browsers. Assumptions about networks. Assumptions about people.
Look, you don’t have control over how people access the web. And that’s okay. That’s that’s not a bad thing.
Ten years after John published A Dao Of Web Design on A List Apart, Ethan Marcotte published Responsive Web Design on A List Apart. And the first thing he does in this article is he quotes John Allsopp’s A Dao Of Web Design. He was building on top of it. It was the same approach, the same mindset that was behind responsive web design.
That was 2010. And now, are we in a new era? Is it time for the next phase? A new era of declarative design maybe?
That’s up to you.
CSS is an incredibly powerful tool now. So let’s use it. Let’s lean into the the fluid, ever-changing nature of the World Wide Web.
It is a very very exciting time for design on the web right now and I can’t wait to see what you build.
Wednesday, February 28th, 2024
The Subversive Hyperlink - Jim Nielsen’s Blog
Subvert the status quo. Own a website. Make and share links.
Wednesday, November 15th, 2023
Of Time And The Web
A presentation from border:none held in Nuremberg in October 2023, ten years after the first border:none in 2013.
- Download the slides
- Watch the video
I want to tell you about a word. And the reaction I had to reading that word. I had a very big reaction to a very small word.
This is the word.
Was.
The past tense of the verb “to be.”
I saw this word and I was struck with a sense of awe.
Now, obviously it’s not just about the word itself—I don’t get struck by feelings of awe anytime anyone says the word “was.” The context matters. Here’s the context…
I was reading the WikiPedia entry for smallpox. Don’t ask me how I ended up here, I don’t remember. But I read the second word in the first sentence, “Smallpox was…” And I think for the first time I really grasped what an astonishing achievement it is to eradicate a deadly disease.
We did that! Humans! Using science! Surely this must stand as one of the greatest achievements of our species?
I was curious as to how this was reported in news outlets at the time. I went searching through newspaper archives on the web to find out.
Here’s an article on Page 21 of The New York Times. It’s five paragraphs long. The first paragraph says:
Smallpox, one of the deadliest and oldest viral diseases of humans, has been eradicated, World Health Organization officials said today in a news conference broadcast here from Geneva.
A few paragraphs down it says:
The health organization began the intensified smallpox eradication program in 1967. In that year, smallpox was reported in 42 countries and killed 2 million people. It also scarred and blinded another eight million people.
In one year! About ten years later, the disease was eradicated! But it was a gradual process.
If something changes gradually, we don’t notice it. We literally exhibit something called change blindness.
But we are hard-wired to notice sudden changes. We pay attention to moments of change.
“Where were you when JFK was assassinated?”
“Where were you on September 11th?”
Nobody is ever going to ask “where were you when smallpox was eradicated?”
We mark the moments when an election is won or lost, the moment war breaks out, the moment a ceasefire is signed.
We also seem to be particular attuned to breaking changes—the moments when bad things happen.
We’re downright suspicious of good news.
We have this phrase: “sounds too good to be true.”
But we don’t have this phrase: “sounds too bad to be true.”
There may well be solid evolutionary reasons for being attuned to danger and threats. But maybe we should occasionally take a step back and notice the changes we’ve been blind to.
The past
What if there were a newspaper that wasn’t published daily or weekly, but once every 100 years? What would the headline on the front page be?
Maybe it would be a moment, like “Yuri Gagarin went into space”—that was a pretty big one!
But maybe the headline would be something we don’t even think about.
Maybe the headline would be about how many more people can read the headline! Adult literacy rates have skyrocketed over the last hundred years—and this is showing percentages, not raw numbers; then the chart would be even more dramatic.
What about a 50 year newspaper? What would the headline be?
Maybe it would be about climate change: “burning coal and oil turns out to have been really bad.” Or maybe the headline would be about the remarkable drop in extreme poverty. Any percentage is still too much, but still, look at that rapid fall… particularly over the last 25 years.
Every single day, a real-time newspaper could’ve run the headline:
“130,000 People Escape Extreme Poverty Today”
…but no newspaper has every reported that. Sounds too good to be true.
What about a newspaper published once every 25 years?
Maybe the headline would still be about the drop in extreme poverty. Or maybe the headline would be about the equally steep drop in violent crime. Or deaths in natural disasters.
Or perhaps the editor would run with the story of infant mortality rates being halved. This time we are looking at the raw numbers; if this were percentages of the world population, the effect would be even more dramatic.
What about a newspaper published every 10 years? That’s the time frame we’re looking at here today, right?
For a newspaper published once a decade, I reckon today’s headline would probably be about climate change and the environment.
Maybe this is the most surprising development in the last 10 years: the huge increase in solar and wind energy. There’s a corresponding graph showing an equally dramatic drop in price, especially for solar.
We could be looking at part of an exponential curve here—time will tell!
But let’s get more specific. Let’s look at the World Wide Web.
How has the web changed since I was standing here 10 years ago?
Thanks to the internet archive, I can show what my own website looked like at the moment I was speaking at the first border: none.
Now let’s compare this to how my website looks today…
Hmmm …not exactly an astonishing amount of change, is it?
I think we need to go further back than 10 years. I think we need to go all the way back.
This is the first website ever made, displayed in the first web browser ever made. They were both made by Tim Berners-Lee 30 years ago. And this website is still online today at its original URL, because it’s cool.
Colour
The World Wide Web was somewhat lacking in colour originally. When I started making websites in the mid nineties, colour had arrived but it was limited.
We had a palette of 216 web safe colours. You knew if a colour was “web safe” if the hexadecimal notation was three sets of duplicated values. If you altered one of those values even slightly, there was no guarantee that the colour would display consistently on the monitors of the time. I have a confession to make: I kind of liked this constraint in a weird way. To this day, if I have a colour value that’s almost web-safe, I can’t resist nudging it slightly.
Fortunately, monitors improved. They got flatter for one thing. They were also capable of displaying plenty of colours.
And we also got more and more ways of specifying colours. As well as hexadecimal, we got RGB: Red, Green, Blue. Better yet, we got RGBa …with alpha transparency. That’s opacity to you and me.
Then we got HSL: hue, saturation, lightness. Or should I say HSLa: hue, saturation, lightness, and alpha transparency.
And there are more colour spaces available today. HWB (hue, whiteness, blackness), LAB, LCH. And now we’ve got a color() function so you can specify even more colour spaces.
Sounds too good to be true.
Typography
In the beginning, typography on the World Wide Web was non-existent. Your browser used whatever was available on your operating system.
That situation continued for quite a while. You’d have to guess which fonts were likely to be available on Windows or Mac.
If you wanted to use a sans-serif typeface, there was Arial on Windows and Helvetica on the Mac. Verdana was a pretty safe bet too.
For a while your only safe option for a serif typeface was Times New Roman. When Mathew Carter’s Georgia was released, it was a godsend. Here was a typeface specifically designed for the screen.
Later Microsoft released another four fonts designed for the screen. Four new fonts! It felt like we were being spoiled.
But what if you wanted to use a typeface that didn’t come installed with an operating system? Well, you went into Photoshop and made an image of the text. Now the user had to download additional images. The text wasn’t selectable and it was a fixed width.
We came up with all sorts of clever techniques to do what was called “image replacement” for text. Some of the techniques involved CSS and background images. One of the techniques involved Flash. It was called sIFR: Scalable Inman Flash Replacement. A later technique called Cufón converted the letter shapes into paths in Canvas.
All of these techniques were hacks. Very clever hacks, but hacks nonetheless. They were clever and they worked but they always reminded me of Samuel Johnson’s description of a dog walking on its hind legs:
It is not done well but you are surprised to find it done at all.
What if you wanted to use an actual font file in a web page?
There was only one browser that supported font embedding: Microsoft’s Internet Explorer. The catch was that you had to use a proprietary font format called Embedded Open Type.
Both type foundries and browser makers were nervous about allowing regular font files to be embedded in web pages. They were worried about licensing. Wouldn’t this lead to even more people downloading fonts illegally? How would the licensing be enforced?
The impasse was broken with a two-pronged approach. First of all, we got a new font format called Web Open Font Format or WOFF. It could be used to take a regular font file and wrap it in a light veneer of metadata about licensing. There’s a sequel that’s even better than the original, WOFF2.
The other breakthrough was the creation of intermediary services like Typekit and Fontdeck. They would take care of serving the actual font files, making sure they couldn’t be easily downloaded. They could also keep track of numbers to ensure that type foundries were being compensated fairly.
Over time it became clear to type foundries that most web designers wanted to do the right thing when it came to licensing fonts. And so these days, you can probably license a font straight from a type foundry for use on the web and host it yourself.
You might need to buy a few different weights. Regular. Bold. Maybe italic. What about extra bold? Or a light weight? It all starts to add up, especially for the end user who has to download all those files.
I remember being at the web typography conference Ampersand years ago and hearing a talk from Nick Sherman. He asked us to imagine one single font file that could go from light to regular to bold and everything in between. What he described sounded like science fiction.
It is now science fact, indistinguishable from magic. Variable fonts are here. You can typeset text on the web to be light, or regular, or bold, or anything in between.
When you use CSS to declare the font-weight property, you can use keywords like “normal” or “bold” but you can also use corresponding numbers like 400 or 700. There’s a scale with nine options from 100 to 900. But why isn’t the scale simply one to nine?
Well, even though the idea of variable fonts would have been pure fantasy when this part of CSS was being specced, the authors had some foresight:
One of the reasons we chose to use three-digit numbers was to support intermediate values in the future.
With the creation of variable fonts, Håkon Wium Lee added:
And the future is now.
On today’s web you could have 999 font-weight options.
Sounds too good to be true.
Images
In the beginning, the World Wide Web was a medium for text only. There were no images and certainly no videos.
In an early mailing list discussion, there was talk of creating a new HTML element for images. Perhaps it should be called “icon”. Or maybe it should be more generic and be called “embed”. Tim Berners-Lee said he imagined using the rel attribute on the A element for embedding images.
While this discussion was happening, Marc Andreessen popped in to say that he had just shipped a new HTML element in the Mosaic browser. It’s called IMG and it takes an attribute called SRC that points to the source of the image.
This was a self-closing tag so there was no way to put fallback content in between the opening and closing tags if the image couldn’t be displayed. So the ALT attribute was introduced instead to provide an alternative description of the image.
For the images themselves, there were really only two choices. JPG for photographic images. GIF for icons or anything that needed basic transparency. GIFs could also do animation and today, that’s pretty much all they’re used for. That’s because there was a concerted campaign to ditch the GIF format on the web. Unisys, who owned the rights to a compression algorithm used by the GIF format, had started to make noises about potentially demanding license fees for its use.
The Portable Network Graphics format—or PNG—was created in response. It was more performant and it allowed you to have proper alpha transparency.
These were all bitmap formats. What if you wanted a vector format for images that would retain crispness at any size or resolution? There was only one option: Flash. You’d have to embed a Flash movie in your web page just to get the benefit of vector graphics.
By the 21st century there were some eggheads working on a text-based vector file format that could be embedded in webpages, but it sounded like a pipe dream. It was called SVG for Scalable Vector Graphics. The format was dreamed up in 2001 but for years, not a single browser supported it. It was like some theoretical graphical Shangri-La.
But by 2011, every major browser supported it. Styleable, scriptable, animatable, vector graphics have gone from fantasy to reality.
There’s more choice in the world of bitmap images too. WebP is well supported. AVIF is is gaining support.
The IMG element itself has grown too. You can use the srcset attribute to give the browser a range of images to choose from to best suit the user’s device and network connection. You can use the loading attribute to get lazy loading of images for free—no JavaScript required.
We now have audio in HTML. No JavaScript required. We now have video in HTML. No JavaScript required.
These elements have been designed with more thought than the IMG element. They are not self-closing elements, by design. You can put fallback content between the opening and closing tags.
The audio and video elements arrived long after the IMG element. For a long time, there was no easy way to do video or audio on the web.
That was very frustrating for me. The first websites I ever built were for bands. The only way to stream music was with a proprietary plug-in like Real Audio.
Or Flash.
While the web standards were still being worked on, Flash delivered the goods with streaming audio and video. This happened over and over. Flash gave us vector graphics, animation, video, and more. But the price was lock-in. Flash was a proprietary format.
Still, Flash showed the web standards bodies the direction of travel. Flash was the hare. Web standards were the tortoise.
We know how that race ended.
In a way, Flash was like the Research and Development incubator for the World Wide Web. We got CSS animations, SVG, and streaming video because Flash showed that there was an appetite for them.
Until web standards provide a way to do something, designers and developers will reach for whatever tool gets the job done. Take layout, for example.
Layout
In the early days of the web, you could have any layout you wanted …as long as it was a single column.
Before long, HTML expanded to provide some rudimentary formatting for that single column of text. Presentational elements and attributes were invented. And even when elements and attributes weren’t meant to be used for formatting, people got creative.
Tables for layout. A single pixel GIF that could be given width and height. These were clever solutions. But they were hacks. And they were in danger of turning HTML into a presentational language instead of a language for structuring content.
CSS came to the rescue. A language specifically for presentation. But we still didn’t get proper layout tools. There was a lot of debate in the early days about whether CSS should even attempt to provide layout tools or whether that was a job for a separate technology.
We could lay things out using the float property, but really that was just another hack.
Floats were an improvement over tables for layout, but we only swapped one tool for another. Our collective thinking still wasn’t very web-like.
For example, designers and developers insisted on building websites with a fixed width. This started in the era of table layouts and carried over into CSS.
To start with, the fixed width was 640 pixels. Then it was 800 pixels. Then people settled on the magical number of 960 pixels. Designers and developers didn’t seem at all concerned that people had different sized screens.
That was until the iPhone came out. Everyone shat the bed. What fixed width were we supposed to design for now?
The answer was there all along. Even before the web appeared in mobile devices, it was possible to build fluid layouts that would adapt to screen size. It’s just that the majority of designers and developers chose not to build in this way.
I was pleased that mobile came along and shook things up. It exposed the assumptions that people were making. And it forced designers and developers to think in a more fluid, webby way.
Even better, CSS had expanded to include media queries so it was possible to alter layouts at different breakpoints.
Ethan came along and put a nice bow on it with his definition of responsive design: fluid media, fluid layouts, and media queries.
I fell in love with responsive web design instantly becuase it matched how I was already thinking about the web. I was one of the handful of weirdos who insisted on building fluid websites when everyone else was using fixed-width layouts.
But I thought that responsive web design would struggle to take hold. I’m delighted to say that I was wrong. Responsive web design has become the default!
If I could go back to my past self in the mid 2000s, I’d love to tell them that in the future, everyone would be building with fluid layouts (and also that time travel had been invented apparently).
Not only that, but we finally have proper layout tools for the web. Flexbox. Grid. No more hacks. We’ve even got container queries, which for years we were told were literally too good to be true.
Web browsers now are positively overflowing with fantastic design tools that would have been unimaginable to my past self. Support for these technologies is pretty much universal.
When browsers differ today, it’s only terms of which standards they don’t yet support.
The present
The web has come along way. It has grown and evolved. Browsers have become more and more powerful while maintaining backward compatibility.
In the past we had to hack our way around the technological limitations of the web and we had a long wish list of features we wanted.
I’m not saying we’re done. I’m sure that more features will keep coming. But our wish list has shrunk.
The biggest challenges facing the World Wide Web today are not technical challenges.
Today it is possible to create beautiful websites that make full use of colour, typography, layout, animation, and more. But this isn’t what users experience.
This is what users experience. A tedious frustrating game of whack-a-mole with websites that claim to value our privacy while asking us to relinquish it.
This is not a technical problem. It is a design decision. The decision might not be made by anyone with designer in their job title, but make no mistake, business decisions have a direct effect on user experience.
On the face of it, the problem seems to be with the business model of advertising. But that’s not quite right. To be more precise, the problem is with the business model of behavioural advertising. That relies on intermediaries to amass huge amounts of personal data so that they can supposedly serve up relevant advertising.
But contextual advertising, which serves up ads based on the content you’re looking at doesn’t require the invasive collection of personal data. And it works. Behavioural advertising, despite being a huge industry that depends on people giving up their privacy, doesn’t even work very well. And on the few occasions when it does work, it just feels creepy.
The problem is not advertising. The problem is tracking. The greatest trick the middlemen ever pulled was convincing us that you can’t have effective advertising without tracking. That is false. But they’ve managed to skew our sense of perspective so that invasive advertising seems inevitable.
Advertising was always possible on the web. You could publish anything and an ad is just one more thing you could choose to publish. But tracking was impossible. That’s because the early web was stateless. A browser requests a resource from a server and once that transaction is done, they both promptly forget about it. That made it very hard to do things like online shopping or logging into an account.
Two technologies were created later that enabled state on the web. Cookies and JavaScript. If these technologies had been limited to a same origin policy (like how cookies were originally specified), they would have nicely solved the problems of online shopping and authentication.
But these technologies work across domains. Third party cookies and third-party JavaScript enables users to be tracked as they move from site to site. The web gone from having no state to having too much.
There is hope. Browsers like Firefox and Safari are blocking third-party cookies by default. Personally, I’d love it if third-party JavaScript got the same treatment. You can also install add-ons to make your browser more secure, although these add-ons are often labelled ad-blockers, which is a shame. Because the problem is not advertising. The problem is tracking.
Perhaps none of this applies to you anyway. You may be thinking that this is a problem for websites. But you build web apps that don’t rely on behavioural advertising.
As I said here ten years ago, I’m not keen on the idea of dividing the entirety of the World Wide Web into two vaguely-defined categories. Ten years on, I still have yet to hear a good definition of “web app” other than “a website that requires JavaScript to work.”
But the phrase “single page app” has a more definite meaning. It refers to an architectural decision. That decision is to reinvent the web browser inside a web browser.
In a sense, it’s a testament to the power of JavaScript that you can choose to do this. Browsers render content and perform navigations, but if you’d rather recreate that functionality from scratch in JavaScript, you can.
But should you? Browsers have increased in complexity so that we can build without complexity. We can use the built-in power of modern HTML, CSS, and JavaScript to make web browsers do the work. If we work with the grain of the web, we can accomplish more and more with less and less code.
But that isn’t what happened. Instead developers have recreated form controls like dropdowns and datepickers from scratch using divs and lashings and lashings of JavaScript.
Perhaps this points to some missing features on the web. It’s still too hard to style native dropdowns and datepickers (but that’s being worked on—there’s standards work underway to give us more styling control over form elements). But that doesn’t explain why developers would choose to recreate something like a button using divs and JavaScript when the button element already exists and can be styled any way you like.
I think there’s a certain mindset being applied to web development here. And that mindset comes from the world of software. Again, it’s a testament to how far the web has come that it can be treated as a software platform on par with operating systems like iOS, Android, or Windows. There’s a lot to be learned from the world of software development, like testing, for example. But the web is different. When a user navigates to a URL, it shouldn’t feel like they’re installing a piece of software.
We should be aiming to keep our payloads as small as possible. And given how powerful browsers have become, we need fewer and fewer dependencies—fewer and fewer polyfills.
But performance has gotten worse. Payloads have gotten bigger. Dependencies like JavaScript frameworks have become more and more widespread even as they became less and less necessary.
When asked to justify the enormous payloads, web developers have responded by saying that user’s expectations have changed. That is correct, but not in the way that I think they mean.
When I talk to people about using the web—especially on mobile—their expectations are that they will have a terrible experience. That websites will be slow to load. And I guarantee you that none of them are saying, “Well I’d be annoyed if this were a website but seeing as this is a web app, I’m absolutely fine with this terrible experience.”
I said that the biggest challenges facing the World Wide Web today are not technical challenges. I think the biggest challenge facing the web today is people’s expectations.
There is no technical reason for websites or web apps to be so frustrating. But we have collectively led people to expect a bad experience on the web.
Our intentions may be have good. We thought users wanted nice page transitions and form elements that were on-brand. But if you talk to people, you find out that what they want is to accomplish their task without megabytes of JavaScript getting in the way.
There’s a great German word, “Verschlimmbessern”: the act of making something worse in the attempt to make it better. Perhaps we verschlimmbessert the web.
Let’s step back. Get some perspective. Instead of assuming that a single page app architecture is needed, ask what users need to accomplish. Instead of assuming you need a CSS framework or a JavaScript library, see what you can do in browsers today with native CSS and vanilla JavaScript. Don’t include a bunch of dependencies by default just in case you might need them. Instead, as Rachel puts it:
Stop solving problems you don’t yet have.
Lean into what web browsers can accomplish today. If you find something missing, that’s the time to reach for a library …but treat it like a polyfill. Whereas web standards stick around, every library and framework comes with a limited lifespan. Treat them as cattle, not pets.
I understand that tools and frameworks can make your life easier. And if we’re talking about server-side frameworks, then I say “Go for it.” Or if you’re using build tools that sit on your computer to do version control, linting, pre-processing, or transpiling, then I say “Go for it.” But once you make users download tools or frameworks, you’re making them pay a tax for your developer convenience.
We need to value user needs above developer convenience. If I have the choice of making something the user’s problem or making it my problem, I’ll make it my problem every time. That’s my job.
We need to change people’s expectations of the World Wide Web, especially on mobile. Otherwise, the web will be lost.
The future
In 2019, I had the great honour of being invited to CERN to mark the 30th anniversary of the original proposal for the World Wide Web. One of the other people there was the journalist Zeynep Tüfekçi. She was on a panel along with Tim Berners-Lee and other luminaries of the early web. At the end of the panel discussion, she was asked:
What would you tell the next generation about how to use this wonderful tool?
She replied:
If you have something wonderful, if you do not defend it, you will lose it. If you do not defend the magic and the things that make it wonderful, it’s just not going to stay magical by itself.
I believe that we can save the web. I believe that we can change people’s expectations. We’ll do that by showing them what the web is capable of.
Tuesday, November 14th, 2023
Pluralistic: The (open) web is good, actually (13 Nov 2023) – Pluralistic: Daily links from Cory Doctorow
The web wasn’t inevitable – indeed, it was wildly improbable. Tim Berners Lee’s decision to make a new platform that was patent-free, open and transparent was a complete opposite approach to the strategy of the media companies of the day. They were building walled gardens and silos – the dialup equivalent to apps – organized as “branded communities.” The way I experienced it, the web succeeded because it was so antithetical to the dominant vision for the future of the internet that the big companies couldn’t even be bothered to try to kill it until it was too late.
Companies have been trying to correct that mistake ever since.
A great round-up from Cory, featuring heavy dollops of Anil and Aaron.
Sunday, November 12th, 2023
[this is aaronland] generative adversarial therapy sessions
Mobile phones and the “app economy”, an environment controlled by exactly two companies and designed to extract a commission from almost every interaction and to promote native and not-portable applications over web applications. But we also see the same behaviour from so-called “native to the web” companies like Facebook who have explicitly monetized reach, access and discovery. Facebook is also the company that gave the world React which is difficult not to understand as deliberate attempt to embrace and extend, to redefine, HTML itself.
Perversely, nearly everything about the mobile/app economy is built on, and designed to use, HTTP precisely because it’s a common and easy to implement standard free and unencumbered by licensing.
Thursday, November 2nd, 2023
Internet Artifacts
I love this timeline of internet firsts. Best of all:
You may touch the artifacts
The websites on display work—even the ones that used Flash!
Sunday, October 15th, 2023
Increment by increment
The bedrock of the World Wide Web is solid. Built atop the protocols of the internet (TCP/IP), its fundamental building blocks remain: URLs of HTML files transmitted over HTTP. Baldur Bjarnason writes:
Even today, the web is like living fossil, a preserved relic from a different era. Anybody can put up a website. Anybody can run a business over it. I can build an app or service, send the URL to anybody I like, and most people in the world will be able to run it without asking anybody’s permission.
Still, the web has evolved. In fact, that evolution is something that’s also built into its fundamental design. Rather than try to optimise the World Wide Web for one particular use-case, Tim Berners-Lee realised the power of being flexible. Like the internet, the World Wide Web is deliberately dumb.
(I get very annoyed when people talk about the web as being designed for scientific work at CERN. That was merely the first use-case. The web was designed for everything …and nothing in particular.)
Robin Berjon compares the web’s evolution to the ship of Theseus:
That’s why it’s been so hard to agree about what the Web is: the Web is architected for resilience which means that it adapts and transforms. That flexibility is the reason why I’m talking about some mythological dude’s boat. Altogether too often, we consider some aspects of the Web as being invariants when they’re potentially just as replaceable as any other part. This isn’t to say that there are no invariants on the Web.
The web can be changed. That’s both a comfort and a warning. There’s plenty that we should change about today’s web. But there’s also plenty—at the root level—that we should fight to preserve.
And if you want change, the worst way to go about it is to promulgate the notion of burning everything down and starting from scratch. As Erin says in the fourth and final part of her devastating series on Meta in Myanmar:
We don’t get a do-over planet. We won’t get a do-over network.
Instead, we have to work with the internet we made and find a way to rebuild and fortify it to support the much larger projects of repair—political, cultural, environmental—that are required for our survival.
Though, as Robin points out, that doesn’t preclude us from sharing a vision:
Proceeding via small, incremental changes can be a laudable approach, but even then it helps to have a sense for what it is that those small steps are supposed to be incrementing towards.
I’m looking forward to reading what Robin puts forward, particularly because he says “I’m no technosolutionist.”
From a technical perspective, the web has never been better. We have incredible features in HTML, CSS, and JavaScript, all standardised and with amazing interoperability between browsers. The challenges that face the web today are not technical.
That’s one of the reasons why I have no patience for the web3 crowd. Apart from the ridiculous name, they’re focusing on exactly the wrong part of the stack.
Listening to their pitch, they’ll point out that while yes, the fundamental bedrock of the web is indeed decentralised—TCP/IP, HTTP(S)—what’s been constructed on that foundation is increasingly centralised; the power brokers of Google, Meta, Amazon.
And what’s the solution they propose? Replace the underlying infrastructure with something-something-blockchain.
Would that it were so simple.
The problems of today’s web are not technical in nature. The problems of today’s web won’t be solved by technology. If we’re going to solve the problems of today’s web, we’ll need to do it through law, culture, societal norms, and co-operation.
(Feel free to substitute “today’s web” with “tomorrow’s climate”.)
Monday, October 2nd, 2023
Making a Website is for Everyone - Jim Nielsen’s Blog
I absolutely love the idea of actively preserving a low barrier to entry for future generations of people.
💯
Over time, the direction of web technology always trends towards complexity. Simplicity is achieved as a concerted, mindful fight against this.
Saturday, August 5th, 2023
Just normal web things.
A plea to let users do web things on websites. In other words, stop over-complicating everything with buckets of JavaScript.
Honestly, this isn’t wishlist isn’t asking for much, and it’s a damning indictment of “modern” frontend development that we’ve come to this:
- Let me copy text so I can paste it.
- If something navigates like a link, let me do link things.
- …
Thursday, April 13th, 2023
Browser history
I woke up today to a very annoying new bug in Firefox. The browser shits the bed in an unpredictable fashion when rounding up single pixel line widths in SVG. That’s quite a problem on The Session where all the sheet music is rendered in SVG. Those thin lines in sheet music are kind of important.
Browser bugs like these are very frustrating. There’s nothing you can do from your side other than filing a bug. The locus of control is very much with the developers of the browser.
Still, the occasional regression in a browser is a price I’m willing to pay for a plurality of rendering engines. Call me old-fashioned but I still value the ecological impact of browser diversity.
That said, I understand the argument for converging on a single rendering engine. I don’t agree with it but I understand it. It’s like this…
Back in the bad old days of the original browser wars, the browser companies just made shit up. That made life a misery for web developers. The Web Standards Project knocked some heads together. Netscape and Microsoft would agree to support standards.
So that’s where the bar was set: browsers agreed to work to the same standards, but competed by having different rendering engines.
There’s an argument to be made for raising that bar: browsers agree to work to the same standards, and have the same shared rendering engine, but compete by innovating in all other areas—the browser chrome, personalisation, privacy, and so on.
Like I said, I understand the argument. I just don’t agree with it.
One reason for zeroing in a single rendering engine is that it’s just too damned hard to create or maintain an entirely different rendering engine now that web standards are incredibly powerful and complex. Only a very large company with very deep pockets can hope to be a rendering engine player. Google. Apple. Heck, even Microsoft threw in the towel and abandoned their rendering engine in favour of Blink and V8.
And yet. Andreas Kling recently wrote about the Ladybird browser. How we’re building a browser when it’s supposed to be impossible:
The ECMAScript, HTML, and CSS specifications today are (for the most part) stellar technical documents whose algorithms can be implemented with considerably less effort and guesswork than in the past.
I’ll be watching that project with interest. Not because I plan to use the brower. I’d just like to see some evidence against the complexity argument.
Meanwhile most other browser projects are building on the raised bar of a shared browser engine. Blisk, Brave, and Arc all use Chromium under the hood.
Arc is the most interesting one. Built by the wonderfully named Browser Company of New York, it’s attempting to inject some fresh thinking into everything outside of the rendering engine.
Experiments like Arc feel like they could have more in common with tools-for-thought software like Obsidian and Roam Research. Those tools build knowledge graphs of connected nodes. A kind of hypertext of ideas. But we’ve already got hypertext tools we use every day: web browsers. It’s just that they don’t do much with the accumulated knowledge of our web browsing. Our browsing history is a boring reverse chronological list instead of a cool-looking knowledge graph or timeline.
For inspiration we can go all the way back to Vannevar Bush’s genuinely seminal 1945 article, As We May Think. Bush imagined device, the Memex, was a direct inspiration on Douglas Engelbart, Ted Nelson, and Tim Berners-Lee.
The article describes a kind of hypertext machine that worked with microfilm. Thanks to Tim Berners-Lee’s World Wide Web, we now have a global digital hypertext system that we access every day through our browsers.
But the article also described the idea of “associative trails”:
Wholly new forms of encyclopedias will appear, ready made with a mesh of associative trails running through them, ready to be dropped into the memex and there amplified.
Our browsing histories are a kind of associative trail. They’re as unique as fingerprints. Even if everyone in the world started on the same URL, our browsing histories would quickly diverge.
Bush imagined that these associative trails could be shared:
The lawyer has at his touch the associated opinions and decisions of his whole experience, and of the experience of friends and authorities.
Heck, making a useful browsing history could be a real skill:
There is a new profession of trail blazers, those who find delight in the task of establishing useful trails through the enormous mass of the common record.
Taking something personal and making it public isn’t a new idea. It was what drove the wave of web 2.0 startups. Before Flickr, your photos were private. Before Delicous, your bookmarks were private. Before Last.fm, what music you were listening to was private.
I’m not saying that we should all make our browsing histories public. That would be a security nightmare. But I am saying there’s a lot of untapped potential in our browsing histories.
Let’s say we keep our browsing histories private, but make better use of them.
From what I’ve seen of large language model tools, the people getting most use of out of them are training them on a specific corpus. Like, “take this book and then answer my questions about the characters and plot” or “take this codebase and then answer my questions about the code.” If you treat these chatbots as calculators for words they can be useful for some tasks.
Large language model tools are getting smaller and more portable. It’s not hard to imagine one getting bundled into a web browser. It feeds on your browsing history. The bigger your browsing history, the more useful it can be.
Except, y’know, for the times when it just make shit up.
Vannevar Bush didn’t predict a Memex that would hallucinate bits of microfilm that didn’t exist.
Wednesday, March 15th, 2023
www91.pdf
This is the flyer that Tim Berners-Lee and Robert Cailliau distributed at the Hypertext 91 Conference—the one where their submission was infamously rejected.
The WWW project merges the techniques of information rerieval and hypertext to make an easy but powerful global information system.
The project is based on the philosophy that much academic information should be freely available to anyone. lt aims to allow information sharing within internationally dispersed teams, and the dissemination of information by support groups.
Monday, November 28th, 2022
jwz: PSA: Do Not Use Services That Hate The Internet
If you’re thinking of signing up to Hive or Post:
If posts in a social media app do not have URLs that can be linked to and viewed in an unauthenticated browser, or if there is no way to make a new post from a browser, then that program is not a part of the World Wide Web in any meaningful way.
Consign that app to oblivion.
Tuesday, November 15th, 2022
CSS Timeline
Here’s a remarkably in-depth timeline of the web’s finest programming language, from before it existed to today’s thriving ecosystem. And the timeline is repsonsive too—lovely!
Monday, November 14th, 2022
inessential: After Twitter
The internet’s town square should never have been one specific website with its own specific rules and incentives. It should have been, and should be, the web itself.
I share Brent’s optimism:
The web is wide open again, for the first time in what feels like forever.
Tuesday, September 6th, 2022
Ancient Web Browsers | tweedy
This is an archive of the very earliest Web browsers — the true pioneers, the Old Gods, the Ancients:
WorldWideWeb, LineMode, Viola, Erwise, Midas, TkWWW, Samba, Lynx, w3, FineWWW
Monday, July 18th, 2022
Fundamentals matter | Go Make Things
I really enjoyed Laurie’s talk in Berlin a few weeks back. I must blog my thoughts on it.
But I must admit that something didn’t sit quite right about the mocking tone he took on the matter of “the fundamentals” (whatever that may mean). Chris shares my misgivings:
Those websites that don’t load on slow connections, or break completely when a JS file fails to load, or don’t work for people with visual or physical impairments?
That’s not an issue of time. It’s an issue of fundamentals.
I think I agree with Laurie that there’s basically no such thing as fundamental technologies (and if there is such a thing, the goalposts are constantly moving). But I agree with Chris with that there is such a thing as fundamental concepts. On the web, for example, accessibility is a core principle of its design that should, in my opinion, be fundamental.
This, basically:
Do I wanna see teenagers building frivolous websites? Absolutely. But when people are getting paid well to build our digital world, they have a responsibility to ensure the right to engage with that world for everyone.
Wednesday, June 22nd, 2022
In And Out Of Style
A presentation from An Event Apart Spring Summit held online in April 2022 and the opening presentation at CSS Day held in Amsterdam in June 2022.
- Download the audio
- Download the slides
- Watch the video (slides + audio)
Hello, my name is Jeremy and I am speaking to you today from Brighton on the south coast of England.
I want to tell you about something that happened here in Brighton back in 1985 (pretty sure it took place in one of those buildings along the seafront there). In 1985 Brighton was host to the International Information Theory Symposium. Fascinating.
Something exciting happened there. Word began to go around that there was an unexpected guest attending the event. This unexpected guest was this man, Claude Shannon. The way it was described later was somebody said it was as if Newton had showed up at a physics conference.
He wasn’t even meant to be there, but he was convinced at the dinner after the event to get up and say a few words. And he did, he got up and he started to talk, but he felt like he was losing the audience. So he proceeded to do some juggling.
That’s so Claude Shannon. He was very much into games. He took games very seriously. He was a very playful kind of person.
For example, he invented this machine, which is called the most beautiful machine, also the most useless machine. But I think it’s just wonderful. I mean, it’s like the perfect encapsulation of cybernetics, the ideal feedback loop.
But the reason why people were excited that Claude Shannon was at this event wasn’t because of the most beautiful machine. And it wasn’t because of his juggling. It was because of information theory.
Because Claude Shannon, it’s not like he just revolutionized the field of information theory; Claude Shannon pretty much invented the field of information theory in one fell swoop. In a paper in 1948 called the Mathematical Theory of Communication.
Here’s the TLDR. This is the mathematical part. I won’t go into the details of the mathematical part, but what I recall from Claude Shannon’s work is that he was able to effectively boil information down into fundamental particles. The idea that there’s a single bit of information.
This idea of entropy, the idea that for information to travel between communicator and the receiver, you’ve got the signal that you’re trying to transmit, but there’s also noise. And this noise is unavoidable.
And like I said, this idea of the bit; that any piece of information could be reduced down to a fundamental particle: a one or a zero; on or off, which of course is exactly how computers work. So it’s no exaggeration to say that Claude Shannon is like the father of the digital age.
And one other thing I take from Claude Shannon’s work is that when it comes to communication of information, context matters. In other words, that the expectation between the receiver and the communicator can make a lot of difference.
Shared context
So to give you an example of shared context being very important in information communication I want to illustrate it with a story from the pre-digital age. This is a story from the age of the electrical telegraph.
Now this story is probably completely apocryphal. In some versions of the story, it involves the novelist Victor Hugo. In other versions, it’s Oscar Wilde. But the point is there’s an author. He’s just published a book and now he’s gone off on holiday after writing the book. But while he’s on holiday, he’s really curious to know, how is the book doing? What are the sales like?
So he sends a telegram to his publisher, but because there’s enough shared context between the publisher and the author, all he sends is a single character. A question mark.
?
And then, because there’s this shared context between the publisher and the author and the publisher wants to let the author know that actually sales are going really, really well, the publisher also sends back a telegram with a single character. An exclamation mark.
!
So this is a classic example of the importance of context. I mean, you’re just sending a single character and yet both parties understand the message being conveyed.
Context matters. Shared context matters.
Now I want to try an experiment with you to test how much shared context there is between me (I’m going to try to transmit a message) and you (the receiver of the message).
So we’re starting with a blank slate. And now I’m going to provide one piece of information. Okay. Here’s the piece of information. Probably doesn’t tell you much. A diagonal line. There’s not enough context here.
All right. Back to the blank slate. I’m now going to provide another piece of information.
Okay. Again, in isolation, this probably doesn’t tell you much just another diagonal line. But if I combine it with the first bit of information, then now maybe it starts to become something you can parse. And if I provide just one more bit of information, now maybe it clicks into place that the piece of information I’m trying to convey is ten minutes past ten.
And yet all I’ve done here is I’ve provided you with two diagonal lines in a circle. Yet somehow two diagonal lines in a circle, when we have the shared context of how to read an analogue clock face, is enough to communicate ten minutes past ten.
(The time, by the way, is completely arbitrary. The only reason I chose that time is just that if you ever look at an advertisement for a watch, it’ll usually be ten past ten because the angles of the arms on the watch nicely frame the logo of the watchmaker.)
But anyway, the point is: with enough shared context, two diagonal lines in a circle are enough for me to communicate the piece of information, “ten minutes past ten o’clock.”
I mean, maybe you’re a digital native born in a 21st century, in which case you’re looking at this and thinking, “I just see two diagonal lines in a circle”, but if you can read an analogue clock face, then we have that shared context.
Where did this context come from? Why is it that that clock faces are set up the way they are? Why do clocks go clockwise? It seems like a fairly arbitrary decision.
It is somewhat arbitrary, but one neat solution is that the reason why clocks go in a clockwise direction is that that’s the way that a shadow on a sundial would travel …in the Northern hemisphere.
Now if you look at a sundial in the Southern hemisphere, like this one here—this is in Wellington, in New Zealand—the shadow would actually go in a counterclockwise direction.
So really it’s almost an accident of history that we have clocks that go clockwise. If clocks had been invented in the Southern hemisphere, then they would go in the other direction. It’s pretty arbitrary, but now we’ve decided, we’ve kind of settled on this arbitrary movement of clocks that they go clockwise and we’re stuck with it.
Because inertia is a very powerful force. If you tried to change the way the clocks work you’d have your work cut out for you, even if the reason why clocks work the way they do is arbitrary to begin with.
Inertia
You know, a very wise person once said the most dangerous phrase in the English language is “We’ve always done it that way.” And that very wise person was the brilliant computer scientist, rear admiral Grace Hopper.
She used to say:
Humans are allergic to change.
She said:
I try to fight that. And that’s why I have a clock on my wall that runs counterclockwise.
Right? It kind of drives home this idea that, hey, this is an arbitrary decision.
And it’s kind of weird for us to look at a clock that runs counterclockwise. I actually managed to find a watch a few years ago that worked like this, that ran counterclockwise. And I wore it for a while and I was able to train my brain to read the clock this way. And it worked fine, but it completely broke my brain for reading normal clocks. So I kind of had to just stop doing it.
But I’m fascinated by these examples of fairly arbitrary decisions made sometime in the past that you’re then stuck with, because it’s very hard to change the inertia. But only recently did I find out that there’s a term for this phenomenon. This is called path dependence.
Path dependence
History is full of path dependence. The classic example is if you wanted to make a new train or a new stretch of railway track, you’re gonna have to use the existing gauge of the railway in question. Now it’s not that there’s one gauge of railway that’s better or worse than any other gauge, but if someone’s made that decision in the past, it’s very hard to change. And you really do want to settle on one gauge so that you don’t have to switch trains when you move between different parts of a country (this actually happened down in Australia, where they had different gauges for the railways, it was kind of a mess).
It’s the canonical example of why you need standards. But really the point of standards isn’t necessarily to enshrine the best way of doing something. The point of standards is to enshrine the agreement. “Hey, let’s all agree to do things this.”
Whether the standard is good, bad, better or worse than other ways of doing things is in some ways less important than the agreement. You just need to have everyone agree on something.
Like, there’s a standard for which side of the road you drive on in your country. And it doesn’t really matter whether the standard is for it to be on the left side of the road or the right hand side of the road. But it really matters that you all agree on the same side of the road.
Agreement and standards brings us very nicely to the World Wide web. Because I think the World Wide web is a fantastic example of agreement.
The web is agreement
There’s a friend of mine, Paul Downey, who does these wonderful illustrations. Fantastic. He has this one called “the web is agreement.” Whenever I think about the word agreement, this is what I think of: that the web is agreement. And he does these kind of Hieronymous Bosch and Breughel-like images of all the different formats and standards that we use on the web.
And if you think about what the World Wide Web is, this combination of HTTP and URLs and HTML. This was, you know, when the web was first created. Yeah, these are just agreements.
I mean, HTTP is a protocol and that word protocol literally means agreement. (If you think about diplomatic protocols that are like diplomatic agreements, right?)
URLs, “Hey, let’s all agree to use this addressing scheme.”
And HTML, “If we all agree to use this format, then we get interoperability.”
So these formats, these protocols, this set of standards or agreements came from Sir Tim Berners-Lee. This was back when he was working at CERN at the nuclear physics laboratory in the late 1980s, early ’90s.
I’m somewhat fascinated about the birth of the web, which is why it was a huge honour and pleasure for me to be invited to CERN a few years back. This was in the run up to the 30th anniversary of the original proposal that Tim Berners-Lee submitted for what later became the World Wide web. And we did this project and you can check out the project at worldwideweb30.com.
This wonderful group of people came together for a week to kind of hack on something. And what we were hacking on was this project to recreate the very first web browser …but that you could run it in a modern web browser. This is what it looked like.
The first web browser was also called confusingly WorldWideWeb. It was created by Tim Berners-Lee on his NeXT machine. And this was the first demonstration of those three things working together: HTTP, URLs and HTML.
Now I say we were working on this. I didn’t make this part. This was the really smart bit; much cleverer people were working on the smart bit. What I worked on was the website that accompanied the project.
And specifically I worked on creating a timeline.
Remember this is coming up on the 30th anniversary of the web, and I thought it’d be fascinating to not just graph out the 30 years that the web has existed, but also look back at the 30 years before the web existed to see what were the influences that fed into the web.
What I was looking at here really was the path dependencies. What were the path dependencies in computing and networks, hypertext and formats that all fed into that creation of the World Wide Web?
So let’s take formats, for example. Tim Berners-Lee creates HTML along with URLs and HTTP.
And if I show you these elements, they should be quite familiar to you. You recognize what this language is, right? Yeah. Clearly this language is…
SGML. Standard Generalized Markup Language.
Specifically, it’s a flavor of SGML that was being used in CERN at the time. And Tim Berners-Lee thought rather than create his own format, he would use what people were already used to.
He kind of had the same insight that Grace Hopper had, that humans are allergic to change. But instead of trying to change that, he sort of went with the flow.
So he took SGML and basically copied it to make HTML, introducing one new element, which is the, A
element.
So, you know, there’s a path dependency, even in the name, right? You think Standard Generalized Markup Language. Oh right. And now we have HyperText Markup Language. So even the name HTML seems to have a path dependency to SGML.
But it goes deeper.
SGML was a specialized version of GML. And GML was supposed to stand for Generalized Markup Language. Except the people who created GML were named Goldfarb, Mosher, and Lorie, which is probably the real reason why it was named GML.
And later we got SGML and then we got HTML. So it turns out there’s a path dependency in the phrase “HTML” that goes back to three dudes wanting to get their names into a format many, many years ago.
Styling
What about styling when it came to the early web?
There’s no CSS at this point. But if you look at this first web browser—and this is the very first web page on the web, which is still available at its original URL—you can see that different types of elements are styled differently.
The links are styled differently than the text around them. The heading is styled differently to the body copy. This definition list has formatting going on. You can see the spacing there. So something is doing some styling.
Well, when we were at this hack week at CERN, we had access to the original source code for this project. We found this file in there.
And this is, I guess, the user agent style sheet. This is the bit that tells the first web browser how to style headings, how to style lists, how to style definitions.
It’s not very readable, but you can tell that, you know, there’s a lot of values here, not many property names, but if you squinted it just right, you can imagine, okay, this is some form of a style sheet.
It became clear though that it wasn’t enough to just allow the user agent to do the styling. Authors—that’s developers and designers—authors also needed a way to provide styling information.
Now for a while there, it looked like the way this was gonna happen was going to be in HTML. People started adding these proprietary elements and attributes to HTML that were all about presentation, all about styling. And that’s not what HTML is for. HTML is about structure, about the semantics, the meaning of a document.
It was really important that there’d be some kind of separation of concerns, that you would use one format—HTML—for your structure, and that there should be a separate format, some other kind of language, for styling.
The question is, what should that other format be?
Well, pretty early on, some proposals started coming in early mailing lists to do with the World Wide Web. Pretty much everyone on the web in the first few months was making their own web browser. It was by nerds for nerds.
Rob Raisch
I think the first proposal for some kind of styling for authors came from Rob Raisch, who was at O’Reilly at the time.
He sent an email to the www-talk mailing list in June of 1993, with this proposal as a way of styling.
@BODY fo(fa=he,si=18)
Now, again, looking at this, it’s not CSS, but if you squint just right, you can sort of make sense of it. It’s kind of like looking at a clock running counterclockwise. It’s not what we’re used to, but you feel like you could parse it.
Clearly the priority here was to do with brevity. We’ve got these two character things like FO for font, FA for face, HE for Helvetica, SI for size. You put that all together and you can say the font face should be Helvetica and the font size should be 18 of whatever unit we’re talking about here.
So, you know, just about able to parse it, there is the concept here of, you know, some kind of selector, right? The way that we say we’re talking about the BODY
, we’re talking about the paragraph or talking about B
or I
.
Pei Wei
The next proposal that came along was by Pei Wei, who was building the Viola web browser. He sent an email to the www-talk mailing list in October of 1993. And he was able to put his entire style sheet in his proposal.
This is what it looks like. Kind of similar to what we saw before. We’ve got the idea of properties and values, but with equal signs rather than colons that we used to now.
But what’s really interesting here is this idea of nesting. We’ve got nesting going on in this proposal which is something that we’re really only just getting in CSS.
Håkon Wium Lie
Now, the next proposal came from Håkon Wium Lie. This was October of 1994 and he called his proposal Cascading HTML Style Sheets. And it looked like this.
h1.font.size = 24pt 100%
And again, you can kind of parse this, right? It’s not what we’re used to, but you squint at it and you can make sense of it. You can see the way that the selector and the properties are kind of scrunched together with this dot syntax. And again, there’s an equal sign rather than a colon, but we get it. It’s like, okay, the font size of an H1
element should be 24 points. Got it.
But wait, what’s this percentage after it, like this 100% or this 40%?
Influence
Well, this is a really interesting part of this proposal. This was this idea of influence. The idea that an author should be able to effectively say how much they care about a particular style being applied.
So if you really want that heading to be that size, you say 100%, I care about this. But if you only half care, you could say 50%.
And the idea was that users would also be providing styles and users would also specify how much they cared, how much influence they wanted to exert exert on the styles.
And then there’s kind of a bit of hand-wavy logic where it’s like, “And then the user agent figures out what the final style should be.”
And that last part it turned out was really hard to do. So this idea of influence somewhat fell by the wayside. But I think it’s very powerful and it definitely matched the ideas of Tim Berners-Lee with his first web browser, this idea that the web should be a read and write medium.
Because that first web browser—WorldWideWeb—wasn’t just a browser. It was also an editor.
The idea was you would open a document from the web, you’re looking at it and you think “I wanna make changes to this document. I’m gonna create my own copy, put it on my server and make the changes.”
Now it turned out that was really hard. And so that was one of the first things that got dropped from the World Wide Web, which is a bit of a shame because I think it is a very, very powerful idea, a very empowering idea.
We somewhat got back this idea of a read/write web with things like wikis and blogs and even social media to a certain extent.
And the idea that users should have influence over the styles of a website? Well, that survived in web browsers for quite a while, with this concept of user style sheets.
This is different to user agent style sheets. This was literally that in your browser, you could specify styles to override what an author has specified.
This got dropped from browsers over time because it turned out to be a real power-user feature. Most people weren’t using this. These days, if you want to apply styles as a user, you have to install a browser extension, some kind of plugin. Or your operating system has some kind of translation of like, “these are my preferences at the operating system level” and those get translated to the browser.
I think it’s a real shame that we lost user style sheets. I thought it was a very empowering feature. I get it. It was, you know, somewhat of an edge case. It was power-user feature, but I think it’s a shame we lost it.
I do see, however, a bit of a resurgence in the idea of giving users control over styling with some of the things we’re seeing in CSS, particularly in the media queries level five, this idea of what are being called preference queries. You can say, you know, prefers a color scheme, like dark mode prefers reduced motion, prefers reduced data.
Now it’s a bit different because it’s still up to the author of the style sheet on that website to honour these preferences, right? You still have to write the styles to do the right thing to respect the colour scheme or reduced motion or reduced data.
Though, you know, some browsers are looking into automatically applying some of this stuff automatically: inverting colors and reducing motion.
And on the whole, I welcome the idea that users should have more of a say in how websites are styled. I think it’s a good thing.
So we’re seeing a bit of a resurgence of this idea of influence in modern CSS.
And speaking of modern CSS being somewhat foreshadowed in Håkon’s original proposal, here’s something else that was in that original proposal…
font.size = 12pt
h1.font.size = font.size * 3
h2.font.size = font.size * 2.5
h3.font.size = font.size * 2
If you look at this, you can kind of figure out what’s going on. That there’s kind of a declaration at the top to say there’s a variable, if you like, that’s 12 points. And then that variable is used throughout the style sheet. It’s multiplied by different numbers.
And really, we’ve got this now in CSS, thanks to custom properties and calc()
, right? The ability to set variables and do calculations on those variables. But it took a long time between this original proposal and this very modern CSS that we have today.
Bert Bos
The final proposal I want to mention came from Bert Bos. This was also in 1994 and his proposal looked like this.
I think this is the first time we started to see colons rather than equal signs for properties and values. But again, you can see the way that the selectors and the properties sort of munged together with this dot syntax.
It’s parsable, right? Again, it’s like looking at a clock running counterclockwise, but you can understand what’s going on here.
So Bert’s proposal is interesting. It’s one more proposal. But what I really like about what Bert did was Bert also provided design principles.
In other words, the thinking behind the proposal. Because like I was kind of saying, you know, the standard itself, in some ways, isn’t the important thing. The important thing is the agreement. So let’s all try and agree on what we’re trying to accomplish with some kind of style sheet language. And I will also freely admit I’m just a sucker for design principles.
Design principles
I’m fascinated by design principles. I even collect them. This is like my equivalent of my interesting rock collection. A collection of design principles at principles.adactio.com.
And if you go there, I’ve collected design principles from individuals, from organizations, and I have Bert’s principles there.
And they’re worth reading through, but one of the issues with Bert’s principles is there’s a lot of them. These are all the different things that feed into the design of a style sheet language. And these are all good things, but I think what’s missing here is some kind of prioritization.
Because the hard part about design principles, isn’t saying what you value. The hard part about design principles is saying we value one thing over another.
So let’s take two of these. We see simplicity and longevity. Well, do we value simplicity more than longevity? Do we value longevity more than simplicity? That’s actually the hard part, to specify the priorities.
So I think it’s a bit of a shame that there isn’t prioritization here, but I think it’s still fascinating that we can look at all of the things that Bert was imagining we have to balance in some kind of style sheet language.
Well, it became pretty clear that Bert and Håkon were working on the same sort of thing. And so they pooled their resources together and kids, that’s where CSS comes from. Jointly from Bert and Håkon.
CSS
And what they settled on—with all of those different design principles and all of the ideas from the different proposals that came before—this is what we got:
selector {
property: value;
}
This one pattern. You’ve got a selector, a property and a value. Then we’ve got these special characters for syntax, right? Curly braces, colons, semicolons, but really it’s somewhat arbitrary. The point is that all of CSS pretty much can be boiled down to this one pattern: selector, property, value.
It’s a very simple pattern. And yet it allows for endless complexity. I mean, this is our shared context on the web for styling. If you think about the number of websites out there, right? Billions. And every one of them has a different style sheet and every one of them is different. And yet all of them use the same pattern at its root.
It’s the classic example of how a simple rule can create a complex system. And I think this might also be at the heart of why CSS can be misunderstood. Because this pattern is very simple and because it’s very simple, people might think well, CSS is therefore easy.
But there’s a difference between simplicity and easiness.
Like, you can learn the idea of CSS in an hour, right? Because effectively this pattern is it. You need to get your head around selector, property, value.
But you can then spend a lifetime trying to master CSS because of all the possible combinations of selectors and properties and values, right? It’s a lifetime of learning.
So this is where I think some of the disconnect comes with people thinking, “Oh yeah, I’ll pick up CSS. No problem. It’s easy.” And actually, no. It’s simple, but it’s not easy.
And CSS has grown over time, right? We keep getting more selectors, we keep getting more properties and we keep getting more values. It grows and grows while still maintaining this fundamental pattern.
Hacks
And if we look at where the growth of CSS has come from, you know, a lot of the time it came from hacks. And I don’t mean literal CSS hacks, like the box model hack or tan hack for any anybody old enough to remember that.
I mean hacks in a sense of its original use of a clever solution to a problem, but probably not a great long term solution.
Layout
So the classic example of hacks on the web would’ve been layout. You know, in the early days we were using tables for layout. We had transparent gifs, one pixel by one pixel gifs that we would give width and height to allow us to make all the layouts we wanted. And it worked, but it was a hack.
So then we got CSS and we switched to using floats for layout, which was better. But, you know, it was still a hack because floats weren’t intended for layout. They were intended for, you know, having text flow around images.
And it’s only relatively recently in the history of the web that we finally are able to throw away our hacks and use proper layout tools.
Because now we’ve got flexbox and we’ve got grid and these are made for layout. It took quite a while for us to get there.
But you know, in the early days of the web, it wasn’t even clear if CSS should attempt to do layout or whether there should be a third format specifically for layout. Because maybe there needed to be that separation of concerns between structure (you’ve got HTML), styling (you’ve got CSS), and some third technology for layout which could be considered like its own its own thing.
I mean, if you think about it today, we kind of sequester layout into media queries. So you could imagine that being a separate technology.
But anyway, it became clear over time that CSS should be the home for layout as well as other kinds of styling.
And that’s what we’ve got now. We’ve got flexbox. We’ve got grid. We got proper layout on the web so we were able to stop using our hacks and use the real native tools.
Typography
It’s a similar story with typography.
If you wanted to use a font that wasn’t one of the system fonts that most people would have installed, well, you went into Photoshop and you made an image of text using the font you wanted, and now the user would have to download that image file and the text wasn’t selectable, it was a fixed width, it came with all sorts of problems. And we came up with very clever solutions to do what’s called image replacement in CSS, but they were all hacks.
And now we don’t need the hacks because we’ve got the @font-face
rule. So we can literally specify the typeface we want to use. We can stop using the hacks.
Graphic design
We used a lot of hacks for graphic design as well. Things that we weren’t quite able to do natively in CSS.
I’m gonna air my laundry here and show you a website I made back in 2005. This was the website for my first book called DOM Scripting and it’s very much of its time.
This is the very 2005-feeling design. You see the way we’ve got that element there with rounded corners? And you see the way that there’s a gradient in the background of the page? Well, back in 2005, we didn’t have rounded corners in CSS and we didn’t have gradients.
So those rounded corners? Those are images that have been absolutely positioned into that element.
And that gradient is actually an image. It’s a one pixel wide, but very, very tall image that is tiled across the entire background.
So these were hacks and they worked, but obviously I wouldn’t need to do that today. Today, I’ve got border-radius
to do my rounded corners and I got linear-gradient
to do my gradients.
Ironically, right as we got the power to do rounded corners and gradients in CSS natively, we all collectively decided that, nah, actually what we want is flat design …which we could have been doing all along!
Anyway, let me show you another example. This is a website that dates back even further. This is my own personal website, adactio.com.
This design hasn’t really changed in over 20 years, but I have updated the technology.
Let’s the take image at the top. You can see that’s been given some treatment as a corner has been sliced out of one edge and a gradient has been applied so it fades out.
Now it used to be that I would have to do that in Photoshop. I’d take the original image, I’d slice off the corner, I’d add a gradient layer on top of it.
Well now I don’t need Photoshop because I can use clip-path
to take off the corner. I can use a linear gradient using generated content—using the ::after
pseudo element—to get the exact same result.
So now I’ve got something that looks pretty much the same, except where I had to do it in Photoshop before, now I’m able to do it natively in CSS.
And that might not sound like much of a win because the end result looks the same, right?
Except now when I’m applying a prefers-color-scheme
style sheet and I give a dark mode to my site, I don’t have to make a separate image. Because this is being done natively in CSS. The gradient is in CSS. The clip path is in CSS. It’s all native to CSS.
Material honesty
This comes down to this idea of material honesty. About using the right material for the job, rather than using a material that’s pretending to be something else, whether that’s, you know, an image of text, pretending to be a font or an image of a gradient, pretending to be a real gradient or, you know, any of those graphic design tricks.
We can now be materially honest in CSS because we’ve got grid and flexbox and border-radius
and @font-face
. It’s more honest.
And also it’s easier, right? It’s less work to avoid the hacks.
Like, one of my favorite examples of something we got recently in CSS to avoid the hacks. It’s a small thing, but it makes a big difference in my opinion, is just styling things like check boxes and radio buttons.
We’ve always been able to do it, but it involved a hack where you’d hide the real checkbox off screen. And then you’d use a background image to show the different states of the checkbox. And it was fine and it worked and we could make it accessible.
But now we can just use accent-color
and it’s easier.
So there’s been this movement from hacks to native CSS. And in a way, the hacks show the direction of travel. The hacks show us what the future could be.
Tools
The other place CSS has borrowed from or learned from, has been in our tools. Like the tools we use to generate our CSS.
Sass is the classic example, right? Sass is this enormously popular pre-processor for CSS and people were using Sass to do things you couldn’t do natively in CSS.
And I feel like one of the genius bits of design in Sass was that it worked a lot like the way HTML worked in the early days compared to SGML.
Remember, I was talking about how Tim Berners-Lee took SGML and literally turned it into HTML? Like, you were able to take an SGML document and change the file extension, and it would be a valid HTML document. And so that really helped with the adoption of HTML.
Well, that’s the same with Sass. You could take your existing style sheet document and just changed the file extension to .scss
and it was already valid Sass, right? You didn’t have to learn a new syntax.
This isn’t supposition on my part—that this was a reason for the huge success of Sass—because actually Sass had two options, two different syntaxes, and you could choose.
There was this .sass
syntax and the .scss
syntax.
And with the .sass
syntax, it used significant white space. It was more condensed, right? It used indentation.
But with .scss
it used the syntax you were already familiar with from CSS.
So you could say that the .sass
syntax was more efficient. You could say it’s a better format, but humans are allergic to change. And the .scss
syntax was familiar enough that people go, “oh yeah, I get this.”
You could, you could take your existing CSS and just start using the features of Sass you wanted to.
And people overwhelmingly chose the .scss
syntax over the .sass
syntax. I got to meet Hampton Catlin who invented Sass and he confirmed the numbers for me. He said, yeah, it was a no brainer. Basically the .sass
syntax lacks familiarity. It’s like looking at a clock running counter-clockwise.
But anyway, people started using Sass to do things like nesting, calculations (these mix-ins), variables; all these things that we now do in CSS.
Of course, the reason we can do these things in CSS is because Sass proved that there was a desire for these things.
So now you really don’t need Sass for a lot of stuff, but the reason you don’t need Sass is because of Sass. Sass paved the way. Sass showed that there was a demand for this stuff. And now it’s native in the CSS. We don’t need that tool anymore.
And I feel like that’s a test of a really good tool. A really successful tool is when it becomes redundant.
In the JavaScript world, jQuery is a classic example of this, right?
With jQuery you were able to do things using a CSS syntax, whereas otherwise you had to use this long winded DOM syntax of document.getElementsByTagName
or getElementById
.
Whereas in jQuerythe idea was, “Hey, if you already know how to select something in CSS, just use that syntax again!”
It’s using what people are familiar with. Humans are allergic to change.
But these days we don’t need jQuery because in the DOM, we’ve got querySelectorAll
, we’ve got querySelector
. We can use CSS selectors to do our DOM scripting.
Why don’t we need jQuery anymore? Because of jQuery.
jQuery showed that this was a really clever idea. It was something people wanted. And so now it’s been standardized. We don’t need jQuery.
So I really feel like the goal of any good library should be to make itself obsolete. It’s so successful, it’s no longer needed.
And you could kind of see this in the history of the web with Sass, with jQuery, even with something like Flash.
You know, Flash showed the way. It showed that, “Hey, we want a way to do animation. We need some way to do video on the web.” And people were using Flash because there was no other way to do those things.
Now we don’t need Flash or jQuery or Sass because we get them natively.
So all of these are almost like research and development for the web.
They’re kind of like hacks, but I think a better way of thinking about them is they’re more like polyfills—these are things we can use until we get a standardized way of doing it.
I think it’s fascinating to look at our tools and see what can they tell us about what’s coming into standards.
Methodologies
A whole set of tools are these methodologies that people came up with, like OOCSS from Nicole Sullivan. And there’s BEM. And SMACSS was another one. There’s a whole bunch.
But I’m fascinated by these because these aren’t an example of some technology we needed to lobby browser makers to implement. Because these are really agreements.
These are agreements. These are saying, “let’s all agree to structure our CSS in a certain way.” Nothing needed to change in browsers, right?
And all of these are testament to the power of the cascade. Because what they do is they almost deliberately limit the cascade, which is seen as almost being too powerful.
So they’re not really tools, they’re methodologies. Or another way of putting it is they are agreements.
Again, the power of saying “let’s all agree to do something.”
Scale
And the problem that most of them are trying to solve is trying to do CSS at scale, trying to do CSS when you’ve got a large team. Which is interesting to think about like, why wasn’t CSS designed to scale well like this?
Large companies find HTML and CSS frustrating “at scale” because the web is fundamentally an anticapitalist mashup art experiment designed to give consumers all the power.
Okay, it’s funny, but it’s kind of funny ’cause it’s true. If you look at those design principles that Bert Bos came up with, it was very much about empowering the end user, that CSS needed to be accessible. It needed to be something you could learn quickly.
So, you know, thinking about CSS as something that needs to be able to scale to multiple teams of people? That wasn’t really on the cards for CSS back then. It wasn’t a priority.
And maybe that’s why we came up with these methodologies like BEM and OOCSS and SMACSS to try and manage this stuff.
But even these methodologies, now the ideas behind them are finding their way into the standards. Now we’re getting cascade layers and scope in CSS.
To me, this feels like a return of this idea of influence that Håkon Wium Lie was talking about all those years ago.
Now it’s not so much about the influence between an author and a user; it’s about the influence between multiple authors working on, on a giant code base.
So it’s a very exciting time for CSS to see these new tools arrive that can solve these scale problems.
But I do ask myself, what’s still missing in CSS? And this is a great question to ask of JavaScript as well:
What’s still missing?
And you can answer the question by looking at what are we still using tools for? What are we still having to polyfil because we don’t yet have it natively in the browser?
And to answer this question, I’m gonna just quickly finish with three components that kind of demonstrate where CSS is still missing some features.
button
Let’s start with a button component.
All right. If you wanna implement a button component, you’ve kind of got two options. You can use a button
element and then you style it with CSS to look however you want. Or you can, you know, make up your own button component using a div
or a span
, add the CSS and JavaScript and ARIA.
Really there’s absolutely no reason to do that. In this case, it’s a no brainer. You use a button element
and you style it with CSS. I cannot think of any reason why you would not do that. There used to be reasons like ages ago in Internet Explorer it used to be hard to style buttons. Those days are long gone.
So in this case, really simple answer to the question. Material honesty. Use a button
element. Use CSS to style it.
dropdown
All right. What about a dropdown component? There’s a number of options, you click in and you get a select dropdown.
Well, again, you can use a select
element style with CSS, or you can just make your own dropdown component with a div
and JavaScript and a bunch of ARIA to try and make it accessible.
Now here, I would still say, use a select
element and style it with CSS, but you are gonna hit a limit. Like the open state of the dropdown is kind of out of our control. There’s not much you can do in CSS. So if you really care about styling the open state of a dropdown, I guess I can understand why you would reach for making your own with a div
and JavaScript and ARIA.
I mean, I personally wouldn’t do it. But I guess I can see it, because CSS isn’t there yet. We don’t yet have the power to style a dropdown.
date picker
What about a date picker component? You click into it, the user chooses a date.
Again, there appears to be an obvious solution here, which is use input type="date"
. Boom. You’re done style it how you want, right?
Well, good luck with that. If you’ve ever try to style input type="date"
, there’s actually very little you can do. And so if you care about the styling of the date selector, you probably are gonna have to make up your own with a bunch of div
s and JavaScript and try to make it accessible with ARIA.
Yeah, it’s a real shame.
So I think these three components kind of show the battle ground, if you will, where CSS is still falling short a bit, where we have to still use hacks. It’s kind of this battle between the under-engineered solution—just use the native HTML element—and the over-engineered solution, right? We’re gonna have to create all the functionality and all the accessibility by ourselves.
And I used to get mad at people choosing the hacks, choosing the over-engineered solution. But I realized that it’s kind of like, you know, trying to reduce teen pregnancy by telling people to just stop having sex. Abstinence isn’t realistic. People are going to do it anyway. And the question is, well, how do we make it better and safer in the long run?
So I think that’s the real battleground, is how do we style elements like select
and date pickers natively in CSS? And that’s why I think the work being done by the open UI group is really, really important.
It’s at open-ui.org.
And they say:
The purpose of open UI to the web platform is to allow web developers to style and extend built in web controls, such as select dropdowns, check boxes, radio buttons, and date and color pickers.
I think it’s really important work. And I think that’s where we should be putting our effort.
The future
Because, you know, the difference between doing something natively in a web browser and doing something with a framework or with JavaScript is context.
Web browsers are the shared context between users and authors.
Whereas, if you want to use a framework or a library, you have to ship that context to the end user. And that puts a burden on them. It’s not good for performance. It’s not good for the user experience.
So web browsers are where past agreements live on today and they live on into the future.
When something lands in a browser, it stays in a browser. So by using what’s in web browsers, you are benefiting from decades of work by multitudes of people. And it’s better for users.
So treat frameworks and libraries as polyfils. Use them as a temporary measure when there’s something that’s still not possible in browsers (this is very true of JavaScript frameworks).
They can point the way to a shared context in the future, but they themselves are not the future. So don’t get too attached. Treat them as cattle, not pets.
Use frameworks and libraries as scaffolding to help you build. But they are not a foundation.
Web standards in the browser are your foundation to build upon.
You know, having an awareness of the history of technologies from sun dials to web browsers, it can help you understand the way things are today. And in some ways the lessons of path dependence and inertia are sort of grim, right? Because of some arbitrary decision in the past, we are now stuck with the consequences in our clockfaces, in CSS. And it’s very, very hard to change that.
But there’s another way to look at this.
Nothing was inevitable. Which means nothing is inevitable (you know, except for entropy and the heat death of the universe).
So if someone tells you, “Hey, that’s just the way things are; accept it”, don’t believe it.
Understand your position in the timeline.
Yes, the present moment is the result of decisions made in the past, many of them arbitrary, but that also means the future will be highly influenced by the decisions you make today even if those decisions seem small and inconsequential.
The choices you make now could turn out to have long-lasting repercussions into the future.
So make your decisions wisely. You are literally creating the future.
And I’m looking forward to seeing the results.
Thank you.