Building on the idea of an IndieWeb zine - Benjamin Parry
Speaking of zines, I really like Benjamin’s ideas about a web-first indie web zine: using print stylesheets with personal websites to make something tangible but webby.
Speaking of zines, I really like Benjamin’s ideas about a web-first indie web zine: using print stylesheets with personal websites to make something tangible but webby.
I love print stylesheets but I was today years old when I found out that print-color-adjust
exists.
Hear, hear!
If you have even a passing knowledge of CSS, I encourage you to experiment with its possibilities.
A collection of stylesheets that don’t use class selectors. Think of them as alternatives to default user-agent stylesheets.
I think this might be the most excited I’ve been in quite some time about an update to browser support, which probably says a lot about my priorities:
Support for the
avoid
value of the CSS fragmentation propertiesbreak-before
,break-after
, andbreak-inside
when printing.
Finally!
I was talking about this with Léonie just yesterday. I, for one, would love to have CSS speech support. You know who else would love it? Content designers!
In these days of voice interaction on every platform, there is a growing expectation that it should be possible to design that experience just like we can the visual experience. In the same way an organisation chooses a logo and colour palette for its website, it stands to reason that they may also choose a particular voice that represents their brand.
It’s wild that there’s no way to do this on the web.
My website has different themes you can choose from. I don’t just mean a dark mode. These themes all look very different from one another.
I assume that 99.99% of people just see the default theme, but I keep the others around anyway. Offering different themes was originally intended as a way of showcasing the power of CSS, and specifically the separation of concerns between structure and presentation. I started doing this before the CSS Zen Garden was created. Dave really took it to the next level by showing how the same HTML document could be styled in an infinite number of ways.
Each theme has its own stylesheet. I’ve got a very simple little style switcher on every page of my site. Selecting a different theme triggers a page refresh with the new styles applied and sets a cookie to remember your preference.
I also list out the available stylesheets in the head
of every page using link
elements that have rel
values of alternate
and stylesheet
together. Each link
element also has a title
attribute with the name of the theme. That’s the standard way to specify alternative stylesheets.
In Firefox you can switch between the specified stylesheets from the View
menu by selecting Page Style
(notice that there’s also a No style
option—very handy for checking your document structure).
Other browsers like Chrome and Safari don’t do anything with the alternative stylesheets. But they don’t ignore them.
Every browser makes a network request for each alternative stylesheet. The request is non-blocking and seems to be low priority, which is good, but I’m somewhat perplexed by the network request being made at all.
I get why Firefox is requesting those stylesheets. It’s similar to requesting a print stylesheet. Even if the network were to drop, you still want those styles available to the user.
But I can’t think of any reason why Chrome or Safari would download the alternative stylesheets.
I love this kind of spelunking into the history of why things are they way they are on the web!
Here, Detective Chief Inspector Suzanne tries to get to the bottom of why every browser has eight pixels of margin applied to the body
element in the user-agent stylesheet.
When I wrote about the new accent-color
property in CSS, I pondered how much control a web developer should have over styling form controls:
Who are we to make that decision? Shouldn’t the user’s choice take primacy over our choices?
But then again, where do we draw the line? We’re allowed over-ride link colours. We’re allowed over-ride font choices.
Ultimately, I came down on the side of granting authors more control:
If developers don’t get a standardised way to customise native form controls, they’ll just recreate their own over-engineered versions.
This question of “who gets to decide?” used to be much more prevelant in the early days of the web. One way to think about this is that there are three stakeholders involved in the presentation of a web page:
These days we tend to think of web design a single-stakeholder undertaking. The author decides how something should be presented and then executes that decision using CSS.
But as Eric once said, every line of you CSS you write is a suggestion to the browser. That’s not how we think about CSS though. We think of CSS like a series of instructions rather than suggestions. Never mind respecting the user’s preferences; one of the first things we do is reset all the user agent’s styles.
In the early days of the web, more consideration was given to the idea of style suggestions rather than instructions. Heck, users could always over-ride any of your suggestions with their own user stylesheet. These days, users would need to install a browser extension to do the same thing.
The first proposal for CSS had a concept called “influence”:
h2.font.size = 20pt 40%
Here, the requested influence is reduced to 40%. If a style sheet later in the cascade also requests influence over h2.font.size, up to 60% can be granted. When the document is rendered, a weighted average of the two requests is calculated, and the final font size is determined.
I think the only remnant of “influence” left in CSS is accidental. It’s in the specificity of selectors …and the !important
declaration.
I think it’s a shame that user stylesheets are no longer a thing. But I get why they were dropped from browsers. They date from a time when it was mostly nerds using the web, before “regular folks” came on board. I understand why it became a little-used feature, suitable for being dropped. But the principle of it still rankles slightly.
But in recent years there has been a slight return to the multi-stakeholder concept of styling websites. Thanks to prefers-reduced-motion
and prefers-color-scheme
, a responsible author can choose to bow to the wishes of the user.
I was reminded of this when I added a dark mode to my website:
Y’know, when I first heard about Apple adding dark mode to their OS—and also to CSS—I thought, “Oh, great, Apple are making shit up again!” But then I realised that, like user style sheets, this is one more reminder to designers and developers that they don’t get the last word—users do.
Given the widespread browser support for prefers-reduced-motion
now, this approach makes a lot of sense.
There are three ways—that I know of—to associate styles with markup.
External CSS
This is probably the most common. Using a link
element with a rel
value of “stylesheet”, you point to a URL using the href
attribute. That URL is a style sheet that is applied to the current document (“the relationship of the linked resource it is that is a ‘stylesheet’ for the current document”).
<link rel="stylesheet" href="/path/to/styles.css">
In theory you could associate a style sheet with a document using an HTTP header, but I don’t think many browsers support this in practice.
You can also pull in external style sheets using the @import
declaration in CSS itself, as long as the @import
rule is declared at the start, before any other styles.
@import url('/path/to/more-styles.css');
When you use link rel="stylesheet"
to apply styles, it’s a blocking request: the browser will fetch the style sheet before rendering the HTML. It needs to know how the HTML elements will be painted to the screen so there’s no point rendering the HTML until the CSS is parsed.
Embedded CSS
You can also place CSS rules inside a style
element directly in the document. This is usually in the head
of the document.
<style>
element {
property: value;
}
</style>
When you embed CSS in the head
of a document like this, there is no network request like there would be with external style sheets so there’s no render-blocking behaviour.
You can put any CSS inside the style
element, which means that you could use embedded CSS to load external CSS using an @import
statement (as long as that @import
statement appears right at the start).
<style>
@import url('/path/to/more-styles.css');
element {
property: value;
}
</style>
But then you’re back to having a network request.
Inline CSS
Using the style
attribute you can apply CSS rules directly to an element. This is a universal attribute. It can be used on any HTML element. That doesn’t necessarily mean that the styles will work, but your markup is never invalidated by the presence of the style
attribute.
<element style="property: value">
</element>
Whereas external CSS and embedded CSS don’t have any effect on specificity, inline styles are positively radioactive with specificity. Any styles applied this way are almost certain to over-ride any external or embedded styles.
You can also apply styles using JavaScript and the Document Object Model.
element.style.property = 'value';
Using the DOM style
object this way is equivalent to inline styles. The radioactive specificity applies here too.
Style declarations specified in external style sheets or embedded CSS follow the rules of the cascade. Values can be over-ridden depending on the order they appear in. Combined with the separate-but-related rules for specificity, this can be very powerful. But if you don’t understand how the cascade and specificity work then the results can be unexpected, leading to frustration. In that situation, inline styles look very appealing—there’s no cascade and everything has equal specificity. But using inline styles means foregoing a lot of power—you’d be ditching the C in CSS.
A common technique for web performance is to favour embedded CSS over external CSS in order to avoid the extra network request (at least for the first visit—there are clever techniques for caching an external style sheet once the HTML has already loaded). This is commonly referred to as inlining your CSS. But really it should be called embedding your CSS.
This language mix-up is not a hill I’m going to die on (that hill would be referring to blog posts as blogs) but I thought it was worth pointing out.
Hidde gave a great talk recently called On the origin of cascades (by means of natural selectors):
It’s been 25 years since the first people proposed a language to style the web. Since the late nineties, CSS lived through years of platform evolution.
It’s a lovely history lesson that reminded me of that great post by Zach Bloom a while back called The Languages Which Almost Became CSS.
The TL;DR timeline of CSS goes something like this:
www-talk
mailing list.www-talk
mailing list.Håkon and Bert joined forces and that’s what led to the Cascading Style Sheet language we use today.
Hidde looks at how the concept of the cascade evolved from those early days. But there’s another idea in Håkon’s proposal that fascinates me:
While the author (or publisher) often wants to give the documents a distinct look and feel, the user will set preferences to make all documents appear more similar. Designing a style sheet notation that fill both groups’ needs is a challenge.
The proposed solution is referred to as “influence”.
The user supplies the initial sheet which may request total control of the presentation, but — more likely — hands most of the influence over to the style sheets referenced in the incoming document.
So an author could try demanding that their lovely styles are to be implemented without question by specifying an influence of 100%. The proposed syntax looked like this:
h1.font.size = 24pt 100%
More reasonably, the author could specify, say, 40% influence:
h2.font.size = 20pt 40%
Here, the requested influence is reduced to 40%. If a style sheet later in the cascade also requests influence over h2.font.size, up to 60% can be granted. When the document is rendered, a weighted average of the two requests is calculated, and the final font size is determined.
Okay, that sounds pretty convoluted but then again, so is specificity.
This idea of influence in CSS reminds me of Cap’s post about The Sliding Scale of Giving a Fuck:
Hold on a second. I’m like a two-out-of-ten on this. How strongly do you feel?
I’m probably a six-out-of-ten, I replied after a couple moments of consideration.
Cool, then let’s do it your way.
In the end, the concept of influence in CSS died out, but user style sheets survived …for a while. Now they too are as dead as a dodo. Most people today aren’t aware that browsers used to provide a mechanism for applying your own visual preferences for browsing the web (kind of like Neopets or MySpace but for literally every single web page …just think of how empowering that was!).
Even if you don’t mourn the death of user style sheets—you can dismiss them as a power-user feature—I think it’s such a shame that the concept of shared influence has fallen by the wayside. Web design today is dictatorial. Designers and developers issue their ultimata in the form of CSS, even though technically every line of CSS you write is a suggestion to a web browser—not a demand.
I wish that web design were more of a two-way street, more of a conversation between designer and end user.
There are occassional glimpses of this mindset. Like I said when I added a dark mode to my website:
Y’know, when I first heard about Apple adding dark mode to their OS—and also to CSS—I thought, “Oh, great, Apple are making shit up again!” But then I realised that, like user style sheets, this is one more reminder to designers and developers that they don’t get the last word—users do.
This is a great talk by Hidde, looking at the history and evolution of cascading style sheets. Right up my alley!
You know what I like? Print stylesheets!
I mean, I’m not a huge fan of trying to get the damn things to work consistently—thanks, browsers—but I love the fact that they exist (athough I’ve come across a worrying number of web developers who weren’t aware of their existence). Print stylesheets are one more example of the assumption-puncturing nature of the web: don’t assume that everyone will be reading your content on a screen. News articles, blog posts, recipes, lyrics …there are many situations where a well-considered print stylesheet can make all the difference to the overall experience.
You know what I don’t like? QR codes!
It’s not because they’re ugly, or because they’ve been over-used by the advertising industry in completely inapropriate ways. No, I don’t like QR codes because they aren’t an open standard. Still, I must grudgingly admit that they’re a convenient way of providing a shortcut to a URL (albeit a completely opaque one—you never know if it’s actually going to take you to the URL it promises or to a Rick Astley video). And now that the parsing of QR codes is built into iOS without the need for any additional application, the barrier to usage is lower than ever.
So much as I might grit my teeth, QR codes and print stylesheets make for good bedfellows.
I picked up a handy tip from a Smashing Magazine article about print stylesheets a few years back. You can the combination of a @media print
and generated content to provide a QR code for the URL of the page being printed out. Google’s Chart API provides a really handy shortcut for generating QR codes:
https://chart.googleapis.com/chart?cht=qr&chs=150x150&chl=http://example.com
Except that there’s no telling how long that will continue to work. Google being Google, they’ve deprecated the simple image chart API in favour of the over-engineered JavaScript alternative. So just as I recently had to migrate all my maps over to Leaflet when Google changed their Maps API from under the feet of developers, the clock is ticking on when I’ll have to find an alternative to the Image Charts API.
For now, I’ve got the QR code generation happening on The Session for individual discussions, events, recordings, sessions, and tunes. For the tunes, there’s also a separate URL for each setting of a tune, specifically for printing out. I’ve added a QR code there too.
I’ve been thinking about another potential use for QR codes. I’m preparing a new talk for An Event Apart Seattle. The talk is going to be quite practical—for a change—and I’m going to be encouraging people to visit some URLs. It might be fun to include the biggest possible QR code on a slide.
I’d better generate the images before Google shuts down that API.
Harry takes a look at the performance implications of loading CSS. To be clear, this is not about the performance of CSS selectors or ordering (which really doesn’t make any difference at this point), but rather it’s about the different ways of getting rid of as much render-blocking CSS as possible.
…a good rule of thumb to remember is that your page will only render as quickly as your slowest stylesheet.
Good advice on print styles from Rachel. The browser support situation is frustrating; I suspect it’s because the people working on browsers would rather get stuck in on shinier stuff.
I think Chris is on to something here when he identifies one of the biggest issues with CSS growing out of control:
The developers are afraid of the CSS.
A great piece from Danielle on the different mental models needed for different languages. When someone describes a language—like CSS—as “broken”, it may well be that there’s a mismatch in mental models.
CSS isn’t a programming language. It’s a stylesheet language. We shouldn’t expect it to behave like a programming language. It has its own unique landscape and structures, ones that people with programming language mental maps might not expect.
I believe that this mismatch of expectation is what has led to the current explosion of CSS-in-JS solutions. Confronted with a language that seems arbitrary and illogical, and having spent little or no time exposed to the landscape, developers dismiss CSS as ‘broken’ and use systems that either sweep it under the rug, or attempt to force it into alignment with the landscape of a programming language — often sacrificing some of the most powerful features of CSS.
I had a chat with Toby Osbourn over Skype. He’s writing a book all about print stylesheets so that’s we talked about.
It’s fascinating to look back at this early proposal for CSS from 1994 and see what the syntax might have been:
A one-statement style sheet that sets the font size of the h1 element:
h1.font.size = 24pt 100%
The percentage at the end of the line indicates what degree of influence that is requested (here 100%).