Tag: Developers

Edge Goes Chromium: What Does it Mean for Front-End Developers?

In December 2018, Microsoft announced that Edge would adopt Chromium, the open source project that powers Google Chrome. Many within the industry reacted with sadness at the loss of browser diversity. Personally, I was jubilant. An official release date has yet to be announced, but it will be at some point this year. With its release, a whole host of HTML, JavaScript and CSS features will have achieved full cross-browser support.

The preview build is now available for Windows, and coming soon for Mac.

Not so long ago, I penned an article titled “The Long Slow Death of Internet Explorer.” Some of us are lucky enough have abandoned that browser already. But it wasn’t the only thing holding us back. Internet Explorer was the browser we all hated and Edge was meant to be its much-improved replacement. Unfortunately, Edge itself was quite the laggard. EdgeHTML is a fork of Trident, the engine that powered Internet Explorer. Microsoft significantly under-invested in Edge. The apple didn’t fall far from the tree. Edge’s User Voice website was a nice idea, allowing developers to vote for which features they wanted to be implemented. Unfortunately, as Dave Rupert put it, voting on the site was “like throwing coins in a wishing well.” The most requested features were left unimplemented for years.

There are a lot of features that pre-Chromium Edge doesn’t currently support but are available in other modern browsers and, once they’ve made the switch, we’ll be able to use them. Many of them can’t be polyfilled or worked around, so this release is a big deal.

caniuse.com comparing the final non-Chromium version of Edge to the other popular modern browser

Features we can look forward to using

So just what are those features, exactly? Let’s outline them right here and start to get excited about all the new things we’ll be able to do.

Custom Elements and Shadow DOM

Together, custom elements and shadow DOM allow developers to define custom, reusable and encapsulated components. A lot of people were asking for this one. People have been voting for its implementation since 2014, and we’re finally getting it.

HTML details and summary elements

The <details> and <summary> elements are part of HTML5 and have been supported since 2011 in Chrome. Used together, the elements generate a simple widget to show and hide content. While it is trivial to implement something similar using JavaScript, the <details> and <summary> elements work even when JavaScript is disabled or has failed to load.

See the Pen
details/summary
by CSS GRID (@cssgrid)
on CodePen.

Javascript Font Loading API

This one means a lot to some people. All modern browsers now support the CSS font-display property. However, you still might want to load your fonts with JavaScript. Font-loading monomaniac Zach Leatherman has an explainer of why you might want to load fonts with JavaScript even though we now have broad support for font-display. Ditching polyfills for this API is important because this JavaScript is, according to Zach:

[…] usually inlined in the critical path. The time spent parsing and executing polyfill JavaScript is essentially wasted on browsers that support the native CSS Font Loading API.”

In an article from 2018, Zach lamented:

[…] browser-provided CSS Font Loading API has pretty broad support and has been around for a long time but is confoundedly still missing from all available versions of Microsoft Edge.”

No longer!

JavaScript flat and flatMap

Most easily explained with a code snippet, flat() is useful when you have an array nested inside another array.

const things = ['thing1', 'thing2', ['thing3', ['thing4']]] const flattenedThings = things.flat(2); // Returns ['thing1', 'thing2', 'thing3', 'thing4']

As its name suggests, flatMap() is equivalent to using both the map() method and flat().

These methods are also supported in Node 11. 🎉

JavaScript TextEncoder and TextDecoder

TextEncoder and TextDecoder are part of the encoding spec. They look to be useful when working with streams.

JavaScript Object rest and object spread

These are just like rest and spread properties for arrays.

const obj1 = {   a: 100,   b: 2000 }  const obj2 = {   c: 11000,   d: 220 }  const combinedObj = {...obj1, ...obj2}  // {a: 100, b: 2000, c: 11000, d: 220}

JavaScript modules: dynamic import

Using a function-like syntax, dynamic imports allow you to lazy-load ES modules when a user needs them.

button.addEventListener("click", function() {   import("./myModule.js").then(module => module.default()); });

CSS background-blend-mode property

background-blend-mode brings Photoshop style image manipulation to the web.

CSS prefers-reduced-motion media query

I can’t help feeling that not making people feel sick should be the default of a website, particularly as not all users will be aware that this setting exists. As animation on the web becomes more common, it’s important to recognize that animation can cause causes dizziness, nausea and headaches for some users.

CSS font-display property

font-display has been well-covered on CSS-Tricks before. It’s a way to control the perceived performance of font loading.

CSS caret-color property

Admittedly a rather trivial feature, and one that could have safely and easily been used as progressive enhancement. It lets you style the blinking cursor in text input fields.

8-digit hex color notation

It’s nice to have consistency in a codebase. This includes sticking to either
the RGB, hexadecimal or HSL color format. If your preferred format is hex, then you had a problem because it required a switch to rgba() any time you needed to define transparency. Hex can now include an alpha (transparency) value. For example, #ffffff80 is equivalent to rgba(255, 255, 255, .5). Arguably, it’s not the most intuitive color format and has no actual benefit over rgba().

Intrinsic sizing

I’ve not seen as much hype or excitement for intrinsic sizing as some other new CSS features, but it’s the one I’m personally hankering for the most. Intrinsic sizing determines sizes based on the content of an element and introduces three new keywords into CSS: min-content, max-content and fit-content(). These keywords can be used most places that you would usually use a length, like height, width, min-width, max-width, min-height, max-height, grid-template-rows, grid-template-columns, and flex-basis.

CSS text-orientation property

Used in conjunction with the writing-mode property, text-orientation, specifies the orientation of text, as you might expect.

See the Pen
text-orientation: upright
by CSS GRID (@cssgrid)
on CodePen.

CSS :placeholder-shown pseudo-element

placeholder-shown was even available in Internet Explorer, yet somehow never made it into Edge… until now. UX research shows that placeholder text should generally be avoided. However, if you are using placeholder text, this is a handy way to apply styles conditionally based on whether the user has entered any text into the input.

CSS place-content property

place-content is shorthand for setting both both the align-content and justify-content.

See the Pen
place-content
by CSS GRID (@cssgrid)
on CodePen.

CSS will-change property

The will-change property can be used as a performance optimization, informing the browser ahead of time that an element will change. Pre-Chromium Edge was actually good at handling animations performantly without the need for this property, but it will now have full cross-browser support.

CSS all property

button { background: none; border: none; color: inherit; font: inherit; outline: none; padding: 0; }

Sadly, though, the revert keyword still hasn’t been implemented anywhere other than Safari, which somewhat limits the mileage we can get out of the all property.

CSS Shapes and Clip Path

Traditionally, the web has been rectangle-centric. It has a box model, after all. While we no longer need floats for layout, we can use them creatively for wrapping text around images and shapes with the shape-outside property. This can be combined with the clip-path property, which brings the ability to display an image inside a shape.

Clippy is an online clip-path editor

CSS :focus-within pseudo-class

If you want to apply special styles to an entire form when any one of its inputs are in focus, then :focus-within is the selector for you.

CSS contents keyword

This is pretty much essential if you’re working with CSS grid. This had been marked as “not planned” by Edge, despite 3,920 votes from developers.

For both flexbox and grid, only direct children become flex items or grid items, respectively. Anything that is nested deeper cannot be placed using flex or grid-positioning. In the words of the spec, when display: contents is applied to a parent element, “the element must be treated as if it had been replaced in the element tree by its contents,” allowing them to be laid out with a grid or with flexbox. Chris goes into a more thorough explanation that’s worth checking out.

There are, unfortunately, still some bugs with other browser implementations that affect accessibility.

The future holds so much more promise

We’ve only looked at features that will be supported by all modern browsers when Edge makes the move to Chromium. That said, the death of legacy Edge also makes a lot of other features feel a lot closer. Edge was the only browser dragging its feet on the Web Animation API and that showed no interest in any part of the Houdini specs, for example.

Credit: https://ishoudinireadyyet.com

The impact on browser testing

Testing in BrowserStack (left) and various browser apps on my iPhone (right)

Of course, the other huge plus for web developers is less testing. A lot of neglected Edge during cross-browser testing, so Edge users were more likely to have a broken experience. This was the main reason Microsoft decided to switch to Chromium. If your site is bug-free in one Chromium browser, then it’s probably fine in all of them. In the words of the Edge team, Chromium will provide “better web compatibility for our customers and less-fragmentation of the web for all web developers.” The large variety of devices and browsers makes browser testing one of the least enjoyable tasks that we’re responsible for as front-end developers. Edge will now be available for macOS users which is great for the many of us who work on a Mac. A subscription to BrowserStack will now be slightly less necessary.

Do we lose anything?

To my knowledge, the only feature that was supported everywhere except Chrome is SVG color fonts, which will no longer work in the Edge browser. Other color font formats (COLR, SBIX, CBDT/CBLC) will continue to work though.

What about other browsers?

Admittedly, Edge wasn’t the last subpar browser. All the features in this article are unsupported in Internet Explorer, and always will be. If you have users in Russia, you’ll need to support Yandex. If you have users in Africa, you’ll need to support Opera Mini. If you have users in China, then UC and QQ will be important to test against. If you don’t have these regional considerations, there’s never been a better time to ditch support for Internet Explorer and embrace the features the modern web has to offer. Plenty of PC users have stuck with Internet Explorer purely out of habit. Hopefully, a revamped Edge will be enough to tempt them away. An official Microsoft blog entry titled “The perils of using Internet Explorer as your default browser” concluded that, “Internet Explorer is a compatibility solution…developers by and large just aren’t testing for Internet Explorer these days.” For its remaining users, the majority of the web must look increasingly broken. It’s time to let it die.

Is Google a megalomaniac?

Life is about to get easier for web developers, yet the response to the Microsoft’s announcement was far from positive. Mozilla, for one, had a stridently pessimistic response, which accused Microsoft of “officially giving up on an independent shared platform for the internet.” The statement described Google as having “almost complete control of the infrastructure of our online lives” and a “monopolistic hold on unique assets.” It concluded that “ceding control of fundamental online infrastructure to a single company is terrible.”

Many have harked back to the days of IE6, the last time a browser achieved such an overwhelming market share. Internet Explorer, having won the browser war, gave in to total stagnation. Chrome, by contrast, ceaselessly pushes new features. Google participates actively with the web standards bodies the W3C and the WHATWG. Arguably though, it has an oversized influence in these bodies and the power to dictate the future shape of the web. Google Developer Relations does have a tendency to hype features that have shipped only in Chrome.

From competition to collaboration

Rather than being the new IE, Edge can help innovate the web forward. While it fell behind in many areas, it did lead the way for CSS grid, CSS exclusions, CSS regions and the new HTML imports spec. In a radical departure from historical behavior, Microsoft have become one of the world’s largest supporters of open source projects. That means all major browsers are now open source. Microsoft have stated that they intend to become a significant contributor to Chromium — in fact, they’ve already racked up over 300 merges. This will help Edge users, but will also benefit users of Chrome, Opera, Brave, and other Chromium-based browsers.

The post Edge Goes Chromium: What Does it Mean for Front-End Developers? appeared first on CSS-Tricks.

CSS-Tricks

, , , , ,

Typography for Developers

Taimur Abdaal leads design at Retool, a fast way to build internal tools. They’re working on a new design system for their platform, to let anyone easily build beautiful custom apps. Typography will be a huge part of this and Taimur wrote this based on that experience.

You may have read the title for this post and thought, “Why on earth does a developer need to know anything about typography?” I mean, there’s already a lot on your plate and you’re making hundreds of decisions a day. Should you use React or Vue? npm or Yarn? ES6 or ES7? Sadly, this often leaves something like type as an afterthought. But, let’s remember that web design is 95% typography:

95% of the information on the web is written language. It is only logical to say that a web designer should get good training in the main discipline of shaping written information, in other words: Typography.

Even though we deal with content everyday — whether reading, writing, or designing it — typography can be daunting to delve into because it’s filled with jargon and subjectivity, and it’s uncommon to see it taught extensively at school.

This is intended as a practical guide for developers to learn web typography. We’ll cover a range of practical and useful topics, like how to choose and use custom fonts on the web, but more importantly, how to lay text out to create a pleasant user experience. We’ll go over the principles of typography and the CSS properties that control them, as well as handy tips to get good results, quickly.

What is typography?

First and foremost, typography is about usability. Type is the user interface for conveying information, and conveying information is what we’re here to do on the web. There are many levers we can pull to affect the usability of reading text, and only by being deliberate about these can we create a pleasant experience for our users.

After (and only after) usability, typography is about emotion. Do the letters complement your content, or contradict it? Do they amplify your brand’s personality, or dampen it? Applied to the same text, different type will make people feel different things. Being deliberate about typography lets us control these feelings.

Same text, different personalities. I’ll bet the first experience is much more expensive. Typefaces: Bodoni 72 (Top), Tsukushi A Round Gothic (Bottom)

Despite what many golden ratio enthusiasts might try to tell you, typography isn’t an exact science. Good guidelines will get you most of the way there, but you’ll need to apply a little intuition too. Luckily, you’ve been reading text your whole life — books, magazines, the Internet — so you have a lot more untapped intuition than you think!

What’s in a font?

Let’s start off by getting a handle on some basic terminology and how fonts are categorized.

Typeface vs. Font

This is how the two have traditionally been defined and distinguished from one another:

  • Typeface: The design of a collection of glyphs (e.g. letters, numbers, symbols)
  • Font: A specific size, weight, or style of a typeface (e.g. regular, bold, italic)

In essence, a typeface is like a song and a font is like its MP3 file. You’ll see both terms used in typography literature, so it’s worth knowing the distinction. “Font vs. Typeface” is also a bit of meme in the design community — you might see it crop up on Twitter, so it’ll help to be “in the know.”

But, more recently, you can essentially use both terms interchangeably and people will know what you mean.

How fonts are categorized

The broadest split is between serif and sans-serif typefaces. It’s likely you’ve come across these terms just by seeing some some typeface names floating around (like, ahem, Comic Sans).

A “serif” is a small stroke attached to the ends of letters, giving them a traditional feel. In fact, most books and newspapers are set in serif typefaces. On the contrary, sans-serif typefaces don’t have these extra strokes, giving them a smooth, modern feel.

Times (left) and Helvetica Neue (right)

Both serif and sans-serif have categories within them. For example, serif has sub-categories including didone, slab and old style.

Didot (left), Rockwell (center) and Hoefler Text (right)

As far as sans-serif goes, it includes humanist, geometric and grotesk as sub-categories.

Gill Sans (left), Futura (center) and Aktiv Grotesk (right)

Monospace fonts (yes, fonts) are a noteworthy category all its own. Each glyph (i.e. letter/number/symbol) in a monospace font has the same width (hence the mono spacing terminology), so it’s possible to arrange them into visual structures. You may be well familiar with monospace because we see it often when writing code, where it’s helpful to make brackets and indents line up visually. The code editor you have open right now is likely using monospace.

Monaco

How to choose fonts and font pairings

This is subjective, and depends on what you’re trying to do. Each typeface has its own personality, so you’ll have to find one that aligns with your brand or the content it’s communicating. Typefaces have to be considered within the context that they’re being applied. Are we looking for formality? Maybe start with the serif family. Warm, fun and friendly? That might be a cue for sans-serif. Heck, there’s a time and a place even for Comic Sans… really! Just know that there is no hard science to choosing a font, and even the most trained of typographers are considering contextual cues to find the “right” one.

But fonts can be paired together in the same design. For example, some designs use one typeface for headings and another for body text. This is a good way to get a unique look, but it does take a fair bit of work to get it right. Like colors in a palette, some typefaces work well together while others clash. And even purposeful clashing can make sense, again, given the right context.

The only way to find out if two fonts are complementary is to see them together. Tools like FontPair and TypeConnection can help with this. If a font catches your eye when surfing the web, WhatFont is a great browser extension to help identify it. Another great resource is Typewolf which allows you to see examples of great web typography, including different font combinations in use:

Alice Lee (left), American Documentary (center) and Studio Stereo (right)

While there’s a lot of subjectivity in choosing fonts, there are some objective considerations.

Font weight as a consideration

Some font families have a wide range of font weights — Light, Book, Regular, Medium, Semi-Bold, Bold, Black — whereas others just have a couple.

Inter UI comes with a fantastic range of weights

If you’re building a complex web app UI, you might need a range of font weights to establish hierarchy in different contexts. For something less complex, say a blog, you’ll likely be fine with just a couple.

Complex UI hierarchy (left) and Simple blog hierarchy (right)

Variable fonts are an exciting new technology that provide precise control over a font’s characteristics. For font weights, this means there’s no longer limitations to using “Light,” “Regular,” and “Bold,” but really any weight in between. Try some variable fonts out here and check out Ollie Williams’ post as well.

It’s still early days — there aren’t many variable fonts available right now, and browser support is limited. But definitely a space worth watching!

Consider the legibility of a font

Some typefaces are harder to read than others. Stay away from elaborate fonts when it comes to paragraphs, and if you must have tiny text somewhere, make sure its typeface is legible at those tiny sizes.

Of these two examples, which is easier on the eyes? (There is a right answer here. 🙂)

See the Pen
Font Comparison: Body
by Geoff Graham (@geoffgraham)
on CodePen.

Remember, fonts come in a variety of styles

Making a font bold isn’t as simple as adding an outline to the text, and italics are more than slanted letters. Good fonts have specific bold and italic styles, without which the browser tries to “fake” it:

Lato

These faux styles tend to reduce legibility and break the text’s visual cohesion because the browser can only do so much with what it’s given. Stick to fonts that offer true bold/italics styles, if you can.

Other things worth consideration

What we’ve looked at so far are the high level characteristics and features of fonts that can help us decide which to choose for a particular design or context. There are many other things that can (and probably should) be taken into consideration, including:

  • Language support: Some fonts have glyphs for foreign characters, which may be a requirement for a project geared toward a multilingual audience or that contains multilingual content.
  • Ligatures: Some fonts (typically serifs) have glyphs to replace otherwise awkward characters, like ffi and ffl which are multiple characters in a single glyph.
  • File size: You’re a developer, so I know you care about performance. Some fonts come in bigger files than others and those can cause a site to take a hit on load times.

Using fonts on the world wide web

A mere 10 years ago, there were two complex ways to use custom fonts on the web:

  • SiFR: Embedding a Flash (remember that thing?) widget to render text.
  • cufon: converting the font to a proprietary format, and using a specific JavaScript rendering engine to generate the text using VML on an HTML <canvas>.

Today, there’s all we need is a single simple one: @font-face. It lets you specify a font file URL, which the browser then downloads and uses on your site.

You can use the @font-face declaration to define your custom font:

@font-face {   font-family: 'MyWebFont';   src: url('webfont.eot'); /* IE9 Compat Modes */   src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */         url('webfont.woff2') format('woff2'), /* Super Modern Browsers */         url('webfont.woff') format('woff'), /* Pretty Modern Browsers */         url('webfont.ttf')  format('truetype'), /* Safari, Android, iOS */         url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */ }

And then refer to it as normal, by the font-family attribute:

body {   font-family: 'MyWebFont', Fallback, sans-serif; }

Even though @font-face is light years ahead of the old school approaches to custom web fonts, there is quite a bit to consider as far as browser support goes. Here’s a guide to getting the right amount of cross-browser support.

The impact of fonts on performance

Performance is the only downside to using custom fonts on the web. Fonts are relatively large assets — often hundreds of kilobytes in size — and will have and adverse effect on the speed of any site.

Here are some tips to soften the blow:

  • Use GZIP compression on your web font files.
  • Disable font features you don’t need, e.g. hinting, kerning.
  • Remove glyphs that you don’t need, e.g. foreign language characters.

One tool that can help tailor a font file to suit your needs is Transfonter. Just make sure you have the rights to any font that you want to use on your site because, well, it’s just the right thing to do.

Some services will host web fonts for you

One other significant way to shed some of the weight of using custom web fonts is to use a service that will host and serve them for you. The benefit here is that third-parties store the files on a speedy CDN, optimize them, and serve them to your site via a JavaScript snippet that gets dropped into the document head. In short: it takes a lot of hassle off your hands.

How easy is it to use a hosted service? Consider that using anything on Google Fonts only requires a single <link> in the HTML head:

<html>   <head>     <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">   <style>     body {       font-family: 'Roboto', sans-serif;     }   </style> </head>  <!-- Rest of the document -->

This example was taken from Google Fonts — the most popular hosted font service. It’s free to use, and, at the time of writing, has a catalogue of 915 font families. The quality of these can be hit-or-miss. Some are truly top-notch — beautiful design, many weights, true bold/italics, and advanced features like ligatures. Others, typically the more novel designs, are bare-bones, and might not be suitable for serious projects with evolving needs.

Adobe Fonts is also very popular. It comes bundled with Adobe’s Creative Cloud offering, which starts at $ 20.99 per month. At the time of writing, it has a catalogue of 1,636 font families. These are typically high quality fonts that you’d have to pay for, but with Adobe Fonts, you can access them all in a Netflix all-you-can-eat model.

Here are some other options:

  • Adobe Edge Web Fonts: This is the free version of Adobe Fonts. Adobe partnered with Google on this, so there’s a lot of overlap with the Google Fonts library. It has 503 font families in total.
  • Fontspring: This is a massive library of over 14,000 font families, but with an individual licensing model. This means paying more up-front, starting at ~$ 20 per individual font (and per weight or style), but no recurring costs. It’s also self-serve — you’ll have to host the files yourself.
  • MyFonts by Monotype: This is major type foundry. Similar to Fontspring: massive library of font families with an individual licensing model.
  • Fonts.com: This is similar to Fontspring. Options for one-off or pay-as-you go pricing (based on page views).
  • Cloud.typography by Hoefler&Co: This is a major type foundry. Over 1,000 font families (all by Hoefler&Co), with options for hosted (subscription, starting at $ 99 per year) or self-hosted (individually licensed) web fonts. The benefit here is that you get access to a library of fonts you cannot find anywhere else.
  • Fontstand: This services allows you to “rent” individual fonts cheaply on a monthly basis, starting ~$ 10 per month), which you get to own automatically after 12 months. To date, it boasts 1,500 families, with a hosted web font service.

CSS and Typography

OK, let’s move on to the intersection of design and development. We’ve covered a lot of the foundational terms and concepts of typography, but now we can turn our attention to what affordances we have to manipulate and style type, specifically with CSS.

Adjusting font sizing

Changing the size of a font is something that inevitably pops up in a typical project. Size is important because it creates hierarchy, implicitly guiding the user through the page. So, in this section, we’re going to look at two CSS features that are available in our tool belt for adjusting font sizes to create better content hierarchy.

Sizes can be expressed in a different units of measure

Did you know that there are 15 different units for sizing in CSS? Crazy, right? Most of us are probably aware of and comfortable working with pixels (px) but there are so many other ways we can define the size of a font.

Some of these are relative units, and others are absolute. The actual size of an element expressed in relative units depends on other parts of the page, while the actual size of an element expressed in absolute units is always the same. And, as you might expect, that difference is important because they serve different functions, depending on a design’s needs.

Of the 15 units we have available, we will selectively look at two in particular: px and em. Not only are these perhaps the two most used units that you’ll see used to define font sizes, but they also perfectly demonstrate the difference between absolute and relative sizing.

First off, px is an absolute unit and it actually doesn’t have much to do with pixels (it’s considered an angular measurement), but it’s defined so that a line of width 1px appears sharp and visible, no matter the screen resolution. The px value corresponds, roughly, to a little more than the distance from the highest ascender (e.g. the top of the letter A) to the lowest descender (e.g. the bottom of the letter p) in the font. Some fonts have taller letters than others, so 16px in one font might look noticeably “bigger” than 16px in another. Yet another consideration to take into account when choosing a font!

Interestingly enough, when it comes to typography, the px is a unit to be understood, but not used. The true purpose of px units is to serve as the foundation of a type system based on relative units. In other words, it’s an absolute value that a relative unit can point to in order to define its own size relative to that value.

Which takes us to em, a relative unit. Text with a font size of 2em would be twice as big as the font-size of its parent element. The body doesn’t have a parent element, but each device has its own default font-size for the body element. For example, desktop browsers usually default to 16px. Other devices (e.g. mobile phones and TVs) might have different defaults that are optimized for their form factors.

The em lets you reason about your typography intuitively: “I want this title to be twice as big as the paragraph text” corresponds directly to 2em. It’s also easy to maintain — if you need a media query to make everything bigger on mobile, it’s a simple matter of increasing one font-size attribute. Dealing in em units also lets you set other typographical elements in relation to font-size, as we’ll see later.

There are semantic HTML elements that CSS can target to adjust size

You’re sold on the em, but how many em units should each element be? You’ll want to have a range of text sizes to establish hierarchy between different elements of your page. More often than not, you’ll see hierarchies that are six level deep, which corresponds to the HTML heading elements, h1 through h6.

The right size scale depends on the use case. As a guideline, many people choose to use a modular scale. That refers to a scale based on a constant ratio for successive text elements in the hierarchy.

Example of a modular scale with a ratio of 1.4

Modular Scales is a tool by Tim Brown, who popularized this approach, which makes it easy to visualize different size scales.

Adjusting a font’s vertical spacing and alignment

The physical size of a font is a super common way we use CSS to style a font, but vertical spacing is another incredibly powerful way CSS can help improve the legibility of content.

Use line-height to define how tall to make a line of text

Line height is one of the most important factors affecting readability. It’s controlled by the line-height property, best expressed as a unit-less number that corresponds to a multiple of the defined font size.

Let’s say we are working with a computed font size of 16px (specified in the CSS as em units, of course), a line-height of 1.2 would make each line 19.2px tall. (Remember that px aren’t actually pixels, so decimals are valid!)

Most browsers default to a line-height of 1.2 but the problem is that this is usually too tight — you probably want something closer to 1.5 because provides a little more breathing room for your eyes when reading.

Here are some general guidelines to define a good line height:

  • Increase line-height for thick fonts
  • Increase line-height when fonts are a dark color
  • Increase line-height for long-form content
Increasing the line-height can drastically improve legibility
Fonts can’t dance, but they still have rhythm

Rhythm describes how text flows vertically on a page. Much like music, some amount of consistency and structure usually leads to good “rhythm.” Like most design techniques, rhythm isn’t an exact science but there are some sensible guidelines that give good results.

One school of thought prescribes the use of paragraph line height as a baseline unit from which all other spacing is derived. This includes gaps between paragraphs and headings, and padding between the text and other page elements.

Under this system, you might set the line height of a heading to twice the line height of paragraphs, and leave a one-line gap between a heading and paragraph. Handily, you can use the same em units to define margins and padding, so there’s really no need to hard-code anything.

Read more about rhythm here.

Horizontal Shape

Hopefully you’re convinced by now that vertical spacing is an important factor in improving legibility that we can control in CSS. Equally important is the horizontal spacing of individual characters and the overall width of content.

CSS can control the space between letters

Letter spacing is one of the most important factors affecting legibility. It is controlled by the CSS letter-spacing property, best expressed (again) in em units to keep everything relative. Tracking (the typography term for “letter spacing”) depends entirely on the font — some fonts will look great by default, while others might need a little tweaking.

In general, you only need to worry about letter spacing for text elements that are particularly big or small because most fonts are spaced well at a typical paragraph size.

For larger text, like headings and titles, you’ll often want to reduce the space between letters. And a little bit of space goes a long way. For example, -0.02em is a tiny decimal, but a good starting point, which can be tweaked until it looks just right to your eye. The only time you should think about increasing letter spacing is when dealing with stylistically unusual text — things like all-capped titles and even some number sequences.

Adding or subtracting as little as 0.02em can refine the appearance of words

Some specific pairs of letters, like AV, can look awkwardly spaced without a little manual tweaking. Well-crafted fonts typically specify custom spacing for such pairs, and setting the font-kerning property to normal lets you enable this. Browsers disable this on smaller text by default. Here is a little more on letter spacing, as well as other CSS tools we have to control font spacing in general.

The length of a line of text is more important than you might think

It’s unpleasant for our eyes to move long distances while reading, so the width of lines should be deliberate. General consensus is that a good width is somewhere between 60 and 70 characters per line. If you find that a line of text (especially for long-form content) drastically falls outside this range, then start adjusting.

The ch is a little-known CSS unit that we didn’t cover earlier, but can be helpful to keep line length in check. It’s a relative unit, defined as the width of the 0 character in the element’s font. Because narrow characters like l and i are relatively frequent, setting the width of a text container to something like 50ch should result in lines that are 60-70 character long.

p {   width: 50ch; }

CSS can smooth otherwise crispy fonts

-webkit-font-smoothing is a nifty CSS property that controls how fonts are anti-aliased. This is a fancy way of saying it can draw shades of gray around otherwise square pixels to create a smoother appearance. Do note, however, the -webkit prefix there, because that indicates that the property is only supported by WebKit browsers, e.g. Safari.

The default setting is subpixel-antialiased, but it’s worth seeing what your type looks like when it’s set to just antialiased. It can improve the way many fonts look, especially for text on non-white backgrounds.

At small font sizes, this should be used with caution — it lowers contrast, affecting readability. You should also make sure to adjust letter-spacing when using this, since greater anti-aliasing will increase the space between letters.

Anti-aliased (left) Subpixel Anti-aliased (right)

Wrapping up

Phew! We covered a lot of ground in a relatively short amount of space. Still, this is by no means an exhaustive guide, but rather, something that I hope will encourage you to take more control over the typography in your future projects, and to seek an even deeper knowledge of the topic. For that, I’ve compiled a list of additional resources to help you level up from here.


Learning about typography

Typography Inspiration

Identifying Fonts

  • WhatFont
  • Identifont
  • WhatTheFont
  • Typography in CSS

    The post Typography for Developers appeared first on CSS-Tricks.

    CSS-Tricks

    ,
    [Top]

    Front-End Developers Have to Manage the Loading Experience

    Web performance is a huge complicated topic. There are metrics like total requests, page weight, time to glass, time to interactive, first input delay, etc. There are things to think about like asynchronous requests, render blocking, and priority downloading. We often talk about performance budgets and performance culture.

    How that first document comes down from the server is a hot topic. That is where most back-end related performance talk enters the picture. It gives rise to architectures like the JAMstack, where gosh, at least we don’t have to worry about index.html being slow.

    Images have a performance story all to themselves (formats! responsive images!). Fonts also (FOUT’n’friends!). CSS also (talk about render blocking!). Service workers can be involved at every level. And, of course, JavaScript is perhaps the most talked about villain of performance. All of this is balanced with perhaps the most important general performance concept: perceived performance. Front-end developers already have a ton of stuff we’re responsible for regarding performance. 80% is the generally quoted number and that sounds about right to me.

    For a moment, let’s assume we’re going to build a site and we’re not going to server-side render it. Instead, we’re going to load an empty document and kick off data API calls as quickly as we can, then render the site with that data. Not a terribly rare scenario these days. As you might imagine, >we now have another major concern: handling the loading experience.

    I mused about this the other day. Here’s an example:

    I’d say that loading experience is pretty janky, and I’m on about the best hardware and internet connection money can buy. It’s not a disaster and surely many, many thousands of people use this particular site successfully every day. That said, it doesn’t feel fast, smooth, or particularly nice like you’d think a high-budget website would in these Future Times.

    Part of the reason is probably because that page isn’t server-side rendered. For whatever reason (we can’t really know from the outside), that’s not the way they went. Could be developer efficiency, security, a temporary state during a re-write… who knows! (It probably isn’t ignorance.)

    What are we to do? Well, I think this is a somewhat new problem in front-end development. We’ve told the browser: “Hey, we got this. We’re gonna load things all out of order depending on when our APIs cough stuff up to us and our front-end framework decides it’s time to do so.” I can see the perspective here where this isn’t ideal and we’ve given up something that browsers are incredibly good at only to do it less well ourselves. But hey, like I’ve laid out a bit here, the world is complicated.

    What is actually happening is that these front-end frameworks are aware of this issue and are doing things to help manage it. Back in April of this year, Dan Abramov introduced React Suspense. It seems like a tool for helping front-end devs like us manage the idea that we now need to deal with more loading state stuff than we ever have before:

    At about 14 minutes, he gets into fetching data with placeholder components, caching and such. This issue isn’t isolated to React, of course, but keeping in that theme, here’s a conference talk by Andrew Clark that hit home with me even more quickly (but ultimately uses the same demo and such):

    Just the idea of waiting to show spinners for a little bit can go a long way in de-jankifying loading.

    Mikael Ainalem puts a point on this in a recent article, A Brief History of Flickering Spinners. He explains more clearly what I was trying to say:

    One reason behind this development is the change we’ve seen in asynchronous programming. Asynchronous programming is a lot easier than it used to be. Most modern languages have good support for loading data on the fly. Modern JavaScript has incorporated Promises and with ES7 comes the async and await keywords. With the async/await keywords one can easily fetch data and process it when needed. This means that we need to think a step further about how we show users that data is loading.

    Plus, he offers some solutions!

    See the Pen Flickering spinners by Mikael Ainalem (@ainalem) on CodePen.

    We’ve got to get better at this.

    The post Front-End Developers Have to Manage the Loading Experience appeared first on CSS-Tricks.

    CSS-Tricks

    , , , ,
    [Top]

    A Guide to Custom Elements for React Developers

    I had to build a UI recently and (for the first time in a long while) I didn’t have the option of using React.js, which is my preferred solution for UI these days. So, I looked at what the built-in browser APIs had to offer and saw that using custom elements (aka Web Components) may just be the remedy that this React developer needed.

    Custom elements can offer the same general benefits of React components without being tied to a specific framework implementation. A custom element gives us a new HTML tag that we can programmatically control through a native browser API.

    Let’s talk about the benefits of component-based UI:

    • Encapsulation – concerns scoped to that component remain in that component’s implementation
    • Reusability – when the UI is separated into more generic pieces, they’re easier to break into patterns that you’re more likely to repeat
    • Isolation – because components are designed to be encapsulated and with that, you get the added benefit of isolation, which allows you scope bugs and changes to a particular part of your application easier

    Use cases

    You might be wondering who is using custom elements in production. Notably:

    • GitHub is using custom elements for their modal dialogs, autocomplete and display time.
    • YouTube’s new web app is built with Polymer and web components.

    Similarities to the Component API

    When trying to compare React Components versus custom elements, I found the APIs really similar:

    • They’re both classes that aren’t “new” and are able that extend a base class
    • They both inherit a mounting or rendering lifecycle
    • They both take static or dynamic input via props or attributes

    Demo

    So, let’s build a tiny application that lists details about a GitHub repository.

    Screenshot of end result

    If I were going to approach this with React, I would define a simple component like this:

    <Repository name="charliewilco/obsidian" />

    This component takes a single prop — the name of the repository — and we implement it like this:

    class Repository extends React.Component {   state = {     repo: null   };    async getDetails(name) {     return await fetch(`https://api.github.com/repos/$ {name}`, {       mode: 'cors'     }).then(res => res.json());   }    async componentDidMount() {     const { name } = this.props;     const repo = await this.getDetails(name);     this.setState({ repo });   }    render() {     const { repo } = this.state;      if (!repo) {       return <h1>Loading</h1>;     }      if (repo.message) {       return <div className="Card Card--error">Error: {repo.message}</div>;     }      return (       <div class="Card">         <aside>           <img             width="48"             height="48"             class="Avatar"             src={repo.owner.avatar_url}             alt="Profile picture for $ {repo.owner.login}"           />         </aside>         <header>           <h2 class="Card__title">{repo.full_name}</h2>           <span class="Card__meta">{repo.description}</span>         </header>       </div>     );   } }

    See the Pen React Demo – GitHub by Charles (@charliewilco) on CodePen.

    To break this down further, we have a component that has its own state, which is the repo details. Initially, we set it to be null because we don’t have any of that data yet, so we’ll have a loading indicator while the data is fetched.

    During the React lifecycle, we’ll use fetch to go get the data from GitHub, set up the card, and trigger a re-render with setState() after we get the data back. All of these different states the UI takes are represented in the render() method.

    Defining / Using a Custom Element

    Doing this with custom elements is a little different. Like the React component, our custom element will take a single attribute — again, the name of the repository — and manage its own state.

    Our element will look like this:

    <github-repo name="charliewilco/obsidian"></github-repo> <github-repo name="charliewilco/level.css"></github-repo> <github-repo name="charliewilco/react-branches"></github-repo> <github-repo name="charliewilco/react-gluejar"></github-repo> <github-repo name="charliewilco/dotfiles"></github-repo>

    See the Pen Custom Elements Demo – GitHub by Charles (@charliewilco) on CodePen.

    To start, all we need to do to define and register a custom element is create a class that extends the HTMLElement class and then register the name of the element with customElements.define().

    class OurCustomElement extends HTMLElement {} window.customElements.define('our-element', OurCustomElement);

    And we can call it:

    <our-element></our-element>

    This new element isn’t very useful, but with custom elements, we get three methods to expand the functionality of this element. These are almost analogous to React’s lifecycle methods for their Component API. The two lifecycle-like methods most relevant to us are the disconnectedCallBack and the connectedCallback and since this is a class, it comes with a constructor.

    Name Called when
    constructor An instance of the element is created or upgraded. Useful for initializing state, settings up event listeners, or creating Shadow DOM. See the spec for restrictions on what you can do in the constructor.
    connectedCallback The element is inserted into the DOM. Useful for running setup code, such as fetching resources or rendering UI. Generally, you should try to delay work until this time
    disconnectedCallback When the element is removed from the DOM. Useful for running clean-up code.

    To implement our custom element, we’ll create the class and set up some attributes related to that UI:

    class Repository extends HTMLElement {   constructor() {     super();      this.repoDetails = null;      this.name = this.getAttribute("name");     this.endpoint = `https://api.github.com/repos/$ {this.name}`         this.innerHTML = `<h1>Loading</h1>`   } }

    By calling super() in our constructor, the context of this is the element itself and all the DOM manipulation APIs can be used. So far, we’ve set the default repository details to null, gotten the repo name from element’s attribute, created an endpoint to call so we don’t have to define it later and, most importantly, set the initial HTML to be a loading indicator.

    In order to get the details about that element’s repository, we’re going to need to make a request to GitHub’s API. We’ll use fetch and, since that’s Promise-based, we’ll use async and await to make our code more readable. You can learn more about the async/await keywords here and more about the browser’s fetch API here. You can also tweet at me to find out whether I prefer it to the Axios library. (Hint, it depends if I had tea or coffee with my breakfast.)

    Now, let’s add a method to this class to ask GitHub for details about the repository.

    class Repository extends HTMLElement {   constructor() {     // ...   }    async getDetails() {     return await fetch(this.endpoint, { mode: "cors" }).then(res => res.json());   } }

    Next, let’s use the connectedCallback method and the Shadow DOM to use the return value from this method. Using this method will do something similar as when we called Repository.componentDidMount() in the React example. Instead, we’ll override the null value we initially gave this.repoDetails — we’ll use this later when we start to call the template to create the HTML.

    class Repository extends HTMLElement {   constructor() {     // ...   }    async getDetails() {     // ...   }    async connectedCallback() {     let repo = await this.getDetails();     this.repoDetails = repo;     this.initShadowDOM();   }    initShadowDOM() {     let shadowRoot = this.attachShadow({ mode: "open" });     shadowRoot.innerHTML = this.template;   } }

    You’ll notice that we’re calling methods related to the Shadow DOM. Besides being a rejected title for a Marvel movie, the Shadow DOM has its own rich API worth looking into. For our purposes, though, it’s going to abstract the implementation of adding innerHTML to the element.

    Now we’re assigning the innerHTML to be equal to the value of this.template. Let’s define that now:

    class Repository extends HTMLElement {   get template() {     const repo = this.repoDetails;        // if we get an error message let's show that back to the user     if (repo.message) {       return `<div class="Card Card--error">Error: $ {repo.message}</div>`     } else {       return `       <div class="Card">         <aside>           <img width="48" height="48" class="Avatar" src="$ {repo.owner.avatar_url}" alt="Profile picture for $ {repo.owner.login}" />         </aside>         <header>           <h2 class="Card__title">$ {repo.full_name}</h2>           <span class="Card__meta">$ {repo.description}</span>         </header>       </div>       `     }   } }

    That’s pretty much it. We’ve defined a custom element that manages its own state, fetches its own data, and reflects that state back to the user while giving us an HTML element to use in our application.

    After going through this exercise, I found that the only required dependency for custom elements is the browser’s native APIs rather than a framework to additionally parse and execute. This makes for a more portable and reusable solution with similar APIs to the frameworks you already love and use to make your living.

    There are drawbacks of using this approach, of course. We’re talking about various browser support issues and some lack of consistency. Plus, working with DOM manipulation APIs can be very confusing. Sometimes they are assignments. Sometimes they are functions. Sometimes those functions take a callback and sometimes they don’t. If you don’t believe me, take a look at adding a class to an HTML element created via document.createElement(), which is one of the top five reasons to use React. The basic implementation isn’t that complicated but it is inconsistent with other similar document methods.

    The real question is: does it even out in the wash? Maybe. React is still pretty good at the things it’s designed to be very very good at: the virtual DOM, managing application state, encapsulation, and passing data down the tree. There’s next to no incentive to use custom elements inside that framework. Custom elements, on the other hand, are simply available by virtue of building an application for the browser.

    Learn more

    The post A Guide to Custom Elements for React Developers appeared first on CSS-Tricks.

    CSS-Tricks

    , , , ,
    [Top]