Developer News

Typography for Developers

Css Tricks - Wed, 02/27/2019 - 5:28am

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."

HOW 2 MAJOR IN GRAPHIC DESIGN:
- CHOOSE A FONT
- "ITS CALLED A TYPEFACE NOT A FONT"
- CHOOSE A GODDAMN TYPEFACE
- U MADE THE WRONG CHOICE

— Deena (@itsDeenasaur) November 2, 2014

I may have used font and typeface interchangeably in this story. Please send all complaints to usuck@whocares.tk. https://t.co/IuHHmlaNAT

— Tristin Hopper (@TristinHopper) January 14, 2019

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 ? and ? 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.

    What We Want from Grid

    Css Tricks - Tue, 02/26/2019 - 3:14pm

    We felt spoiled with CSS grid for a minute there. It arrived hot and fast in all the major browsers all at once. Now that we're seeing a lot more usage, we're seeing people want more from grid.

    Michelle Barker lists hers wants (and I'll put my commentary after):

    • Styling row and column gaps. I've also heard requested styling grid cells directly, rather than needing to place an element there and style that element.
    • Multiple gap values. I wanted this just the other week, and I was told to use an empty column or row instead of a gap. The size of that column can be controlled, and things are placed accordingly to treat it like a gap. Sort of OK, except that isn't particularly friendly to implicit grids.
    • Autoflow patterns. This is clever. Check out Michelle's use case and proposal.
    • calc() with the fr unit. This is a mindbender. I can see wanting to do something like calc(1fr - 100px), but then isn't the leftover space 100px short and 1fr recalcuated to fill that space? Seems infinite loopy.
    • Aspect ratio grid cells. I suspect, if we get this, it'll be a generic aspect ratio solution that will work on any element, including elements placed onto a grid.

    Subgrid is also starting to be hotly requested, and I can see why. While building the last page layout I did using grid, I found myself strongly wishing I could share the overall page grid lines within sub-elements.

    Rachel Andrew talked about its status about six months ago in CSS Grid Level 2: Here Comes Subgrid. I'm not sure where it's at now, but I don't think any browser is supporting it quite yet. (I'm not even sure if the spec is technically done.)

    Brad put a point on the desire here:

    Container queries and subgrid would make my design system work so much easier.

    Define a grid and throw some components in there, then watch them snap into place to the parent grid and look great no matter what the container dimensions are.

    — Brad Frost (@brad_frost) February 11, 2019

    And Ken Bellows writes:

    • If we combine subgrid with grid-template-areas within the cards (read my last post if you don't know about Grid Areas, it'll blow your mind), complex responsive card-based layouts become trivial.
    • The prospect of a subgrid on both axes gives us a way to sort of accomplish relative grid positioning, at least for semantically grouped items, like I wished I had above! Group your stuff in a container, position your container on the grid, make that container a subgrid on both axes, and declare your tracks relative to the subgrid element's grid position!
    • Between Flexbox, Grid, display: contents, and subgrids, we will finally have everything we need to write very slim, clean, semantic markup with basically no fluff or purely structural elements. It will be a huge boon for accessibility, SEO, and just developers trying to understand your markup!

    Eric Meyer called subgrid an essential feature three years ago:

    This is why I’ve come to the same conclusion other grid experts (like Rachel) already have: subgrids are a major component of grid layout, and should be a part of any grid layout implementation when it emerges from developer-preview status.  If that means delaying the emergence of grids, I think it’s worth it.

    And of course, everybody still wants native masonry. ;)

    The post What We Want from Grid appeared first on CSS-Tricks.

    Look Ma, No Media Queries! Responsive Layouts Using CSS Grid

    Css Tricks - Tue, 02/26/2019 - 3:14pm

    Not only has CSS Grid reshaped the way we think and build layouts for the web, but it has also contributed to writing more resilient code, replacing "hacky" techniques we've used before, and in some cases, killing the need to rely on code for specific resolutions and viewports. What's so cool about this era in web development is that we're capable of doing more and more with fewer lines of code.

    In this article, we'll start dipping our toes into the power of CSS Grid by building a couple of common responsive navigation layouts. It's easier than what you may think, and since CSS Grid was built with responsiveness in mind, it'll take less code than writing media queries all over the place. Let’s do this!

    Layout #1: Hero content and list of articles

    See the Pen
    Hero Content and List of Articles
    by Juan Martín García (@imjuangarcia)
    on CodePen.

    We'll kick off this set of examples by creating a common website layout: A full-width hero section, with a grid of cards below.

    Both elements will respond to window resizing and adapt accordingly. Though this might seem like a lot of code at first glance, the responsive behavior is done with only six lines of CSS Grid code, and without writing a single @media rule. Let's break down the code to see what's going on:

    The hero section

    Let’s take a look at the code for the .hero element:

    <section class="hero"> <h1>You thirsty?</h1> <article> <p>Explore local breweries with just one click and stirred by starlight across the centuries light years great turbulent clouds circumnavigated paroxysm of global death.</p> <a href="#breweries">Browse Breweries</a> </article> </section> .hero { /* Photo by mnm.all on Unsplash */ background: url('https://images.unsplash.com/photo-1518176258769-f227c798150e') center; background-size: cover; padding: 4rem 2rem; /* Grid styles */ display: grid; align-items: center; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

    We have a bunch of background styles to enable the beer background, a bit of padding to separate the content from the edge of the screen, and then three lines of grid styles:

    1. The first line (display: grid;) is changing the behavior of the .hero element to be a grid container. That means the elements inside .hero are now grid items.
    2. The second line (align-items: center;) is going to vertically center the columns on our grid. But these two lines don't do anything on their own until we set the columns of our grid.
    3. And that's where the third line comes in. A lot of stuff is going on in that single property, so let's go one step at a time.
    The repeat() function

    Generally speaking, what we usually do to define our columns and rows on a CSS Grid is to add the value for each track after defining the property, like this:

    .element { /* This will result on four columns, each one of 1fr */ grid-template-columns: 1fr 1fr 1fr 1fr; /* This will result on two rows, each one of 300px */ grid-template-rows: 300px 300px; }

    Now, that's quite dull. We can use the repeat() function to make that less verbose and easier to follow. The function takes two parameters:

    1. The number of times to repeat the value.
    2. The value itself.

    After refactoring our code to use repeat(), we should expect the same results from these lines of code:

    .element { /* this is the same as grid-template-columns: 1fr 1fr 1fr 1fr; */ grid-template-columns: repeat(4, 1fr); /* this is the same as grid-template-rows: 300px 300px; */ grid-template-rows: repeat(2, 300px); }

    Much cleaner, yeah?

    The minmax() function

    Now, the above examples are explicitly defining sizes for the tracks (1fr and 300px). That might work for some scenarios, but for our beer example here, we need to be able to automatically calculate the size of the track, based on the width of the viewport, and automatically adjust the number of columns shown. To be able to do that, we'll define a range of values using the minmax() function. What will we be defining? You've probably guessed by now: The *minimum* and *maximum* values we want these columns to be able to resize to.

    In the hero for our beer example above, we set our minmax() property to be 240px at its minimum size, and 1fr at its maximum size. fr units, if you've never heard of them, stand for fractional units. Nobody can explain them better than Jen Simmons on this video and Robin Rendle in this post.

    Using the Firefox Grid Inspector to check the change on the track's size when resizing

    That results in our tracks being 1fr when there's plenty of space on our viewport (aka desktop resolutions), and 240px when there's not enough space for both columns (like on mobile devices). That's why they nicely grow when we make our browser wider, since they're taking the remaining space and equally dividing it across the existing columns. Now, moving to the last piece of the puzzle!

    The auto-fit keyword

    The auto-fit keyword allows us to wrap our columns into rows when there's not enough space in our viewport to fit the 240px minimum value without overflowing the content. Sara Soueidan wrote an excellent article about auto-sizing columns using the auto-fill and auto-fit keywords, in case you want to dive a little deeper into what's going on under the hood. Now, with that last bit of code in place, we should be able to achieve this result:

    The column is automatically wrapping when there's not enough space in the viewport The article list

    Now that we've thoroughly reviewed the behavior of the elements inside our hero element, it's likely that the first two lines of CSS code for the breweries list below it might already seem familiar to you:

    .breweries > ul { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); grid-gap: 1rem; }

    That's right! We're using the exact same approach: On the first line we define our grid, on the second one we size our tracks using the same magic one-liner, and on the third line we set a gap for these columns. Nothing new under the sun, and what's really neat about this, is that our code is resilient enough to adjust the number of tracks and their sizes, according to the number of items we have inside our unordered list:

    The grid responds to the change in the number of tracks, and adapts the layout

    That's all, folks! A fully responsive website layout, using just six lines of CSS code. Not bad, huh? Make sure you check the source code and play around with this example on CodePen.

    Layout #2: Full-width image gallery

    See the Pen
    Full Width Image Gallery
    by Juan Martín García (@imjuangarcia)
    on CodePen.

    On this next example, we'll embrace the power of our newly learned combination of repeat(), auto-fit and minmax() to create this responsive image gallery. We'll also be sizing our tracks using grid-column and grid-row, and learning about the handy property:value combination of grid-auto-flow: dense; that allows us to change the default behavior of the elements that can't fit on our explicit tracks: Instead of wrapping themselves in new rows or columns, we'll make them fit into the unused spots on our grid. Let's get into the coding!

    The grid setup

    The grid is created using our familiar display: grid; property, where columns are defined using repeat(), auto-fit and minmax(). We also added a bunch rows with a repeat() function and defined a gap to our images, using grid-gap. But the new player here is the grid-auto-flow: dense;. We’ll get to it in a second.

    .gallery > .gallery__list { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); grid-template-rows: repeat(6, 200px); grid-gap: 1rem; grid-auto-flow: dense; }

    We also created a repetition pattern using the nth-child() pseudo-selector to set different sizes for our tracks using grid-column and grid-row. Notice here that we’re using the span keyword to allow the selected item to occupy more than one column or row.

    /* This will create 2x images every 4 elements */ .gallery > .gallery__list > li:nth-child(4n) { grid-column: span 2; /* Spans two columns */ grid-row: span 2; /* Spans two rows */ } /* This will create 3x images every 8 elements */ .gallery > .gallery__list > li:nth-child(8n) { grid-column: span 3; grid-row: span 3; }

    And finally, we'll make sure our images cover the entire area of its container, regardless if it's 1x, 2x or 3x, using object-fit: cover;. If you have never heard of object-fit, it works fairly similar to how background-image does, but with HTML <img> tags:

    .gallery > .gallery__list > li > figure > img { width: 100%; height: 100%; object-fit: cover; }

    Now, the real deal here is grid-auto-flow: dense;. Check what happens when we take that out from our code:

    Removing grid-auto-flow: dense; leads to inconsistent placement of the elements on the grid

    See those holes on our beautifully crafted grid? That's because some of the elements on it are taking 2x or 3x spots, and when there isn't enough space on our tracks to fit them, they'll wrap into a new row, since that's the default behavior. By changing it from row to dense, we're telling the grid to fill any gaps we might have with elements that could fit them, regardless of their source order on the DOM.

    That's why this technique might come especially handy for things like image galleries, but might not be suitable for other use cases where you might need to preserve the order of the markup. Feel free to play around with the CodePen demo to check the differences between where items are placed.

    Layout #3: Trello-style card layout

    See the Pen
    Trello-Style Card Layout
    by Juan Martín García (@imjuangarcia)
    on CodePen.

    Now, on to the last demo, where we'll take advantage of the ability to nest grids to recreate this Trello Board. We'll be creating a grid to hold our four different columns, and inside of those, we'll create a child grid for our cards. Even though this example won't explore new properties or revolutionary methods, it'll help us to get a grasp on how easy it is to build complex layouts with a few lines of CSS code. This demo has a lot of extra code to achieve the styling of the Trello layout, so we’ll focus solely on the grid styles.

    The columns

    To create the four columns, we'll use display: grid; on the container and use our magical one-liner for our grid-template-columns. We'll also be defining a gap between them, and use align-items: flex-start; to ensure that our columns don't stretch to the bottom of the screen.

    .column__list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); grid-gap: .5rem; align-items: flex-start; }

    Now, the original Trello is not responsive by default: If you resize your browser on a Trello Board, you'll notice that you'll end up having a horizontal scroll on your columns, rather than wrapping them on a new row. We're not following that behavior here since we want to build responsive layouts, but in case you're curious, and want to emulate Trello's functionality, you can achieve that by adding two more lines of CSS code:

    .column__list { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); grid-gap: .5rem; align-items: flex-start; /* Uncomment these lines if you want to have the standard Trello behavior instead of the column wrapping */ grid-auto-flow: column; grid-auto-columns: minmax(260px, 1fr); }

    We learned about grid-auto-flow in our previous demo and discovered that it let us control how the auto-placement algorithm work, and how implicit elements should be added in the flow of the grid. The default behavior is row, meaning that any extra element that won't fit on our grid will wrap into a new line. We changed that to be dense on our previous demo, and we'll change it to be column on this one: That way, any new column added here will end up in an implicit column, and have a horizontal scroll. We'll also define a width for those auto-generated columns with the grid-auto-columns property.

    Modifying the grid-auto-flow property will make this demo behave like the real-world Trello The cards

    For the cards grid, we'll use a similar approach. We'll display: grid; on the container. We won't define any columns here, since we don't want to have any, and we'll put grid-template-rows: auto; to use to avoid all cards having the same height — we want some of them to be bigger and some of them smaller, based on the type of content being added to them.

    .card__list { display: grid; grid-template-rows: auto; grid-gap: .5rem; margin: .5rem 0; }

    And, again, that's all folks! Two more lines to set a gap and a margin to the cards, and we're done! Everything else in the Pen is standard CSS to achieve the Trello look and feel.

    So then... are media queries dead?

    Back in the day, when we were building layouts using display: inline-block or floats, media queries made a lot of sense in order to change the size of our elements as the viewport got smaller. But now, with the incredibly powerful layouts that we're able to create with a couple of CSS lines, you might feel tempted to think that media queries are doomed. I strongly disagree with that: I believe that we should change the way we think about them, and therefore use them differently.

    As Rachel Andrew stated about a year ago, we should use media queries to fix our layout when it breaks, rather than targeting devices: There are so many out there! With the advent of Media Queries Level 4 and 5, we're not only able to detect screen sizes now, but pointer types as well. As a result, we can dig into a user’s system preferences and adapt our code for those who prefer reduced motion or whether we should use inverted colors. That means media queries are not dead; on the flipside, I'd say it's an exciting time for using media queries, but we need to learn to use them right. In the meantime, building robust layouts using modern techniques such as Flexbox or CSS Grid, will save you a bunch of time, code, and headaches.

    The post Look Ma, No Media Queries! Responsive Layouts Using CSS Grid appeared first on CSS-Tricks.

    Responsive Designs and CSS Custom Properties: Building a Flexible Grid System

    Css Tricks - Tue, 02/26/2019 - 5:28am

    Last time, we looked at a few possible approaches for declaring and using CSS custom properties in responsive designs. In this article, we’ll take a closer look at CSS variables and how to use them in reusable components and modules. We will learn how to make our variables optional and set fallback values.

    As an example, we will build a simple grid system based on flexbox. Grid systems play a vital role in responsive designs. However, building a grid system that is flexible and lightweight at the same time can be a tricky task. Let’s see what the common approaches towards grid systems are and how CSS custom properties can help us build them.

    Article Series:
    1. Defining Variables and Breakpoints
    2. Building a Flexible Grid System (This Post)
    A simple CSS grid system

    Let’s start with a 12-column grid system:

    .container { max-width: 960px; margin: 0 auto; display: flex; } .col-1 { flex-basis: 8.333%; } .col-2 { flex-basis: 16.666%; } .col-3 { flex-basis: 25%; } .col-4 { flex-basis: 33.333%; } .col-5 { flex-basis: 41.666%; } .col-6 { flex-basis: 50%; } /* and so on up to 12... */

    See the Pen
    #5 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    There’s quite a lot of repetition and hard-coded values here. Not to mention how many more will be generated once we add more breakpoints, offset classes, etc.

    Building a grid system with Sass

    To make our grid example more readable and maintainable, let’s use Sass to preprocess our CSS:

    $columns: 12; // Number of columns in the grid system .container { display: flex; flex-wrap: wrap; margin: 0 auto; max-width: 960px; } @for $width from 1 through $columns { .col-#{$width} { flex-basis: $width / $columns * 100%; } }

    See the Pen
    #6 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    This is definitely much easier to work with. As we develop our grid further and, let’s say, would like to change it from 12 columns to 16 columns, all we have to do is to update a single variable (in comparison to dozens of classes and values). But... as long as our Sass is shorter and more maintainable now, the compiled code is identical to the first example. We are still going to end up with a massive amount of code in the final CSS file. Let’s explore what happens if we try to replace the Sass variables with CSS custom properties instead.

    Building a grid system with CSS custom properties

    Before we start playing with CSS custom properties, let’s start with some HTML first. Here’s the layout we’re aiming for:

    It consists of three elements: a header, a content section and a sidebar. Let’s create markup for this view, giving each of the elements a unique semantic class (header, content, sidebar) and a column class which indicates that this element is a part of a grid system:

    <div class="container"> <header class="header column"> header </header> <main class="content column"> content </main> <aside class="sidebar column"> sidebar </aside> </div>

    Our grid system, as before, is based on a 12-column layout. You can envision it as an overlay covering our content areas:

    So .header takes all 12 columns, .content takes eight columns (66.(6)% of the total width) and .sidebar takes four columns (33.(3)% of the total width). In our CSS, we would like to be able to control the width of each section by changing a single custom property:

    .header { --width: 12; } .content { --width: 8; } .sidebar { --width: 4; }

    To make it work, all we need to do is write a rule for the .column class. Lucky for us, most of the work is already done! We can re-use the Sass from the previous chapter and replace the Sass variables with CSS custom properties:

    .container { display: flex; flex-wrap: wrap; margin: 0 auto; max-width: 960px; } .column { --columns: 12; /* Number of columns in the grid system */ --width: 0; /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); }

    Notice two important changes here:

    1. The --columns variable is now declared inside of the .column rule. The reason is that this variable is not supposed to be used outside of the scope of this class.
    2. The math equation we perform in the flex-basis property is now enclosed within a calc() function. Math calculations that are written in Sass are compiled by the preprocessor and don’t need additional syntax. calc(), on the other hand, lets us perform math calculations in live CSS. The equation always needs to be wrapped within a calc() function.

    On a very basic level, that’s it! We’ve just built a 12-column grid system with CSS custom properties. Congratulations! We could call it a day and happily finish this article right now, but... we usually need a grid system that is a bit more sophisticated. And this is when things are getting really interesting.

    See the Pen
    #8 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Adding a breakpoint to the grid

    Most times, we need layouts to look different on various screen sizes. Let’s say that in our case we want the layout to remain as it is on a large viewport (e.g. desktop) but have all three elements become full-width on smaller screens (e.g. mobile).

    So, in this case, we would like our variables to look as follows:

    .header { --width-mobile: 12; } .content { --width-mobile: 12; --width-tablet: 8; /* Tablet and larger */ } .sidebar { --width-mobile: 12; --width-tablet: 4; /* Tablet and larger */ }

    .content and .sidebar each hold two variables now. The first variable (--width-mobile) is a number of columns an element should take by default, and the second one (--width-tablet) is the number of columns an element should take on larger screens. The .header element doesn’t change; it always takes the full width. On larger screens, the header should simply inherit the width it has on mobile.

    Now, let’s update our .column class.

    CSS variables and fallback

    To make the mobile version work as expected, we need to alter the .column class as follows:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); }

    Basically, we replace the value of the --width variable with --width-mobile. Notice that the var() function takes two arguments now. The first of them is a default value. It says: "If a --width-mobile variable exists in a given scope, assign its value to the --width variable." The second argument is a fallback. In other words: "If a --width-mobile variable is not declared in a given scope, assign this fallback value to the --width variable." We set this fallback to prepare for a scenario where some grid elements won’t have a specified width.

    For example, our .header element has a declared --width-mobile variable which means the --width variable will be equal to it and the flex-basis property of this element will compute to 100%:

    .header { --width-mobile: 12; } .column { --columns: 12; --width: var(--width-mobile, 0); /* 12, takes the value of --width-mobile */ flex-basis: calc(var(--width) / var(--columns) * 100%); /* 12 ÷ 12 × 100% = 100% */ }

    If we remove the --width-mobile variable from the .header rule, then the --width variable will use a fallback value:

    .header { /* Nothing here... */ } .column { --columns: 12; --width: var(--width-mobile, 0); /* 0, takes the the fallback value */ flex-basis: calc(var(--width) / var(--columns) * 100%); /* 0 ÷ 12 × 100% = 0% */ }

    Now, as we understand how to set fallback for CSS custom properties, we can create a breakpoint, by adding a media query to our code:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet); /* Width of the element on tablet and up */ } }

    This works exactly as expected, but only for the content and sidebar, i.e. for the elements that have specified both --width-mobile and --width-tablet. Why?

    The media query we created applies to all .column elements, even those that don’t have a --width-tablet variable declared in their scope. What happens if we use a variable that is not declared? The reference to the undeclared variable in a var() function is then considered invalid at computed-value time, i.e. invalid at the time a user agent is trying to compute it in the context of a given declaration.

    Ideally, in such a case, we would like the --width: var(--width-tablet); declaration to be ignored and the previous declaration of --width: var(--width-mobile, 0); to be used instead. But this is not how custom properties work! In fact, the invalid --width-tablet variable will still be used in the flex-basis declaration. A property that contains an invalid var() function always computes to its initial value. So, as flex-basis: calc(var(--width) / var(--columns) * 100%); contains an invalid var() function the whole property will compute to auto (the initial value for flex-basis).

    What else we can do then? Set a fallback! As we learned before, a var() function containing a reference to the undeclared variable, computes to its fallback value, as long as it’s specified. So, in this case, we can just set a fallback to the --width-tablet variable:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet, var(--width-mobile, 0)); } }

    See the Pen
    #9 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    This will create a chain of fallback values, making the --width property use --width-tablet when available, then --width-mobile if --width-tablet is not declared, and eventually, 0 if neither of the variables is declared. This approach allows us to perform numerous combinations:

    .section-1 { /* Flexible on all resolutions */ } .section-2 { /* Full-width on mobile, half of the container's width on tablet and up */ --width-mobile: 12; --width-tablet: 6; } .section-3 { /* Full-width on all resolutions */ --width-mobile: 12; } .section-4 { /* Flexible on mobile, 25% of the container's width on tablet and up */ --width-tablet: 3; }

    One more thing we can do here is convert the default 0 value to yet another variable so we avoid repetition. It makes the code a bit longer but easier to update:

    .column { --columns: 12; /* Number of columns in the grid system */ --width-default: 0; /* Default width, makes it flexible */ --width: var(--width-mobile, var(--width-default)); /* Width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet, var(--width-mobile, var(--width-default))); } }

    See the Pen
    #10 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Now, we have a fully functional, flexible grid! How about adding some more breakpoints?

    Adding more breakpoints

    Our grid is already quite powerful but we often need more than one breakpoint. Fortunately, adding more breakpoints to our code couldn’t be easier. All we have to do is to re-use the code we already have and add one variable more:

    .column { --columns: 12; /* Number of columns in the grid system */ --width-default: 0; /* Default width, makes it flexible */ --width: var(--width-mobile, var(--width-default)); /* Width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width: var(--width-tablet, var(--width-mobile, var(--width-default))); } } @media (min-width: 768px) { .column { --width: var(--width-desktop, var(--width-tablet, var(--width-mobile, var(--width-default)))); } }

    See the Pen
    #11 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Reducing fallback chains

    One thing that doesn’t look that great in our code is that feedback chains are getting longer and longer with every breakpoint. If we’d like to tackle this issue, we can change our approach to something like this:

    .column { --columns: 12; /* Number of columns in the grid system */ --width: var(--width-mobile, 0); /* Width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } @media (min-width: 576px) { .column { --width-tablet: var(--width-mobile); --width: var(--width-tablet); } } @media (min-width: 768px) { .column { --width-desktop: var(--width-tablet); --width: var(--width-desktop); } }

    See the Pen
    #12 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    This code is doing exactly the same job but in a bit different way. Instead of creating a full fallback chain for each breakpoint, we set a value of each variable to the variable from the previous breakpoint as a default value.

    Why so complicated?

    It looks like we’ve done quite a lot of work to complete a relatively simple task. Why? The main answer is: to make the rest of our code simpler and more maintainable. In fact, we could build the same layout by using the techniques described in the previous part of this article:

    .container { display: flex; flex-wrap: wrap; margin: 0 auto; max-width: 960px; } .column { --columns: 12; /* Number of columns in the grid system */ --width: 0; /* Default width of the element */ flex-basis: calc(var(--width) / var(--columns) * 100%); } .header { --width: 12; } .content { --width: 12; } .sidebar { --width: 12; } @media (min-width: 576px) { .content { --width: 6; } .sidebar { --width: 6; } } @media (min-width: 768px) { .content { --width: 8; } .sidebar { --width: 4; } }

    In a small project, this approach could work perfectly well. For the more complex solutions, I would suggest considering a more scalable solution though.

    Why should I bother anyway?

    If the presented code is doing a very similar job to what we can accomplish with preprocessors such as Sass, why should we bother at all? Are custom properties any better? The answer, as usually, is: it depends. An advantage of using Sass is better browser support. However, using custom properties has a few perks too:

    1. It’s plain CSS. In other words, it’s a more standardized, dependable solution, independent from any third parties. No compiling, no package versions, no weird issues. It just works (apart from the browsers where it just doesn’t work).
    2. It’s easier to debug. That’s a questionable one, as one may argue that Sass provides feedback through console messages and CSS does not. However, you can’t view and debug preprocessed code directly in a browser, whilst working with CSS variables, all the code is available (and live!) directly in DevTools.
    3. It’s more maintainable. Custom properties allow us to do things simply impossible with any preprocessor. It allows us to make our variables more contextual and, therefore, more maintainable. Plus, they are selectable by JavaScript, something Sass variables are not.
    4. It’s more flexible. Notice, that the grid system we’ve built is extremely flexible. Would you like to use a 12-column grid on one page and a 15-column grid on another? Be my guest—it’s a matter of a single variable. The same code can be used on both pages. A preprocessor would require generating code for two separate grid systems.
    5. It takes less space. As long as the weight of CSS files is usually not the main bottleneck of page load performance, it still goes without saying that we should aim to optimize CSS files when possible. To give a better image of how much can be saved, I made a little experiment. I took the grid system from Bootstrap and rebuilt it from scratch with custom properties. The results are as follows: the basic configuration of the Bootstrap grid generates over 54KB of CSS whilst a similar grid made with custom properties is a mere 3KB. That’s a 94% difference! What is more, adding more columns to the Bootstrap grid makes the file even bigger. With CSS variables, we can use as many columns as we want without affecting the file size at all.

    The files can be compressed to minimize the difference a bit. The gzipped Bootstrap grid takes 6.4KB in comparison to 0.9KB for the custom properties grid. This is still an 86% difference!

    Performance of CSS variables

    Summing up, using CSS custom properties has a lot of advantages. But, if we are making the browser do all the calculations that had been done by preprocessors, are we negatively affecting the performance of our site? It’s true that using custom properties and calc() functions will use more computing power. However, in cases similar to the examples we discussed in this article, the difference will usually be unnoticeable. If you’d like to learn more about this topic, I would recommend reading this excellent article by Lisi Linhart.

    Not only grid systems

    After all, understanding the ins and outs of custom properties may not be as easy as it seems. It will definitely take time, but it’s worth it. CSS variables can be a huge help when working on reusable components, design systems, theming and customizable solutions. Knowing how to deal with fallback values and undeclared variables may turn out to be very handy then.

    Thanks for reading and good luck on your own journey with CSS custom properties!

    The post Responsive Designs and CSS Custom Properties: Building a Flexible Grid System appeared first on CSS-Tricks.

    Moving a Self-Hosted WordPress Site to WordPress.com

    Css Tricks - Tue, 02/26/2019 - 5:23am

    I have a habit of getting some hosting when I need a new WordPress site. That is, a self-installed, self-hosted WordPress.org site. That's served me well over the years. I like my control. But along with that control comes a certain level of extra responsibility that sometimes just isn't worth it.

    That's the case for me now with my little blog Email is Good.

    Right from the get-go, I knew I wanted Email is Good to be as absolutely simple as could be. At the moment, I can't prioritize a fancy custom design or really any specialized functionality at all. All I want is a simple, clean blog in which to publish blog posts. And as powerful and flexible as WordPress is, it's still extra good at that use case.

    Email is Good uses an untouched, stock copy of the TwentySixteen theme.

    I'd like to move it over to WordPress.com, so that I don't have to deal with hosting, upgrades, backups, security... it'll just host my simple blog and I can unburden myself of that little spoonful of technical debt.

    Their docs for this are there, but a little on the light side, so I'll document my process here.

    Set up the WordPress.com side first

    There is a nice clean URL for kicking off a new WordPress.com site:

    https://wordpress.com/start/

    There isn't really a one-click just suck everything over in one shot system. Instead, you set up the site on WordPress.com, deal with the domain, and import the content. It might feel a little weird, but this first step is just kinda re-setting up the basics:

    Deal with the domain

    By "domain", I mean the URL that you may already own. I own "email-is-good.com" which is what I want to continue to use.

    During setup you can buy a domain (or get a free one! They'll give you a wordpress.com or .blog subdomain), but since I'm moving a site here, I'll select the option that I already own the domain.

    My domain name is already registered on GoDaddy.com. I could just leave the domain name there and map the domain over to WordPress.com. I think that's generally a smart thing to do, but I wanted to try what seems to be the default which is transferring it over to WordPress.com.

    Part of the beauty of transferring the domain is there is no settings to screw up, as it will be handled by WordPress.com

    I went through a process of basically re-registering the domain with WordPress.com.

    In order to actually transfer the domain, I had to go to GoDaddy and "unlock" the domain as well as request a transfer authorization code.

    If you're transferring a domain, it can take a little while.

    The note on the page above tells me it might take a full week to complete. It took me one day less. I got the success email on February 18th instead of 19th.

    I did have to "flip the switch", as the email suggests, to use the WordPress nameservers.

    But before I did, I made sure the new WordPress.com site had all the old content!

    Exporting Content & Media

    There is an export tool baked right into WordPress. Find it under Tools.

    You'll get an .xml file as output. Mine was called:

    emailisgood.wordpress.2019-02-12.xml

    Importing Content & Media

    On the WordPress.com side, there is a big Import option right in the sidebar. In those options, there is a WordPress option to choose.

    Drag and drop the .xml file there.

    Mine was pretty quick, but I imagine it could take a while. You'll even get an email when it's done.

    All my content and media made the journey just fine!

    Clean Up

    I had to do a little cleanup here and there to get the site exactly as it was. My site is so basic, it was hardly any work, but it's worth knowing you might have to mop up a little. For example, the site already had a contact page, so I had to nuke the one that was imported (which was using a contact form plugin I didn't need any more anyway) and make sure it was all functional.

    Another thing that didn't make the trip to the new site was the widgets. I had a sidebar with some widgets that I had to re-build, but that was no big deal. I literally copy-pasted the content from them from the old site before I flipped the switch.

    So now! I've ditched a pile of technical debt. No more worrying about my SSL certifiate. No more having to manually follow up with any hosting company about downtime. Performance is largely in the hands of someone else.

    I just have a simple site where I can write write write.

    Video!

    If it's helpful for you to watch me talk all this out, I've put it on YouTube:

    The post Moving a Self-Hosted WordPress Site to WordPress.com appeared first on CSS-Tricks.

    iconsvg.xyz

    Css Tricks - Mon, 02/25/2019 - 10:45am

    There is a lot to like about Gaddafi Rusli's ICONSVG.

    1. It provides inline <svg>, which is the most generically useful way to deliver them, and probably how they should be used anyway. Each icon is a tiny amount of SVG and I'd bet they were all hand-golfed.
    2. They are all stroke-based, so they can be beefed up or slimmed down as needed.
    3. The stroke-linecap and stroke-linejoin properties can be adjusted, which presents an opportunity to make their edges sharper or more rounded. I often find icons that are close to what I want, but the weight isn't right or the edges are either too sharp or too round. This quick and easy configuration is awesome.

    Direct Link to ArticlePermalink

    The post iconsvg.xyz appeared first on CSS-Tricks.

    Dealing with overflow and position: sticky;

    Css Tricks - Mon, 02/25/2019 - 10:44am

    Any overflow value other than visible and no height is the enemy of child elements with position: sticky;. It's like that element is ready to stick when the parent scrolls, but it never does because the height is unconstrained. Adding a fixed height can solve the issue, but that's not always desirable.

    Dannie Vinther digs into a way of dealing with that. The end result is avoiding that situation all together by removing the element that wants to be sticky from the element that needs an overflow. But as soon as you do that, the elements no longer scroll together since they aren't siblings. The use case here is a table with sticky headers on vertical scrolling and allowing for horizontal scrolling as well. Dannie uses a script to sync the scroll positions.

    Direct Link to ArticlePermalink

    The post Dealing with overflow and position: sticky; appeared first on CSS-Tricks.

    Responsive Designs and CSS Custom Properties: Defining Variables and Breakpoints

    Css Tricks - Mon, 02/25/2019 - 5:22am

    CSS custom properties (a.k.a. CSS variables) are becoming more and more popular. They finally reached decent browser support and are slowly making their way into various production environments. The popularity of custom properties shouldn’t come as a surprise, because they can be really helpful in numerous use cases, including managing color palettes, customizing components, and theming. But CSS variables can also be really helpful when it comes to responsive design.

    Article Series:
    1. Defining Variables and Breakpoints (This Post)
    2. Building a Flexible Grid System

    Let’s consider an <article> element with a heading and a paragraph inside:

    <article class="post"> <h2 class="heading">Post's heading</h2> <p class="paragraph"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium numquam adipisci recusandae officiis dolore tenetur, nisi, beatae praesentium, soluta ullam suscipit quas? </p> </article>

    It’s a common scenario in such a case to change some sizes and dimensions depending on the viewport’s width. One way to accomplish this is by using media queries:

    .post { padding: 0.5rem 1rem; margin: 0.5rem auto 1rem; } .heading { font-size: 2rem; } @media (min-width: 576px) { .post { padding: 1rem 2rem; margin: 1rem auto 2rem; } .heading { font-size: 3rem; } }

    See the Pen
    #1 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Such an approach gives us an easy way to control CSS properties on different screen sizes. However, it may be hard to maintain as the complexity of a project grows. When using media queries, keeping code readable and DRY at the same time quite often turns out to be challenging.

    The most common challenges when scaling this pattern include:

    • Repeated selectors: Apart from bloating code with multiple declarations, it also makes future refactoring more difficult, e.g. every time a class name changes it requires remembering to update it in multiple places.
    • Repeated properties: Notice that when overwriting CSS rules within media queries, it requires repeating the entire declaration (e.g. font-size: 3rem;) even though it’s just the value (3rem) that actually changes.
    • Repeated media queries: To keep responsive styles contextual, it’s a common practice to include the same media queries in multiple places, close to the styles they override. Unfortunately, it not only makes code heavier, but also might make breakpoints much harder to maintain. On the other hand, keeping all responsive styles in one place, away from their original declarations, may be very confusing: we end up with multiple references to the same elements sitting in completely different places.

    We can argue that repeated declarations and queries shouldn’t be such a big deal with proper file compression enabled, at least as long as we’re referring to performance. We can also merge multiple queries and optimize your code with post-processing tools. But wouldn’t it be easier to avoid these issues altogether?

    There’s a lot of ways to avoid the issues listed above. One of them, that we will explore in this article, is to use CSS custom properties.

    Using CSS variables for property values

    There are plenty of amazing articles on the web explaining the concept of CSS custom properties. If you haven’t got chance to get familiar with them yet, I would recommend starting with one of the beginner articles on this topic such as this awesome piece by Serg Hospodarets as we are not going to get into details of the basic usage in this article.

    The most common way of utilizing CSS custom properties in responsive design is to use variables to store values that change inside of media queries. To accomplish this, declare a variable that holds a value that is supposed to change, and then reassign it inside of a media query:

    :root { --responsive-padding: 1rem; } @media (min-width: 576px) { :root { --responsive-padding: 2rem; } } .foo { padding: var(--responsive-padding); }

    Assigning variables to the :root selector is not always a good idea. Same as in JavaScript, having many global variables is considered a bad practice. In real life, try to declare the custom properties in the scope they will actually be used.

    This way, we are avoiding multiple rules of the .foo class. We are also separating the logic (changing values) from the actual designs (CSS declarations). Adapting this approach in our example from above gives us the following CSS:

    .post { --post-vertical-padding: 0.5rem; --post-horizontal-padding: 1rem; --post-top-margin: 0.5rem; --post-bottom-margin: 1rem; --heading-font-size: 2rem; } @media (min-width: 576px) { .post { --post-vertical-padding: 1rem; --post-horizontal-padding: 2rem; --post-top-margin: 1rem; --post-bottom-margin: 2rem; --heading-font-size: 3rem; } } .post { padding: var(--post-vertical-padding) var(--post-horizontal-padding); margin: var(--post-top-margin) auto var(--post-bottom-margin); } .heading { font-size: var(--heading-font-size); }

    See the Pen
    #2 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Notice that the use of variables in shorthand properties (e.g. padding, margin or font) allow some very interesting repercussions. As custom properties may hold almost any value (more on this later), even an empty string, it’s unclear how the value of a shorthand property will be separated out into longhand properties that are used in the cascade later. For example, the auto used in the margin property above may turn out to be a top-and-bottom margin, a left-and-right margin, a top margin, a right margin, a bottom margin or a left margin — it all depends on the values of the custom properties around.

    It’s questionable whether the code looks cleaner than the one from the previous example, but on a larger scale, it’s definitely more maintainable. Let’s try to simplify this code a bit now.

    Notice that some values are repeated here. What if we try to merge duplicate variables together? Let’s consider the following alteration:

    :root { --small-spacing: 0.5rem; --large-spacing: 1rem; --large-font-size: 2rem; } @media (min-width: 576px) { :root { --small-spacing: 1rem; --large-spacing: 2rem; --large-font-size: 3rem; } } .post { padding: var(--small-spacing) var(--large-spacing); margin: var(--small-spacing) auto var(--large-spacing); } .heading { font-size: var(--large-font-size); }

    See the Pen
    #3 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    It looks cleaner but is it actually better? Not necessarily. For the sake of flexibility and readability, this may not be the right solution in every case. We definitely shouldn’t merge some variables just because they accidentally turned out to hold the same values. Sometimes, as long as we’re doing this as a part of a well thought out system, it may help us simplify things and preserve consistency across the project. However, in other cases, such a manner may quickly prove to be confusing and problematic. Now, let’s take a look at yet another way we can approach this code.

    Using CSS variables as multipliers

    CSS custom properties are a fairly new feature to the modern web. One of the other awesome features that rolled out in the last years is the calc() function. It lets us perform real math operations in live CSS. In terms of the browser support, it’s supported in all browsers that support CSS custom properties.

    calc() tends to play very nicely with CSS variables, making them even more powerful. This means we can both use calc() inside custom properties and custom properties inside calc()!

    For example, the following CSS is perfectly valid:

    :root { --size: 2; } .foo { --padding: calc(var(--size) * 1rem); /* 2 × 1rem = 2rem */ padding: calc(var(--padding) * 2); /* 2rem × 2 = 4rem */ }

    Why does this matter to us and our responsive designs? It means that we can use a calc() function to alter CSS custom properties inside media queries. Let’s say we have a padding that should have a value of 5px on mobile and 10px on desktop. Instead of declaring this property two times, we can assign a variable to it and multiply it by two on larger screens:

    :root { --padding: 1rem; --foo-padding: var(--padding); } @media (min-width: 576px) { :root { --foo-padding: calc(var(--padding) * 2); } } .foo { padding: var(--foo-padding); }

    Looks fine, however all the values (--padding, calc(--padding * 2)) are away from their declaration (padding). The syntax may also be pretty confusing with two different padding variables (--padding and --foo-padding) and an unclear relationship between them.

    To make things a bit clearer, let’s try to code it the other way around:

    :root { --multiplier: 1; } @media (min-width: 576px) { :root { --multiplier: 2; } } .foo { padding: calc(1rem * var(--multiplier)); }

    This way, we accomplished the same computed output with much cleaner code! So, instead of using a variable for an initial value of the property (1rem), a variable was used to store a multiplier (1 on small screens and 2 on larger screens). It also allows us to use the --multiplier variable in other declarations. Let’s apply this technique to paddings and margins in our previous snippet:

    :root { --multiplier: 1; } @media (min-width: 576px) { :root { --multiplier: 2; } } .post { padding: calc(.5rem * var(--multiplier)) calc(1rem * var(--multiplier)); margin: calc(.5rem * var(--multiplier)) auto calc(1rem * var(--multiplier)); }

    Now, let’s try to implement the same approach with typography. First, we’ll add another heading to our designs:

    <h1 class="heading-large">My Blog</h1> <article class="post"> <h2 class="heading-medium">Post's heading</h2> <p class="paragraph"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium numquam adipisci recusandae officiis dolore tenetur, nisi, beatae praesentium, soluta ullam suscipit quas? </p> </article>

    With multiple text styles in place, we can use a variable to control their sizes too:

    :root { --headings-multiplier: 1; } @media (min-width: 576px) { :root { --headings-multiplier: 3 / 2; } } .heading-medium { font-size: calc(2rem * var(--headings-multiplier)) } .heading-large { font-size: calc(3rem * var(--headings-multiplier)) }

    You may have noticed that 3 / 2 is not a valid CSS value at all. Why does it not cause an error then? The reason is that the syntax for CSS variables is extremely forgiving, which means almost anything can be assigned to a variable, even if it’s not a valid CSS value for any existing CSS property. Declared CSS custom properties are left almost entirely un-evaluated until they are computed by a user agent in certain declarations. So, once a variable is used in a value of some property, this value will turn valid or invalid at the computed-value time.

    Oh, and another note about that last note: in case you’re wondering, I used a value of 3 / 2 simply to make a point. In real life, it would make more sense to write 1.5 instead to make the code more readable.

    Now, let’s take a look at the finished live example combining everything that we discussed above:

    See the Pen
    #4 Building responsive features with CSS custom properties
    by Miko?aj (@mikolajdobrucki)
    on CodePen.

    Again, I would never advocate for combining calc() with custom properties to make the code more concise as a general rule. But I can definitely imagine scenarios in which it helps to keep code more organized and maintainable. This approach also allows the weight of CSS to be significantly reduced, when it’s used wisely.

    In terms of readability, we can consider it more readable once the underlying rule is understood. It helps to explain the logic and relations between values. On the other hand, some may see it as less readable, because it’s tough to instantly read what a property holds as a value without first doing the math. Also, using too many variables and calc() functions at once may unnecessarily obscure code and make it harder to understand, especially for juniors and front-end developers who are not focused on CSS.

    Conclusion

    Summing up, there’s a lot of ways to use CSS custom properties in responsive design, definitely not limited to the examples shown above. CSS variables can be used simply to separate the values from the designs. They can also be taken a step further and be combined with some math. None of the presented approaches is better nor worse than the others. The sensibility of using them depends on the case and context.

    Now that you know how CSS custom properties can be used in responsive design, I hope you will find a way to introduce them in your own workflow. Next up, we’re going to look at approaches for using them in reusable components and modules, so let's check that out.

    The post Responsive Designs and CSS Custom Properties: Defining Variables and Breakpoints appeared first on CSS-Tricks.

    Using CSS Grid the right way

    Css Tricks - Fri, 02/22/2019 - 12:59pm

    Violet Peña has shared her recommendations for using CSS Grid. They basically boil down to these high-level points:

    1. Use names instead of numbers for setting up our grid columns.
    2. fr should be our flexible unit of choice.
    3. We don’t really need a grid system anymore.

    Although this is all great advice and Violet provides a few examples to support her recommendations, I particularly like what she has to say about learning CSS Grid:

    “Learning” CSS Grid requires developing working knowledge of many new properties that don’t just describe one aspect of appearance or behavior, but feed into a completely new layout system. This system includes around 18 properties which use paradigms and syntax rarely (or never) seen anywhere else in the CSS spec.

    This means that CSS Grid has a pretty high skill floor — a developer needs to learn and internalize lots of new information in order to be effective with it. Once you’re above that skill floor, Grid is an amazing ally in layout creation. Below that skill floor, Grid is an encumbrance. You wonder why you’re bothering to use it at all, since it seems to require lots of additional work for little reward.

    In this post, I want to help you overcome that skill floor by showing you the most effective ways to leverage the Grid spec.

    Also this post reminded me that, although I’m not sure why, I tend to avoid naming my grid columns up. Like in this bit of code that Violet walks us through:

    .container { display: grid; grid-template-columns: [sidebar] 3fr [content] 4fr; }

    Now we can use the sidebar or content names when we define our grid-column like this:

    .content { grid-column: content; }

    I really like that! It seems super easy to read and if we wanted to change the size of our .content, class then it only requires going back to where the grid is defined in the first place. Anyway, I’ll be sure to name my grid columns from here on out.

    Direct Link to ArticlePermalink

    The post Using CSS Grid the right way appeared first on CSS-Tricks.

    Writing Animations That Bring Your Site to Life

    Css Tricks - Fri, 02/22/2019 - 7:36am

    Web animation is one of the factors that can strongly enhance your website’s look and feel. Sadly, unlike mobile apps, there aren’t as many websites using animation to their benefit as you would think. We don’t want to count yours among those, so this article is for you and anyone else looking for ways to use animation for a better user experience! Specifically, we’re going to learn how to make web interactions delightful using CSS animations.

    Here’s what we’re going to build together:

    Live Demo GitHub Repo

    Before we move ahead, it’s worth mentioning that I’m going to assume you have at least some familiarity with modern front-end frameworks and a basic understanding of CSS animations. If you don’t, then no fear! CSS-Tricks has a great guides on React and Vue, as well as a thorough almanac post on the CSS animation property.

    Good? OK, let’s talk about why we’d want to use animation in the first place and cover some baseline information about CSS animations.

    Why would we to animate anything?

    We could probably do an entire post on this topic alone. Oh, wait! Sarah Drasner already did that and her points are both poignant and compelling.

    But, to sum things up based on my own experiences:

    • Animations enhance the way users interact with an interface. For example, smart animations can reduce cognitive load by giving users better context between page transitions.
    • They can provide clear cues to users, like where we want them to focus attention.
    • Animations serve as another design pattern in and of themselves, helping users to get emotionally attached to and engage with the interface.
    • Another benefit of using animations is that they can create a perception that a site or app loads faster than it actually does.
    A couple of house rules with animations

    Have you ever bumped into a site that animates all the things? Wow, those can be jarring. So, here’s a couple of things to avoid when working with animations so our app doesn’t fall into the same boat:

    • Avoid animating CSS properties other than transform and opacity. If other properties have to be animated, like width or height, then make sure there aren’t a lot of layout changes happening at the same time. There’s actually a cost to animations and you can see exactly how much by referring to CSS Triggers.
    • Also, just because animations can create perceived performance gains, there’s actually a point of diminishing return when it comes to using them. Animating too many elements at the same time may result in decreased performance.

    Now we can get our hands dirty with some code!

    Let’s build a music app

    We’re going to build the music app we looked at earlier, which is inspired by Aurélien Salomon’s Dribbble shot. I chose this example so that we can focus on animations, not only within a component, but also between different routes. We’ll build this app using Vue and create animations using vanilla (i.e. no framework) CSS.

    Animations should go hand-in-hand with UI development. Creating UI before defining their movement is likely to cost much more time. In this case, the Dribbble shot provides that scope for us.

    Let’s start with the development.

    Step 1: Spin up the app locally

    First things first. We need to set up a new Vue project. Again, we’re assuming some base-level understanding of Vue here, so please check out the Learning Vue guide for more info on setting up.

    We need a couple of dependencies for our work, notably vue-router for transitioning between views and sass-loader so we can write in Sass and compile to CSS. Here’s a detailed tutorial on using routes and Sass can be installed by pointing the command line at the project directory and using npm install -D sass-loader node-sass.

    We have what we need!

    Step 2: Setting up routes

    For creating routes, we’re first going to create two bare minimum components — Artists.vue and Tracks.vue. We’ll drop a new file in the src folder called router.js and add routes for these components as:

    import Vue from 'vue' import Router from 'vue-router' import Artists from './components/Artists.vue' import Tracks from './components/Tracks.vue' Vue.use(Router) export default new Router({ mode: 'history', routes: [ { path: '/', name: 'artists', component: Artists }, { path: '/:id', name: 'tracks', component: Tracks } ] })

    Import router.js into the main.js and inject it to the Vue instance. Lastly, replace the content of your App.vue by <router-view/>.

    Step 3: Create the components and content for the music app

    We need two components that we’ll transition between with animation. Those are going to be:

    1. Artists.vue: a grid of artists
    2. Tracks.vue: An artist image with a back button

    If you wanna jump ahead a bit, here are some assets to work with:

    1. Images and sample data in JSON format.
    2. Content for the components

    When all is said and done, the two views will come out to something like this:

    Artists.vue (left) and Tracks.vue (right) Step 4: Animate!

    Here we are, the part we’ve really wanted to get to all this time. The most important animation in the app is transitioning from Artists to Tracks when clicking on an artist. It should feel seamless where clicking on an artist image puts that image in focus while transitioning from one view into the next. This is exactly the type of animation that we rarely see in apps but can drastically reduce cognitive load for users.

    To make sure we’re all on the same page, we’re going to refer to the first image in the sequence as the “previous” image and the second one as the "current" image. Getting the effect down is relatively easy as long as we know the dimensions and position of the previous image in the transition. We can animate the current image by transforming it as per previous image.

    The formula that I’m using is transform: translate(x, y) scale(n), where n is equal to the size of previous image divided by the size of current image. Note that we can use a static value of n since the dimensions are fixed for all the images. For example, the image size in the Artists view is 190x190 and 240x240 in the Tracks view. Thus, we can replace n by 190/240 = 0.791. That means the transform value becomes translate(x, y) scale(0.791) in our equation.

    Animating from Artists to Tracks

    Next thing is to find x and y. We can get these values though click event in the Artists view as:

    const {x, y} = event.target.getBoundingClientRect()

    ...and then send these values to the Tracks view, all while switching the route. Since we aren’t using any state management library, the two components will communicate via their parent component, which is the top level component, App.vue. In App.vue, let’s create a method that switches the route and sends the image info as params.

    gotoTracks(position, artistId) { this.$router.push({ name: 'tracks', params: { id: artistId, position: position } }) }

    Here’s the relevant code from the repo to reference, in case you’re interested.

    Since we have received the position and ID of the image in Tracks, we have all the required data to show and animate it. We’ll first fetch artist information (specifically the name and image URL) using artist ID.

    To animate the image, we need to calculate the transform value from the image’s starting position. To set the transform value, I’m using CSS custom properties, which can be done with CSS-in-JS techniques as well. Note that the image’s position that we received through props will be relative to window. Therefore we’ll have to subtract some fixed offset caused by the padding of the container <div> to even out our math.

    const { x, y } = this.$route.params.position // padding-left const offsetLeft = 100 // padding-top const offsetTop = 30 // Set CSS custom property value document.documentElement.style.setProperty( '--translate', `translate(${x - offsetLeft}px, ${y - offsetTop}px) scale(0.792)` )

    We’ll use this value to create a keyframe animation to move the image:

    @keyframes move-image { from { transform: var(--translate); } }

    This gets assigned to the CSS animation:

    .image { animation: move-image 0.6s; }

    ...and it will animate the image from this transform value to its original position on component load.

    Transitioning from Artists to Tracks

    We can use the same technique when going the opposite direction, Tracks to Artists. As we already have the clicked image’s position stored in the parent component, we can pass it to props for Artists as well.

    Transitioning from Tracks to Artists Step 5: Show the tracks!

    It’s great that we can now move between our two views seamlessly, but the Tracks view is pretty sparse at the moment. So let’s add the track list for the selected artist.

    We’ll create an empty white box and a new keyframe to slide it upwards on page load. Then we’ll add three subsections to it: Recent Tracks, Popular Tracks, and Playlist. Again, if you want to jump ahead, feel free to either reference or copy the final code from the repo.

    The Tracks view with content

    Recent Tracks is the row of thumbnails just below the artist image where each thumbnail includes the track name and track length below it. Since we’re covering animations here, we’ll create a scale-up animation, where the image starts invisible (opacity: 0) and a little smaller than it’s natural size (scale(0.7)), then is revealed (opacity: 1 )and scales up to its natural size (transform: none).

    .track { opacity: 0; transform: scale(0.7); animation: scale-up 1s ease forwards; } @keyframes scale-up { to { opacity: 1; transform: none; } }

    The Popular Tracks list and Playlist sit side-by-side below the Recent Tracks, where Popular tracks takes up most of the space. We can slide them up a bit on initial view with another set of keyframes:

    .track { ... animation: slide-up 1.5s; } @keyframes slide-up { from { transform: translateY(140px); } }

    To make the animation feel more natural, we’ll create a stagger effect by adding an incremental animation delay to each item.

    @for $i from 1 to 5 { &:nth-child(#{$i + 1}) { animation-delay: #{$i * 0.05}s; } }

    The code above is basically looking for each child element, then adding a 0.05 second delay to each element it finds. So, for example, the first child gets a 0.05 second delay, the second child gets a 0.10 second delay and so on.

    Check out how nice and natural this all looks:

    Bonus: micro-interactions!

    One of the fun things about working with animations is thinking through the small details because they’re what tie things together and add delight to the user experience. We call these micro-interactions and they serve a good purpose by providing visual feedback when an action is performed.

    Depending on the complexity of the animations, we might need a library like anime.js or GSAP. This example is pretty straightforward, so we can accomplish everything we need by writing some CSS.

    First micro-interaction: The volume icon

    Let’s first get a volume icon in SVG format (Noun Project and Material Design are good sources). On click, we’ll animate-in and out its path element to show the level of volume. For this, we’ll create a method which switches its CSS class according to the volume level.

    <svg @click="changeVolume"> <g :class="`level-${volumeLevel}`"> <path d="..."/> <!-- volume level 1 --> <path d="..."/> <!-- volume level 2 --> <path d="..."/> <!-- volume level 3 --> <polygon points="..."/> </g> </svg>

    Based on this class, we can show and hide certain path elements as:

    path { opacity: 0; transform-origin: left; transform: translateX(-5px) scale(0.6); transition: transform 0.25s, opacity 0.2s; } .level-1 path:first-child, .level-2 path:first-child, .level-2 path:nth-child(2), .level-3 path { opacity: 1; transform: none; } The animated volume control Second micro-interaction: The favorite icon

    Do you like it when you click on Twitter’s heart button? That’s because it feels unique and special by the way it animates on click. We’ll make something similar but real quick. For this, we first get an SVG heart icon and add it to the the markup. Then we’ll add a bouncy animation to it that’s triggered on click.

    @keyframes bounce { 0%, 100% { transform: none; } 30% { transform: scale(1.3); } 60% { transform: scale(0.9); } }

    Another fun thing we can do is add other small heart icons around it with random sizes and positions. Ideally, we’d add a few absolute-positioned HTML elements that a heart as the background. Let’s Arrange each of them as below by setting their left and bottom values.

    We’ll also include a fade away effect so the icons appear to dissolve as they move upward by adding a keyframe animation on the same click event.

    @keyframes float-upwards { 0%, 100% { opacity: 0; } 50% { opacity: 0.7; } 50%, 100% { transform: translate(-1px, -5px); } } The animated favorite button Summing up

    That’s all! I hope you find all this motivating to try animations on your own websites and projects.

    While writing this, I also wanted to expand on the fundamental animation principles we glossed over earlier because I believe that they help choose animation durations, and avoid non-meaningful animations. That’s important to discuss because doing animations correctly is better than doing them at all. But this sounds like a whole another topic to be covered in a future article.

    The post Writing Animations That Bring Your Site to Life appeared first on CSS-Tricks.

    Blobs!

    Css Tricks - Thu, 02/21/2019 - 12:01pm

    I was recently a guest editor for an issue of Bizarro Devs. It's a great newsletter! Go sign up! I put in a bunch of links around blobs. Like those weird squishy random shapes that are so "in" right now. Here are those links as well. I'm always a fan of publishing stuff I write ;)

    Blobs! Blobs are in! Blobs are — ahem — a bit bizarre. I'll bask in a design like this annual report cover by Matt Pamer all day. I enjoy watching a design trend like this manifest itself in design tooling and become applied in lots of creative and crafty different ways.

    We could start with <svg> and draw our own blob using the Pen tool that is pretty much stock in every vector design application. I'm a cheater though, and would probably wind up checking The Noun Project for some blob examples and steal the SVG from there. But sadly, there isn't much there, at least as far as blobs go.

    Thank god for... (wait for it)... THE BLOBMAKER:

    Once we have a blob, it's just begging to be moved around. Monica Dinculescu shows how to do just that with pure CSS and liberal use of various CSS transforms in a keyframe animation:

    See the Pen
    CSS only morphing blob
    by Monica Dinculescu (@notwaldorf)
    on CodePen.

    Or we can use a JavaScript library like KUTE.js to get all morph-y, like Heartbeat has done here:

    See the Pen
    Morphing shapes with KUTE.js
    by Heartbeat.UA (@hbagency)
    on CodePen.

    A library like Greensock could help moving and morphing the blobs around. Greensock even has a plugin that is probably the most powerful morphing tool out there. This Pen uses Greensock, but adds some native SVG filters so that the blobs squish into each other satisfyingly. We could call it the gooey effect:

    See the Pen
    SVG blob mask
    by ATCOM (@Atcom)
    on CodePen.

    We've only looked at SVG so far, but don't rule out <canvas>! Liam Egan has make this canvas-based blob downright jiggly:

    See the Pen
    Blob
    by Liam Egan (@shubniggurath)
    on CodePen.

    Why not add a little physics to the party, like gravity, and let them blobs get squishy that way! Hakim El Hattab got it done here:

    See the Pen
    Blob
    by Hakim El Hattab (@hakimel)
    on CodePen.

    And blobs don't have to be alone! Blobs that are squished together are like fluid. You might get a kick out of Peeke Kuepers article Simulating blobs of fluid.

    The post Blobs! appeared first on CSS-Tricks.

    Deliver your best work with the help of monday.com

    Css Tricks - Thu, 02/21/2019 - 11:58am

    (This is a sponsored post.)

    Here's the situation: You've bashed out a complicated design over two weeks of near full-time effort, gotten everything down to the exact spec of the design file, turn it in for stakeholder review and... you're way off scope. Turns out a few folks on the team put their heads together, made some changes, and never sent you an updated comp.

    Boo!

    The unfortunate truth is that this happens all too often in front-end development, but it's really no one person's fault because it boils down to simple collective miscommunication and a lack of transparency on the team.

    Well, that's where a project management platform like monday.com comes into play. Even if you're on a remote team or sitting in an office with cubicle walls up to the ceiling, monday.com bridges gaps and tears down walls that could throw a project off-track. With powerful and intuitive tools, like instant messaging for those ad hoc meetings, file storage for a centralized repository of assets, and an activity dashboard for catching up on the status of a project at a glance, monday.com brings project out into the light so everyone is in the loop and on the same page.

    Seriously, you'll wonder what you ever did without monday.com in your life once you've used it. It does everything any other project management tool can do — from task lists and milestones to budgets and human resources — but does one important thing that separates it from the rest: the personal touch that makes everyone on the team feel valuable, included and heard. That's tough to beat and unique to the project management landscape.

    Like most things, seeing is believing, so give monday.com a try today. The first 14 days are on the house and will give you a feel for what makes it so great.

    Try it Free

    Direct Link to ArticlePermalink

    The post Deliver your best work with the help of monday.com appeared first on CSS-Tricks.

    CSS Variables + calc() + rgb() = Enforcing High Contrast Colors

    Css Tricks - Thu, 02/21/2019 - 6:26am

    As you may know, the recent updates and additions to CSS are extremely powerful. From Flexbox to Grid, and — what we’re concerned about here — Custom Properties (aka CSS variables), all of which make robust and dynamic layouts and interfaces easier than ever while opening up many other possibilities we used to only dream of.

    The other day, I was thinking that there must be a way to use Custom Properties to color an element's background while maintaining a contrast with the foreground color that is high enough (using either white or black) to pass WCAG AA accessibility standards.

    It’s astonishingly efficient to do this in JavaScript with a few lines of code:

    var rgb = [255, 0, 0]; function setForegroundColor() { var sum = Math.round(((parseInt(rgb[0]) * 299) + (parseInt(rgb[1]) * 587) + (parseInt(rgb[2]) * 114)) / 1000); return (sum > 128) ? 'black' : 'white'; }

    This takes the red, green and blue (RGB) values of an element’s background color, multiplies them by some special numbers (299, 587, and 144, respectively), adds them together, then divides the total by 1,000. When that sum is greater than 128, it will return black; otherwise, we’ll get white. Not too bad.

    The only problem is, when it comes to recreating this in CSS, we don't have access to a native if statement to evaluate the sum. So,how can we replicate this in CSS without one?

    Luckily, like HTML, CSS can be very forgiving. If we pass a value greater than 255 into the RGB function, it will get capped at 255. Same goes for numbers lower than 0. Even negative integers will get capped at 0. So, instead of testing whether our sum is greater or less than 128, we subtract 128 from our sum, giving us either a positive or negative integer. Then, if we multiply it by a large negative value (e.g. -1,000), we end up with either very large positive or negative values that we can then pass into the RGB function. Like I said earlier, this will get capped to the browser’s desired values.

    Here is an example using CSS variables:

    :root { --red: 28; --green: 150; --blue: 130; --accessible-color: calc( ( ( (var(--red) * 299) + (var(--green) * 587) + (var(--blue) * 114) / 1000 ) - 128 ) * -1000 ); } .button { color: rgb( var(--accessible-color), var(--accessible-color), var(--accessible-color) ); background-color: rgb( var(--red), var(--green), var(--blue) ); }

    If my math is correct (and it's very possible that it's not) we get a total of 16,758, which is much greater than 255. Pass this total into the rgb() function for all three values, and the browser will set the text color to white.

    At this point, everything seems to be working in both Chrome and Firefox, but Safari is a little cranky and gives a different result. At first, I thought this might be because Safari was not capping the large values I was providing in the function, but after some testing, I found that Safari didn't like the division in my calculation for some reason.

    Taking a closer look at the calc() function, I noticed that I could remove the division of 1,000 by increasing the value of 128 to 128,000. Here’s how that looks so far:

    :root { --red: 28; --green: 150; --blue: 130; --accessible-color: calc( ( ( (var(--red) * 299) + (var(--green) * 587) + (var(--blue) * 114) ) - 128000 /* HIGHLIGHT */ ) * -1000 ); } .button { color: rgb( var(--accessible-color), var(--accessible-color), var(--accessible-color) ); background-color: rgb( var(--red), var(--green), var(--blue) ); }

    Throw in a few range sliders to adjust the color values, and there you have it: a dynamic UI element that can swap text color based on its background-color while maintaining a passing grade with WCAG AA.

    See the Pen
    CSS Only Accessible Button
    by Josh Bader (@joshbader)
    on CodePen.

    Putting this concept to practical use

    Below is a Pen showing how this technique can be used to theme a user interface. I have duplicated and moved the --accessible-color variable into the specific CSS rules that require it, and to help ensure backgrounds remain accessible based on their foregrounds, I have multiplied the --accessible-color variable by -1 in several places. The colors can be changed by using the controls located at the bottom-right. Click the cog/gear icon to access them.

    See the Pen
    CSS Variable Accessible UI
    by Josh Bader (@joshbader)
    on CodePen.

    There are other ways to do this

    A little while back, Facundo Corradini explained how to do something very similar in this post. He uses a slightly different calculation in combination with the hsl function. He also goes into detail about some of the issues he was having while coming up with the concept:

    Some hues get really problematic (particularly yellows and cyans), as they are displayed way brighter than others (e.g. reds and blues) despite having the same lightness value. In consequence, some colors are treated as dark and given white text despite being extremely bright.

    What in the name of CSS is going on?

    He goes on to mention that Edge wasn’t capping his large numbers, and during my testing, I noticed that sometimes it was working and other times it was not. If anyone can pinpoint why this might be, feel free to share in the comments.

    Further, Ana Tudor explains how using filter + mix-blend-mode can help contrast text against more complex backgrounds. And, when I say complex, I mean complex. She even goes so far as to demonstrate how text color can change as pieces of the background color change — pretty awesome!

    Also, Robin Rendle explains how to use mix-blend-mode along with pseudo elements to automatically reverse text colors based on their background-color.

    So, count this as yet another approach to throw into the mix. It’s incredibly awesome that Custom Properties open up these sorts of possibilities for us while allowing us to solve the same problem in a variety of ways.

    The post CSS Variables + calc() + rgb() = Enforcing High Contrast Colors appeared first on CSS-Tricks.

    Colorful Typographic Experiments

    Css Tricks - Wed, 02/20/2019 - 1:05pm

    There have been some interesting, boundary-pushing typography-related experiments lately. I was trying to think of a joke like "somethings in the descenders" but I just can't find something that will stand on its own leg without being easy to counter.

    Codrin Pavel created a fascinating multi-color typeface called CSSans.

    It's not a "font", because a font is a file, like "lato.woff2" or whatever. This is a CSS file, and you write in it like this:

    <div class="cssans cssans--center"> <div class="cssans__accessible">Cool News</div> <div class="cssans__word"> <b class="cssans:C"></b> <b class="cssans:o"></b> <b class="cssans:o"></b> <b class="cssans:l"></b> </div> <div class="cssans__word"> <b class="cssans:N"></b> <b class="cssans:e"></b> <b class="cssans:w"></b> <b class="cssans:s"></b> </div> </div>

    Note the special <div> at the top with the full word in it, while those empty <b> elements do the actual drawing of the glyphs. I wouldn't call it entirely accessible, as I'd argue part of accessibility is stuff like find-on-page with highlighting and selectable text. But this is obviously an artistic experiment and your implementation could go any number of ways. I'd love to see an attempt at setting transparent SVG <text> over the top of it that is sized the same so that the text is selectable.

    Looks like the landing page was built in CodePen Projects!

    This technique and its relationship with accessibility is pretty interesting and actually more relevant than you might think. In fact, it looks like Facebook uses a similar span technique to fight ad-blocking.

    Harbor Type recently put out Rocher Color, a free color font. Yes, color font. That's a thing. And Rocher Color is actually a color font and a variable font.

    Support seems kinda decent to me, but it's complicated because there are a bunch of different kinds all with different support across browsers.

    The other story is that they are, well, kinda humongous, size-wise. The woff2 file is probably the most relevant here as it's such a modern feature anyway. The download from the site (RocherColorGX.woff2) clocks in at 178KB. Not something you'd just toss on a page for a single headline probably, considering it's not just weight with fonts — but you're also always fighting the FOUT/FOIT battle.

    I think to justify using a beefy color font like this you'd...

    1. Use it quite a bit around the site for dynamic headlines
    2. Customize the colors to be perfect for you (ahead of time)
    3. Make use of the fancy variable font features like the bevel and shadow adjustments (on the fly)

    If you don't see yourself doing those things, you might be better off using <svg> with these shapes all expanded out to paths. You could still use this font to make the SVG, assuming your design tool supports this kind of font. You won't get text wrapping or anything, but the file size and loading speed will be much faster. Or you could even use a graphic format like PNG/WebP, and there's no terrible shame in that if you still use a semantic element for the headline (visually hidden, of course). You won't get find-on-page highlighting or select-ability, but might be an OK trade-off for a one-off.

    Kenneth Ormandy has rounded up some more interesting typographic experiments in CSS. In his post, he mentions Diana Smith's Pure CSS Font, which builds itself from empty elements and all kinds of fancy CSS trickery to draw the shapes.

    The point of this project is right in the header:

    For private, SEO-hidden, CAPTCHA-friendly unselectable text. Deter plagiarism and spambots!

    Hidden for assistive technology too, so careful there, but it seems to me this project is more about exploring possibilities. After all, it's the letters that power Diana's remarkable CSS paintings like Zigaro.

    Don't miss Kenneth's post, as he links to lots more fascinating examples of people being typographers with very unconventional tools. Kenneth takes a crack himself with this fascinating little experiment, using a button there to expose the tricks within:

    See the Pen
    START Pure CSS Lettering test 1
    by Kenneth Ormandy (@kennethormandy)
    on CodePen.

    The post Colorful Typographic Experiments appeared first on CSS-Tricks.

    <span>L</span><span>e</span><span>t</span><span>t</span><span>e</span><span>r</span><span>s</span>

    Css Tricks - Wed, 02/20/2019 - 11:05am

    Did you see this Facebook crap?

    "Why do I need a 4Ghz quadcore to run facebook?" This is why. A single word split up into 11 HTML DOM elements to avoid adblockers. pic.twitter.com/Zv4RfInrL0

    — Mike Pan (@themikepan) February 6, 2019

    I popped over to Facebook to verify that and what I saw was a different and even more nested mess:

    They are trying to fight your ad blocker browser extension. Of course they are. I'm sure at their scale not doing this means losing millions of dollars. But I wonder if it's really losing money when you factor in losing trust, and potentially losing people on the platform entirely.

    It just feels so rude, doesn't it? Like a user specifically installs technology onto their computer in order to exert some control over what they allow onto their computers and into their eyeballs. And they are saying, "No, we do not respect that choice. We are going to fight your technology with our technology and force feed this stuff onto your computer and your eyeballs." Doesn't sit right.

    I'm not unaware that ad blockers have ad adverse effect on the ability for websites to make money. That's quite literally how I make money. But I don't want to do it fighting and at the expense of breaking trust. I want to do it gracefully while building trust.

    Anyway.

    I wonder what writing HTML to help ad blockers would look like instead:

    <!-- start: advertisement --> <div class="ad sponsor paid" id="ad-1" data-ad="true"> <div>Sponsor:</div> <a href="https://sponsor.com" rel="nofollow">Company</span> </div> <!-- end: advertisement -->

    The good ones have been doing it for ages.

    This span-based lettering stuff makes me think of libraries like Splitting.js and Lettering.js that break up text into individual <span>s for styling reasons.

    Turns out that doesn't affect on-page search (i.e. if you search for "dog," you'll find <span>d</span><span>o</span><span>g</span>), but it does affect some screen readers in that they will treat each letter distinctly, which can result in pretty awful audio output, like pauses between letters where you wouldn't expect or want them.

    It's totally solvable though!

    I just read about how powerful aria-label is via Web Platform News, quoting Amelia Bellamy-Royds:

    An aria-label attribute on a button or link effectively replaces the text content of that element with the new label.

    It was cool to see that's what Lettering.js does by default! And Splitting.js is figuring out the best method for them, which involves aria-label.

    Oh, and as ever, ::nth-letter() would be cool. 2018 recap of a 2011 request.

    The post <span>L</span><span>e</span><span>t</span><span>t</span><span>e</span><span>r</span><span>s</span> appeared first on CSS-Tricks.

    Diana Smith’s Top 5 CSS Properties She Uses to Produce CSS Art

    Css Tricks - Wed, 02/20/2019 - 11:04am

    Have you seen Diana Smith's CSS drawings? Stunning. These far transcend the CSS drawings that sort of crudely replicate a flat SVG scene, like I might attempt. We were lucky enough for her to post some of her CSS drawing techniques here last year.

    Well, Diana has also listed the top five CSS properties she uses to get these masterpieces done, and they are surprising in their plainness:

    1. border-radius
    2. box-shadow
    3. transform
    4. gradients
    5. overflow

    ...but of course, layered in trickery!

    ... for custom rounded elements that are meant to mimic organic objects like faces, it is imperative that you become intimately familiar with all eight available parameters in the border-radius property.

    Diana shows her famous Francine drawing with each of the most used properties turned off:

    Without border-radius Without transform

    Be sure to check out this VICE interview she did as well. She covers gems like the fact that Francine was inspired by American Dad (lol) and that the cross-browser fallbacks are both a fascinating and interesting mess.

    Direct Link to ArticlePermalink

    The post Diana Smith’s Top 5 CSS Properties She Uses to Produce CSS Art appeared first on CSS-Tricks.

    Social Cards as a Service

    Css Tricks - Tue, 02/19/2019 - 5:19am

    I love the idea of programmatically generated images. That power is close at hand these days for us front-end developers, thanks to the concept of headless browsers. Take Puppeteer, the library for controlling headless Chrome. Generating images from URLs is their default use case:

    const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); await page.screenshot({path: 'example.png'}); await browser.close(); })();

    That ought to get the ol' mind grape going. What if we had URLs on our site that — with the power of our HTML and CSS skills — created perfect little designs for sharing using dynamic data... then turned them into images and used them for our meta tags?

    The first I saw of this idea was Drew McLellan's Dynamic Social Sharing Images. Drew wrote a script to fire up Puppeteer and get the job done.

    Since the design part is entirely an HTML/CSS adventure, I'm sure you could imagine a setup where the URL passed in parameters that did things like set copy and typography, colors, sizes, etc. Zeit built exactly that!

    The URL is like this:

    https://og-image.now.sh/I%20am%20Chris%20and%20I%20am%20**cool**%20la%20tee%20ding%20dong%20da..png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.zeit.co%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fhyper-color-logo.svg

    Kind of amazing that you can spin up an entire browser in a cloud function! Netlify also offers cloud functions, and when I mentioned this to Phil Hawksworth, he told me he was already doing this for his blog!

    So on a blog post like this one, an image like this is automatically generated:

    Which is inserted as meta:

    <meta property="og:image" content="https://www.hawksworx.com/card-image/-blog-find-that-at-card.png">

    I dug through Phil's repos, naturally, and found his little machine for doing it.

    I'm madly envious of all this and need to get one set up for myself.

    The post Social Cards as a Service appeared first on CSS-Tricks.

    Don’t Get Clever with Login Forms

    Css Tricks - Tue, 02/19/2019 - 5:18am

    Brad points out some UX problems with a variety of apps that are doing things a little outside of the norm when it comes to their login forms. There is already a bunch of things to get right with forms to begin with (e.g. use the right input types, label your inputs, don't have whack password requirements, use SSL, etc.)... OMG why complicate it even more?!

    A "password manager test" should be a development best practice here. Does it work cleanly with the built-in browser password manager? How about 1Password and LastPass? No? Give it some love, please and thank you.

    Direct Link to ArticlePermalink

    The post Don’t Get Clever with Login Forms appeared first on CSS-Tricks.

    How @supports Works

    Css Tricks - Mon, 02/18/2019 - 7:39am

    CSS has a neat feature that allows us to test if the browser supports a particular property or property:value combination before applying a block of styles — like how a @media query matches when, say, the width of the browser window is narrower than some specified size and then the CSS within it takes effect. In the same spirit, the CSS inside this feature will take effect when the property:value pair being tested is supported in the current browser. That feature is called @supports and it looks like this:

    @supports (display: grid) { .main { display: grid; } }

    Why? Well, that's a bit tricky. Personally, I find don't need it all that regularly. CSS has natural fallback mechanisms such that if the browser doesn't understand a property:value combination, then it will ignore it and use something declared before it if there is anything, thanks to the cascade. Sometimes that can be used to deal with fallbacks and the end result is a bit less verbose. I'm certainly not a it's-gotta-be-the-same-in-every-browser kinda guy, but I'm also not a write-elaborate-fallbacks-to-get-close kinda guy either. I generally prefer a situation where a natural failure of a property:value doesn't do anything drastic to destroy functionality.

    That said, @supports certainly has use cases! And as I found out while putting this post together, plenty of people use it for plenty of interesting situations.

    A classic use case

    The example I used in the intro is a classic one that you'll see used in lots of writing about this topic. Here it is a bit more fleshed out:

    /* We're gonna write a fallback up here in a minute */ @supports (display: grid) { .photo-layout { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-gap: 2rem; } }

    Nice grid! Repeating and auto-filling columns is a sweet feature of CSS grid. But, of course, there are browsers that don't support grid, or don't support all the specific features of it that I'm using above there.

    For example, iOS shipped support for CSS grid in version 10.2, but iOS has had flexbox support since version 7. That's a decent gap of people with older iOS devices that do support flexbox but not grid. I'm sure there are more example gaps like that, but you probably get the idea.

    I was running on an older version of mobile safari and many many many many many sites were flat out broken that used grid

    I’m waiting another year or so before messing about with it

    — David Wells (@DavidWells) February 6, 2019

    It may be acceptable to let the fallback for this be nothing, depending on the requirements. For example, vertically stacked block-level elements rather than a multi-column grid layout. That's often fine with me. But let's say it's not fine, like a photo gallery or something that absolutely needs to have some basic grid-like structure. In that case, starting with flexbox as the default and using @supports to apply grid features where they're supported may work better...

    .photo-layout { display: flex; flex-wrap: wrap; > div { flex: 200px; margin: 1rem; } } @supports (display: grid) { .photo-layout { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-gap: 2rem; > div { margin: 0; } } }

    The "fallback" is the code outside of the @supports block (the properties above the block in the example above), and the grid code is either inside or after. The @supports block doesn't change any specificity, so we need the source order to help make sure the overrides work.

    Notice I had to reset the margin on the divs inside the @supports block. That's the kind of thing I find a bit annoying. There is just enough crossover between the two scenarios that it requires being super aware of how they impact each other.

    Doesn't that make you wish it could be entirely logically separated...

    There is "not" logic in @supports blocks, but that doesn't mean it should always be used

    Jen Simmons put this example in an article called Using Feature Queries in CSS a few years ago:

    /* Considered a BAD PRACTICE, at least if you're supporting IE 11 and iOS 8 and older */ @supports not (display: grid) { /* Isolated code for non-support of grid */ } @supports (display: grid) { /* Isolated code for support of grid */ }

    Notice the not operator in the first block. That's checking for browsers that do not support grid in order to apply certain styles to those browsers. The reason this approach is considered bad practice is that the browser support for @supports itself has to be considered!. That's what makes this so dang tricky.

    It's very appealing to write code in logically separated @supports blocks like that because then it's starting from scratch each time and doesn't need to be overriding previous values and dealing with those logical mind-benders. But let's go back to the same iOS situation we considered before... @supports shipped in iOS in version 9 (right between when flexbox shipped in iOS 7 and grid shipped in iOS 10.2). That means any flexbox fallback code in a @supports block using the not operator to check for (display: grid) {} support wouldn't work in either iOS 7 or 8, meaning the fallback now needs a fallback from working in browsers it otherwise would have. Phew!

    The big reason to reach for @supports is to account for very different implementations of something depending on feature support where it becomes easier to reason and distinguish between those implementations if the blocks of code are separated.

    We'll probably get to a point where we can use mutually-exclusive blocks like that without worry. Speaking of which...

    @supports is likely to be more useful over time.

    Once @supports is supported in all browsers you need to support, then it's good to start using it more aggressively and without having to factor in the complication of considering whether @supports itself is supported. Here's the support grid on that:

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

    DesktopChromeOperaFirefoxIEEdgeSafari2812.122No129Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox9.0-9.246all4.47164

    Basically, IE 11 and any iOS device stuck on iOS 8 are the pain points. If your requirements are already past those, then you're good to use @supports more freely.

    The irony is that there hasn't been a ton of CSS features shipping that have big clear @supports use cases — but there are some! Apparently, it's possible to test new fancy stuff like Houdini:

    Using it on my wedding website to check for Houdini support &#x1f3a9;&#x1f430;

    — Sam Richard (@Snugug) February 6, 2019

    (I'm not sure entirely what you'd put in the @supports block to do that. Has anyone else done this?)

    When @supports isn't doing anything useful

    I've seen a good amount of @supports uses in the wild where the end result is exactly as it would be without using it. For example...

    @supports (transform: rotate(5deg)) { .avatar { transform: rotate(5deg); } }

    On some level, that makes perfect logical sense. If transforms are supported, use them. But it's unnecessary if nothing different is happening in a non-support scenario. In this case, the transform can fail without the @supports block and the result is the same.

    Here's another example of that shaking out.

    There are browser extensions for playing with @supports

    There are two of them!

    They are both centered around the idea that we can write @supports blocks in CSS and then toggle them on and off as if we're looking at a rendering of the code in a browser that does or doesn't support that feature.

    Here's a video of Keith's tool applied to the scenario using grid with a flexbox fallback:

    This is fun to play with and is very neat tech. But in this exact scenario, if I was able to pull off the layout identically with flexbox, then I'd probably just do that and save that little bit of technical debt.

    Ire's tool, which she wrote about in the article Creating The Feature Queries Manager DevTools Extension, has a slightly different approach in that it shows the feature queries that you actually wrote in your CSS and provides toggles to flip them on and off. I don't think it works through iframes though, so I popped open Debug Mode to use it on CodePen.

    More real world use cases for @supports

    Here's one from Erik Vorhes. He's styling some custom checkboxes and radio buttons here, but wraps all of it in a @supports block. None of the styling gets applied unless the block passes the support check.

    @supports (transform: rotate(1turn)) and (opacity: 0) { /* all the styling for Erik's custom checkboxes and radio buttons */ }

    Here are several more I've come across:

    • Joe Wright and Tiago Nunes mentioned using it for position: sticky;. I'd love to see a demo here! As in, where you go for position: sticky;, but then have to do something different besides let it fail for a non-supporting browser.
    • Keith Grant and Matthias Ott mention using it for object-fit: contain;. Matthias has a demo where positioning trickery is used to make an image sort of fill a container, which is then made easier and better through that property when it's available.
    • Ryan Filler mentions using it for mix-blend-mode. His example sets more opacity on an element, but if mix-blend-mode is supported, it uses a bit less and that property which can have the effect of seeing through an element on its own.
    • .thing { opacity: 0.5; } @supports (mix-blend-mode: multiply) { .thing { mix-blend-mode: multiply; opacity: 0.75; } }
    • Rik Schennink mentioned the backdrop-filter property. He says, "when it's supported the opacity of the background color often needs some fine tuning."
    • Nour Saud mentioned it can be used to detect Edge through a specific vendor-prefixed property: @supports (-ms-ime-align:auto) { }.
    • Amber Weinberg mentioned using it for clip-path because adjusting the sizing or padding of an element will accommodate when clipping is unavailable.
    • Ralph Holzmann mentioned using it to test for that "notch" stuff (environment variables).
    • Stacy Kvernmo mentioned using it for the variety of properties needed for drop capping characters. Jen Simmons mentions this use case in her article as well. There is an initial-letter CSS property that's pretty fantastic for drop caps, but is used in conjunction with other properties that you may not want to apply at all if initial-letter isn't supported (or if there's a totally different fallback scenario).

    Here's a bonus one from Nick Colley that's not @supports, but @media instead! The spirit is the same. It can prevent that "stuck" hover state on touch devices like this:

    @media (hover: hover) { a:hover { background: yellow; } } Logic in @supports

    Basic:

    @supports (initial-letter: 4) { }

    Not:

    @supports not (initial-letter: 4) { }

    And:

    @supports (initial-letter: 4) and (transform: scale(2)) { }

    Or:

    @supports (initial-letter: 4) or (-webkit-initial-letter: 4) { }

    Combos:

    @supports ((display: -webkit-flex) or (display: -moz-flex) or (display: flex)) and (-webkit-appearance: caret) { } JavaScript Variant

    JavaScript has an API for this. To test if it exists...

    if (window.CSS && window.CSS.supports) { // Apparently old Opera had a weird implementation, so you could also do: // !!((window.CSS && window.CSS.supports) || window.supportsCSS || false) }

    To use it, either pass the property to it in one param and the value in another:

    const supportsGrid = CSS.supports("display", "grid");

    ...or give it all in one string mirroring the CSS syntax:

    const supportsGrid = CSS.supports("(display: grid)"); Selector testing

    At the time of this writing, only Firefox supports this sort of testing (behind an experimental flag), but there is a way to test the support of selectors with @supports. MDN's demo:

    @supports selector(A > B) { } You?

    Of course, we'd love to see Pens of @supports use cases in the comments. So share 'em!

    The post How @supports Works appeared first on CSS-Tricks.

    instant.page

    Css Tricks - Mon, 02/18/2019 - 7:25am

    instant.page is a pretty cool project from Alexandre Dieulot. Alexandre has been at this idea for half a decade now, as InstantClick is his and is essentially the same exact idea.

    The idea is that there is a significant delay between hovering over a link and clicking that link. Say it takes you 300ms of delay. That 300ms could have been spent preloading the next page. And if you do use that time preloading, that page loads that much faster.

    This new project makes use of newer tech to get it done. It's hardly any code., the core of which is appending a <link rel="prefetch" href=""> to the document of the link you're about to click/touch.

    The page encourages you to hotlink the script, which means possible cache-hits in case you've already visited a page using this. It's not risky in the way other third-party JavaScript can be because the integrity attribute means that if you trust the code as it is now, it can't ever change unless you change that attribute along with it. It also cleverly uses the type="module" to prevent it from loading anything in browsers that don't support prefetching anyway.

    Still, you could self-host it if you wanted. I have no idea who's ponying up the for the bandwidth here, so another risk is a hung script should it stop responding one day.

    You could argue that it doesn't do the prefetching as absolutely responsibly as it could. Google's similar quick link library (which we covered here) does two interesting things in which to attempt to be more responsible with prefetching: 1) wait for requestIdleCallback and 2) respects info from navigator.connection, like a user enabling data-saver mode.

    Direct Link to ArticlePermalink

    The post instant.page appeared first on CSS-Tricks.

    Syndicate content
    ©2003 - Present Akamai Design & Development.