typography – CSS-Tricks https://css-tricks.com Tips, Tricks, and Techniques on using Cascading Style Sheets. Mon, 29 Jul 2024 19:03:51 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 https://i0.wp.com/css-tricks.com/wp-content/uploads/2021/07/star.png?fit=32%2C32&ssl=1 typography – CSS-Tricks https://css-tricks.com 32 32 45537868 Letter Spacing is Broken and There’s Nothing We Can Do About It… Maybe https://css-tricks.com/letter-spacing-is-broken-and-theres-nothing-we-can-do-about-it-maybe/ https://css-tricks.com/letter-spacing-is-broken-and-theres-nothing-we-can-do-about-it-maybe/#comments Mon, 29 Jul 2024 16:41:34 +0000 https://css-tricks.com/?p=379318 This post came up following a conversation I had with Emilio Cobos — a senior developer at Mozilla and member of the CSSWG — about the last CSSWG group meeting. I wanted to know what he thought were the …


Letter Spacing is Broken and There’s Nothing We Can Do About It… Maybe originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
This post came up following a conversation I had with Emilio Cobos — a senior developer at Mozilla and member of the CSSWG — about the last CSSWG group meeting. I wanted to know what he thought were the most exciting and interesting topics discussed at their last meeting, and with 2024 packed with so many new or coming flashy things like masonry layout, if() conditionals, anchor positioning, view transitions, and whatnot, I thought his answers had to be among them.

He admitted that my list of highlights was accurate on what is mainstream in the community, especially from an author’s point of view. However, and to my surprise, his favorite discussion was on something completely different: an inaccuracy on how the letter-spacing property is rendered across browsers. It’s a flaw so ingrained on the web that browsers have been ignoring the CSS specification for years and that can’t be easily solved by a lack of better options and compatibility issues.

Emilios’s answer makes sense — he works on Gecko and rendering fonts is an art in itself. Still, I didn’t get what the problem is exactly, why he finds it so interesting, and even why it exists in the first place since letter-spacing is a property as old as CSS. It wasn’t until I went into the letter-spacing rabbit hole that I understood how amazingly complex the issue gets and I hope to get you as interested as I did in this (not so) simple property.

What’s letter spacing?

The question seems simple: letter spacing is the space between letters. Hooray! That was easy, for humans. For a computer, the question of how to render the space between letters has a lot more nuance. A human just writes the next letter without putting in much thought. Computers, on the other hand, need a strategy on how to render that space: should they add the full space at the beginning of the letter, at the end, or halve it and add it on both sides of the letter? Should it work differently from left-to-right (LTR) languages, like English, to right-to-left (RTL) like Hebrew? These questions are crucial since choosing one as a standard shapes how text measurement and line breaks work across the web.

Which of the three strategies is used on the web? Depends on who you ask. The implementation in the CSS specifications completely differs from what the browsers do, and there is even incompatibility between browsers rendering engines, like Gecko (Firefox), Blink (Chrome, Brave, Opera, etc.), and WebKit (Safari).

What the CSS spec says

Let’s backpedal a bit and first know how the spec says letter spacing should work. At the time of writing, letter-spacing:

Specifies additional spacing between typographic character units. Values may be negative, but there may be implementation-dependent limits.

The formal specification has more juice to it, but this one gives us enough to understand how the CSS spec wants letter-spacing to behave. The keyword is between, meaning that the letter spacing should only affect the space between characters. I know, sounds pretty obvious.

So, as the example given on the spec, the following HTML:

<p>a<span>bb</span>c</p>

…with this CSS:

p {
  letter-spacing: 1em;
}

span {
  letter-spacing: 2em;
}

…should give an equal space between the two “b” letters:

Letter spacing on paper. The letter spacing is only applied between the letters "b"s

However, if we run the same code on any browser (e.g., Chrome, Firefox, or Safari), we’ll see the spacing isn’t contained between the “b” letters, but also at the end of the complete word.

Letter spacing on browsers. The letter spacing is applied between the letters "b"s and on the right-hand side of the last letter "b"

What browsers do

I thought it was normal for letter-spacing to attach spacing at the end of a character and didn’t know the spec said otherwise. However, if you think about it, the current behavior does seem off… it’s just that we’re simply used to it.

Why would browsers not follow the spec on this one?

As we saw before, letter spacing isn’t straightforward for computers since they must stick to a strategy for where spacing is applied. In the case of browsers, the standard has been to apply an individual space at the end of each character, ignoring if that space goes beyond the full word. It may have not been the best choice, but it’s what the web has leaned into, and changing it now would result in all kinds of text and layout shifts across the web.

This leaves a space at the end of elements with bigger letter spacing, which is somewhat acceptable for LTR text, but it leaves a hole at the beginning of the text in an RTL writing mode.

The issue is more obvious with centered text, where the ending space pushes the text away from the element’s dead center. You’ve probably had to add padding on the opposite side of an element to make up for any letter-spacing you’ve applied to the text at least one time, like on a button.

As you can see, the blue highlight creates a symmetrical pyramid which our text sadly doesn’t follow.

What’s worse, the “end of each character” means something different to browsers, particularly when working in an RTL writing mode. Chrome and Safari (Blink/WebKit) say the end of a character is always on the right-hand side. Firefox (Gecko), on the other hand, adds space to the “reading” end — which in Hebrew and Arabic is the left-hand side. See the difference yourself:

Side-by-side comparison of letter spacing on Gecko and Blink/Webkit

Can this be fixed?

The first thought that comes to mind is to simply follow what the spec says and trim the unnecessary space at the ending character, but this (anti) solution brings compatibility risks that are simply too big to even consider; text measurement and line breaks would change, possibly causing breakage on lots of websites. Pages that have removed that extra space with workarounds probably did it by offsetting the element’s padding/margin, which means changing the behavior as it currently stands makes those offsets obsolete or breaking.

There are two real options for how letter-spacing can be fixed: reworking how the space is distributed around the character or allowing developers an option to choose where we want the ending space.

Option 1: Reworking the space distribution

The first option would be to change the current letter-spacing definition so it says something like this:

Specifies additional spacing applied to each typographic character unit except those with zero advance. The additional spacing is divided equally between the inline-start and -end sides of the typographic character unit. Values may be negative, but there may be implementation-dependent limits.

Simply put, instead of browsers applying the additional space at the end of the character, they would divide it equally at the start and end, and the result is symmetrical text. This would also change text measurements and line breaks, albeit to a lesser degree.

Letter spacing with the symmetrical fix. The letter spacing is equally applied around the letters "b"s

Now text that is center-aligned text is correctly aligned to the center:

Different examples of letter spacing being distributed between letters and achieving a symmetrical look

Option 2: Allowing developers an option to choose

Even if the offset is halved, it could still bring breaking layout shifts to pages which to some is still (rightfully) unacceptable. It’s a dilemma: most pages need, or at least would benefit, from leaving letter-spacing as-is, while new pages would enjoy symmetrical letter spacing. Luckily, we could do both by giving developers the option to choose how the space is applied to characters. The syntax is anybody’s guess, but we could have a new property to choose where to place the spacing:

letter-spacing-justify: [ before | after | left | right | between | around];

Each value represents where the space should be added, taking into account the text direction:

  • before: the spacing is added at the beginning of the letter, following the direction of the language.
  • after: the spacing is added at the end of the letter, following the direction of the language.
  • left: the spacing is added at the left of the letter, ignoring the direction of the language.
  • right: the spacing is added at the right of the letter, ignoring the direction of the language.
  • between: the spacing is added between characters, following the spec.
  • around: the spacing is divided around the letter.

Logically, the current behavior would be the default to not break anything and letter-spacing would become a shorthand for both properties (length and placing).

letter-spacing: 1px before;
letter-spacing: 1px right;
letter-spacing: 1px around;

letter-spacing: 1px;
/* same as: */
letter-spacing: 1px before;

What about a third option?

And, of course, the third option is to leave things as they are. I’d say this is unlikely since the CSSWG resolved to take action on the issue, and they’ll probably choose the second option if I had to bet the nickel in my pocket on it.

Now you know letter-spacing is broken… and we have to live with it, at least for the time being. But there are options that may help correct the problem down the road.


Letter Spacing is Broken and There’s Nothing We Can Do About It… Maybe originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/letter-spacing-is-broken-and-theres-nothing-we-can-do-about-it-maybe/feed/ 6 379318
Solved With :has(): Vertical Spacing in Long-Form Text https://css-tricks.com/solved-with-has-vertical-spacing-in-long-form-text/ https://css-tricks.com/solved-with-has-vertical-spacing-in-long-form-text/#comments Wed, 18 Jan 2023 13:44:00 +0000 https://css-tricks.com/?p=376435 If you’ve ever worked on sites with lots of long-form text — especially CMS sites where people can enter screeds of text in a WYSIWYG editor — you’ve likely had to write CSS to manage the vertical spacing between different …


Solved With :has(): Vertical Spacing in Long-Form Text originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
If you’ve ever worked on sites with lots of long-form text — especially CMS sites where people can enter screeds of text in a WYSIWYG editor — you’ve likely had to write CSS to manage the vertical spacing between different typographic elements, like headings, paragraphs, lists and so on.

It’s surprisingly tricky to get this right. And it’s one reason why things like the Tailwind Typography plugin and Stack Overflow’s Prose exist — although these handle much more than just vertical spacing.

Firefox supports :has() behind the layout.css.has-selector.enabled flag in about:config at the time of writing.

What makes typographic vertical spacing complicated?

Surely it should just be as simple as saying that each element — p, h2, ul, etc. — has some amount of top and/or bottom margin… right? Sadly, this isn’t the case. Consider this desired behavior:

  • The first and last elements in a block of long-form text shouldn’t have any extra space above or below (respectively). This is so that other, non-typographic elements are still placed predictably around the long-form content.
  • Sections within the long-form content should have a nice big space between them. A “section” being a heading and all the following content that belongs to that heading. In practice, this means having a nice big space before a heading… but not if that heading is immediately preceded by another heading!
Example of a Heading 3 following a paragraph and another following a Heading 2.
We want to more space above the Heading 3 when it follows a typographic element, like a paragraph, but less space when it immediately follows another heading.

You need to look no further than right here at CSS-Tricks to see where this could come in handy. Here are a couple of screenshots of spacing I pulled from another article.

A Heading 2 element directly above a Heading 3.
The vertical spacing between Heading 2 and Heading 3
A Heading 3 element directly following a paragraph element.
The vertical space between Heading 3 and a paragraph

The traditional solution

The typical solution I’ve seen involves putting any long-form content in a wrapping div (or a semantic tag, if appropriate). My go-to class name has been .rich-text, which I think I use as a hangover from older versions of the Wagtail CMS, which would add this class automatically when rendering WYSIWYG content. Tailwind Typography uses a .prose class (plus some modifier classes).

Then we add CSS to select all typographic elements in that wrapper and add vertical margins. Noting, of course, the special behavior mentioned above to do with stacked headings and the first/last element.

The traditional solution sounds reasonable… what’s the problem? I think there are a few…

Rigid structure

Having to add a wrapper class like .rich-text in all the right places means baking in a specific structure to your HTML code. That’s sometimes necessary, but it feels like it shouldn’t have to be in this particular case. It can also be easy to forget to do this everywhere you need to, especially if you need to use it for a mix of CMS and hard-coded content.

The HTML structure gets even more rigid when you want to be able to trim the top and bottom margin off the first and last elements, respectively, because they need to be immediate children of the wrapper element, e.g., .rich-text > *:first-child. That > is important — after all, we don’t want to accidentally select the first list item in each ul or ol with this selector.

Mixing margin properties

In the pre-:has() world, we haven’t had a way to select an element based on what follows it. Therefore, the traditional approach to spacing typographic elements involves using a mix of both margin-top and margin-bottom:

  1. We start by setting our default spacing to elements with margin-bottom.
  2. Next, we space out our “sections” using margin-top — i.e. very big space above each heading
  3. Then we override those big margin-tops when a heading is followed immediately by another heading using the adjacent sibling selector (e.g. h2 + h3).

Now, I don’t know about you, but I’ve always felt it’s better to use a single margin direction when spacing things out, generally favoring margin-bottom (that’s assuming the CSS gap property isn’t feasible, which it is not in this case). Whether this is a big deal, or even true, I’ll let you decide. But personally, I’d rather be setting margin-bottom for spacing long-form content.

Collapsing margins

Because of collapsing margins, this mix of top and bottom margins isn’t a big problem per se. Only the larger of two stacked margins will take effect, not the sum of both margins. But… well… I don’t really like collapsing margins.

Collapsing margins are yet one more thing to be aware of. It might be confusing for junior devs who aren’t up to speed with that CSS quirk. The spacing will totally change (i.e. stop collapsing) if you were to change the wrapper to a flex layout with flex-direction: column for instance, which is something that wouldn’t happen if you set your vertical margins in a single direction.

I more-or-less know how collapsing margins work, and I know that they’re there by design. I also know they’ve made my life easier on occasion. But they’ve also made it harder other times. I just think they’re kinda weird, and I’d generally rather avoid relying on them.

The :has() solution

And here is my attempt at solving these issues with :has().

To recap the improvements this aims to make:

  • No wrapper class is required.
  • We’re working with a consistent margin direction.
  • Collapsing margins are avoided (which may or may not be an improvement, depending on your stance).
  • There’s no setting styles and then immediately overriding them.

Notes and caveats on the :has() solution

  • Always check browser support. At time of writing, Firefox only supports :has() behind an experimental flag.
  • My solution doesn’t include all possible typographic elements. For instance, there’s no <blockquote> in my demo. The selector list is easy enough to extend though.
  • My solution also doesn’t handle non-typographic elements that may be present in your particular long-form text blocks, e.g. <img>. That’s because for the sites I work on, we tend to lock down the WYSIWYG as much as possible to core text nodes, like headings, paragraphs, and lists. Anything else — e.g. quotes, images, tables, etc. — is a separate CMS component block, and those blocks themselves are spaced apart from each other when rendered on a page. But again, the selector list can be extended.
  • I’ve only included h1 for the sake of completeness. I usually wouldn’t allow a CMS user to add an h1 via WYSIWYG, as the page title would be baked into the page template somewhere rather than entered in the CMS page editor.
  • I’m not catering for a heading followed immediately by the same level heading (h2 + h2). This would mean that the first heading wouldn’t “own” any content, which seems like a misuse of headings (and, correct me if I’m wrong, but it might violate WCAG 1.3.1 Info and Relationships). I’m also not catering for skipped heading levels, which are invalid.
  • I am in no way knocking the existing approaches I mentioned. If and when I build another Tailwind site I’ll use the excellent Typography plugin, no question!
  • I’m not a designer. I came up with these spacing values by eyeballing it. You probably could (and should) use better values.

Specificity and project structure

I was going to write a whole big thing here about how the traditional method and the new :has() way of doing it might fit into the ITCSS methodology… But now that we have :where() (the zero-specificity selector) you can pretty much choose your preferred level of specificity for any selector now.

That said, the fact that we’re no longer dealing with a wrapper — .prose, .rich-text, etc. — to me makes it feel like this should live in the “elements” layer, i.e. before you start dealing with class-level specificity. I’ve used :where() in my examples to keep specificity consistent. All the selectors in both of my examples have a specificity score of 0,0,1 (except for the bare-bones reset).

Wrapping up

So there you have it, a bleeding-edge solution to a very boring problem! This newer approach is still not what I’d call “simple” CSS — as I said at the beginning, it’s a more complex topic than it might seem at first. But aside from having a few slightly complex selectors, I think the new approach makes more sense overall, and the less rigid HTML structure seems very appealing.

If you end up using this, or something like it, I’d love to know how it works out for you. And if you can think of ways to improve it, I’d love to hear those too!


Solved With :has(): Vertical Spacing in Long-Form Text originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/solved-with-has-vertical-spacing-in-long-form-text/feed/ 10 376435
Designing for Long-Form Articles https://css-tricks.com/designing-for-long-form-articles/ https://css-tricks.com/designing-for-long-form-articles/#comments Wed, 10 Aug 2022 14:30:01 +0000 https://css-tricks.com/?p=367370 Designing a beautiful “article” is wrought with tons of considerations. Unlike, say, a homepage, a long-form article is less about designing an interface than it is designing text in a way that creates a relaxed and comfortable reading experience.

That’s …


Designing for Long-Form Articles originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Designing a beautiful “article” is wrought with tons of considerations. Unlike, say, a homepage, a long-form article is less about designing an interface than it is designing text in a way that creates a relaxed and comfortable reading experience.

That’s because articles deal with long-form content which, in turn, tends to be valued by a ”time on page” interaction with users. We want someone to read a complete narrative. There’s a natural space between the time someone lands on an article and reads all the words. And hopefully, that space is immersive enough to not only hold a user’s, but provoke thoughts, ideas, and, possibly, actions. At least that’s what I’m hoping as I have your attention and you make your way through the very article you’re reading.

There’s a balance. On one hand, we hear that “no one reads the Internet.” On the other, a long-form article demands careful attention. Considering the current value of content marketing and the growing impatience in users, captivating readers for as long as possible should be a key concern. Let’s take a look at some best practices and examples of incredible article pages to get a better idea of what makes a visually appealing reading experience for long-form articles (without sacrificing user experience), and how we can replicate the effects.

Quick wins

Let me quickly list out what I think might already be obvious to many of you, but are effective things for content legibility:

  • Increase the font size: We know that 16px is the default and is perfectly fine in many designs, but a larger font size is inviting in that it implies the user is free to lean back and settle in without having to angle forward with the screen in their face to read.
  • Aim for characters per line: Very few people I know like to work harder than they need to, and that goes for reading too. Rather than using the full viewport width, try to narrow things down and balance that with your larger font size to get fewer characters on each line of text. Your sweet spot may vary, though many folks suggest somewhere between 45-75 characters per line to help limit how far the reader’s eye has to work to go from left to right. Chris has a bookmarklet to help count characters, but we also have the ch unit in CSS to get predictable results.
  • Bump up the line height: A default line height is going to feel smashed. It’s funny, but more space between lines (up to a point, of course) is less work for eyes, which seems antithetical to the characters-per-line advice where we generally want eyes to travel a shorter distance. A line height between 1.2 and 1.5 seems to be a pretty typical range for long-form content.

If you haven’t seen it before, Pierrick Calvez has a great “five-minute” guide to typography that packs in a bunch of low-hanging fruit like these.

Design for extra breathing room

You may be accustomed to designing “above the fold” where real estate is a prime commodity. That’s sort of like beach-front property in the web world because it’s where we’re used to packing in high-value things, like hero banners, calls to action, and anything else to help sell a thing. Above the fold can be a lot like a dense urban downtown with high traffic and high-rise buildings.

Articles are different. They allow you to stretch out a bit. If we want to take the city development analogy a little further, articles have the acreage to lean into a “less is more” sort of design approach. That’s what makes seemingly small design choices — like type — so important to the overall experience.

Check out the example below. The link underlines have a little more room to breathe (specifically, they appear below the descenders). This is actually something that you can enable sitewide but looks especially nice on article pages since it increases readability. That’s the sort of subtle design choice that contributes to extra breathing room.

A long-form article on the Taste website.

text-underline-position: under; is the line of CSS that makes this work. Naturally, text-decoration must be set to something other than none (underline in this case), too.

The example above also features text-decoration-thickness, which alters the thickness of underlines (and other line types). You can use this CSS property to match a line’s thickness to a font’s size and/or weight.

Here’s a full example:

a {
  text-decoration: underline;
  text-decoration-thickness: 2px;

  /* or */
  text-decoration: underline 2px;
  text-underline-position: under;
}

But before you reach for the text-decoration shorthand, Šime Vidas has a few “gotchas” when it comes to using it that are worth reviewing.

Leading into the content

Drop caps are stylized letters that can be placed at the beginning of a document or document section. They were once used in Latin texts, but today they’re mostly used for decorative reasons.

Personally, I think that drop caps hinder readability. However, they can be a nice way to “lead” a reader into the main content, and they shouldn’t introduce any serious accessibility issues as long as you’re using the ::first-letter pseudo-element. There are other (older) methods that involve more HTML and CSS as well as the use of ARIA attributes in order for the content to remain accessible.

Using ::first-letter, the CSS would look something like this:

/* select the first letter of the first paragraph */
article > p:first-child::first-letter {
  color: #903;
  float: left;
  font-family: Georgia;
  font-size: 75px;
  line-height: 60px;
  padding-top: 4px;
  padding-right: 8px;
  padding-left: 3px;
}

It sure would be nice if we could use the initial-letter property, but there’s pretty much no support for it at the time I’m writing this. If we had it, all that math for font size and line height would be calculated for us!

CodePen challenged folks to show off their drop-cap-styling skills several years ago and you can see a whole bunch of neat examples from it in this collection.

Skip to main content

Screen readers allow users to skip to the main content as long as it wraps it within a <main> element. However, those who navigate websites by tabbing don’t benefit from this. Instead, we must create a “skip to main content” anchor link. This link is customarily hidden but revealed once the user makes their first tab (i.e. show on focus).

It would look something like this:

<!-- anchor -->
<a id="skip-link" href="#main">Skip to main content</a>

<!-- target -->
<main class="main">
  <!-- main content -->
</main>
#skip-link {
  position: absolute; /* remove it from the flow */
  transform: translateX(-100%); /* move it off-screen so that it appears hidden but remains focusable */
}
#skip-link:focus {
  position: unset; /* insert it back into the flow */
  transform: unset; /* move it back onto the screen */
}

.main {
  scroll-margin: 1rem; /* adds breathing room above the scroll target */
}

There are other ways to go about it, of course. Here are a couple of deeper dives on creating skip links.

Seamless visuals

I love the illustrations in this article. Despite how incredible they look, they don’t demand too much cognitive attention. They introduce brief moments of delight but also suggest that the article itself has something more important to say. Partly, this comes down to the use of transparency, whereas rectangular images capture more negative space and therefore demand more attention (which is fine if that’s the desired effect and images are crucial to the story).

However, it’s important to know that the images aren’t actually transparent at all, but instead are non-transparent JPEGs with the same background color as the content. I’m presuming that’s to keep the size of the images smaller compared to PNGs that support transparency.

Inspecting an image element in DevTools showing the JPEG images in the source.

The downside to “faking” a transparent background like this is that it would require additional trickery (and maintenance) to support a dark mode UI if your site happens to offer one. If the illustrations are pretty flat and simple, then SVG might be the way to go instead since it’s small, scalable, and capable of blending into whatever background it’s on.

But if you’re bound to using raster images and would rather work with PNG files for transparency, you’ll want to look into using responsive images and the loading="lazy" attribute for faster loading times.

Put the focus on the type and semantics

You may have very little say over how or where someone reads content on the web these days. Whether the user receives it in an RSS feed, gets it delivered by email, sees it copy-and-pasted from a colleague, finds it on a scraped site, or whatnot, your content might look different than you prefer. You could design what you think is the most gorgeous article in all the land and the user still might smash that Reader Mode button to your dismay.

That’s ok! The discoverability of content is very much as important as the design of it, and many users have their own ways of discovering content and preferences for what makes a good reading experience.

But there are reasons why someone would want a Reader Mode. For one, it’s like “not seeing any CSS” at all. By that, I mean Safari’s Reader Mode or Brave SpeedReader, which use machine learning to detect articles. There’s no fetching or executing of CSS, JavaScript, or non-article images, which boosts performance and also blocks ads and tracking.

Fong-form article viewed with Brave's SpeedReader feature.

This sort of “brute minimalism” puts the focus on the content rather than the styles. So, you might actually want to embrace a browser’s opinionated reading styles specifically for that purpose.

The way to do that is not by using CSS, but by paying closer attention to your HTML. Reader modes work best with markup that uses simple, semantic, article-related HTML. You’ve got to do more than simply slapping <article> tags around the article to get the most from it.

You might just find that a minimal design that emphasizes legibility over slickness is actually a good strategy to use in your site’s design. I’d strongly suggest reading Robin’s post on the “smallest CSS” for a solid reading experience.

Roundup of long-form articles!

I’ve shared a lot of what I think makes for a great reading experience for long-form articles on the web. But seeing is believing and I’ve rounded up a bunch of examples that showcase what we’ve covered.


Designing for Long-Form Articles originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/designing-for-long-form-articles/feed/ 5 367370
Improving Icons for UI Elements with Typographic Alignment and Scale https://css-tricks.com/improving-icons-for-ui-elements-with-typographic-alignment-and-scale/ https://css-tricks.com/improving-icons-for-ui-elements-with-typographic-alignment-and-scale/#comments Tue, 17 May 2022 14:30:18 +0000 https://css-tricks.com/?p=365531 Utilizing icons in user interface elements is helpful. In addition to element labeling, icons can help reinforce a user element’s intention to users. But I have to say, I notice a bit of icon misalignment while browsing the web. Even …


Improving Icons for UI Elements with Typographic Alignment and Scale originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Utilizing icons in user interface elements is helpful. In addition to element labeling, icons can help reinforce a user element’s intention to users. But I have to say, I notice a bit of icon misalignment while browsing the web. Even if the icon’s alignment is correct, icons often do not respond well when typographic styles for the element change.

I took note of a couple real-world examples and I’d like to share my thoughts on how I improved them. It’s my hope these techniques can help others build user interface elements that better accommodate typographic changes and while upholding the original goals of the design.

Example 1 — Site messaging

I found this messaging example on a popular media website. The icon’s position doesn’t look so bad. But when changing some of the element’s style properties like font-size and line-height, it begins to unravel.

Identified issues

  • the icon is absolutely positioned from the left edge using a relative unit (rem)
  • because the icon is taken out of the flow, the parent is given a larger padding-left value to help with overall spacing – ideally, our padding-x is uniform, and everything looks good whether or not an icon is present
  • the icon (it’s an SVG) is also sized in rems – this doesn’t allow for respective resizing if its parent’s font-size changes

Recommendations

Screenshot of the site messaging element. It is overlayed with a red-dashed line indicating the icon's top edge and a blue-dashed line indicating the text's topmost point. The red-dashed line is slightly higher than the blue-dashed line.
Indicating the issues with aligning the icon and typography.

We want our icon’s top edge to be at the blue dashed line, but we often find our icon’s top edge at the red dashed line.

Have you ever inserted an icon next to some text and it just won’t align to the top of the text? You may move the icon into place with something like position: relative; top: 0.2em. This works well enough, but if typographic styles change in the future, your icon could look misaligned.

We can position our icon more reliably. Let’s use the element’s baseline distance (the distance from one line’s baseline to the next line’s baseline) to help solve this.

Screenshot of the site messaging element. It is overlayed with arrows indicating the baseline distance from the baseline of one line to the next line's baseline.
Calculating the baseline distance.

Baseline distance is font-size * line-height.

We’ll store that in a CSS custom property:

--baselineDistance: calc(var(--fontSize) * var(--lineHeight));

We can then move our icon down using the result of (baseline distance – font size) / 2.

--iconOffset: calc((var(--baselineDistance) - var(--fontSize)) / 2);

With a font-size of 1rem (16px) and line-height of 1.5, our icon will be moved 4 pixels.

  • baseline distance = 16px * 1.5 = 24px
  • icon offset = (24px16px) / 2 = 4px

Demo: before and after

Example 2 – unordered lists

The second example I found is an unordered list. It uses a web font (Font Awesome) for its icon via a ::before pseudo-element. There have been plenty of great articles on styling both ordered and unordered lists, so I won’t go into details about the relatively new ::marker pseudo-element and such. Web fonts can generally work pretty well with icon alignment depending on the icon used.

Identified issues

  • no absolute positioning used – when using pseudo-elements, we don’t often use flexbox like our first example and absolute positioning shines here
  • the list item uses a combination of padding and negative text-indent to help with layout – I am never able to get this to work well when accounting for multi-line text and icon scalability

Recommendations

Because we’ll also use a pseudo-element in our solution, we’ll leverage absolute positioning. This example’s icon size was a bit larger than its adjacent copy (about 2x). Because of this, we will alter how we calculate the icon’s top position. The center of our icon should align vertically with the center of the first line.

Start with the baseline distance calculation:

--baselineDistance: calc(var(--fontSize) * var(--lineHeight));

Move the icon down using the result of (baseline distance – icon size) / 2.

--iconOffset: calc((var(--baselineDistance) - var(--iconSize)) / 2);

So with a font-size of 1rem (16px), a line-height of 1.6, and an icon sized 2x the copy (32px), our icon will get get a top value of -3.2 pixels.

  • baseline distance = 16px * 1.6 = 25.6px
  • icon offset = (25.6px32px) / 2 = -3.2px

With a larger font-size of 2rem (32px), line-height of 1.2, and 64px icon, our icon will get get a top value of -12.8 pixels.

  • baseline distance = 32px * 1.2 = 38.4px
  • icon offset = (38.4px64px) / 2 = -12.8px

Demo: before and after

Conclusion

For user interface icons, we have a lot of options and techniques. We have SVGs, web fonts, static images, ::marker, and list-style-type. One could even use background-colors and clip-paths to achieve some interesting icon results. Performing some simple calculations can help align and scale icons in a more graceful manner, resulting in implementations that are a bit more bulletproof.

See also: Previous discussion on aligning icon to text.


Improving Icons for UI Elements with Typographic Alignment and Scale originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/improving-icons-for-ui-elements-with-typographic-alignment-and-scale/feed/ 3 365531
COLRv1 and CSS font-palette: Web Typography Gets Colorful https://css-tricks.com/colrv1-and-css-font-palette-web-typography/ https://css-tricks.com/colrv1-and-css-font-palette-web-typography/#comments Wed, 11 May 2022 14:12:51 +0000 https://css-tricks.com/?p=365677 According to Toshi Omagari, the author of Arcade Game Typography, the world’s first multi-colored digital font was created in 1982 for a never-released video game called Insector. Multi-colored fonts, sometimes called chromatic type, are still relatively rare on the …


COLRv1 and CSS font-palette: Web Typography Gets Colorful originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
According to Toshi Omagari, the author of Arcade Game Typography, the world’s first multi-colored digital font was created in 1982 for a never-released video game called Insector. Multi-colored fonts, sometimes called chromatic type, are still relatively rare on the web, even though the COLR font format has had full cross-browser support since 2018 (even in Internet Explorer!).

The technology opens up an entirely new vein of typographic creativity. While some of the color fonts I’ve seen have been lurid, at best, chromatic fonts are fun, innovative and attention-grabbing. With both the addition of a new CSS features — including the font-palette property and @font-palette-values rule — for controlling the color palette of color fonts and the evolution of the COLR font format, it’s a great time to dive in and experiment with with what modern web typography can do.

Hello in a cursive rainbow color font.

COLR support

I last wrote about color fonts in 2018. At the time, there were four different standards for multicolored typefaces: OpenType-SVG, COLR, SBIX, and CBDT/CBLC. You can use ChromaCheck to see what color font formats your own browser supports.

Google Chrome has marked OpenType-SVG as “wontfix” meaning that format will never be supported by Chrome or Edge. SBIX and CBDT/CBLC can mostly be ignored for use on the web as they’re both based on raster images and become blurry at larger font sizes. The large file size of bitmap-based fonts also makes them a bad choice for the web.

Ulrike Rausch is the creator of LiebeHeide, a bitmap color font which uncannily replicates the look of a ballpoint pen. “My biggest goal was always to reproduce handwritten text as authentically as possible,” she told me. “For LiebeHeide, I was finally able to simulate these handmade attributes with a font. The downside? All the PNG images in the font file add up and result in an enormous OTF file size. This might not be a problem for desktop applications, like Adobe InDesign, but for use on the web the font is hardly applicable.”

All browsers support COLR fonts (now generally referred to as COLRv0). Version 98 of Chrome (and Edge), released in February, added support for COLRv1, an evolution of the format.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
713291211

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712711.0-11.2

COLRv0 and COLRv1

Screenshot of font.
Plakato from Underware foundry

COLRv1 is part of the OpenType 1.9 standard. While the initial COLRv0 lacked many of the creative possibilities of OpenType-SVG, COLRv1 matches those possibilities while avoiding certain drawbacks. COLRv0, for example, could only do solid colors whereas COLRv1 can do linear, radial, and conic gradients. The format also adds compositing and blending and allows for shape reuse to save on file size.

Typography expert Roel Nieskins explains: “I used to say the OpenType-SVG format was the best format as it offered the most versatility — until I realized this is just too complex for a low-level job like text rendering. It implements a basic subset of SVG on the font rendering level. But it doesn’t work well with other font tech (hinting, variable axes, etc.), and it’s a pain to implement. So, I switched sides to COLR. COLR basically re-uses everything that OpenType fonts already have. It ‘only’ adds layering, and the possibility to change the color of each layer. Simple, but effective.”

COLRv1 is entirely compatible with variable font axes, and there are already examples of variable COLR fonts like Merit Badge, Plakato Color and Rocher Color.

Here’s a striking example from Ulrike Rausch of what’s possible with the format, a (currently unreleased) typeface which digitally recreates the look of a neon sign:

Screenshot of COLR font in bright pink against light and dark backgrounds.

Akiem Helmling of the type foundry Underware is enamored with COLRv1, telling me that “[t]he COLRv1 format can potentially have a similar (or even bigger) impact on type design than variable fonts had in recent years.” For Akiem, it’s undoubtedly the superior format. “All former color formats have been bad hacks to add colors to glyphs. While OpenType-SVG is regarded by some people as a good solution, it is, from my point of view, not at all. From a pragmatic point of view, SVG is a ‘locked room’ within the open structure of OpenType. There is no way to re-use or link data or to create a connection between other font tables and the SVG table. And because of this, we can not make a variable font with variable SVG data.”

It’s still early days for the format. Mozilla hasn’t yet shipped COLRv1 but has taken a positive position on the format, stating that it has “the potential to supersede OpenType-SVG fonts in web use.” Apple is reluctant to implement it in Safari.

COLRv1 fonts will still show up and be readable in these browsers but all the letter’s will be a single solid color (which you can set with the CSS color property, just like with a normal font). We’re yet to see many type foundries release COLRv1 typefaces, and some popular design tools like Figma don’t even support COLRv0, but I’m hopeful and believe it will be the future of color typography on the web. In the short time COLRv1 has been around there have already been some beautiful examples of what the technology can do, such as Reem Kufi and Bradley Initials.

COLR fonts in Figma
COLR fonts in Sketch.

COLR and CSS

If you’re using a color font, you probably want to be able to control its colors. Until now, that was impossible to do with CSS. The font-palette property brings the power to override the default color scheme of a typeface and apply your own. This property works on COLRv0 and COLRv1 typefaces. (Apple’s Myles Maxfield explains that SVG fonts can opt-in to using palettes, whereas all the colors of a COLR typeface are automatically overridden by CSS.)

Coming up with a decent color palette is a fine art. Some type designers have done the hard work for us and include alternative palettes inside the font. You can select from these different color schemes using base-palette in CSS.

How do you find out if a font offers an alternate palette? The site for the font might tell you. If not, there’s a handy tool called Wakamai Fondue that will list all the available color schemes (shown in the image below). For this example, I’ll use Rocher Color, a free variable color font from Henrique Beier with a Flintstones vibe. From looking at Wakamai Foundue we can see that this typeface uses four colors and comes with eleven different palette options.

Grid of hex color values.

Using base-palette: 0 will select the default color palette (in the case of Rocher, that’s shades of orange and a brown).

Rocher COLR font.

Using base-palette: 1 will select the first alternative palette defined by the creator of the typeface, and so on. In the following code example, I’m selecting a color palette that’s different shades of gray:

 @font-palette-values --Grays {
  font-family: Rocher;
  base-palette: 9;
}

Once you’ve selected a palette with the CSS @font-palette-values rule, you can apply it using the font-palette property:

.grays {
  font-family: 'Rocher';
  font-palette: --Grays;
}

Of course, you might want to create your own palette to match your brand colors or to meet your own design sensibility. If you’re going to override all the colors then you don’t need to specify the base-palette.

Let’s take Bungee from pioneering type designer David Jonathan Ross as an example. It only uses two colors by default, red and white. In the following example, I’m overriding both colors of the font, so the base-palette doesn’t matter and is omitted:

 @font-palette-values --PinkAndGray {
  font-family: bungee;
  override-colors:
    0 #c1cbed,
    1 #ff3a92;
}

@font-palette-values --GrayAndPink {
  font-family: bungee;
  override-colors:
    0 #ff3a92,
    1 #c1cbed;
}
The word color in pink and fonts in light gray against a pink-saturated photo background.

Alternatively, you can set the base-palette as a starting point and selectively change just some of the colors. Below I’m using the gray color palette of Rocher, but overriding one color with a minty green:

@font-palette-values --GraysRemix {
  font-family: Rocher;
  base-palette: 9;
  override-colors: 
    2 rgb(90,290,210);
}

body {
  font-family: "Rocher";
  font-palette: --GraysRemix;
}

When specifying override-colors it’s difficult to know which bit of the font will be overridden by which number — you have to play around and experiment and achieve the desired effect through trial and error.

Rocher COLR font.

Should you wish, you can even change the color of emoji fonts, such as Twemoji (shown below) or Noto. Here’s a fun demo from a font engineer at Google.

Brown illustrated cartoon dog with green ears and tongue.

Current limitations

One regrettable limitation, at least for the time being is that CSS custom properties don’t work in @font-palette-values. That means the following is invalid:

@font-palette-values --PinkAndBlue {
  font-family: bungee;
  override-colors:
    0 var(--pink),
    1 var(--blue);
}

Another limitation: animations and transitions from one font-palette to another don’t interpolate — meaning you can switch instantly from one palette to another, but can’t gradually animate between them. My dream of a luridly animated emoji font is sadly unrealized.

Browser support

font-palette and @font-palette-values have been supported in Safari since version 15.4, and landed in Chrome and Edge with the release of version 101.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
101107No10515.4

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712715.4

Use cases

You can probably already imagine how you might use color fonts in your own projects. There are a couple of specific use cases, though, that are worth calling out.

COLR and icon fonts

Icon fonts may no longer be the most popular method for displaying icons on the web (Chris explains why) but they are still widely used. If you use an icon font with multiple colors, like Duotone from FontAwesome or the two-tone icons from Material Design, font-palette could offer an easier method for customization.

Grid of Duotone icons.

Solving the emoji problem

Nolan Lawson recently wrote about the problems of using emoji on the web. The Chrome developer blog explains one rather complex current solution:

If you support user generated content, your users probably use emojis. Today it’s very common to scan text and replace any emoji encountered with images to ensure consistent cross-platform rendering and the ability to support newer emojis than the OS supports. Those images then have to be switched back to text during clipboard operations.

If it receives greater browser support, COLRv1 emoji fonts will offer a far simpler approach. COLRv1 also comes with the benefit of looking crisp at any size, whereas native browser emojis get blurry and pixelated at larger font sizes.

Wrapping up

Before color fonts, typographic creativity on the web was limited to applying strokes or gradient fills with CSS. You could always do something more custom with a vector image, but that’s not real text — it can’t be selected by the user and copied to the clipboard, it can’t be searched on the page with Command+F, it isn’t read by screen readers or search engines, and you’d need to open Adobe Illustrator just to edit the copy.

Color fonts have the potential to really grab a user’s attention, making them perfect for landing pages and banners. They may not be something you reach for often, but they promise new expressive and creative possibilities for web design that can make your site stand out.


COLRv1 and CSS font-palette: Web Typography Gets Colorful originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/colrv1-and-css-font-palette-web-typography/feed/ 7 365677
8 Interesting Typography Links for January 2022 https://css-tricks.com/typography-links-january-2022/ https://css-tricks.com/typography-links-january-2022/#comments Fri, 07 Jan 2022 22:31:52 +0000 https://css-tricks.com/?p=360711 Every now and then, I find that I’ve accumulated a bunch of links about various things I find interesting. Typography is one of those things! Here’s a list of typography links to other articles that I’ve been saving up and …


8 Interesting Typography Links for January 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Every now and then, I find that I’ve accumulated a bunch of links about various things I find interesting. Typography is one of those things! Here’s a list of typography links to other articles that I’ve been saving up and think are worth sharing.

A specimen of the Retail typeface, once of the typography links in the list.
An awesome new font from OH no Type Company

Do you have any interesting typography links from the past month worth sharing? Drop ’em in the comments!


8 Interesting Typography Links for January 2022 originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/typography-links-january-2022/feed/ 5 360711
Consistent, Fluidly Scaling Type and Spacing https://css-tricks.com/consistent-fluidly-scaling-type-and-spacing/ https://css-tricks.com/consistent-fluidly-scaling-type-and-spacing/#comments Thu, 16 Dec 2021 22:06:03 +0000 https://css-tricks.com/?p=358029 When Chris first sent me this prompt, I was thinking about writing about progressive enhancement, but that subject is so wide-reaching to be one thing and all too predictable, especially for those already familiar with my writing. Saying that, what …


Consistent, Fluidly Scaling Type and Spacing originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
When Chris first sent me this prompt, I was thinking about writing about progressive enhancement, but that subject is so wide-reaching to be one thing and all too predictable, especially for those already familiar with my writing. Saying that, what I’m going to outline in this article also isn’t just one thing either, but the day I meet a writing prompt exactly will be the day pigs start flying. This one group of things, though, will change how you write CSS.

I personally think this group of things lets a lot of sites down—especially in a responsive design sense. The things in this group are typography and spacing. So often, I see inconsistent spacing—especially vertically—that makes content hard to scan and creates this subtle, disjointed feeling. The same goes for type: huge headings on small viewports, or heading hierarchies that visually have no contrast in size, rendering them useless in a visual sense.

There is a pretty easy fix for all of this using a sizing scale and fluid type, and I promise it’ll make your websites look and feel heaps better. Let’s get into it.

What the heck is a sizing scale?

A sizing scale is a uniform progression of sizes based on a scale—or, more accurately, a ratio.

Screensjhot of the type-scale.com type scale tool. It displays eight variations of font sizes in black on a white background starting from largest to smallest vertically. To the left of the examples are options to configure the output, including base font size, type of scale, Google font selection, and preview text.

In that screenshot of type-scale.com, I’ve selected a “Perfect Fourth” scale which uses a ratio of 1.333. This means each time you go up a size, you multiply the current size by 1.333, and each time you go down a size, you divide by 1.333.

If you have a base font size of 16px, using this scale, the next size up is 16 * 1.333, which is 21.33px. The next size up is 21.33 * 1.333, which is 28.43px. This provides a lovely curve as you move up and down the scale.

CSS clamp() and type fluidity

For years, if you were to say, “Hey Andy, what’s your favorite CSS feature?” I would immediately say flexbox, but nah, not these days. I am a clamp() super fan. I wrote about it in more detail here, but the summary of clamp() is that it does clever stuff based on three parameters you give it:

  • a minimum value
  • an ideal value
  • a maximum value

This makes for a very useful tool in the context of fluid typography and spacing, because you write CSS like this:

.my-element {
  font-size: clamp(1rem, calc(1rem * 3vw), 2rem);
}

This tiny bit of CSS gives us full responsive text sizes based on the viewport width with handy locks to make sure sizes don’t get too big or too small.

It’s really important to test that your text is legible when you zoom in and zoom out when using clamp. It should be very obviously larger or smaller. Because we’re using a rem units as part of our fluid calculation, we’re helping that considerably.

Putting it all together

Right, so we’ve got a size scale and CSS clamp() all set up—how does it all come together? The smart people behind Utopia came up with the simplest, but handiest of approaches. I use their type tool and their spacing tool to create size scales for small and large viewports. Then, using clamp(), I generate a master size scale that’s completely fluid, as well as a Sass map that informs Gorko’s configuration.

$gorko-size-scale: (
  '300': clamp(0.7rem, 0.66rem + 0.2vw, 0.8rem),
  '400': clamp(0.88rem, 0.83rem + 0.24vw, 1rem),
  '500': clamp(1.09rem, 1rem + 0.47vw, 1.33rem),
  '600': clamp(1.37rem, 1.21rem + 0.8vw, 1.78rem),
  '700': clamp(1.71rem, 1.45rem + 1.29vw, 2.37rem),
  '800': clamp(2.14rem, 1.74rem + 1.99vw, 3.16rem),
  '900': clamp(2.67rem, 2.07rem + 3vw, 4.21rem),
  '1000': clamp(3.34rem, 2.45rem + 4.43vw, 5.61rem)
);

This snippet is from my site, piccalil.li, and the typography is super simple to work with because of it.

You could also translate that into good ol’ CSS Custom Properties:

:root {
  --size-300: clamp(0.7rem, 0.66rem + 0.2vw, 0.8rem);
  --size-400: clamp(0.88rem, 0.83rem + 0.24vw, 1rem);
  --size-500: clamp(1.09rem, 1rem + 0.47vw, 1.33rem);
  --size-600: clamp(1.37rem, 1.21rem + 0.8vw, 1.78rem);
  --size-700: clamp(1.71rem, 1.45rem + 1.29vw, 2.37rem);
  --size-800: clamp(2.14rem, 1.74rem + 1.99vw, 3.16rem);
  --size-900: clamp(2.67rem, 2.07rem + 3vw, 4.21rem);
  --size-1000: clamp(3.34rem, 2.45rem + 4.43vw, 5.61rem);
};

This approach also works for much larger sites, too. Take the new web.dev design or this fancy software agency’s site. The latter has a huge size scale for large viewports and a much smaller, more sensible, scale for smaller viewports, all perfectly applied and without media queries.

I’m all about keeping things simple. This approach combines a classic design practice—a sizing scale—and a modern CSS feature—clamp()—to make for much simpler CSS that achieves a lot.


Consistent, Fluidly Scaling Type and Spacing originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/consistent-fluidly-scaling-type-and-spacing/feed/ 7 358029
Coding Font Game https://css-tricks.com/coding-font-game/ https://css-tricks.com/coding-font-game/#comments Fri, 19 Nov 2021 21:18:50 +0000 https://css-tricks.com/?p=357227 A tournament bracket UI where you pick your favorite between two coding fonts and your choices are whittled down all the way to a final winner. A clever way to suss out your own taste and arrive at a choice.…


Coding Font Game originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
A tournament bracket UI where you pick your favorite between two coding fonts and your choices are whittled down all the way to a final winner. A clever way to suss out your own taste and arrive at a choice.

(P.S. We have our own little coding fonts website to showcase some high-quality favorites.)

Wenting Zhang documented in a newsletter (update: that was originally published on the Retool blog, so updating the link) that she built it the whole thing with Retool, meaning she had to write very little code directly, and instead used pre-built components. That’s kind of the point of Retool. It’s like a UI library with existing components for building stuff out quickly, but it goes the extra mile in connecting to your own data.

Five years ago, if I wanted to build this coding font game, I would have had to spend days or weeks hand-coding it in React or other frameworks. But since then, I have discovered no code and low code apps which are essentially libraries of pre-existing informational or functional things. They can be powered by a database or an API, and the interaction layer is standard, often with minimal customization needs.

The two bits of code shared in that post look… pretty complicated. So, in this case, it’s a “low code” thing where those bits of code really hone in on the core functionality and experience, but a lot of the rest of the more mundane and boilerplate code is avoided. Seems compelling to me. In the end, the whole “game” is an <iframe> pointing to the Retool widget thing.


Coding Font Game originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/coding-font-game/feed/ 6 357227
Line length revisited: following the research https://css-tricks.com/line-length-revisited-following-the-research/ https://css-tricks.com/line-length-revisited-following-the-research/#comments Tue, 16 Nov 2021 21:35:39 +0000 https://css-tricks.com/?p=356849 Mary Dyson produces nitty gritty research on the long-accepted notion that shorter line lengths are more legible than longer ones. The study finds that shorter lines do not necessarily lead to faster reading. If you’re looking for a definitive answer …


Line length revisited: following the research originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
Mary Dyson produces nitty gritty research on the long-accepted notion that shorter line lengths are more legible than longer ones. The study finds that shorter lines do not necessarily lead to faster reading. If you’re looking for a definitive answer to use in your next design review debate, though, no dice. The big finding is that long lines don’t slow things down as much as previously thought, not that they’re better or worse.

But there’s so much more meat in here that I found much more interesting, mostly because I’m largely ignorant on the topic and gained a dollop of context on writing, legibility, and behavior.

Things like…

There’s a term for transitioning between lines of text

It’s return sweeps. You know, like your eye hits the Return key at the end of the line and sweeps to the start of the next line. Then, there are undershoots. The idea is that eyes may not sweep to the exact start of the next line, instead stopping a bit short.

Showing four muted lines of test with jump arrows across each line taking the eye to the end of the line, followed by dashed arrow leading to the next line. Red arrows highlight where the eye could undershoot a new line and miss content.

Those little rapid eye movements between words and phrases? Those are called saccades. I had to look that up.

The impact of undershoots is what’s being challenged

The previous research we’ve relied on for years comes from 1940(!), a time when we obviously were more concerned with paper pages than bright digital displays. Longer lines, it said, increased the likelihood that eyes undershoot during a return sweep, and undershooting results in a regression that results in a 130ms to 250ms delay where the brain needs to get its bearings. The report refers to that as undersweep-fixation.

We can still process words during undersweep-fixation

This report cites a 2019 study that tried to correct undershoots by bolding the first word at the start of each new line, sort of like an anchor that naturally draws the eye closer to the left margin.

The 2019 study did find that the bolded words did decrease undershot return sweeps But despite that, reading speed did not improve. That’s the impetus for challenging the long-held assumption that shorter is better.

Mary explains further:

In seeking to reconcile why longer line lengths may not slow down reading on screen but do so when reading print, I outlined some differences, e.g. visual angle, time spent scrolling. But although physical differences between reading from screen and reading print still exist, we now have direct evidence to explain why longer lines were read at least as fast as shorter lines. Readers can process words during the brief fixation when undershooting the start of the new line. This saves time in subsequent processing. Now we might also acknowledge that there is greater consistency between the range of optimal line lengths for print and screen.

Where does this leave us today?

Well, nowhere closer to a clear answer we can use in our day-to-day work. But it’s good to dust off our collection of design and copywriting best practices and know that line length is less of a constraint than perhaps it has been.

Again, none of this tells us whether long or short lines are better. Mary ends her report by saying she cannot definitely recommend using longer lines of text because there are clear because there are still some factors at play, including:

  • Shorter lines are more effective for people with dyslexia.
  • More questions about return sweeps and undershooting need to be answered.
  • Several other studies indicate that users prefer shorter lines and judge longer lines as more difficult to read.

To Shared LinkPermalink on CSS-Tricks


Line length revisited: following the research originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

]]>
https://css-tricks.com/line-length-revisited-following-the-research/feed/ 2 356849
Some Typography Links VIII https://css-tricks.com/some-typography-links-viii/ https://css-tricks.com/some-typography-links-viii/#respond Wed, 20 Oct 2021 23:25:22 +0000 https://css-tricks.com/?p=353866
  • Do you know what to use the @ sign for something other than email addresses and Twitter handles? I do! —  Pawel Grzybek notes how some old physical typewriters had an “Arroba” on them which was represented with the @

  • Some Typography Links VIII originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
  • Do you know what to use the @ sign for something other than email addresses and Twitter handles? I do! —  Pawel Grzybek notes how some old physical typewriters had an “Arroba” on them which was represented with the @ sign.
  • Atkinson Hyperlegible Font — The Braille Institute is giving away this font that “focuses on letterform distinction to increase character recognition, ultimately improving readability.” The page itself is set in it so you can get a taste for it just by going there. Looks nice to me. Sorta evokes a slab serif without actually being one?
  • Marvel Character or Font? — 14/20 and I think I fat-fingered one. Proxima Midnight?! C’mon!
  • Firefox 92 — Ruth John notes that Firefox now supports font-size-adjust in CSS, as well as size-adjust (which you can only use within a @font-face rule). The point is jiggering your fonts such that if a user sees FOUT at all, there is little reflow jank when the custom font loads. In theory, it makes perfect font fallbacks easier.
  • Typography for Data — Michael Yom has to re-evalute the type styles in a design system to accomodate some some components with fairly dense/complex type needs.
  • Improving the New York Times’ line wrap balancer — Daniel Aleksandersen: “A text wrapping balancer is a program that tries to more evenly distribute words over multiple lines. There are at least two dozen algorithms used to achieve this.” This new one is faster than Adobe’s popular one.
  • Line length revisited: following the research — Mary Dyson goes deep. Apparently most of the older research on this was based on print, which, I hope we all know by now, just ain’t the same as a digital screen. We might be able to go a little longer, but as with anything, it depends.

  • Some Typography Links VIII originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/some-typography-links-viii/feed/ 0 353866
    Firefox’s `bolder` Default is a Problem for Variable Fonts https://css-tricks.com/firefoxs-bolder-default-is-a-problem-for-variable-fonts/ https://css-tricks.com/firefoxs-bolder-default-is-a-problem-for-variable-fonts/#comments Tue, 07 Sep 2021 14:41:57 +0000 https://css-tricks.com/?p=351017 Variable fonts make it easy to create a large set of font styles from a single font file. Unfortunately, the default rendering of the <b> and <strong> elements in browsers today is not very compatible with the wide range of …


    Firefox’s `bolder` Default is a Problem for Variable Fonts originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    Variable fonts make it easy to create a large set of font styles from a single font file. Unfortunately, the default rendering of the <b> and <strong> elements in browsers today is not very compatible with the wide range of font-weight values enabled by variable fonts.

    https://twitter.com/zachleat/status/1374443096281280517

    Browsers disagree on the default font-weight of <b>

    The purpose of the <b> and <strong> elements is to draw attention to a specific word or span of text on the page. Browsers make these elements stand out by increasing their font-weight. This works well under normal conditions. For example, MDN Web Docs uses <b> in a few places in the “Found a problem?” card at the bottom of each page.

    Screenshot of an MDN article with red arrows pointing at instances of bolded words on the page.

    Things become more complicated when the text on the page has a custom font-weight. The default weight of text is 400, but the font-weight property accepts any number between 1 and 1000 (inclusive). Let’s take a look at how Chrome and Firefox render text wrapped in <b> by default depending on the font-weight of the surrounding text.

    View on CodePen

    Chrome and Firefox disagree on the default rendering of <b> elements. Chrome uses a constant font-weight of 700 (Safari behaves the same), while Firefox chooses between three values (400, 700, and 900) depending on the font-weight of the surrounding text.

    Where is this difference coming from?

    As you might have guessed, Chrome and Firefox use different font-weight values for the <b> and <strong> elements in their user agent stylesheets.

    /* Chrome and Safari’s user agent stylesheet */
    strong, b {
      font-weight: bold;
    }
    
    /* Firefox’s user agent stylesheet */
    strong, b {
      font-weight: bolder;
    }

    The bold and bolder values are specified in the CSS Fonts module; bold is equivalent to 700, while bolder is a relative weight that is calculated as follows:

    If the outer text has a font-weight of…the bolder keyword computes to…
    1 to 349400
    350 to 549700
    550 to 899900
    900 to 1000No change (same value as outer text)

    Chrome and Firefox disagree on the default rendering of <b>, but which browser follows the standards more closely? The font-weight property itself is defined in the CSS Fonts module, but the suggested font-weight values for different HTML elements are located in the Rendering section of the HTML Standard.

    /* The HTML Standard suggests the following user agent style */
    strong, b {
      font-weight: bolder;
    }

    The HTML Standard started suggesting bolder instead of bold all the way back in 2012. As of today, only Firefox follows this recommendation. Chrome and Safari have not made the switch to bolder. Because of this inconsistency, the popular Normalize base stylesheet has a CSS rule that enforces bolder across browsers.

    Which of the two defaults is better?

    There are two different defaults in browsers, and Firefox’s default matches the standard. So, should Chrome align with Firefox, or is Chrome’s default the better one? Let’s take another look at the default rendering of the <b> element.

    View on CodePen

    Each of the two defaults has a weak spot: Chrome’s bold default breaks down at higher font-weight values (around 700), while Firefox’s bolder default has a problem with lower font-weight values (around 300).

    In the worst-case scenario for Firefox, text wrapped in <b> becomes virtually indiscernible. The following screenshot shows text at a font-weight of 349 in Firefox. Can you spot the single word that is wrapped in <b>? Firefox renders this element at a default font-weight of 400, which is an increase of only 51 points.

    Three paragraphs of text about English scientist Tim Berners-Lee. All of the text appears to be the same font weight.
    (View on CodePen)

    The takeaway

    If you use thin fonts or variable fonts at font-weight values below 350, be aware that the <b> and <strong> elements may not always be discernible in Firefox by default. In this case, it is probably a good idea to manually define a custom font-weight for <b> and <strong> instead of relying on the browser’s sub-optimal default, which insufficiently increases the font-weight of these elements.

    /* Defining the regular and bold font-weight at the same time */
    
    body {
      font-weight: 340;
    }
    
    b,
    strong {
      font-weight: 620;
    }

    The bolder value is outdated and doesn’t work well with variable fonts. Ideally, text wrapped in <b> should be easy to spot regardless of the font-weight of the surrounding text. Browsers could achieve that by always increasing the font-weight by the same or a similar amount.

    On that note, there is a discussion in the CSS Working Group about allowing percentages in font-weight in the same manner as in font-size. Lea Verou writes:

    A far more common use case is when we want a bolder or lighter stroke than the surrounding text, in a way that’s agnostic to the weight of the surrounding text.

    /* Increasing font-size by 100% */
    h1 {
      font-size: 200%;
    }
    
    /* PROPOSAL - Increasing font-weight by 50% */
    strong, b {
      font-weight: 150%;
    }

    Taking variable fonts into account, a value like 150% would probably be a better default than the existing bold/bolder defaults in browsers today.


    Firefox’s `bolder` Default is a Problem for Variable Fonts originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/firefoxs-bolder-default-is-a-problem-for-variable-fonts/feed/ 4 351017
    Some Typography Links VII https://css-tricks.com/some-typography-links-vii/ https://css-tricks.com/some-typography-links-vii/#comments Wed, 01 Sep 2021 14:37:38 +0000 https://css-tricks.com/?p=350569 All-things-typography, from a hard-edged monospaced variable font to fonts in the "Twilight Zone" ... and much, much more.


    Some Typography Links VII originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
  • SKWAR — Heydon Pickering made a hard-edged monospaced variable font. The axes are width and weight.
  • Twenty Bits I Learned About Making Fonts Book — Dan Cederholm has been making fonts, like Captain Edward and Ship Whistle and has turned his learnings into a book.
  • The perfect cross-platform serif and sans-serif font stacks — Daniel Aleksandersen has lots of details about pre-installed fonts across operating systems, like: Mac and iOS also come with Helvetica Neue preinstalled. It addresses some of Helvetica’s legibility issues … On Windows, you might find a more modern version of Arial called Arial Nova. Arial Nova makes much the same legibility improvements and compromises as Helvetica Neue.
  • Pairing fonts – 3 ways to find great typeface combinations — Oliver Schöndorfer says it’s an artistist decision so don’t be afraid to try stuff. But also, do you even need more than one? If so, have a reason. Repeat your font choices as often as you can, and only when something does not work in a given situation, add a new style.
  • Twitter thread about Really Sans — Riley Cran gets into optical sizing and how Really Sans […] is a sans serif typeface with two optical sizes. The small optical size works for text. The large optical size revives the tone of the 1970s headlines. I see Riley is using the pricing model based on # of employees rather than pageviews which I love.
  • Helvetica® Now Variable — I think having major fonts like Helvetica, that a lot of brands rely on, is the kind of thing that pushes the needle on variable fonts forward.
  • Fonts in the Twilight Zone — John Boardley looks at some rather unclassifiable fonts: Among my favorite kinds of typefaces are those that don’t fit neatly into predefined or existing categories; those that dip their toes into more than one genre, or take their cues from disparate historical periods.
  • Coding with Character — Doug Wilson looks at coding typefaces: If you spend all day looking at code, letters, and characters—why not make it fun? I’m down.

  • Some Typography Links VII originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/some-typography-links-vii/feed/ 1 350569
    Some Typography Links VI https://css-tricks.com/some-typography-links-vi/ https://css-tricks.com/some-typography-links-vi/#respond Fri, 16 Jul 2021 14:42:40 +0000 https://css-tricks.com/?p=344411
  • Glitter text — whO (I learned a name for people who go by a one-word moniker like that: Mononymous) created a builder for fancy SVG-based type. It’s a custom font with <text>, and the fancy comes in with a

  • Some Typography Links VI originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
  • Glitter text — whO (I learned a name for people who go by a one-word moniker like that: Mononymous) created a builder for fancy SVG-based type. It’s a custom font with <text>, and the fancy comes in with a gradient and somewhat exotic filters that make noise and blend the noise into the color.
  • Optical Size tweaking for dark mode — Mark Boulton opens by questioning the usefulness of variable fonts (blaspheme!) but then finds a nice use case in adjusting the optical size in dark mode. Robin covered that right here not too long ago.
  • Optical size, the hidden superpower of variable fonts — Speaking of optical size, Roel Nieskens digs into that here. It’s not just a weight thing… This feature will make letters actually change the way they look when shown in small or large sizes. It all happens automatically in the browser.”
  • Updates to v-fonts.com — Annnnd speaking of variable fonts, Piper Haywood talks about some updates to v-fonts.com, introducing some browsable taxonomies. It takes me about 20 seconds browing this site to want to redesign everything using variable fonts.
  • All you need is 5 fonts — (Matej Latin) I’ve been hearing about these mythical designers who focus all their creative energy on deep-learning how to use a very limited set of fonts. Maybe it’s kinda the same as us web nerds who only know HTML, CSS, and JavaScript and leave it at that.
  • Best practices for fontsJust like CSS, fonts affect Web Core Vitals in big ways (e.g. layout shifts and paints). Katie Hempenius is at it again here covering how to make fonts faster. I think these best practices are starting to set in a bit… preconnecting to the font host, subsetting, font-display, etc.
  • Sans Bullshit Sans — Kinda like the Cloud to Butt browser plugin, only the text replacements are done via ligatures (🤯) converting them into little Comic Sans badges. Some of them are angled? How the heck does that work?
  • Bryan Font — Jon Hicks builds a font for his father, John Bryan Hicks, who passed away. What a loving tribute.
  • Inherit ancestor font-size, for fun and profit — Lea Verou finds yet another use case for @property. I wonder if it’s an emerging best practice to register all your custom properties, since it unlocks possibilites and makes them behave more like you expect them to behave. Lea shows how you can browser test for @property in JavaScript, but if you for some reason you can’t do that and don’t mind pretty mind-bending CSS, Jane has pure CSS way.

  • Some Typography Links VI originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/some-typography-links-vi/feed/ 0 344411
    Working around the viewport-based fluid typography bug in Safari https://css-tricks.com/working-around-the-viewport-based-fluid-typography-bug-in-safari/ https://css-tricks.com/working-around-the-viewport-based-fluid-typography-bug-in-safari/#respond Mon, 28 Jun 2021 21:17:26 +0000 https://css-tricks.com/?p=343139 Sara digs into a bug I happened to have mentioned back in 2012 where fluid type didn’t resize when the browser window resized. Back then, it affected Chrome 20 and Safari 6, but the bug still persists today in Safari …


    Working around the viewport-based fluid typography bug in Safari originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    Sara digs into a bug I happened to have mentioned back in 2012 where fluid type didn’t resize when the browser window resized. Back then, it affected Chrome 20 and Safari 6, but the bug still persists today in Safari when a calc() involves viewport units.

    Sara credits Martin Auswöger for a super weird and clever trick using -webkit-marquee-increment: 0vw; (here’s the documentation) to force Safari into the correct behavior. I’ll make a screencast just to document it:

    I randomly happened to have Safari Technology Preview open, which at the moment is Safari 15, and I see the bug is fixed. So I wouldn’t rush out the door to implement this.

    To Shared LinkPermalink on CSS-Tricks


    Working around the viewport-based fluid typography bug in Safari originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/working-around-the-viewport-based-fluid-typography-bug-in-safari/feed/ 0 343139
    Some Typography Links V https://css-tricks.com/some-typography-links-v/ https://css-tricks.com/some-typography-links-v/#comments Fri, 18 Jun 2021 13:44:17 +0000 https://css-tricks.com/?p=342326
  • I studied the fonts of the top 1000 websites. Here’s what I learned. — Michael Li brings the data. San-serif has total dominance. “[…] it is rare to go below 10px or above 24px.” And poor <h5> always being the

  • Some Typography Links V originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
  • I studied the fonts of the top 1000 websites. Here’s what I learned. — Michael Li brings the data. San-serif has total dominance. “[…] it is rare to go below 10px or above 24px.” And poor <h5> always being the same size as <p>. Makes me feel extra sad for <h6>, are you destined to be smaller than body copy?
  • How tracking and kerning improves all caps text — Oliver Schöndorfer gets into why ALL CAPS text generally looks better when spaced out (i.e. letter-spacing in CSS). I’m not exactly a renowned typographer, but this tracks with what I’ve always felt. All-caps looks good spaced out (sometimes quite a bit), and conversely, it almost never looks good to track out lowercase. Like the PG version of the famous quote.
  • Leveraging System Fonts on the Web — Jim Nielsen shared some of my confusion with “system fonts” in CSS. Like we have system-ui now, which I use pretty often because it actually works in Chrome and Safari for selecting the system font (i.e. getting to use San Francisco on macOS). Before that was a thing, to leverage the same kind of thing, you’d do a big long stack. But we kinda still need the stack for real production sites, since system-ui isn’t universally supported. There is a nice world going forward though, because we’re getting ui-sans-serif, ui-sans-serif, ui-monospace, and ui-rounded. Browser support is quite limited, but it’s gonna be nice.
  • Simpler Font Licensing: Introducing V2 — “The core of V2 is this: you buy a font, and then you can use it.” God bless ’em. As the owner of several sites that get a lot of page views but don’t have waterfalls of cash as a budget, I need web font pricing that is sane.
  • 5 steps to faster web fonts — Iain Bean goes through the biggies: WOFF2, font-display, <link rel="preload" ...>, Subsetting, and self-hosting. And never forget about the holy bible.
  • A New Way To Reduce Font Loading Impact: CSS Font Descriptors — Barry Pollard looks at new CSS descriptors (not just regular properties as they only work within @font-face blocks) like size-adjust and ascent-override. YES. THIS IS AWESOME. I declared perfect font fallbacks one of the all-time great CSS tricks, but alas, it required a smidge of JavaScript and hackery. This brings it all into CSS perfectly.
  • Why You Should Stop Using Times New Roman — Vanessa Hill was asked to reformat a research paper into Times New Roman. She was told it’s because it’s so readable and researches the truth: it’s not. Personally, I can’t stand the look of it because it looks like your font-stack failed in CSS.
  • Pixel font converter! — Looks like an ancient tool (via Remy Sharp) but I love it as it opens up the idea of creating a font to anyone who knows how to draw some letters and save a static image.

  • Some Typography Links V originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

    ]]>
    https://css-tricks.com/some-typography-links-v/feed/ 1 342326