Links
A CSS-Tricks roundup of use cases for pseudo-elements
cssreference.io is a free visual guide to CSS. It features the most popular properties, and explains them with illustrated and animated examples.
Drawing with CSS
Wenting Zhang has this great video where she gives an introduction to drawing with CSS. She created an icon set in CSS, which doubles as a great learning resource.
She mentions that she decided to create CSS Icon because she wanted to leverage CSS animations. What I don't understand about the whole drawing with CSS movement is why not use SVG instead.
I looked into this because I had been seeing many examples of people drawing amazing things on CodePen using CSS. I was blown away by this Simpson's collection.
CSS3 Patterns Gallery is a great
resource to learn how to produce CSS-only background and filler patterns. Great
for mastering the background
property, CSS gradients and the creative use of
color and transparency.
CSSBattle. CSS code-golfing. Replicate targets with the smallest possible code. It's great deliberate practice although only for a subset of CSS. You also won't be using in production many of the tricks and hacks that you'll learn to keep the code small, but it's a lot of fun and it will get you to master positioning, pseudo-elements, backgrounds, borders, box-shadows and many others.
Agathe Cocco has a three-part series on drawing with CSS (1, 2 and 3).
CSS-in-JS
- Chris Biscardi provides a nice set of ideas on the topic of naming and structuring components using Emotion.
Using system fonts
Triggered by "The New System Font Stack?", I decided to look into using that on my web projects. That article suggests using the following snippet:
body {font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;}
That's from September 2016, inspired by WordPress 4.6, so it's a bit out of date. In September 2017, CSS-Tricks provides a similar stack but gives this warning:
This method should only be used on the font-family property instead of the font shorthand. Booking.com published a thorough write-up on the warnings it generates due to the leading font appearing to be a vendor prefix.
They also mention an alternative interesting strategy, using @font-face
:
/* Define the "system" font family */@font-face {font-family: system;font-style: normal;font-weight: 300;src: local('.SFNSText-Light'), local('.HelveticaNeueDeskInterface-Light'),local('.LucidaGrandeUI'), local('Ubuntu Light'), local('Segoe UI Light'),local('Roboto-Light'), local('DroidSans'), local('Tahoma');}/* Now, let's apply it on an element */body {font-family: 'system';}
Using the
system-font.css
you can use eight variations of the system-ui font family; light (300) light
italic, normal (400), normal italic, medium (500), medium italic, bold (700),
and bold italic. Like this:
body {font-family: system-ui;}blockquote {font: italic 300 system-ui;}p {font: 400 system-ui;}
Note that in the previous two cases, the font faces system
and system-ui
were being defined in the accompanying CSS. On the other hand, system-ui
was
added as a possible value for the font-family
property in CSS. It seems
decently supported.
It seems appropriate to use the following:
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto','Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
But this, so W(ho)TF knows. I just checked Bootstrap and they use this:
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'HelveticaNeue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'SegoeUI Symbol', 'Noto Color Emoji';
Loading fonts
To read: Web Font Optimization.
This article gives a great overview of strategies to improve the loading of Google Fonts. Some of the tips apply to fonts in general.
We typically load Google Fonts by adding this piece of markup:
<linkhref="https://fonts.googleapis.com/css?family=Muli:400"rel="stylesheet"/>
That returns a stylesheet full of @font-face
declarations like this one:
@font-face {font-family: 'Muli';font-style: normal;font-weight: 400;src: local('Muli Regular'), local('Muli-Regular'),url(https://fonts.gstatic.com/s/muli/v12/7Auwp_0qiz-afTzGLQjUwkQ1OQ.woff2)format('woff2');unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;}
This tries to load fonts locally if they're available, before going to
fonts.gstatic.com
. That's not too bad, specially considering that Google's
severs are good, but we have a couple of problems with this approach:
We're performing a minimum of 2 separate requests to different hosts - first for the stylesheet at
fonts.googleapis.com
, and then to a unique URL for each font hosted atfonts.gstatic.com
.We have no control over flash-of-invisible-text (FOIT) and flash-of-unstyled-text (FOUT) while fonts are loading. Setting the
font-display
property in the@font-face
would give us that control, but it’s defined in the Google Fonts stylesheet.Finally, while rare, if Google Fonts is down, we won’t get our fonts. If our own CDN is down, then at least we are consistently delivering nothing to our users, right?
Two strategies are suggested. At the very least, warm up the DNS lookup, TCP
handshake, and TLS negotiation to fonts.gstatic.com
with preconnect
:
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin /><linkhref="https://fonts.googleapis.com/css?family=Muli:400"rel="stylesheet"/>
Alternatively, self-host. Use google-webfonts-helper and follow instructions.
“Modern Browsers” will give you WOFF and WOFF2 formats while “Best Support” will also give you TTF, EOT, and SVG. A reasonable option is to chose to only host WOFF and WOFF2 while selecting system fonts as fallbacks for older browsers.
In your pages, use preload
for fonts that you're sure you'll be using:
"Preload is a declarative fetch, allowing you to force the browser to make a
request for a resource without blocking the document’s onload event." (Preload,
Prefetch And Priorities in
Chrome).
All the browsers that support preload
also support WOFF2 so we can safely
choose only WOFF2.
<linkrel="preload"as="font"type="font/woff2"href="./fonts/muli-v12-latin-regular.woff2"crossorigin/><linkrel="preload"as="font"type="font/woff2"href="./fonts/muli-v12-latin-700.woff2"crossorigin/>
rel="preload"
tells the browser to declaratively fetch the resource but not “execute” it (our CSS will queue usage).as="font"
tells the browser what it will be downloading so that it can set an appropriate priority. Without it, the browser would set a default low priority.type="font/woff2
tells the browser the file type so that it only downloads the resource if it supports that file type.crossorigin
is required because fonts are fetched using anonymous mode CORS.
If you’re okay with FOUT, or flash of unstyled text, then we can fix FOIT by
adding font-display: swap;
to our @font-face
declarations. More info in this
glitch. It explains the use of the
font-display
property:
Font loading follows three stages: block, swap, failure.
font-display
is applied per font-face.font-display: block
produces FOIT but is good in cases where your font branding is important and you don't want people to see you site with fallback fonts.font-display: swap
produces FOUT, the text is shown immediately in the fallback font until the custom font loads.font-display: fallback
somewhere in between block and swap. The text is invisible for a short period of time (100ms). Then if the custom font hasn't downloaded, the text is shown in a fallback font (for about 3s), then swapped after the custom font loads.font-display: optional
like fallback but the browser can decide to not use the custom font at all, based on the user's connection speed.
subfont is a command line tool to optimize your webfont loading. Aggressive subsetting based on your font use, self-hosting of Google fonts and preloading. If you're cool, you use Gatsby and life's good: there's a plugin for that.