
This past weekend, I discovered a real rabbit hole of a thing: Desktop Safari has the ability to load custom style sheets!
š±
What does this mean, exactly?
-
It means I no longer have to harangue the proprietors of horribly designed websites to change things up šš¼
-
It means bye bye Arial, and hello Avenir šÆ
-
It means I can finally read Daring Fireball without Reader mode š¤
Table of Contents
The History of User-defined Style Sheets in Desktop Safari ¶
As far as I can tell, Safariās had the option of loading a custom style sheet since version 1 was released in January 2003.
I scoured the web for official Safari release notes from those early days, but alas, I couldnāt find any.
The best evidence Iāve found that custom style sheets have been an option since version 1 is Sven-S. Porstās snarky blog post from January 2003, entitled Quarter Life Crisis. In his post, Porst compares the newly-released Safari with Chimera:
Then, everything thatās missing in Chimera is there: Font encoding menu? Check. Google search field? Check. Location bar/sheet that autocompletes, taking into account both the history and your bookmarks? Check. Popup window blocking thatās easy to toggle on and off in case thereās a stubborn site? Check. Same for cache cleaning? Check. (Well, thatād be rather useless, frankly, if Safari were cleverer about reloading pages. Itās cache seems to be a bit more reluctant to reload pages and see changes in them while Chimera has no troubles whatsoever with this.) Very easy preferences? Check. ā¦that still enables you to set a style sheet? Check. That oneās quite cool. [emphasis added]
I checked the page source, but his post predates the convention of including a <meta>
tag with the publishing time. So I checked the Wayback Machine. The earliest cached entry for Porstās post was March 2004. So while thereās no cached version of the post from January 2003, March of the next year is definitely still pre-Safari 2 (April 2005).
Of course I went to the source. Gramps, also known as Don Melton, is a former Director of Internet Technologies at Apple, and headed the teams behind Safari and WebKit development.
@donmelton Gramps, I have a Safari history question for you.
— Anthony Craig (@ToniWonKanobi) March 13, 2018
I *just* discoverd/realized that Desktop Safari has the ability to load custom style sheets š±
Was this in Safari 1 in ~2003?
I honestly donāt remember. Does it matter? I mean, itās not like youāre going to use old versions of Safari now. :)
— Don Melton (@donmelton) March 13, 2018
So no help there, but it seems custom style sheets have been around since the beginning.
Although Iām elated the Safari/WebKit team decided to include this feature, part of me wonders why it was included at all.
Apple has never been that open of a company. Allowing users to make their own decisions about how things should function, or how things should lookāor what they even wantāthat isnāt exactly Appleās M.O.
Because my own Apple journey started in 2006, Safari 1 was before my time. My hunch is that the Safari/WebKit team added a custom style sheet option because back then, most web designers were not utilizing CSS. From what I gather about the early days of the web, referencing external style sheets was not commonplace at first. Moreover, having a nice-looking website wasnāt necessarily a priority back then. Rather than have a sub-optimal web browsing experience, Safari/WebKit engineers let power users choose their own styles.
Of course, CSS eventually became more prominent, and then a web standard. Itās 2018. The case for a custom style sheet option in todayās Safari may not be as strong as it was 15 years ago. But itās probably one of those things that current Safari engineers look at every year and ask, āWhy take it out now?ā
I sure am glad itās there š
And thatās it for my brief history of Safariās custom style sheet option.[1]
Now letās talk about implementing the custom style sheet, so that you can make your web browsing dreams come true.
Implementing Safariās Custom Style Sheet ¶
Itās easy:
-
Create a style sheet and put it somewhere youāll remember
Hereās mine in SCSS/Sass, because I forget whether CSS finally has variables:[2]
Never have I used so many -
Open Safari preferences, and navigate to the Advanced tab
-
From the `Style sheet` dropdown menu, locate and select the style sheet you created in Step 1
-
Be happy.
Issues ¶
After spending the better part of last weekend tweaking my custom style sheet, I have to say: Iām pretty impressed with myself š
I meant what I said earlier, though: this has been such a rabbit hole. I thought endlessly tweaking the minutia of my own websites was tiring. Little did I know it would be even more daunting to mess with everyone elseās websites.
And in scratching that itch, I have run into a few walls šļø
All or Nothing ¶
After fiddling with it a bit, I realized my custom style sheet was being applied to all websites I visited. (Duh š¤¦š¼āāļø) And the problem with that is some websites have great styles without my helpāwhy would I want inject my own styles if theirās were already okay?
And if I needed to selectively apply my styles, what was the best way to go about it?
Blacklisting vs./and/or Whitelisting Websites ¶
At first, I was trying to target each website individually. I would peek at the page source, looking for id
ās or class
ās that were unique to each website, and target those specific websites in my style sheetāsort of like a blacklist. But then I realizedāI did a lot of realizing this past weekendāthat method would be untenable, because bad websites with horrible styles likely outnumber the good websites with pleasing stylesāby a huge margin, no doubt.[3]
So what about applying the opposite approach? Instead of targeting specific ugly websites and their specific ugly website selectors, I could just assume that most websites look like trash![4] And then I could just apply my styles to all websites, and selectively un-style those sites that already looked good. In other words, I could have a whitelist.
What I ended up doing was something more like a blacklist, but with some whitelist characteristics mixed in.
I knew I didnāt want to apply my generic website styles to my personal websites (or websites for which I am a quasi-administrator).
So I applied a class toni
to the <html>
elements of all my websites:
<html class="toni">
That allowed me to use the negation pseudo-class :not()
to prevent any of my custom styles from being applied to the websites Iāve made or administer:
html:not(.toni) {
body {
font-family: Avenir !important;
font-weight: 500 !important;
// (More styles)
}
}
Iām effectively selecting-out the āgoodā (my) websites that need no stylingālike a whitelist. Theoretically, I could have done the same for other websites with good styles, but Iām too lazy for that, and I think my styles generally look better than theirāsāeven if they werenāt that bad to begin with.[5]
And for any situations where my styles are not specific enough, Iāve also included a few selectors targeting those stubborn sitesālike a blacklist.
This is a portion of my style sheet targeting Marco Armentās blog. I had to adjust the size of his āmasthead,ā because when I increased the font-size
across the board, it overwhelms his colorful āmastheadā at the top of the webpage:
#mastheadbackground {
height: 200px !important;
margin-bottom: -200px !important;
}


Thatās just one example. If you dive into my style sheet, youāll see more of what Iām talking about.
JavaScript Ruins Everything ¶
Most of the websites/blogs I follow adhere to web standards and common practices. They have semantic document models, with id
ās and class
ās that make sense, and eschew inline styles for referenced external style sheets. Basically, I can style most websites easily enough.
However, the recent trendāespecially for big publishersāis to dynamically generate content and styles using server-side and client-side JavaScript. Scripts running in the browser window collect data such as the browser type, and use that and other information to determine how to best present the content.
As far as styles go, that usually means inlining. If styles are based on classes that are generated by JavaScript, itās that much more difficult for me to isolate them and override them. Moreover, the big websites usually have super complex style sheetsāsome with thousands of lines of code.
JavaScript inlining and complex style sheets make for a specificity nightmare! In those situations, I may have Avenir for the title of the site, or maybe in the other headings, for instance, but the body text may still be whatever the author chose. Youāll notice that Iāve included !important
after every declaration. (Thatās sort of like the `ignore everything else and just do what I said in this declaration` CSS command.) Sometimes, thatās not even enough to overcome the insane levels of specificity for some of these websites.
Still, mostly Avenir is better than mostly Arial /or Helvetica, Verdana, or Comic Sans (š)āIāll take what I can get.
If you havenāt already done so, try playing around with a custom style sheet in SafariāI think youāll be glad you did š»
If there are any early Netscape/Chimera/Safari/WebKit engineers or historians or experts reading this blog post, please let me know whether my version of history is correct, and/or if I should add something for clarity š¤ ā©
Vanilla CSS does have variables, but CSS still doesnāt have nesting, or that neat little
&
that makes SCSS/Sass so great. ā©My style sheet would be littered with stupid selectors like this:
ā©#collection-55f20fcce4b00eb5577ba5e2.transparent-header.enable-nav-button.nav-button-style-outline.nav-button-corner-style-rounded.banner-button-style-outline.banner-button-corner-style-rounded.banner-slideshow-controls-arrows.meta-priority-date.hide-entry-author.hide-list-entry-footer.hide-sidebar-title.hide-blog-sidebar.center-navigation--info.hide-site-info.event-thumbnails.event-thumbnail-size-32-standard.event-date-label.event-date-label-time.event-list-show-cats.event-list-date.event-list-time.event-list-address.event-icalgcal-links.event-excerpts.event-item-back-link.gallery-design-grid.aspect-ratio-auto.lightbox-style-light.gallery-navigation-bullets.gallery-info-overlay-show-on-hover.gallery-aspect-ratio-32-standard.gallery-arrow-style-no-background.gallery-transitions-fade.gallery-show-arrows.gallery-auto-crop.product-list-titles-under.product-list-alignment-center.product-item-size-11-square.product-image-auto-crop.product-gallery-size-11-square.show-product-price.show-product-item-nav.product-social-sharing.newsletter-style-light.opentable-style-light.small-button-style-solid.small-button-shape-square.medium-button-style-solid.medium-button-shape-square.large-button-style-solid.large-button-shape-square.image-block-poster-text-alignment-center.image-block-card-dynamic-font-sizing.image-block-card-content-position-center.image-block-card-text-alignment-left.image-block-overlap-dynamic-font-sizing.image-block-overlap-content-position-center.image-block-overlap-text-alignment-left.image-block-collage-dynamic-font-sizing.image-block-collage-content-position-top.image-block-collage-text-alignment-left.image-block-stack-dynamic-font-sizing.image-block-stack-text-alignment-left.button-style-solid.button-corner-style-square.tweak-product-quick-view-button-style-floating.tweak-product-quick-view-button-position-bottom.tweak-product-quick-view-lightbox-excerpt-display-truncate.tweak-product-quick-view-lightbox-show-arrows.tweak-product-quick-view-lightbox-show-close-button.tweak-product-quick-view-lightbox-controls-weight-light.native-currency-code-usd.collection-type-page.collection-layout-default.collection-55f20fcce4b00eb5577ba5e2.homepage.mobile-style-available.has-banner-image.general-page
𤣠ā©
I donāt mean to imply that Iām some sort of amazing front-end designer or anything! I am not suggesting that someone elseās style looks bad (okay, maybe a little). Mostly, I just know what I think looks good, and thatās what done with my style sheet. ā©