emGee Software Solutions Custom Database Applications

Share this

Smashing Magazine

Recent content in Articles on Smashing Magazine — For Web Designers And Developers
Updated: 2 weeks 4 days ago

How To Integrate Social Media Into Mobile Web Design

Thu, 07/04/2019 - 04:00
How To Integrate Social Media Into Mobile Web Design How To Integrate Social Media Into Mobile Web Design Suzanne Scacca 2019-07-04T13:00:59+02:00 2019-07-06T05:35:43+00:00

There are a number of reasons why social media is a popular form of socialization and communication today. For starters, it gives us a chance to connect with exponentially more people than in-person communities allow for (which is fantastic for both consumer and business). It’s also encouraged a new style of communication where brevity and visual storytelling rules.

So, why aren’t we using more social media-like features in mobile web design?

To be clear, I’m not referring to the kinds of social media elements we already see on websites, like:

  • Social logins
  • Social follow icons
  • Social share icons
  • Social feeds
  • YouTube embeds
  • Pinnable images.

I’m talking about drawing inspiration from the abbreviated way in which we talk to others there. After all, mobile websites, PWAs, and native apps give us very little space to tell a story and engage an audience with it. Adopting a social media-inspired design would be helpful in quickly getting our message across on mobile screens.

These elements, in particular, are worth exploring in your mobile design work.

1. Use a Notification Symbol to Direct Visitors to Action

You don’t have much space or time to waste on mobile, so why literally spell out what kind of action you want visitors to take? A lot of the symbols we use on social media can easily be repurposed for mobile websites.

One such symbol is a notification ticker, a lot like the ones we’re accustomed to seeing in the header or footer of social media apps when there’s a message or reminder we need to be made aware of. Like this blue one found in the bottom bar on Facebook:

Facebook uses a small blue dot to signify that a new notification awaits you. (Source: Facebook) (Large preview)

On occasion, the Red Bull website will put a similar-looking red ticker on its hamburger menu icon (this one is flashing though):

The Red Bull mobile website displays a flashing red ticker on the hamburger menu. (Source: Red Bull) (Large preview)

This flashing notification has nothing to do with alerting me to account activity (because I’m not logged into the website). However, it does certainly draw my eye to the navigation before anything else.

If you have something pertinent you want visitors to see in the navigation or header of the site, a notification icon is a good way to grab their attention fast. And it doesn’t have to be a colored dot the way Facebook or Red Bull have handled it. You could also use a number counter like the ones that appear when items sit in a shopping cart or emails in an inbox.

2. Boost Branding with Hashtags and Handles

The way we talk to one another on social media is quite unique. Not only do many people use acronyms to truncate how much they say in a tiny amount of space, but we’ve also adopted a quicker way of getting our messages in front of target users.

Take, for example, this message I’ve written on Twitter about a post Jad Joubran recently wrote about PWAs.

Example of a basic message shared on Twitter. (Source: Twitter) (Large preview)

Now, I could leave my message as is and hope that Jad runs across the mention or that people interested in learning how to build PWAs find it. But there’s just too much noise on social media, which is why the usage of the handle (@) and hashtag (#) symbols has become helpful in getting our messages in front of the right people:

Example of a Twitter message with hashtags and handles. (Source: Twitter) (Large preview)

Take a look at the message above and note the differences. First, I’ve included hashtags in this post for #pwa and #progressivewebapp. That way, if someone is interested in related topics, it’ll be easier to locate this post now.

In addition, I’ve tagged Jad. This way, he’ll see my shout-out. I’ve also tagged Smashing Magazine since that’s the magazine in which the article appeared. This is good for them since it’ll increase the visibility of the brand while helping people who encounter the post make a direct connection between #pwa and @smashingmag.

The hashtag and handle have become such an innate part of how we communicate online, that I’m surprised more brands don’t use them on their websites. And I’m not talking about listing social media handles on a page. I mean actually integrating branded hashtags or handles within their designs as eos does here:

eos includes a branded hashtag within an image. (Source: eos) (Large preview)

A couple of years back, I saw more hashtags and handles incorporated into web designs. Today, I don’t see it as much.

My guess is that designers have moved away from placing handles and hashtags into designs since visitors can’t readily copy or click and do anything with them. But there is value in placing branded handles and hashtags into your designs on mobile.

Think of it as a watermark for your brand images. Like the example above, people won’t just walk away thinking about how cool that chapstick “egg” looks. They’ll take note of the hashtag sitting perpendicular to it, too. And for those that are on their way to becoming loyal eos customers, that hashtag will stick with them.

3. Add Trust Marks into the Design

There are certain social media platforms that give brands and public figures the ability to verify their identity. That way, anyone who wants to follow them will know who the person on the other side of the profile actually is (instead of, say, a bot or someone pretending to be them).

Rather than slap a “Verified Profile” label on these profiles, platforms like Twitter and Instagram use a tiny symbol that lets people know it’s okay to trust that the user is who they say they are. And it comes in the form of a small blue checkmark next to their username.

Instagram uses a small blue checkmark to let people know it’s a real profile.. (Source: Instagram) (Large preview)

Trust marks are already used on the web to let visitors know when a site is safe enough to engage with and make a purchase through. However, they usually come in the form of big security provider logos like Norton Security that build consumer trust just before checkout.

Instead, you should find ways to leverage smaller trust marks to reinforce trust throughout the entire experience. Here’s how Sephora does this for its store:

Sephora uses the same trust mark stamps to call attention to more notable products. (Source: Sephora) (Large preview)

There are two trust marks present in the screenshot above.

The GlamGlow product has a red-and-white stamp on it that says “Allure Readers’ Choice Award Winner”. You already know how much people trust in the reviews and recommendations of other consumers, so you can imagine what this sort of symbol does to pique their interest and build trust in the product.

The Farmacy product has a green-and-white stamp on it that says “Clean at Sephora”. This is a label Sephora slaps onto any product that’s free of questionable ingredients. For customers that are extra conscious about where their products come from and what they’re made from, this symbol will quickly direct their attention to the kinds of products they’re looking for.

4. Lead with a Singular Memorable Image

When you scroll through your social media feed, you’re not likely to see post after post with galleries of images attached to them. Unless, that is, someone just went on vacation and they want to show off everything they did or saw.

Usually, most of the social media posts you encounter keep it simple: a text message with a complementary image attached to it. And if the image didn’t come courtesy of the link they’re promoting, then they’ll attach something equally as memorable and relevant.

Social media feeds are full of posts from the people we’re connected to, so it’s important to have one strong image that helps ours stand out among the crowd. A mobile website would benefit from that same approach.

In this case, I’m going to point you to this promotional element on the West Elm mobile website for the approaching July 4th holiday in the United States:

A sparkler GIF used to promote West Elm’s July 4th promotion. (Source: West Elm) (Large preview)

Since sparklers are a big part of how we celebrate Independence Day, this sparkler GIF is an incredibly effective, yet simplistic way to draw visitors’ attention to the relevant promotion.

Not only is the GIF memorable, but it’s very relevant to what online shoppers are looking for at the moment. Plus, it all fits within the space of a smartphone screen, which makes it a more convenient way to read about the promotion before clicking through to claim the 20% offer.

5. Make Your Brand Meme-like

When brands use social media, they have to think about more than just pairing a carefully crafted message with an engaging image. They also have to consider the consistency of their posts. In some cases, brands will use color to tie their posts together. Others will rely on the messaging itself to create a cohesive identity.

Then, there are brands that have turned their brands into memes. Old Spice’s “The Man Your Man Could Smell Like” or Terry Crews campaigns are some of the more successful and memorable examples of how to do this.

It’s not just brands like Old Spice or Dollar Shave Club whose humorous advertising become memes that can pull this off. Take a brand like Oreo, for example.

Oreo is a household name. And, yet, would anyone have considered sharing posts about Oreo cookies with others? Before 2013, I’m not so sure. After Oreo published its now-famous post during the Super Bowl blackout, though, things changed.

Oreo gave a boost to its already iconic image during the 2013 Super Bowl. (Source: Oreo) (Large preview)

This might not be a meme on the level of Old Spice. However, it most certainly is on a similar level of trendiness and shareability.

Oreo has continued to find ways to turn its iconic Oreo cookie image into a meme-like status symbol.

Oreo has turned its cookie into a meme of its own. (Source: Oreo) (Large preview)

You know how everyone and their mother has been sharing cookies notices on their websites, thanks to GDPR? Oreo utilizes its brand image to have a little fun with it.

As you can see here, the drop-down creatively uses the Oreo image while also playing on the word “cookie” itself. It’s a fantastic example of how to be creative, even in the smallest of spaces and for a limited amount of time. It certainly grabbed my attention enough to deem it worth sharing here.

6. Embrace the Selfie

I recognize that selfies don’t always have the most positive of connotations, but it’s really difficult to have a discussion about using social media-like elements in design without addressing them. So, I’m going to go out on a limb here and say that mobile websites would benefit from including selfie-like portraits… when not used in a phony or obnoxious context.

I mean, that’s the main complaint about selfies, right? They’re staged and not at all realistic of a person’s actual life. Or they’re not staged because they’re taken at the worst possible time and in the least professional of contexts.

That said, selfies do stand out from super-glossy headshots and other staged company photos. And when you present them on a mobile interface, it gives a website (and the brand behind it) a more social-like presence. In other words, you’re inviting people to engage with you, not to just casually glance through copy and photos on their way to mindlessly converting. There’s something more to this experience when a selfie is present.

One example of this that I particularly love comes from Aleyda Solis, an SEO consultant and author.

Aleyda Solis uses selfies as promotional images on her website. (Source: Aleyda Solis) (Large preview)

Just looking at the above screenshot out of context, I feel like I’m scrolling through her personal feed on Instagram. And because I’m so accustomed to seeing interesting-looking photos on Instagram and then immediately seeking out the captions for more information on them, I’m compelled to do the same here. Talk about Pavlov’s dog, right?

For brands with a recognizable figure or team behind them, a selfie could be a great way to up your visitors’ engagement with a website. Just make sure it paints the person or people in a positive light.

7. Use Filters to Tell Individual Stories

Way, way back in the day, we used to take photos using film and pray that the images came out okay and would be acceptable enough to frame. Then, we got digital cameras that allowed us to see what our pictures looked like in real-time, though it often led to too many rounds of picture-taking to try to capture the perfect lighting or shot.

Nowadays, our smartphones and social media platforms make all of this so much simpler. We can take photos wherever we are, whenever we feel like it and many of the tools we need to clean up a shot and apply an attractive filter are already built into our apps.

Needless to say, filters are a big part of what makes sharing photos on social media so appealing to users.

Now, it’s not as though brands haven’t utilized filters before to spruce up their branding or photography. However, have you considered what using different filters in different contexts could do for your mobile website? They could effectively turn different pages or products into unique experiences or stories of their own.

Abel is an online perfume shop that sells a small collection of perfumes, with scents like pink iris, red santal and green cedar. Notice the trend? Each scent is described by a distinct color, as this example of golden neroli demonstrates:

An example of one of Abel’s product pages. (Source: Abel) (Large preview)

Although the perfume itself is clear in color, the design of this image gives the bottle a golden color to match its namesake. Now, here’s where it gets interesting:

Abel applies a color-specific filter to images on each product page. (Source: Abel) (Large preview)

This is one of the images lower on the product’s page. While I suspect the sunset captured in the photo is real, it’s obvious that a filter has been applied to lighten and warm the overall tone of the image.

The same is done with another image further down on the page:

Another filter-enhanced image on Abel’s product page. (Source: Abel) (Large preview)

Again, the emphasis is placed on making the image lighter and warmer in tone. And if you look at the snippet of text just above, you can see that Abel even compares the sensation of this perfume to “the warm warm blanket of the night falling over Lisbon”.

So, rather than get hung up on designing your mobile website with one singular color palette, consider the individual emotion and identity of each of its pages or elements. You may find that filters and colors help you tell a stronger and unique story for each than the words alone could.

The Benefits Of A Social Media-Inspired Mobile Design

As we attempt to unlock more ways to design for mobile without stifling creativity or overwhelming the user experience, I think it’s important to look to other kinds of media for inspiration.

It’s not like we haven’t already found ways to tell a visual story through design on smaller or more isolated screens. Just look at video game design. Social media is another type of media that’s successfully carved out a style of its own. And considering how addictive and engaging social media often is for consumers, it’s a good platform to turn to for design inspiration.

(ra, yk, il)
Categories: Web Design

Using Slots In Vue.js

Wed, 07/03/2019 - 03:30
Using Slots In Vue.js Using Slots In Vue.js Joseph Zimmerman 2019-07-03T12:30:59+02:00 2019-07-03T20:06:04+00:00

With the recent release of Vue 2.6, the syntax for using slots has been made more succinct. This change to slots has gotten me re-interested in discovering the potential power of slots to provide reusability, new features, and clearer readability to our Vue-based projects. What are slots truly capable of?

If you’re new to Vue or haven’t seen the changes from version 2.6, read on. Probably the best resource for learning about slots is Vue’s own documentation, but I’ll try to give a rundown here.

What Are Slots?

Slots are a mechanism for Vue components that allows you to compose your components in a way other than the strict parent-child relationship. Slots give you an outlet to place content in new places or make components more generic. The best way to understand them is to see them in action. Let’s start with a simple example:

// frame.vue <template> <div class="frame"> <slot></slot> </div> </template>

This component has a wrapper div. Let’s pretend that div is there to create a stylistic frame around its content. This component is able to be used generically to wrap a frame around any content you want. Let’s see what it looks like to use it. The frame component here refers to the component we just made above.

// app.vue <template> <frame><img src="an-image.jpg"></frame> </template>

The content that is between the opening and closing frame tags will get inserted into the frame component where the slot is, replacing the slot tags. This is the most basic way of doing it. You can also specify default content to go into a slot simply by filling it in:

// frame.vue <template> <div class="frame"> <slot>This is the default content if nothing gets specified to go here</slot> </div> </template>

So now if we use it like this instead:

// app.vue <template> <frame /> </template>

The default text of “This is the default content if nothing gets specified to go here” will show up, but if we use it as we did before, the default text will be overridden by the img tag.

Multiple/Named Slots

You can add multiple slots to a component, but if you do, all but one of them is required to have a name. If there is one without a name, it is the default slot. Here’s how you create multiple slots:

// titled-frame.vue <template> <div class="frame"> <header><h2><slot name="header">Title</slot></h2></header> <slot>This is the default content if nothing gets specified to go here</slot> </div> </template>

We kept the same default slot, but this time we added a slot named header where you can enter a title. You use it like this:

// app.vue <template> <titled-frame> <template v-slot:header> <!-- The code below goes into the header slot --> My Image’s Title </template> <!-- The code below goes into the default slot --> <img src="an-image.jpg"> </titled-frame> </template>

Just like before, if we want to add content to the default slot, just put it directly inside the titled-frame component. To add content to a named slot, though, we needed to wrap the code in a template tag with a v-slot directive. You add a colon (:) after v-slot and then write the name of the slot you want the content to be passed to. Note that v-slot is new to Vue 2.6, so if you’re using an older version, you’ll need to read the docs about the deprecated slot syntax.

Scoped Slots

One more thing you’ll need to know is that slots can pass data/functions down to their children. To demonstrate this, we’ll need a completely different example component with slots, one that’s even more contrived than the previous one: let’s sorta copy the example from the docs by creating a component that supplies the data about the current user to its slots:

// current-user.vue <template> <span> <slot v-bind:user="user"> {{ user.lastName }} </slot> </span> </template> <script> export default { data () { return { user: ... } } } </script>

This component has a property called user with details about the user. By default, the component shows the user’s last name, but note that it is using v-bind to bind the user data to the slot. With that, we can use this component to provide the user data to its descendant:

// app.vue <template> <current-user> <template v-slot:default="slotProps">{{ slotProps.user.firstName }}</template> </current-user> </template>

To get access to the data passed to the slot, we specify the name of the scope variable with the value of the v-slot directive.

There are a few notes to take here:

  • We specified the name of default, though we don’t need to for the default slot. Instead we could just use v-slot="slotProps".
  • You don’t need to use slotProps as the name. You can call it whatever you want.
  • If you’re only using a default slot, you can skip that inner template tag and put the v-slot directive directly onto the current-user tag.
  • You can use object destructuring to create direct references to the scoped slot data rather than using a single variable name. In other words, you can use v-slot="{user}" instead of v-slot="slotProps" and then you can use user directly instead of slotProps.user.

Taking those notes into account, the above example can be rewritten like this:

// app.vue <template> <current-user v-slot="{user}"> {{ user.firstName }} </current-user> </template>

A couple more things to keep in mind:

  • You can bind more than one value with v-bind directives. So in the example, I could have done more than just user.
  • You can pass functions to scoped slots too. Many libraries use this to provide reusable functional components as you’ll see later.
  • v-slot has an alias of #. So instead of writing v-slot:header="data", you can write #header="data". You can also just specify #header instead of v-slot:header when you’re not using scoped slots. As for default slots, you’ll need to specify the name of default when you use the alias. In other words, you’ll need to write #default="data" instead of #="data".

There are a few more minor points you can learn about from the docs, but that should be enough to help you understand what we’re talking about in the rest of this article.

What Can You Do With Slots?

Slots weren’t built for a single purpose, or at least if they were, they’ve evolved way beyond that original intention to be a powerhouse tool for doing many different things.

Reusable Patterns

Components were always designed to be able to be reused, but some patterns aren’t practical to enforce with a single “normal” component because the number of props you’ll need in order to customize it can be excessive or you’d need to pass large sections of content and potentially other components through the props. Slots can be used to encompass the “outside” part of the pattern and allow other HTML and/or components to placed inside of them to customize the “inside” part, allowing the component with slots to define the pattern and the components injected into the slots to be unique.

For our first example, let’s start with something simple: a button. Imagine you and your team are using Bootstrap*. With Bootstrap, your buttons are often strapped with the base `btn` class and a class specifying the color, such as `btn-primary`. You can also add a size class, such as `btn-lg`.

* I neither encourage nor discourage you from doing this, I just needed something for my example and it’s pretty well known.

Let’s now assume, for simplicity’s sake that your app/site always uses btn-primary and btn-lg. You don’t want to always have to write all three classes on your buttons, or maybe you don’t trust a rookie to remember to do all three. In that case, you can create a component that automatically has all three of those classes, but how do you allow customization of the content? A prop isn’t practical because a button tag is allowed to have all kinds of HTML in it, so we should use a slot.

<!-- my-button.vue --> <template> <button class="btn btn-primary btn-lg"> <slot>Click Me!</slot> </button> </template>

Now we can use it everywhere with whatever content you want:

<!-- somewhere else, using my-button.vue --> <template> <my-button> <img src="/img/awesome-icon.jpg"> SMASH THIS BUTTON TO BECOME AWESOME FOR ONLY $500!!! </my-button> </template>

Of course, you can go with something much bigger than a button. Sticking with Bootstrap, let’s look at a modal, or least the HTML part; I won’t be going into functionality… yet.

<!-- my-modal.vue --> <template> <div class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <slot name="header"></slot> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <slot name="body"></slot> </div> <div class="modal-footer"> <slot name="footer"></slot> </div> </div> </div> </div> </template>

Now, let’s use this:

<!-- somewhere else, using my-modal.vue --> <template> <my-modal> <template #header><!-- using the shorthand for `v-slot` --> <h5>Awesome Interruption!</h5> </template> <template #body> <p>We interrupt your use of our application to let you know that this application is awesome and you should continue using it every day for the rest of your life!</p> </template> <template #footer> <em>Now back to your regularly scheduled app usage</em> </template> </my-modal> </template>

The above type of use case for slots is obviously very useful, but it can do even more.

Reusing Functionality

Vue components aren’t all about the HTML and CSS. They’re built with JavaScript, so they’re also about functionality. Slots can be useful for creating functionality once and using it in multiple places. Let’s go back to our modal example and add a function that closes the modal:

<!-- my-modal.vue --> <template> <div class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <slot name="header"></slot> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <slot name="body"></slot> </div> <div class="modal-footer"> <!-- using `v-bind` shorthand to pass the `closeModal` method to the component that will be in this slot --> <slot name="footer" :closeModal="closeModal"></slot> </div> </div> </div> </div> </template> <script> export default { //... methods: { closeModal () { // Do what needs to be done to close the modal... and maybe remove it from the DOM } } } </script>

Now when you use this component, you can add a button to the footer that can close the modal. Normally, in the case of a Bootstrap modal, you could just add data-dismiss="modal" to a button, but we want to hide Bootstrap specific things away from the components that will be slotting into this modal component. So we pass them a function they can call and they are none the wiser about Bootstrap’s involvement:

<!-- somewhere else, using my-modal.vue --> <template> <my-modal> <template #header><!-- using the shorthand for `v-slot` --> <h5>Awesome Interruption!</h5> </template> <template #body> <p>We interrupt your use of our application to let you know that this application is awesome and you should continue using it every day for the rest of your life!</p> </template> <!-- pull in `closeModal` and use it in a button’s click handler --> <template #footer="{closeModal}"> <button @click="closeModal"> Take me back to the app so I can be awesome </button> </template> </my-modal> </template> Renderless Components

And finally, you can take what you know about using slots to pass around reusable functionality and strip practically all of the HTML and just use the slots. That’s essentially what a renderless component is: a component that provides only functionality without any HTML.

Making components truly renderless can be a little tricky because you’ll need to write render functions rather than using a template in order to remove the need for a root element, but it may not always be necessary. Let’s take a look at a simple example that does let us use a template first, though:

<template> <transition name="fade" v-bind="$attrs" v-on="$listeners"> <slot></slot> </transition> </template> <style> .fade-enter-active, .fade-leave-active { transition: opacity 0.3s; } .fade-enter, .fade-leave-to { opacity: 0; } </style>

This is an odd example of a renderless component because it doesn’t even have any JavaScript in it. That’s mostly because we’re just creating a pre-configured reusable version of a built-in renderless function: transition.

Yup, Vue has built-in renderless components. This particular example is taken from an article on reusable transitions by Cristi Jora and shows a simple way to create a renderless component that can standardize the transitions used throughout your application. Cristi’s article goes into a lot more depth and shows some more advanced variations of reusable transitions, so I recommend checking it out.

For our other example, we’ll create a component that handles switching what is shown during the different states of a Promise: pending, successfully resolved, and failed. It’s a common pattern and while it doesn’t require a lot of code, it can muddy up a lot of your components if the logic isn’t pulled out for reusability.

<!-- promised.vue --> <template> <span> <slot name="rejected" v-if="error" :error="error"></slot> <slot name="resolved" v-else-if="resolved" :data="data"></slot> <slot name="pending" v-else></slot> </span> </template> <script> export default { props: { promise: Promise }, data: () => ({ resolved: false, data: null, error: null }), watch: { promise: { handler (promise) { this.resolved = false this.error = null if (!promise) { this.data = null return } promise.then(data => { this.data = data this.resolved = true }) .catch(err => { this.error = err this.resolved = true }) }, immediate: true } } } </script>

So what is going on here? First, note that we are receiving a prop called promise that is a Promise. In the watch section we watch for changes to the promise and when it changes (or immediately on component creation thanks to the immediate property) we clear the state, and call then and catch on the promise, updating the state when it either finishes successfully or fails.

Then, in the template, we show a different slot based on the state. Note that we failed to keep it truly renderless because we needed a root element in order to use a template. We’re passing data and error to the relevant slot scopes as well.

And here’s an example of it being used:

<template> <div> <promised :promise="somePromise"> <template #resolved="{ data }"> Resolved: {{ data }} </template> <template #rejected="{ error }"> Rejected: {{ error }} </template> <template #pending> Working on it... </template> </promised> </div> </template> ...

We pass in somePromise to the renderless component. While we’re waiting for it to finish, we’re displaying “Working on it…” thanks to the pending slot. If it succeeds we display “Resolved:” and the resolution value. If it fails we display “Rejected:” and the error that caused the rejection. Now we no longer need to track the state of the promise within this component because that part is pulled out into its own reusable component.

So, what can we do about that span wrapping around the slots in promised.vue? To remove it, we’ll need to remove the template portion and add a render function to our component:

render () { if (this.error) { return this.$scopedSlots['rejected']({error: this.error}) } if (this.resolved) { return this.$scopedSlots['resolved']({data: this.data}) } return this.$scopedSlots['pending']() }

There isn’t anything too tricky going on here. We’re just using some if blocks to find the state and then returning the correct scoped slot (via this.$scopedSlots['SLOTNAME'](...)) and passing the relevant data to the slot scope. When you’re not using a template, you can skip using the .vue file extension by pulling the JavaScript out of the script tag and just plunking it into a .js file. This should give you a very slight performance bump when compiling those Vue files.

This example is a stripped-down and slightly tweaked version of vue-promised, which I would recommend over using the above example because they cover over some potential pitfalls. There are plenty of other great examples of renderless components out there too. Baleada is an entire library full of renderless components that provide useful functionality like this. There’s also vue-virtual-scroller for controlling the rendering of list item based on what is visible on the screen or PortalVue for “teleporting” content to completely different parts of the DOM.

I’m Out

Vue’s slots take component-based development to a whole new level, and while I’ve demonstrated a lot of great ways slots can be used, there are countless more out there. What great idea can you think of? What ways do you think slots could get an upgrade? If you have any, make sure to bring your ideas to the Vue team. God bless and happy coding.

(dm, il)
Categories: Web Design

How Sitejet Helps Your Agency Design Websites Faster Than Ever

Tue, 07/02/2019 - 03:00
How Sitejet Helps Your Agency Design Websites Faster Than Ever How Sitejet Helps Your Agency Design Websites Faster Than Ever Suzanne Scacca 2019-07-02T12:00:59+02:00 2019-07-02T13:05:55+00:00

(This is a sponsored article.) Spend enough time in a Facebook group for professional web developers and designers and the question will inevitably come up:

“I was approached by a small client with a small budget. Should I work with them?”

Those that have been around a long time will probably scream “No!” and tell you that you’re under no obligation to work with smaller clients. The reasoning being that it’s impossible to make a worthwhile profit on those kinds of projects and that many of the clients end up being difficult to work with.

But is the problem really with the quality of clients with small- and medium-sized businesses? In some cases, that may be so — though, honestly, that’s really only the case if you attract and agree to work with discount seekers (i.e. “How much can you give me for $X?”). In most cases, though, the underlying issue is that your process isn’t efficient enough to design high-quality websites for SMBs at a price point they can afford.

Which is why Sitejet as an all-in-one web design platform is so exciting.

In almost any economy, it’s companies with 10 employees or less that make up well over 80% of the total number of businesses. Although it may not have seemed like an attractive segment of businesses to target in the past, Sitejet makes it not only an option worth considering, but an attractive one at that.

Sitejet gives you a way to design beautiful, feature-rich and responsive websites for SMBs without killing your profits. In the following post, I’m going to show you how Sitejet makes that possible.

Why Sitejet Decided to Share Its Internal Software with the World

In 2013, a German web design agency called Websitebutler was formed.

This is the website for the Websitebutler design agency. (Source: Websitebutler) (Large preview)

Their business model is this:

  • Give small companies the chance to have a high-quality website even without an agency-sized budget.
  • Design professional-looking websites for SMBs.
  • Charge them a monthly subscription fee for the website, maintenance, website updates, domain, hosting and so on. Websitebutler would take care of the rest.

The thing is, their cheapest subscription plan starts at € 29.99.

The subscription plans and pricing for Websitebutler’s website-as-a-service. (Source: Websitebutler) (Large preview)

It soon became clear, however, that they couldn’t afford to charge SMBs so little.

While it was a website-as-a-service offering, they weren’t willing to cut corners. Websitebutler still took the time to understand what the client wanted in order to build the right solution.

Because that approach was so time- and resource-consuming, they either needed to:

  1. Reevaluate their pricing,
  2. Phase out smaller clients who couldn’t afford it,
  3. Find a more efficient way to work.
Sitejet Was Born

The Websitebutler team decided to go with option #3:

Find a more efficient way to work.

When I spoke to Hendrik Köhler, co-founder and the lead of Marketing & Product for Sitejet, he said:

“It took five years to create the perfect tool for ourselves.”

It also took building over 4,000 SMB websites in-house before they were happy with the refinements they’d made to their internal solution. That’s when they started thinking about sharing their high-performance content and project management system with other web designers and design agencies. And why wouldn’t they?

Sitejet enabled Websitebutler to decrease the time spent on web design projects by 70%.

As I’ll show you in just a few moments, Sitejet gives designers a way to effectively manage everything from one place while still being able to develop fast, beautiful and responsive websites.

Time-Savings For Your Web Design Workflow With Sitejet

Think about your design process: realistically, there probably isn’t much more you could shave off of it without compromising the quality of your work. If you were to pick up speed in your workflow it would have to be in client communication and project management, right?

That’s why Sitejet deserves to stand out from other site builder solutions. It’s not that they’re the first to create an easy-to-use visual editor. However, they are the first to successfully combine project management, communication, and web design into one tool.

A quick look into the Sitejet website and project management dashboard. (Source: Sitejet) (Large preview)

One thing to note before I give you a look at how Sitejet saves you time is that I’m not going to focus too much on how to design with Sitejet. If you’ve worked with enough site builders, then you have a good idea of what you can do with Sitejet. So, what I’m going to focus on are the key differentiators that make this a powerhouse in terms of managing web design projects.

Before we get started looking into this platform, though, here is a highlight reel of how Sitejet revolutionizes your workflows:

Now, let’s take a closer look at what you need to know about this web design tool built by web designers for web designers.

1. Built-In Project Management

Sitejet is like other site builders in that it allows you to build and manage multiple websites from a single dashboard. However, nothing else about this dashboard is like the rest:

A close-up of the project management panel in Sitejet. (Source: Sitejet) (Large preview)

If you’re currently managing multiple website projects simultaneously, my guess is that you’re using a project management platform like Asana, Trello or Basecamp for collecting files, communicating with clients and managing your task list.

But that creates an additional step for you, right? Plus, you have to account for the errant email or voicemail from clients that fail to use the project management system as it was intended.

There’s just too much logging in and out platforms and hunting around for all of the information and assets you need when you work with two systems for the same workflow.

With Sitejet, that’s no longer a problem as project management is automatically built in.

2. Faster Communications

You know how clients are, especially small business owners who don’t have a dedicated team member whose sole job it is to help you to create their website. They don’t have the patience for all these systems (especially when they’re complicated to use), which is why they end up emailing and calling even though you’ve pleaded with them to use the tools you’ve given them.

So, you end up throwing away a bunch of time dealing with these unexpected and disorganized communications.

In Sitejet, that’s not a problem. All communication takes place in the same system that everything else does. This is what the email system looks like from your end:

Sitejet makes email communications much easier to organize and execute. (Source: Sitejet) (Large preview)

You can message team members privately, insert messages or information from your client or send them a new one. You can also create email templates to reuse as certain phases of each project are completed.

Sitejet reduces your workload even further by automatically assigning new emails to your customers to ensure they never miss an important communication. In addition, any files that are attached to emails are automatically uploaded to your file management center — just one less asset you have to worry about moving from Point A to Point B and then over to Point C.

From the client’s perspective, this is great, too. Here’s a message as seen from the client’s Gmail account:

Sitejet emails end up in the client’s own email account and not lost in the system. (Source: Sitejet) (Large preview)

If a response is needed, the client can reply directly from their email provider and not have to worry about logging back into Sitejet if no other actions are needed there (like a simple “Yes”, “No”, “I approve this”). If action is needed, they’ll simply click on the link and do as you’ve requested.

Otherwise, all of the communication — emails, task assignments, and feedback — is handled within Sitejet.

3. Smart Project Status System

One of the features to pay close attention to in Sitejet is the first column in the dashboard:

Sitejet’s project status list for more effective project management. (Source: Sitejet) (Large preview)

This isn’t some meaningless system that helps you know which stage each project is in either. It actually opens up new functionality in Sitejet for you and your clients.

The Customer Portal is an incredibly powerful tool for Sitejet users and their clients.

Unlike many page builder tools and content management systems which require your clients to work in the same exact interface as you do, Sitejet has created a simpler and more intuitive interface for clients. This way, you don’t have to spend your time spelling out what each area of the portal means or demonstrating what they need to do inside of it.

For example, this is what the Customer Portal looks like when a website is in the Preparation phase:

This is the Sitejet Preparation phase, as seen from the client. (Source: Sitejet) (Large preview)

They’re asked to:

  • Set up their user account and data,
  • Upload files like photos, videos, documents and much more,
  • Provide info on their “Wishes” for the website.

After completing their portion of the “Preparation” phase, the system automatically notifies you. That way, you don’t have to chase down the client or try to gather all of those details from other platforms.

Managing phase completion from the Sitejet dashboard. (Source: Sitejet) (Large preview)

With confirmation that they’ve completed their tasks, you can then get to work on subsequent phases. As you complete new ones, their dashboard will continue to transform.

For example, here is what they see when you enter the Feedback phase:

A new option appears for clients as you enter new phases in Sitejet. (Source: Sitejet) (Large preview)

Notice how there’s now a prompt for feedback. When they click on either of those links, they’re taken into the website where they can leave notes on the website you’ve designed.

For many clients, project management tools are often overwhelming. With Sitejet, however, you control what they focus on to ensure that you get the right information without any issue. As a bonus, you’re able to stay abreast of any and all changes they make on their end, so you can more quickly get your websites through all project phases.

4. Remove The Client Bottleneck

When it comes to building websites, there are a number of ways in which your clients can become the bottleneck in your workflow. Like in the matter of content collection.

When you work with SMBs, it’s common to leave it to the clients to provide content for their sites. It’s then your responsibility to put it together and shape a great-looking design around it.

Despite knowing that they’re accountable for the content, many designers still have issues getting it from clients. But as we’ve seen already, Sitejet makes it easy to inform clients when certain actions are needed. It also makes the act of content collection one that won’t make you want to tear your hair out.

Remember the Preparation phase we saw earlier from the client’s perspective? This is what they find under File Management:

An example of files uploaded to the Sitejet file management tool. (Source: Sitejet) (Large preview)

This is where they can upload any kind of data (e.g. image files, PDF documents, and more) they owe you for the project. They may be photographs to use on the site (as in the example above). Or partner or customer logos they want to showcase. Or even style guides or other PDFs that’ll guide you along as you design their website.

For those of you who convert your files from one format to another, Sitejet allows you to do that from within the platform, too. Let’s say you want to reduce the size of an image by going from PNG to JPG or you want to turn a PDF into a JPG. There’s no need to leave Sitejet to do this.

In traditional website workflows, you’d have your clients upload their content to the project management platform or to a file sharing system. You’d then download each of the files and re-upload them into your site builder. This removes the middle man.

Then, there’s the Wishes section of the Client Portal:

Sitejet lets your client define what they “wish” you’ll include on their website. (Source: Sitejet) (Large preview)

This system retrieves all of the details you need from clients in order to build their websites:

  • What other websites are they a fan of and why?
  • Do they want a single-page or multi-page site?
  • Do they have a logo or need one created?
  • Do they have a color palette or shall you create it for them?
  • Is content for the website ready to be uploaded or is there an old website you can retrieve it from?
  • What is the business’s contact information to show on the website?
  • Are there any special legal notices they want to be included?

You can also fill in as much of it as you can before they ever get there. For instance, say you already know you’re going to create a multi-page website that includes an About page, a Menu page and a Contact page. You can add that information into the Construction and Content tabs for them.

It’s also worth mentioning that the client portal is a great sales tool as well. Because, not only can you create accounts for current clients, you can do so for prospective clients. They can upload files and data, and email you from within the platform, all while you’re still in the early stages of talking.

If you want to build trust with clients early on, a branded Client Portal that simplifies all of your exchanges would help immensely. Again, this would reduce the amount of time you have to spend hand holding clients or manually taking them through the process.

5. Control Client Activity On The Site

Let’s say you want to give your clients the option to edit their website while you’re working on it. This can be risky at any stage as clients are often easily overwhelmed by what they see when they have a brand new website. They also have a tendency to hurriedly make changes and then act surprised when something looks bad or “breaks”.

There’s a feature you can use called “Editable for customers” to cut down on the overwhelm many clients face when confronted with a site builder. This’ll also cut down on the time you have to spend repairing something they “didn’t mean to do”.

To activate it, step inside the Sitejet builder. Next, right-click on an element you want them to be able to edit. If you want them to be able to edit more than that, right-click anywhere on the page.

Sitejet’s “Editable for customer” setting lets you control how much of the site the client can alter. (Source: Sitejet) (Large preview)

You’ll see three options:

  1. This element.
  2. All elements of the same type.
  3. All elements on the page.

If you only want the client to edit a particular section (say, if you’re into your final round of revisions and don’t want them to backtrack and try to edit something already finalized), this would really come in handy.

Or, if you don’t trust them to make edits to the site at all, you can opt to collect their feedback instead.

The second you change the Project Status to “Feedback”, your client will then see the Feedback option open up on their end along with a link to the site builder. Just be sure to send them an email to let them know they can step inside.

The first time the client steps into the editor, they’ll see this message. (Source: Sitejet) (Large preview)

As they hover over different parts of the web page, the element will display a blue overlay.

Leaving feedback on websites with Sitejet is easy for clients. (Source: Sitejet) (Large preview)

When they click on the element, a new note field will appear where they can leave their feedback. The note will show up on their feedback sidebar like this:

All feedback notes show up in the sidebar until the client is ready to submit. (Source: Sitejet) (Large preview)

Once they’ve completed adding their notes, they can click the “Submit” button which will then push new to-dos (one for each note) over to your queue.

A list of sample to-dos inside the web designer’s dashboard of Sitejet. (Source: Sitejet) (Large preview)

This way, you don’t have to copy down all of the feedback from an email, text message or phone call with the client and try to decipher where they meant for you to make a change. Their notes happen directly on the website and end up as alerts in your to-do box as well as inside the page editor tool where they reveal themselves within the context of the page.

Collaboration isn’t just easier with your clients either. Sitejet simplifies collaboration with team members as well as external service providers. You can assign them to-dos as well as define permissions and roles which restrict the type of actions they can or cannot take within the platform.

6. Faster Website Generation

With Sitejet, you have numerous options to build a website for your clients. However, if you really want to save time up front, you’ll want to use the platform’s templates, matching presets and website generator.


Sitejet has dozens of beautifully made templates for you to start with:

Sitejet has dozens of website templates. (Source: Sitejet) (Large preview)

What’s nice about this — and something you don’t often find with site builders — is that the best templates aren’t hidden behind a paywall. You have access to all of their templates without any additional fees.

What’s more, because this platform was made to cater to the SMB client, you’re going to find templates built specifically for those niches. Restaurants. Bars. Salons. Real estate agents. And much more.

If you’re normally spending too much time trying to find the right starter design, having to customize the ones available or search hours for the right template on marketplaces, Sitejet is a way out of that time-consuming cycle. You can also create and save your own template if there’s a specific style of site you tend to use for your niche.

Matching Presets

There’s a related feature Sitejet includes that you should also know about. I wouldn’t call it a section template tool, though it kind of looks like one at first glance. Let me show you.

This is the Sitejet builder. You can edit universal website settings, add elements and drag-and-drop elements around as you like:

A look inside the Sitejet builder and editor interface. (Source: Sitejet) (Large preview)

Now, let’s say that this great-looking template took care of most of the work for you. However, you’re not 100% satisfied with the layout of this section. What you could do is customize it using the builder’s system of elements and the edit container. Or…

You can use what’s called “Find Matching Presets”:

Sitejet’s Matching Presets feature is a huge time-saver. (Source: Sitejet) (Large preview)

When you right-click on any section, you’re given a bunch of options for adding elements, editing them, as well as customizing the code. You will also find matching presets.

At the bottom of the screen, the Preset Wizard appears:

This is the Sitejet Preset Wizard when you want to redesign a section. (Source: Sitejet) (Large preview)

When you select one of the Presets, this allows you to change the structure of the section without losing any of the content. For example:

Restructuring the layout and design of a section can happen in seconds. (Source: Sitejet) (Large preview)

It’s an insanely quick way to edit your designs without having to make more than a couple of clicks.

Website Generator

If you really want to save yourself time building websites and you’ve left the content piece in your clients’ hands, have a look at the website generation tool.

To use this tool, you first need to add a new website. When you’re asked to choose a template in the next screen, you’ll click “Choose template later”. This way, all you’ve done is create an empty shell of a website.

Then, locate “More” options next to that website in your dashboard:

Use Sitejet’s website generator to speed up design. (Source: Sitejet) (Large preview)

The “Generate website” tool will then pull all of the “Wishes” images, information and content from the Client Portal into the new website. You’ll see a quick preview of those details and can make last-minute changes before letting Sitejet auto-generate the new website for you:

You get a chance to review and edit the information and content provided by the client. (Source: Sitejet) (Large preview)

When it’s done, you’ll have a brand new website filled with all of the content the client sent to you:

An example of an auto-generated website with Sitejet. (Source: Sitejet) (Large preview)

If you find that anything’s not in the right place or that there are some missing spots that need filling in, you can edit the website as you would one you built from scratch or from a template. At least this way you have a running head start.

Things I Didn’t Talk About

As I mentioned at the beginning of this roundup, I didn’t want to dig too deeply into all of the features of Sitejet since it would take too much time. That said, there are so many great features here that ensure that you can do everything you can with other website builder tools — and more.

For example:

  • Manage hosting and domains.
  • Automate backups.
  • Set up mail transfers.
  • Whitelabel the CMS with your branding.
  • Perform website checks.
  • Design using the page builder or with code.
  • Track time.
  • Manage users and permissions.
  • Review website statistics.

Clearly, it’s a robust all-in-one platform that takes into account every aspect of your workflow, simplifying as much as possible so you can work faster and more efficiently.

Wrapping Up

Let’s be real: when looking for new clients, you’re probably focused on the big dogs with the big budgets. Because those have traditionally been the only ones you could make a hefty profit on.

If you’ve ever felt bad about turning away small businesses, Sitejet makes it possible for you to start saying “yes” to them.

Not only is that great for the smaller players who otherwise wouldn’t have the means to get a high-performance website for their business, this is great for you because it means you can exponentially increase your client base. You can still take on big projects and then fill in the gaps with a bunch of smaller ones who’ll take significantly less time now thanks to Sitejet.

(ms, il)
Categories: Web Design

CSS Custom Properties In The Cascade

Mon, 07/01/2019 - 03:30
CSS Custom Properties In The Cascade CSS Custom Properties In The Cascade Miriam Suzanne 2019-07-01T12:30:59+02:00 2019-07-01T12:46:47+00:00

Last month, I had a conversation on Twitter about the difference between “scoped” styles (generated in a build process) and “nested” styles native to CSS. I asked why, anecdotally, developers avoid the specificity of ID selectors, while embracing “scoped styles” generated by JavaScript? Keith Grant suggested that the difference lies in balancing the cascade* and inheritance, i.e. giving preference to proximity over specificity. Let’s take a look.

The Cascade

The CSS cascade is based on three factors:

  1. Importance defined by the !important flag, and style origin (user > author > browser)
  2. Specificity of the selectors used (inline > ID > class > element)
  3. Source Order of the code itself (latest takes precedence)

Proximity is not mentioned anywhere — the DOM-tree relationship between parts of a selector. The paragraphs below will both be red, even though #inner p describes a closer relationship than #outer p for the second paragraph:

See the Pen [Cascade: Specificity vs Proximity](https://codepen.io/smashingmag/pen/OexweJ/) by Miriam Suzanne.

See the Pen Cascade: Specificity vs Proximity by Miriam Suzanne. <section id="outer"> <p>This text is red</p> <div id="inner"> <p>This text is also red!</p> </div> </section> #inner p { color: green; } #outer p { color: red; }

Both selectors have the same specificity, they are both describing the same p element, and neither is flagged as !important — so the result is based on source-order alone.

BEM And Scoped Styles

Naming conventions like BEM (“Block__Element—Modifier”) are used to ensure that each paragraph is “scoped” to only one parent, avoiding the cascade entirely. Paragraph “elements” are given unique classes specific to their “block” context:

See the Pen [BEM Selectors & Proximity](https://codepen.io/smashingmag/pen/qzPyeM/) by Miriam Suzanne.

See the Pen BEM Selectors & Proximity by Miriam Suzanne. <section class="outer"> <p class="outer__p">This text is red</p> <div class="inner"> <p class="inner__p">This text is green!</p> </div> </section> .inner__p { color: green; } .outer__p { color: red; }

These selectors still have the same relative importance, specificity, and source order — but the results are different. “Scoped” or “modular” CSS tools automate that process, re-writing our CSS for us, based on the HTML. In the code below, each paragraph is scoped to its direct parent:

See the Pen [Scoped Style Proximity](https://codepen.io/smashingmag/pen/NZaLWN/) by Miriam Suzanne.

See the Pen Scoped Style Proximity by Miriam Suzanne. <section outer-scope> <p outer-scope>This text is red</p> <div outer-scope inner-scope> <p inner-scope>This text is green!</p> </div> </section> p[inner-scope] { color: green } p[outer-scope] { color: red; } Inheritance

Proximity is not part of the cascade, but it is part of CSS. That’s where inheritance becomes important. If we drop the p from our selectors, each paragraph will inherit a color from its closest ancestor:

See the Pen [Inheritance: Specificity vs Proximity](https://codepen.io/smashingmag/pen/mZBGyN/) by Miriam Suzanne.

See the Pen Inheritance: Specificity vs Proximity by Miriam Suzanne. #inner { color: green; } #outer { color: red; }

Since #inner and #outer describe different elements, our div and section respectively, both color properties are applied without conflict. The nested p element has no color specified, so the results are determined by inheritance (the color of the direct parent) rather than cascade. Proximity takes precedence, and the #inner value overrides the #outer.

But there’s a problem: In order to use inheritance, we are styling everything inside our section and div. We want to target the paragraph color specifically.

(Re-)Introducing Custom Properties

Custom properties provide a new, browser-native solution; they inherit like any other property, but they don’t have to be used where they are defined. Using plain CSS, without any naming conventions or build tools, we can create a style that is both targeted and contextual, with proximity taking precedence over the cascade:

See the Pen [Custom Props: Specificity vs Proximity](https://codepen.io/smashingmag/pen/gNGdaO/) by Miriam Suzanne.

See the Pen Custom Props: Specificity vs Proximity by Miriam Suzanne. p { color: var(--paragraph); } #inner { --paragraph: green; } #outer { --paragraph: red; }

The custom --paragraph property inherits just like the color property, but now we have control over exactly how and where that value is applied. The --paragraph property acts similar to a parameter that can be passed into the p component, either through direct selection (specificity-rules) or context (proximity-rules).

I think this reveals a potential for custom properties that we often associate with functions, mixins, or components.

Custom “Functions” And Parameters

Functions, mixins, and components are all based on the same idea: reusable code, that can be run with various input parameters to get consistent-but-configurable results. The distinction is in what they do with the results. We’ll start with a striped-gradient variable, and then we can extend it into other forms:

html { --stripes: linear-gradient( to right, powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

That variable is defined on the root html element (could also use :root, but that adds unnecessary specificity), so our striped variable will be available everywhere in the document. We can apply it anywhere gradients are supported:

See the Pen [Custom Props: Variable](https://codepen.io/smashingmag/pen/NZwrrm/) by Miriam Suzanne.

See the Pen Custom Props: Variable by Miriam Suzanne. body { background-image: var(--stripes); } Adding Parameters

Functions are used like variables, but define parameters for changing the output. We can update our --stripes variable to be more function-like by defining some parameter-like variables inside it. I’ll start by replacing to right with var(--stripes-angle), to create an angle-changing parameter:

html { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

There are other parameters we could create, depending on what purpose the function is meant to serve. Should we allow users to pick their own stripe colors? If so, does our function accept 5 different color parameters or only 3 that will go outside-in like we have now? Do we want to create parameters for color-stops as well? Every parameter we add provides more customization at the cost of simplicity and consistency.

There is no universal right answer to that balance — some functions need to be more flexible, and others need to be more opinionated. Abstractions exist to provide consistency and readability in your code, so take a step back and ask what your goals are. What really needs to be customizable, and where should consistency be enforced? In some cases, it might be more helpful to have two opinionated functions, rather than one fully-customizable function.

To use the function above, we need to pass in a value for the --stripes-angle parameter, and apply the output to a CSS output property, like background-image:

/* in addition to the code above… */ html { --stripes-angle: 75deg; background-image: var(--stripes); }

See the Pen [Custom Props: Function](https://codepen.io/smashingmag/pen/BgwOjj/) by Miriam Suzanne.

See the Pen Custom Props: Function by Miriam Suzanne. Inherited Versus Universal

I defined the --stripes function on the html element out of habit. Custom properties inherit, and I want my function available everywhere, so it makes some sense to put it on the root element. That works well for inheriting variables like --brand-color: blue, so we might also expect it to work for our “function” as well. But if we try to use this function again on a nested selector, it won’t work:

See the Pen [Custom Props: Function Inheritance Fail](https://codepen.io/smashingmag/pen/RzjRrM/) by Miriam Suzanne.

See the Pen Custom Props: Function Inheritance Fail by Miriam Suzanne. div { --stripes-angle: 90deg; background-image: var(--stripes); }

The new --stripes-angle is ignored entirely. It turns out we can’t rely on inheritance for functions that need to be re-calculated. That’s because each property value is computed once per element (in our case, the html root element), and then the computed value is inherited. By defining our function at the document root, we don’t make the entire function available to descendants — only the computed result of our function.

That makes sense if you frame it in terms of the cascading --stripes-angle parameter. Like any inherited CSS property, it is available to descendants but not ancestors. The value we set on a nested div is not available to a function we defined on the html root ancestor. In order to create a universally-available function that will re-calculate on any element, we have to define it on every element:

See the Pen [Custom Props: Universal Function](https://codepen.io/smashingmag/pen/agLaNj/) by Miriam Suzanne.

See the Pen Custom Props: Universal Function by Miriam Suzanne. * { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); }

The universal selector makes our function available everywhere, but we can define it more narrowly if we want. The important thing is that it can only re-calculate where it is explicitly defined. Here are some alternatives:

/* make the function available to elements with a given selector */ .stripes { --stripes: /* etc… */; } /* make the function available to elements nested inside a given selector */ .stripes * { --stripes: /* etc… */; } /* make the function available to siblings following a given selector */ .stripes ~ * { --stripes: /* etc… */; }

See the Pen [Custom Props: Scoped Function](https://codepen.io/smashingmag/pen/JQMvGM/) by Miriam Suzanne.

See the Pen Custom Props: Scoped Function by Miriam Suzanne.

This can be extended with any selector logic that doesn’t rely on inheritance.

Free Parameters And Fallback Values

In our example above, var(--stripes-angle) has no value and no fallback. Unlike Sass or JS variables that must be defined or instantiated before they are called, CSS custom properties can be called without ever being defined. This creates a “free” variable, similar to a function parameter that can be inherited from the context.

We can eventually define the variable on html or :root (or any other ancestor) to set an inherited value, but first we need to consider the fallback if no value is defined. There are several options, depending on exactly what behavior we want

  1. For “required” parameters, we don’t want a fallback. As-is, the function will do nothing until --stripes-angle is defined.
  2. For “optional” parameters, we can provide a fallback value in the var() function. After the variable-name, we add a comma, followed by the default value:
var(--stripes-angle, 90deg)

Each var() function can only have one fallback — so any additional commas will be part of that value. That makes it possible to provide complex defaults with internal commas:

html { /* Computed: Hevetica, Ariel, sans-serif */ font-family: var(--sans-family, Hevetica, Ariel, sans-serif); /* Computed: 0 -1px 0 white, 0 1px 0 black */ test-shadow: var(--shadow, 0 -1px 0 white, 0 1px 0 black); }

We can also use nested variables to create our own cascade rules, giving different priorities to the different values:

var(--stripes-angle, var(--global-default-angle, 90deg))
  1. First, try our explicit parameter (--stripes-angle);
  2. Fallback to a global “user default” (--user-default-angle) if it’s available;
  3. Finally, fallback to our “factory default” (90deg).

See the Pen [Custom Props: Fallback Values](https://codepen.io/smashingmag/pen/jjGvVm/) by Miriam Suzanne.

See the Pen Custom Props: Fallback Values by Miriam Suzanne.

By setting fallback values in var() rather than defining the custom property explicitly, we ensure that there are no specificity or cascade restrictions on the parameter. All the *-angle parameters are “free” to be inherited from any context.

Browser Fallbacks Versus Variable Fallbacks

When we’re using variables, there are two fallback paths we need to keep in mind:

  1. What value should be used by browsers without variable support?
  2. What value should be used by browsers that support variables, when a particular variable is missing or invalid?
p { color: blue; color: var(--paragraph); }

While old browsers will ignore the variable declaration property, and fallback to blue — modern browsers will read both and use the latter. Our var(--paragraph) might not be defined, but it is valid and will override the previous property, so browsers with variable support will fallback to the inherited or initial value, as if using the unset keyword.

That may seem confusing at first, but there are good reasons for it. The first is technical: browser engines handle invalid or unknown syntax at “parse time” (which happens first), but variables are not resolved until “computed-value time” (which happens later).

  1. At parse time, declarations with invalid syntax are ignored completely — falling back on earlier declarations. This is the path that old browsers will follow. Modern browsers support the variable syntax, so the previous declaration is discarded instead.
  2. At computed-value time the variable is compiled as invalid, but it’s too late — the previous declaration was already discarded. According to the spec, invalid variable values are treated the same as unset:

See the Pen [Custom Props: Invalid/Unsupported vs Undefined](https://codepen.io/smashingmag/pen/VJMGbJ/) by Miriam Suzanne.

See the Pen Custom Props: Invalid/Unsupported vs Undefined by Miriam Suzanne. html { color: red; /* ignored as *invalid syntax* by all browsers */ /* - old browsers: red */ /* - new browsers: red */ color: not a valid color; color: var(not a valid variable name); /* ignored as *invalid syntax* by browsers without var support */ /* valid syntax, but invalid *values* in modern browsers */ /* - old browsers: red */ /* - new browsers: unset (black) */ --invalid-value: not a valid color value; color: var(--undefined-variable); color: var(--invalid-value); }

This is also good for us as authors, because it allows us to play with more complex fallbacks for the browsers that support variables, and provide simple fallbacks for older browsers. Even better, that allows us to use the null/undefined state to set required parameters. This becomes especially important if we want to turn a function into a mixin or component.

Custom Property “Mixins”

In Sass, the functions return raw values, while mixins generally return actual CSS output with property-value pairs. When we define a universal --stripes property, without applying it to any visual output, the result is function-like. We can make that behave more like a mixin, by defining the output universally as well:

* { --stripes: linear-gradient( var(--stripes-angle), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

As long as --stripes-angle remains invalid or undefined, the mixin fails to compile, and no background-image will be applied. If we set a valid angle on any element, the function will compute and give us a background:

div { --stripes-angle: 30deg; /* generates the background */ }

Unfortunately, that parameter-value will inherit, so the current definition creates a background on the div and all descendants. To fix that, we have to make sure the --stripes-angle value doesn’t inherit, by resting it to initial (or any invalid value) on every element. We can do that on the same universal selector:

See the Pen [Custom Props: Mixin](https://codepen.io/smashingmag/pen/ZdXMJx/) by Miriam Suzanne.

See the Pen Custom Props: Mixin by Miriam Suzanne. * { --stripes-angle: initial; --stripes: /* etc… */; background-image: var(--stripes); } Safe Inline Styles

In some cases, we need the parameter to be set dynamically from outside CSS — based on data from a back-end server or front-end framework. With custom properties, we can safely define variables in our HTML without worrying about the usual specificity issues:

See the Pen [Custom Props: Mixin + Inline Style](https://codepen.io/smashingmag/pen/qzPMPv/) by Miriam Suzanne.

See the Pen Custom Props: Mixin + Inline Style by Miriam Suzanne. <div style="--stripes-angle: 30deg">...</div>

Inline styles have a high specificity, and are very hard to override — but with custom properties, we we have another option: ignore it. If we set the div to background-image: none (for example) that inline variable will have no impact. To take it even farther, we can create an intermediate variable:

* { --stripes-angle: var(--stripes-angle-dynamic, initial); }

Now we have the option to define --stripes-angle-dynamic in the HTML, or ignore it, and set --stripes-angle directly in our stylesheet.

See the Pen [Custom Props: Mixin + Inline / Override](https://codepen.io/smashingmag/pen/ZdXMao/) by Miriam Suzanne.

See the Pen Custom Props: Mixin + Inline / Override by Miriam Suzanne. Preset Values

For more complex values, or common patterns we want to re-use, we can also provide a few preset variables to choose from:

* { --tilt-down: 6deg; --tilt-up: -6deg; }

And use those presets, rather than setting the value directly:

<div style="--stripes-angle: var(--tilt-down)">...</div>

See the Pen [Custom Props: Mixin + Presets](https://codepen.io/smashingmag/pen/LKemZm/) by Miriam Suzanne.

See the Pen Custom Props: Mixin + Presets by Miriam Suzanne.

This is great for creating charts and graphs based on dynamic data, or even laying out a day planner.

See the Pen [Bar chart in CSS grid + variables](https://codepen.io/smashingmag/pen/wLrEyg/) by Miriam Suzanne.

See the Pen Bar chart in CSS grid + variables by Miriam Suzanne. Contextual Components

We can also re-frame our “mixin” as a “component” by applying it to an explicit selector, and making the parameters optional. Rather than relying on the presence-or-absence of --stripes-angle to toggle our output, we can rely on the presence-or-absence of a component selector. That allows us to set fallback values safely:

See the Pen [Custom Props: Component](https://codepen.io/smashingmag/pen/QXqVmM/) by Miriam Suzanne.

See the Pen Custom Props: Component by Miriam Suzanne. [data-stripes] { --stripes: linear-gradient( var(--stripes-angle, to right), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

By putting the fallback inside the var() function, we can leave --stripes-angle undefined and “free” to inherit a value from outside the component. This is a great way to expose certain aspects of a component style to contextual input. Even “scoped” styles generated by a JS framework (or scoped inside the shadow-DOM, like SVG icons) can use this approach to expose specific parameters for outside influence.

Isolated Components

If we don’t want to expose the parameter for inheritance, we can define the variable with a default value:

[data-stripes] { --stripes-angle: to right; --stripes: linear-gradient( var(--stripes-angle, to right), powderblue 20%, pink 20% 40%, white 40% 60%, pink 60% 80%, powderblue 80% ); background-image: var(--stripes); }

These components would also work with a class, or any other valid selector, but I chose the data-attribute to create a namespace for any modifiers we want:

[data-stripes='vertical'] { --stripes-angle: to bottom; } [data-stripes='horizontal'] { --stripes-angle: to right; } [data-stripes='corners'] { --stripes-angle: to bottom right; }

See the Pen [Custom Props: Isolated Components](https://codepen.io/smashingmag/pen/agLaGX/) by Miriam Suzanne.

See the Pen Custom Props: Isolated Components by Miriam Suzanne. Selectors and Parameters

I often wish I could use data-attributes to set a variable — a feature supported by the CSS3 attr() specification, but not yet implemented in any browsers (see the resources tab for linked issues on each browser). That would allow us to more closely associate a selector with a particular parameter:

<div data-stripes="30deg">...</div> /* Part of the CSS3 spec, but not yet supported */ /* attr( , ) */ [data-stripes] { --stripes-angle: attr(data-stripes angle, to right); }

In the meantime, we can achieve something similar by using the style attribute:

See the Pen [Custom Props: Style Selectors](https://codepen.io/smashingmag/pen/PrJdBG/) by Miriam Suzanne.

See the Pen Custom Props: Style Selectors by Miriam Suzanne. <div style="--stripes-angle: 30deg">...</div> /* The `*=` atttribute selector will match a string anywhere in the attribute */ [style*='--stripes-angle'] { /* Only define the function where we want to call it */ --stripes: linear-gradient(…); }

This approach is most useful when we want to include other properties in addition to the parameter being set. For example, setting a grid area could also add padding and background:

[style*='--grid-area'] { background-color: white; grid-area: var(--grid-area, auto / 1 / auto / -1); padding: 1em; } Conclusion

When we start to put all these pieces together, it becomes clear that custom properties go far beyond the common variable use-cases we’re familiar with. We’re not only able to store values, and scope them to the cascade — but we can use them to manipulate the cascade in new ways, and create smarter components directly in CSS.

This calls for us to re-think many of the tools we’ve relied on in the past — from naming conventions like SMACSS and BEM, to “scoped” styles and CSS-in-JS. Many of those tools help work around specificity, or manage dynamic styles in another language — use-cases that we can now address directly with custom properties. Dynamic styles that we’ve often calculated in JS, can now be handled by passing raw data into the CSS.

At first, these changes may be seen as “added complexity” — since we’re not used to seeing logic inside CSS. And, as with all code, over-engineering can be a real danger. But I’d argue that in many cases, we can use this power not to add complexity, but to move complexity out of third-party tools and conventions, back into the core language of web design, and (more importantly) back into the browser. If our styles require calculation, that calculation ought to live inside our CSS.

All of these ideas can be taken much further. Custom properties are just starting to see wider adoption, and we’ve only begun to scratch the surface of what’s possible. I’m excited to see where this goes, and what else people come up with. Have fun!

Further Reading (dm, il)
Categories: Web Design

The Joys Of July (2019 Wallpapers Edition)

Sun, 06/30/2019 - 01:30
The Joys Of July (2019 Wallpapers Edition) The Joys Of July (2019 Wallpapers Edition) Cosima Mielke 2019-06-30T10:30:34+02:00 2019-07-01T12:46:47+00:00

A scoop of their favorite ice cream, a bike ride in the summer rain, or listening to the frog concert by the nearby lake — a lot of little things and precious moments have inspired the design community to create a wallpaper this July.

This monthly wallpapers challenge has been going on for more than nine years now, and each time anew, artists and designers from across the globe take it as an occasion to tickle their creativity and cater for beautiful, unique, and thought-provoking wallpaper designs. Wallpapers that are bound to get your ideas sparking, too.

The wallpapers in this collection all come in versions with and without a calendar for July 2019 and can be downloaded for free. A big thank-you to everyone who submitted their designs! At the end of this post, we also compiled some July favorites from past years’ editions that are just too good to be forgotten. Enjoy!

Please note that:

  • All images can be clicked on and lead to the preview of the wallpaper,
  • You can feature your work in our magazine, too. So if you have an idea for an August wallpaper design, please don’t hesitate to submit it. We’d love to see what you’ll come up with.

Further Reading on SmashingMag:

Hello, Strawberry Sundae!

“Is there anything more refreshing (and more delicious!) than a strawberry sundae on a hot summer day? Well, we don’t think so. And did you know that strawberry celebration is on its way in the U.S. Oh, yes! July 7th is the National Strawberry Sundae Day, and we predict that it’s going to be sweet and yummy. So, make your favorite dessert and start preparing yourself for the festive July days.” — Designed by PopArt Studio from Serbia.

Riding In The Drizzle

“Rain has come, showering the existence with new seeds of life… Everywhere life is blooming, as if they were asleep and the falling music of raindrops have awakened them… Feel the drops of rain… Feel this beautiful mystery of life… Listen to its music, melt into it…” — Designed by DMS Software from India.

We All Scream For Ice Cream

“There are two things that come to mind when I think about July: ice cream and the Fourth of July!” — Designed by Alyssa Merkel from the United States.

My July

Designed by Cátia Pereira from Portugal.

Alentejo Plain

“Based on the Alentejo region, south of Portugal, where there are large plains used for growing wheat. It thus represents the extensions of the fields of cultivation and their simplicity. Contrast of the plain with the few trees in the fields. Storks that at this time of year predominate in this region, being part of the Alentejo landscape and mentioned in the singing of Alentejo.” — Designed by José Guerra from Portugal.

Frogs In The Night

“July is coming and the nights are warmer. Frogs look at the moon while they talk about their day.” — Designed by Veronica Valenzuela from Spain.

July Rocks!

Designed by Joana Moreira from Portugal.

Plastic Bag Free Day

“The objective of this date is to draw attention to the production and over-consumption of plastic bags worldwide, presenting alternatives to solve this serious environmental problem. It is urgent to change the behavior of all human beings regarding the use of plastic bags. For the preservation of the environment, we should use the same plastic bag for shopping, recycling or use paper bags. In this wallpaper I drew a plastic bag with a turtle inside it, as if it was imprisoned by its own bag, as if the ocean was reduced to a plastic bag, emphasizing the seriousness of this environmental problem, which has tortured both turtles and many others marine species.” — Designed by Carolina Santos from Portugal.

Save The Tigers

“Global Tiger Day, often called International Tiger Day, is an annual celebration to raise awareness for tiger conservation, held annually on July 29. It was created in 2010 at the Saint Petersburg Tiger Summit. The goal of the day is to promote a global system for protecting the natural habitats of tigers and to raise public awareness and support for tiger conservation issues.” — Designed by Athulya from Calicut.


“I was inspired by Hawaii type of scenarios with some reference to surf.” — Designed by Sónia Fernandes from Portugal.

Friendship Day

“The lower part of the image is represented in a more realistic and detailed form and represents the basis of the friendship, conveying a strong connection both in the simplicity and strength of the gestures, hands and medals that both children wear around their necks are symbols of this union. In terms of color I chose to use the ash scale, referring to the old photograph, implying the idea of a long duration of the relations of friendships and the memories we keep of our childhood friends, the illustration represented portrays a memory of mine, which makes it very personal. At the top of the wallpaper, the identity of the two characters appears pixelated, suggesting an idea of building deconstruction, through colored squares that come together and move away, as a symbol of connections and the sharing of emotions, which build and strengthen bonds of friendship.” — Designed by Carolina Santos from Portugal.

Yellow Lemon Tree

“Summer is here, enjoy it and cool and stay hydrated!” — Designed by Melissa Bogemans from Belgium.

Summer Energy

Designed by IQUADART from Belarus.

Heat Wave

Designed by Ricardo Gimenes from Sweden.

Season Of Wind

“Summer is the season of wind. I like to stand on top of the mountains, hearing the song of the wind flying through the meadow.” — Designed by Anh Nguyet Tran from Vietnam.

Oldies But Goodies

Let’s go an a journey back in time: Down in our wallpaper archives, we rediscovered some July classics that are just too good to gather dust. May we present… (Please note that these designs don’t come with a calendar.)

Fire Camp

“What’s better than a starry summer night with an (unexpected) friend around a fire camp with some marshmallows? Happy July!” — Designed by Etienne Mansard from the UK.

Heated Mountains

“Warm summer weather inspired the color palette.” — Designed by Marijana Pivac from Croatia.

Tutti Frutti

“July is National Ice Cream Month and who needs an invitation for a scoop or two, or three! Lacking the real thing, our Tutti Frutti wallpaper can satisfy until your next creamy indulgence.” — Designed by Karen Frolo from the United States.

Memories In July

“Words are few, thoughts are deep, memories of you we’ll always keep.” — Designed by Suman Sil from India.

Cactus Hug

Designed by Ilaria Bagnasco from Italy.

Keep Moving Forward

“Snails can be inspiring! If you keep heading towards your goal, even if it is just tiny steps, enjoy the journey and hopefully it will be worth the effort.” — Designed by Glynnis Owen from Australia.

Sand And Waves

“What do you do in summer? You go to the beach. Even if you can’t go — feel the waves and sand and sun through this funny wallpaper.” — Designed by Olga Lepaeva from Russia.

Island River

“Make sure you have a refreshing source of ideas, plans and hopes this July. Especially if you are to escape from urban life for a while.” — Designed by Igor Izhik from Canada.

Ice Cream vs. Hot Dog

“It’s both ‘National Ice Cream Month’ and ‘National Hot Dog Month’ over in the US, which got me thinking — which is better? With this as your wallpaper, you can ponder the question all month!” — Designed by James Mitchell from the UK.

Summer Heat

Designed by Xenia Latii from Berlin, Germany.

Peaceful Memories

“July is one of the most beautiful months of the year. Enjoy every day, every hour, which gives us this month!” — Designed by Nikolay Belikov from Russia.

Floral Thing

“The wallpaper which I created consists of my personal sketches of Polish herbs and flowers and custom typography. I wanted it to be light and simple with a hint of romantic feeling. I hope you’ll enjoy it!” — Designed by Beata Kurek from Poland.

An Intrusion Of Cockroaches

“Ever watched Joe’s Apartment when you were a kid? Well that movie left a soft spot in my heart for the little critters. Don’t get me wrong: I won’t invite them over for dinner, but I won’t grab my flip flop and bring the wrath upon them when I see one running in the house. So there you have it… three roaches… bringing the smack down on that pesky human… ZZZZZZZAP!!” — Designed by Wonderland Collective from South Africa.

Celebrate Freedom

“This wallpaper encourages you to appreciate and celebrate the country’s freedom as well as your own!” — Designed by Marina Zhukov from the USA.

Hot Air Balloon

Designed by Studcréa from France

Only One

Designed by Elise Vanoorbeek from Belgium

Cool Summer

“Even though it is not summer in my country, I made a summer theme. A cool approach to summer themes, tough, very fresh and ‘twilighty’.” — Designed by Marcos Sandrini from Brazil.

Birdie Nam Nam

“I have created a pattern that has a summer feeling. For me July and summer is bright color, joy and lots of different flowers and birds. So naturally I incorporated all these elements in a crazy pattern.” — Designed by Lina Karlsson, Idadesign Ab from Sweden.

Sun In July

”…enjoy the sun in July!” — Designed by Marco Palma from Italy/Germany.

Join In Next Month!

Please note that we respect and carefully consider the ideas and motivation behind each and every artist’s work. This is why we give all artists the full freedom to explore their creativity and express emotions and experience throughout their works. This is also why the themes of the wallpapers weren’t anyhow influenced by us but rather designed from scratch by the artists themselves.

Thank you to all designers for their participation. Join in next month!

Categories: Web Design

Better Search UX Through Microcopy

Fri, 06/28/2019 - 03:30
Better Search UX Through Microcopy Better Search UX Through Microcopy Andrew Millen 2019-06-28T12:30:59+02:00 2019-07-01T12:46:47+00:00

It’s hard to overstate the importance of web search. Searching is as old as the Internet itself, and by some measures, even older. A well-designed search benefits both you and your users; it increases conversions, reduces bounce rates, and improves the user experience.

Search is especially important on large scale sites and e-commerce experiences, where the majority of revenue comes from search-driven sessions. Studies show that up to 50% of users go straight to the internal search bar of a website, and that 15% outright prefer using the search function to browsing the hierarchical menu. This means that for all the love and care that goes into determining the information architecture of a site, just as much has to go into designing the search experience.

Complicating the problem is the fact that users’ search skills are flimsy at best, and incompetent at worst. Getting good results from a search engine often requires multiple attempts and reformulations, which users rarely do. And as search technology improves over time, users are increasingly likely to accept the results of a search as the answer to their question, even if their query was flawed. Users who favor searches tend to move quickly, scanning the page for that familiar-looking rectangle, and bouncing quickly when they don’t find what they’re looking for.

Communicating with those users “at speed” is a tricky job that requires a specialized tool: microcopy. The name ‘microcopy’ belies its own importance. It may be small, but big successes often hinge on it. It’s a place where voice can shine through, where good impressions are made, and where utility and branding intersect. With that in mind, let’s dive into the many ways that microcopy and contextualization can vastly improve a search experience.

Placing And Labeling Your Search

In accordance with Jakob’s Law, your first instinct when designing a search bar should be to put a rectangular box in the upper right or upper left corner. You should add a label or A11y-friendly placeholder text, and include a submit button that says “Search.”

Hiding the search bar behind a link, forgoing placeholder text, or opting for magnifying glass icon CTA instead of plain text are all valid design decisions in the right context. Just make sure you’re not abstracting the function of the search bar unnecessarily because searching already has a higher interaction cost than browsing.

Every barrier, however inconsequential you may find it as a designer, risks negatively affecting the UX and your bottom line. If there’s a risk your users may confuse the magnifying glass icon for a “zoom” button, you should mitigate that.

Placeholder Text

Placeholder text is a great place to enhance the experience. It can be informational, it can be a place for brand expression, and it can nudge wavering users in the right direction. Anytime I see a search bar that just says “Search,” I see a missed opportunity.

So what’s a better approach? It varies from site to site. First, familiarize yourself with your business goals, your brand, and your users’ existing habits. Then, consider how you can be the most helpful.

Nudge The User

A suggestive approach can reduce the user’s anxiety. Clue your users into the fact that they can search in multiple ways, especially if they may not be familiar with your full range of products or services. ASOS suggests searching for inspiration in addition to products and brands:

(Image source: ASOS) (Large preview) Be Informative

Tell the user exactly what they’ll be getting when they hit submit. On Shutterstock, a site wholly devoted to the search of a massive photo archive, this placeholder text cleverly doubles as a tagline when paired with the logo:

(Image source: Shutterstock) (Large preview) Reinforce The Brand

Home Depot’s search bar doesn’t lead the user, but instead presents a helpful, personal tone which I’m sure is in line with their brand voice guidelines. This is probably the best approach considering the size of their product catalog:

(Image source: The Home Depot) (Large preview) Using Search Logs To Your Advantage

If you’re not sure the best way to optimize your placeholder text, a good place to start is your search log database. Learning how to break down these results can be incredibly valuable when formulating helpful content design. You’ll be able to see first-hand the vocabulary people use to search your site, and more importantly, the gaps between what you offer and what your users are looking for.

Suggested, Related, And Recent Searches

During the search process, your copy should offer as much help along the way as possible without being overbearing. That includes everything from an obvious “Cancel” or “Clear” button to logging each user’s recent searches for surfacing later. When choosing the right microcopy to accompany these features, add a dash of brown sauce.


Users who use the search bar are doing so because they’re looking for something specific, which makes autosuggestions a valuable (and increasingly expected) tool. Specificity, in this case, may be as focused as “Women’s gray shoe size 9M” or as open-ended as “Sandwich shops near me.”

Autosuggestions also reduce the risk of returning bad results, alleviate the mental effort on the user, and present an opportunity to surface your most popular products.

(Image source: Chewy) (Large preview)

Often these don’t require additional context or copy at all, but can just be listed below the search bar as the user types, as shown in the example above.

Related Searches

Showing related searches on the results page is another way to help guide users without getting in the way. A common pattern is providing a few clickable keywords related to the original query above the results. A little copy that states “Other users searched for” is a good way to incorporate social proof into the search experience.

Recent Searches

If your technology allows it, saving and resurfacing recent searches is another way to helpfully reduce the memory load on the user. Make sure you add context with copy, but it can be as straightforward as this:

(Image source: Macy’s) (Large preview) Handling Results

There are a two pieces of copy that I’d consider required when displaying search results:

  1. The query itself.
    If the search bar is highly visible, it can be displayed here. You can also create an H1 that states "Results for {{terms}}."
  2. The number of results.
    If the results are paginated, you might also include the number of pages.
(Image source: REI Co-op) (Large preview) No Results

Whether through their own error not, users will inevitably encounter a “no results” page at some point. Luckily, there are ways to handle this gracefully; in fact, with the right approach, this dead end can actually be a great opportunity for content discovery.

First of all, don’t expect your users to refine their search if they get no results — at least not without a UI that encourages it. Users are reluctant to reformulate their query and have trouble when trying to. They’re more likely to engage with whatever information they’re presented with and take it from there, or abandon the task entirely. (When was the last time you clicked through to the second page of Google search results?)

That said, it’s easy to see how a little copywriting and contextualization can improve the experience. Nielsen Norman Group has a comprehensive guide on how to handle No Results SERPs, with the gist being:

  • Make it obvious there are no results.
    It’s easy to get cute and accidentally bury the lede. It’s also tempting to intentionally hide the “no results” messaging to obfuscate the error entirely. Either way, don’t trick the user.
  • Offer paths forward.
    Suggest ways to refine the search query (such as checking your spelling), and also provide links to popular content or products that have the highest likelihood of connecting with the user.
  • Strike the right tone.
    Use your brand voice, but don’t run the risk of exacerbating the situation with humor that might be ill-received by a frustrated user.

Also, bear in mind that empty SERPs may arise because a user mistakenly submitted without entering any query at all. You should have a content plan for this scenario as well rather than returning all items in the database, for example.

Wrapping Up

Writing a good search experience comes down to thoughtfulness. As designers, we’ve probably used and created hundreds of different web search experiences, so we breeze through the process. But when we consider every small step of the process (every microinteraction and every edge case), the minor changes we make can have a major impact on the experience. Next time you find yourself reaching for a visual solution to a search problem, consider using your words instead.

Further Reading on SmashingMag: (dm, yk, il)
Categories: Web Design

Build A PWA With Webpack And Workbox

Thu, 06/27/2019 - 04:00
Build A PWA With Webpack And Workbox Build A PWA With Webpack And Workbox Jad Joubran 2019-06-27T13:00:59+02:00 2019-07-01T12:46:47+00:00

A Progressive Web App (PWA) is a site that uses modern technology to deliver app-like experiences on the web. It’s an umbrella term for new technologies such as the ‘web app manifest’, ‘service worker’, and more. When joined together, these technologies allow you to deliver fast and engaging user experiences with your website.

This article is a step-by-step tutorial for adding a service worker to an existing one-page website. The service worker will allow you to make your website work offline while also notifying your users of updates to your site. Please note that this is based on a small project that is bundled with Webpack, so we’ll be using the Workbox Webpack plugin (Workbox v4).

Using a tool to generate your service worker is the recommended approach as it lets you manage your cache efficiently. We will be using Workbox — a set of libraries that make it easy to generate your service worker code — to generate our service worker in this tutorial.

Depending on your project, you can use Workbox in three different ways:

  1. A command-line interface is available which lets you integrate workbox into any application you have;
  2. A Node.js module is available which lets you integrate workbox into any Node build tool such as gulp or grunt;
  3. A webpack plugin is available which lets you easily integrate with a project that is built with Webpack.

Webpack is a module bundler. To simplify, you can think of it as a tool that manages your JavaScript dependencies. It allows you to import JavaScript code from libraries and bundles your JavaScript together into one or many files.

To get started, clone the following repository on your computer:

git clone git@github.com:jadjoubran/workbox-tutorial-v4.git cd workbox-tutorial-v4 npm install npm run dev

Next, navigate to http://localhost:8080/. You should be able to see the currency app we’ll be using throughout this tutorial:

‘Currencies’ is a PWA that lists conversion fees of currencies against the Euro (€) currency. (Large preview) Start With An App Shell

The application shell (or ‘app shell’) is a pattern inspired from Native Apps. It will help give your app a more native look. It simply provides the app with a layout and structure without any data — a transitional screen that is aimed to improve the loading experience of your web app.

Here are some examples of app shells from native apps:

Google Inbox App Shell: A few milliseconds before the emails load into the app shell. (Large preview) Twitter’s native app on Android: App shell showing navbar, tabs, and loader. (Large preview)

And here are examples of app shells from PWAs:

The app shell of Twitter’s PWA (Large preview) The app shell of Flipkart’s PWA (Large preview)

Users like the loading experience of app shells because they despise blank screens. A blank screen makes the user feel that the website is not loading. It makes them feel as if the website were stuck.

App shells attempt to paint the navigational structure of the app as soon as possible, such as the navbar, the tab bar as well as a loader signifying that the content you’ve requested is being loaded.

So How Do You Build An App Shell?

The app shell pattern prioritizes the loading of the HTML, CSS and JavaScript that will render first. This means that we need to give those resources full priority, hence you have to inline those assets. So to build an app shell, you simply have to inline the HTML, CSS and JavaScript that are responsible for the app shell. Of course, you should not inline everything but rather stay within a limit of around 30 to 40KB total.

You can see the inlined app shell in the index.html. You can inspect the source code by checking out the index.html file, and you can preview it in the browser by deleting the <main> element in dev tools:

The App Shell that we’re building in this article. (Large preview) Does It Work Offline?

Let’s simulate going offline! Open DevTools, navigate to the network tab and tick the ‘Offline’ checkbox. When you reload the page, you will see that we will get the browser’s offline page.

The request to the homepage failed so we obviously see this as a result. (Large preview)

That’s because the initial request to / (which will load the index.html file) will fail because the Internet is offline. The only way for us to recover from that request failure is by having a service worker.

Let’s visualize the request without a service worker:

Network request goes from the browser to the Internet and back. (Icons from flaticon.com) (Large preview)

A service worker is a programmable network proxy, which means it sits in between your web page and the Internet. This lets you control incoming and outgoing network requests.

Network request gets intercepted by the service worker. (Icons from flaticon.com) (Large preview)

This is beneficial because we can now re-route this failed request to the cache (assuming we have the content in the cache).

Network request gets redirected to the cache when it already exists in the cache. (Icons from flaticon.com) (Large preview)

A service worker is also a type of Web Worker, meaning that it runs separately from your main page and doesn’t have access to either the window or document object.

Precache The App Shell

In order to make our app work offline, we’re going to start by precaching the app shell.

So let’s start by installing the Webpack Workbox plugin:

npm install --save-dev workbox-webpack-plugin

Then we’re going to open our index.js file and register the service worker:

if ("serviceWorker" in navigator){ window.addEventListener("load", () => { navigator.serviceWorker.register("/sw.js"); }) }

Next, open the webpack.config.js file and let’s configure the Workbox webpack plugin:

//add at the top const WorkboxWebpackPlugin = require("workbox-webpack-plugin"); //add inside the plugins array: plugins: [ … , new WorkboxWebpackPlugin.InjectManifest({ swSrc: "./src/src-sw.js", swDest: "sw.js" }) ]

This will instruct Workbox to use our ./src/src-sw.js file as a base. The generated file will be called sw.js and will be in the dist folder.

Then create a ./src/src-sw.js file at the root level and write the following inside of it:


Note: The self.__precacheManifest variable will be imported from a file that will be dynamically generated by workbox.

Now you’re ready to build your code with npm run build and Workbox will generate two files inside the dist folder:

  • precache-manifest.66cf63077c7e4a70ba741ee9e6a8da29.js
  • sw.js

The sw.js imports workbox from CDN as well as the precache-manifest.[chunkhash].js.

//precache-manifest.[chunkhash].js file self.__precacheManifest = (self.__precacheManifest || []).concat([ "revision": "ba8f7488757693a5a5b1e712ac29cc28", "url": "index.html" }, "url": "main.49467c51ac5e0cb2b58e.js" ]);

The precache manifest lists the names of the files that were processed by webpack and that end up in your dist folder. We will use these files to precache them in the browser. This means that when your website loads the first time and registers the service worker, it will cache these assets so that they can be used the next time.

You can also notice that some entries have a ‘revision’ whereas others don’t. That’s because the revision can sometimes be inferred from the chunkhash from the file name. For example, let’s take a closer look at the file name main.49467c51ac5e0cb2b58e.js. It has a revision is in the filename, which is the chunkhash 49467c51ac5e0cb2b58e.

This allows Workbox to understand when your files change so that it only cleans up or updates the files that were changed, rather than dumping all the cache every time you publish a new version of your service worker.

The first time you load the page, the service worker will install. You can see that in DevTools. First, the sw.js file is requested which then requests all the other files. They are clearly marked with the gear icon.

Requests marked with the ⚙️ icon are requests initiated by the service worker. (Large preview)

So Workbox will initialize and it will precache all the files that are in the precache-manifest. It is important to double check that you don’t have any unnecessary files in the precache-manifest file such as .map files or files that are not part of the app shell.

In the network tab, we can see the requests coming from the service worker. And now if you try to go offline, the app shell is already precached so it works even if we’re offline!

API calls fail when we go offline. (Large preview) Cache Dynamic Routes

Did you notice that when we went offline, the app shell works but not our data? That’s because these API calls are not part of the precached app shell. When there’s no Internet connection, these requests will fail and the user won’t be able to see the currency information.

However, these requests cannot be precached because their value comes from an API. Moreover, when you start having multiple pages, you don’t want to cache all API request in one go. Instead, you want to cache them when the user visits that page.

We call these ‘dynamic data’. They often include API calls as well as images and other assets that are requested when a user does a certain action on your website (e.g. when they browse to a new page).

You can cache these using Workbox’s routing module. Here’s how:

//add in src/src-sw.js workbox.routing.registerRoute( /https:\/\/api\.exchangeratesapi\.io\/latest/, new workbox.strategies.NetworkFirst({ cacheName: "currencies", plugins: [ new workbox.expiration.Plugin({ maxAgeSeconds: 10 * 60 // 10 minutes }) }) );

This will set up dynamic caching for any request URL that matches the URL https://api.exchangeratesapi.io/latest.

The caching strategy that we used here is called NetworkFirst; there are two other ones that are often used:

  1. CacheFirst
  2. StaleWhileRevalidate

CacheFirst will look for it in the cache first. If it’s not found, then it will get it from the network. StaleWhileRevalidate will go to the network and the cache at the same time. Return the cache’s response to the page (while in the background) it will use the new network response to update the cache for the next time it’s used.

For our use case, we had to go with NetworkFirst because we’re dealing with currency rates that change very often. However, when the user goes offline, we can at least show them the rates as they were 10 minutes ago — that’s why we used the expiration plugin with the maxAgeSeconds set to 10 * 60 seconds.

Manage App Updates

Everytime a user loads your page, the browser will run the navigator.serviceWorker.register code even though the service worker is already installed and running. This allows the browser to detect if there’s a new version of the service worker. When the browser notices that the file has not changed, it just skips the registration call. Once that file changes, the browser understands that there’s a new version of the service worker, thus it installs the new service worker parallel to the currently running service worker.

However, it pauses at the installed/waiting phase because only one service worker can be activated at the same time.

A simplified life cycle of a service worker (Large preview)

Only when all the browser windows controlled by the previous service worker are installed, then it becomes safe for the new service worker to activate.

You can also manually control that by calling skipWaiting() (or self.skipWaiting() since self is the global execution context in the service worker). However, most of the time you should only do that after asking the user if they want to get the latest update.

Thankfully, workbox-window helps us achieve this. It’s a new window library introduced in Workbox v4 that aims at simplifying common tasks on the window’s side.

Let’s start by installing it with the following:

npm install workbox-window

Next, import Workbox at the top of the file index.js:

import { Workbox } from "workbox-window";

Then we’ll replace our registration code with the below:

if ("serviceWorker" in navigator) { window.addEventListener("load", () => { const wb = new Workbox("/sw.js"); wb.register(); }); }

We’ll then find the update button which has the ID app-update and listen for the workbox-waiting event:

//add before the wb.register() const updateButton = document.querySelector("#app-update"); // Fires when the registered service worker has installed but is waiting to activate. wb.addEventListener("waiting", event => { updateButton.classList.add("show"); updateButton.addEventListener("click", () => { // Set up a listener that will reload the page as soon as the previously waiting service worker has taken control. wb.addEventListener("controlling", event => { window.location.reload(); }); // Send a message telling the service worker to skip waiting. // This will trigger the `controlling` event handler above. wb.messageSW({ type: "SKIP_WAITING" }); }); });

This code will show the update button when there’s a new update (so when the service worker is in a waiting state) and will send a SKIP_WAITING message to the service worker.

We’ll need update the service worker file and handle the SKIP_WAITING event such that it calls the skipWaiting:

//add in src-sw.js addEventListener("message", event => { if (event.data && event.data.type === "SKIP_WAITING") { skipWaiting(); });

Now run npm run dev then reload the page. Go into your code and update the navbar title to “Navbar v2”. Reload the page again, and you should be able to see the update icon.

Wrapping Up

Our website now works offline and is able to tell the user about new updates. Please keep in mind though, that the most important factor when building a PWA is the user experience. Always focus on building experiences that are easy to use by your users. We, as developers, tend to get too excited about technology and often end up forgetting about our users.

If you’d like to take this a step further, you can add a web app manifest which will allow your users to add the site to their home screen. And if you’d like to know more about Workbox, you can find the official documentation on the Workbox website.

Further Reading on SmashingMag: (dm, yk, il)
Categories: Web Design

What Web Designers Can Do To Speed Up Mobile Websites

Wed, 06/26/2019 - 05:00
What Web Designers Can Do To Speed Up Mobile Websites What Web Designers Can Do To Speed Up Mobile Websites Suzanne Scacca 2019-06-26T14:00:59+02:00 2019-07-01T12:46:47+00:00

I recently wrote a blog post for a web designer client about page speed and why it matters. What I didn’t know before writing it was that her agency was struggling to optimize their mobile websites for speed. As a result, she came back to me concerned with publishing a post on a strategy her agency had yet to adopt successfully.

She was torn though. She understood how important mobile page speeds were to the user experience and, by proxy, SEO. However, their focus has always been on making a great-looking and effective design. Something like page speed optimization was always left to the developers to worry about.

In the end, we decided to hold on publishing it until they could get their own website as well as their clients’ sites properly optimized. In the meantime, it got me thinking:

Is there anything designers can do when creating mobile websites to help developers optimize for speed?

Developers are already optimizing front end performance with:

  • Fast web hosting
  • CDNs
  • Clean coding practices
  • Caching
  • Minification
  • Image optimization
  • And more

So, is there anything left?

To me, this is a lot like how search optimization is handled. As a writer, I take care of the on-page optimizations while the developer I hand content over to does the technical SEO stuff. Web designers and developers can easily tackle the parts of speed optimization that are in each of their wheelhouses.

Understanding What “Slow” Means On The Mobile Web

There are a number of tools to help you analyze page speeds and implement various fixes to improve them. One tool that’s particularly helpful is called Lighthouse. The only thing is, it’s meant for web developers.

Instead, I suggest that web designers use another Google testing tool called Test My Site.

Test My Site is a mobile page speed testing tool from Think with Google. (Source: Test My Site) (Large preview)

This is strictly for those who want to get a quick evaluation of their mobile site speed. All you need to do is enter your domain name into the field and let the test run.

An example of your page speed test results from Test My Site. (Source: Test My Site) (Large preview)

What I like about this tool compared to other site speed tests is that it’s all spelled out for you in layman’s terms. In this case, my website is “slow”, even when served on 4G networks. Although we’ve been told for years that visitors are willing to wait three seconds for a web page to load, Google considers 2.9 seconds too long. (Which I wholeheartedly agree with.)

You can get an expanded report from Google that tells you how to speed up your mobile loading times, but the suggestions are no different than the updates you’d make on the development side. For example:

Think with Google suggests the typical page speed optimizations. (Source: Test My Site) (Large preview)

We already know this. However, if you (or your developer) haven’t yet implemented any of these fixes, this is a good checklist to work off of.

That said, I didn’t point you to this tool so you could keep doing the same optimizations over and over again, expecting the same result. What is it they always say about the definition of insanity?

Instead, I think you should use this as a quick gut check:

Is my mobile site fast enough in Google’s eyes? No? Then, it won’t be fast enough in your visitors’ eyes either.

And if you want to really drive that point home, scroll to the bottom of the Test My Site analysis page and run your numbers through the impact analysis calculator:

Test My Site’s revenue impact assessment. (Source: Test My Site) (Large preview)

If you aren’t completely convinced that you need to take your 3-second mobile speed down any further, look at the financial impact just .5 seconds would have on your monthly bottom line.

What Web Designers Can Do To Optimize Mobile Sites For Speed

Let the web developer handle all of the necessary speed optimizations like caching and file minification while you take on the following design tips and strategies:

1. Host Fonts From A CDN

There’s enough you have to worry about when it comes to designing fonts for the mobile experience that you probably don’t want to hear this… but custom web fonts suck when it comes to loading. In fact, there are two recent case studies that demonstrate why custom web fonts are detrimental to page loading speeds.

Thankfully, a CDN could end up being your saving grace.

The Downtime Monkey Example

The first comes from Downtime Monkey. In this case study, Downtime Monkey boasts a page speed improvement of 58% through a variety of optimizations — two of which pertained to how they served fonts to their site.

For their Font Awesome icons, they decided to host them from a CDN. However, Font Awesome’s own CDN proved unreliable, so they switched to the Bootstrap CDN. As a result, this saved them between 200 and 550 milliseconds per page load.

For their Google Font “Cabin”, they decided to host it from the Google CDN. What’s funny to note, however, is that when they ran a page speed test on the site afterwards, they received an optimization suggestion related to the font.

It seems that the link they put in the head of their site was slowing down the rendering of the page. So, they had to implement a workaround that would allow the font to load asynchronously without harming the display of the page as it loaded. They used Web Font Loader to fix the issue and ended up saving between 150 and 300 milliseconds per page load as a result.

Brian Jackson’s Test

Brian Jackson, the Chief Marketing Officer at Kinsta, wrote a post for KeyCDN that demonstrates the best way to serve custom web fonts on a website.

You can see in his example that he suggests a number of optimizations, like limiting which styles and character sets are available for use on the website. However, it’s his experimentation with CDN hosting that’s really interesting.

First, he isolated the most popular Google Fonts and tested how quickly they loaded through Google’s CDN:

Open Sans was the fast Google Font. (Source: KeyCDN) (Large preview)

Open Sans loaded the fastest.

But that shouldn’t automatically make Open Sans the best choice if you’re trying to speed up your website. After all, Opens Sans is a Google Font that has to be served from Google’s servers. When compared against Arial, a web-safe font that isn’t pulled from an external source, this is what happened:

A comparison of loading speeds between Arial and Open Sans. (Source: KeyCDN) (Large preview)

Arial beat Open Sans by almost 200 milliseconds.

Before we move on, I’ll just say that this is one way to solve the slow-loading font dilemma: rather than use externally hosted fonts, use your system ones. They might not be as exciting to design with, but they won’t force users to sit around and wait for your website to load, costing you visitors and customers in the process.

You might be thinking that downloading and hosting your Google font would make more sense then. That way, you don’t have to compromise on which fonts you use and it’ll shave time off of their normal loading speeds. Right?

Well, Brian was curious about that, too, so he did a test:

A comparison between Open Sans hosted locally vs. hosted on Google CDN. (Source: KeyCDN) (Large preview)

When served from a local server, Open Sans took 0.530 milliseconds to load. It’s not a huge difference, but it’s obviously not the right direction to go in.

So, what’s the conclusion? Well, you have a few options.

  1. You can use a web safe font and avoid the issues that come with using externally hosted fonts in the first place.
  2. You can use a Google font and make sure it’s hosted through Google’s CDN.
  3. You can download a Google font and upload it to your own CDN (if you can get it loading faster from there, that is).

Either way, hosting your fonts and icons from a location where they’ll load more quickly can help you optimize your website for performance.

2. Stop Using Cumbersome Design Elements

The following list is somewhat of a rehashing of topics that have been covered before, so I don’t want to waste your time trying to recreate the wheel here. However, I do think this strategy of removing unnecessary design elements (especially weightier ones) to optimize the mobile experience is one worth summarizing here:

Stop with On-Page Ads

When I wrote about elements you should ditch on mobile websites, I called out advertisements as one of the things you could easily toss out. I still stand by that conviction.

For starters, advertisements are served from a third party. Any time you have to call on another party’s servers, you’re further increasing your own loading times as you wait for them to deliver the content to your page.

Secondly, over 26% of the U.S. population alone uses ad-blocking technology on their devices, so they’re not likely to see your on-page ads anyway.

Statista data on the usage of ad-blocking technology in the U.S. (Source: Statista) (Large preview)

Instead, use monetization methods that move the advertising away from your website, increase your own on-site conversions and won’t drain your server’s resources:

  • Remarketing
    Let your tracking pixel follow visitors around the web and then serve your own ads on someone else’s site.
  • PPC
    There’s good money to be made if you can nail the pay-per-click advertising formula in Google.
  • Social media ads
    These are especially easy to run if your site is publishing new content on a regular basis and you have a compelling offer.
Stop With Pop-Ups

I know that Google says that mobile pop-ups are okay in certain instances. However, if you’re building a website with WordPress or another content management system and you’re using a plugin to create those pop-ups, that’s going to slow down your loading times. It might not be by much, but you’ll notice the difference.

ThemeIsle decided to do some analysis of how certain plugins affect WordPress website speeds. Here is what happened when they tested the effects each of these plugins had on the loading time:

Base loading time (in seconds) Loading time after install (in seconds) Change in % Security plugins 0.93 s 1.13 s 21.50% Backup plugins 0.93 s 0.94 s 1.07% Contact form plugins 0.93 s 0.96 s 3.22% SEO plugins 0.93 s 1.03 s 10.75% E-commerce plugins 0.93 s 1.22 s 31.10%

Granted, some plugins are coded to be more lightweight than others, but there will always be some sort of difference felt in your loading times. Based on this data, the difference could be as small as .01 and as much as .29 seconds.

If you know that pop-ups aren’t really kosher on the mobile web anyway, why push your luck? Instead, take that promotional offer, cookie notice or announcement and place it on your web pages.

Stop With Cumbersome Contact Channels

Don’t forget about your website’s contact channels. In particular, you have to be careful about designing mobile forms. Of course, part of that has to do with how long it actually takes a user to fill one out. However, there’s also what a lengthy or multi-page form does to your loading speeds that you should think about.

In general, your mobile forms should be lean — only include what’s absolutely necessary.

There is an alternate school of thought to consider as well.

You could ditch the contact form altogether, something I discussed when talking about the trend of replacing mobile forms with chatbots. There are websites that have removed their forms and left information like FAQs, email addresses and phone numbers for visitors to use if they need to get in touch. That would certainly lighten things up from a loading standpoint. I just don’t know if it would be ideal for the user experience.

3. Create A Single-Page Website

The above tips are going to be the simplest and quickest ones to implement, so you should definitely start there if a client or web developer comes to you with issues of too-slow websites. However, if page speed tests still show that a site takes more than 2.5 seconds to load, consider a different approach to redesigning a website for the purposes of speed optimization.

As Adam Heitzman said in an article for Search Engine Journal:

“Single page sites typically convert much easier to mobile and users find them simple to navigate.”

But does that mean that a single-page website will always load more quickly than a multi-page website? Of course not. However, most professional designers choose a single-page design over multi-page for very specific purposes. DevriX has a nice graphic that sums this up:

DevriX sums up the limitations of single-page websites. (Source: DevriX) (Large preview)

To be clear, I’m not suggesting that you turn your website into a single-page application (SPA). If you want to speed up your client’s digital property with service workers, a PWA is a better solution. (More info on that in the next point.)

Instead, what I’m suggesting is that you convert a multi-page website into a single-page one if your client fulfills certain criteria:

  • Businesses with an extremely narrow and singular focus.
  • Websites that don’t require much content to get their point across.
  • A limited range of keywords you need to rank for.

That said, if you are designing a website that fits within those three criteria (or at least two out of three), you could realistically move your website to a more simplistic single-page design.

Because single-page websites force you to do more with less, the limited content and features naturally create a lightweight website. Even if you did push the limits slightly, you could still create a faster-loading website for mobile as Tempus does:

Test My Site reports that the Tempus website loads in 2.1 seconds. (Source: Test My Site) (Large preview)

What’s cool about this single-page website is that it doesn’t skimp on the extensive imagery needed to sell luxury homes. And, yet, its mobile site loads in 2.1 seconds.

On the other hand, not all single-page websites are built with speed in mind. Take developer Davide Marchet’s website:

Test My Site reports that Davide Marchet’s website loads in 5.4 seconds. (Source: Test My Site) (Large preview)

Because it’s overloaded with animations, it takes 5.4 seconds for the page to load on mobile. You can even see this from the screenshot presented by Think with Google. The image seen there is actually the message that appears while the first animation loads in the background.

So, I would suggest being careful if you’re hoping to use a single-page design to solve your website’s performance woes. The design needs to be simple, super focused and unencumbered by scripts and animation effects that undo the benefits of trimming your content down to one page.

4. Turn Your Mobile Site Into A PWA

According to Google, there are three characteristics that define every PWA:

  1. Reliable
  2. Fast
  3. Engaging

Speed is an inherent part of progressive web apps thanks to the service workers they’re built with. Because service workers exist outside of the web browser and are not contingent on the speed of the user’s network, they load cached content for visitors more quickly.

I would also say that because the design of a PWA more closely resembles that of a native mobile app (at least the shell of it), this forces the design itself to be more trimmed-back than a mobile website.

If you’re struggling to speed up your website after implementing all of the traditional performance optimizations you’re supposed to, now would be a good time to turn your mobile website into a PWA.

Let me show you why:

Imagine you are planning a trip to Chicago with a friend. You’re out at a bar or coffee shop discussing the trip, then realize you have no idea where to stay. So, you do a search for “downtown Chicago hotels” on one of your smartphones.

You’re not thinking about purchasing a room yet; you just want to research your options. So, you click on the website links for two of the top listings Google provides you.

This is the progressive web app for the Best Western River North Hotel:

The home page of the Best Western River North Hotel PWA. (Source: Best Western River North Hotel) (Large preview)

This is the website of the Palmer House Hilton, a nearby hotel in downtown Chicago:

The home page of the Palmer House Hilton website. (Source: Palmer House Hilton) (Large preview)

For starters, the PWA is a much better looking and easier to navigate on your smartphone, so it’s going to win major points there. There’s also the matter of speed:

Test My Site compares the two competing hotels’ loading speeds. (Source: Test My Site) (Large preview)

The River North Hotel loads in 2.4 seconds on mobile whereas its Hilton competitor loads in 4 seconds. (You can actually see in the Hilton screenshot that the site hadn’t completely loaded yet.) That’s a difference that visitors are sure to notice.

Even if we’re not doing a side-by-side comparison between the competing websites, the River North Hotel’s PWA blows its former mobile website out of the water.

Brewer Digital Marketing, the agency that developed the PWA for them, shared what happened after they made the switch over. The hotel saw a 300% increase in earnings and a 500% increase in nights booked with the PWA.

5. Convert Your Website Or Blog Into AMP

We have Google to thank for another speedy design trick for the mobile web. This one is called Accelerated Mobile Pages, or AMP, for short.

Initially, AMP was released to help publishers strip down their blog or news pages for faster loading on mobile devices. However, AMP is a web component framework you can use to design whole websites or just specific parts of them (like blog posts). Once implemented, pages load almost instantaneously from search.

Why is AMP so fast to load? There are a number of reasons:

With AMP, you can only load asynchronous JavaScript and inline CSS on your website, which means that your code won’t block or delay page rendering.

Images are also another source of slower loading times. However, AMP solves that issue by automatically loading the page layout before the resources (e.g. images, ads, etc.) Think of it as a form of lazy loading.

There’s a lot more to it, but the basic idea is that it cuts out the elements that tend to drag websites down and forces designers to mostly depend on lightweight HTML to build their pages.

If you want to see an example of this in action, you can look at pretty much any leading digital magazine or news site. If you’re unfamiliar with AMP content, simply look for the lightning bolt icon that appears next to the web page name in Google search. Like this:

Pages with the recognizable lightning bolt symbol were created using Google AMP. (Source: Google AMP) (Large preview)

Gizmodo is a good example of AMP content:

This Gizmodo AMP page loaded almost instantly from search results. (Source: Gizmodo) (Large preview)

In fact, when Gizmodo made the transition to AMP back in 2016, it saw huge lifts in terms of performance. Its page speeds increased by 300% and it got 50% more page impressions as a result.

If you really want to get the most out of AMP speeds, Mobify suggests pairing AMP with your PWA. That way, you can load your web pages lightning-fast for visitors:

First Page Load With AMP Percent of Websites Load Time (seconds) 10% 0.3 20% 0.5 50% 1.1 60% 1.4 80% 2.2 90% 3.4 95% 5.2

Mobify reports on the loading times of AMP (Source: Mobify)

Then, sustain those fast-loading times with the PWA:

Subsequent Page Loads On PWA Percent of Websites Load Time (seconds) 10% 0.6 20% 0.8 50% 1.4 60% 1.8 80% 3.0 90% 4.5 95% 6.2

Mobify reports on the loading times of PWAs (Source: Mobify)</>

Just be careful with AMP and PWAs.

Look at the tables above and you’ll see that some sites have implemented these speedy design tactics and they still don’t beat Google’s 2.5-second benchmark for mobile loading. Just because there is a promise of faster-loading web pages with both, that doesn’t necessarily mean your website will automatically be lightning-fast.

Wrapping Up

As Google does more to reward mobile websites over desktop, this isn’t really a matter you can table for much longer. All versions of your website — but mobile especially — must be optimized for the user experience.

That means the design, the code, the content and everything else within and around it must be optimized. Once the developer has taken care of the traditional performance optimizations to speed up the website, it’s time for the designer to make some changes of their own. In some cases, simple changes like how fonts are served through the website will help. In other cases, more drastic matters may need to be considered, like redesigning your website as a PWA.

First, consider how slowly your client’s website is loading. Then, examine what’s causing the biggest issue on mobile. Trim the fat, bit by bit, and see what you can do as a designer to complement the developer’s technical speed optimizations.

(ra, il)
Categories: Web Design

The Case For Brand Systems: Aligning Teams Around A Common Story

Tue, 06/25/2019 - 06:00
The Case For Brand Systems: Aligning Teams Around A Common Story The Case For Brand Systems: Aligning Teams Around A Common Story Laura Busche 2019-06-25T15:00:59+02:00 2019-07-01T12:46:47+00:00

There’s a disconnect. If you’ve been in business for enough time you’ve definitely felt it. Teams are pulling companies in different directions with internal processes and specialized frameworks for absolutely everything. They’re focused on building their “part” of the product, and doing it incredibly well. There’s just one problem: our internal divisions mean nothing to customers.

In customers’ eyes, it’s the same brand replying to their support tickets and explaining something in a modal; the same entity is behind the quality of the product they use and the ads that led them to that product in the first place. To them, there are no compartments, no org charts, no project managers. There is only one brand experience. At the end of the day, customers are not tasting individual ingredients, or grabbing a bite during each stage of preparation, they’re eating the entire meal. At once. In sit-downs that keep getting shorter.

Something is getting lost in the process. Somewhere between our obsession with specializing and our desire to excel at individual roles, we’ve lost perspective of the entire brand experience. We spend our days polishing individual touchpoints, but not enough time zooming out to understand how they come together to shape our customer’s journey. The time for shying away from the word “holistic” is up — it’s the only way customers will ever perceive you. And that is the ultimate inspiration behind Brand Systems, a tool we will explore throughout this article.

What Is A Brand System?

At its core, a Brand System is a shared library that helps define, preserve, and improve the customer’s experience with the brand.

Just like we can’t assume that the sum of quality ingredients will result in a great meal, our individual contributions won’t magically translate into a memorable brand experience for customers. Their brand experiences are blended, multifaceted, and owner-blind. It’s time for the product, design, engineering, marketing, support, and various other functions to establish a single source of truth about the brand that is accessible to, understood, and used by all. That source is a Brand System.

Why Is It Useful? The Benefits Of Building A Brand System

Your brand is the story that customers recall when they think about you. When you document that story, your team can align to live up to and protect those standards consistently. There are multiple benefits to building and maintaining a Brand System:

  • Cohesion
    It helps preserve a uniform presence for the brand.
  • Access
    It empowers teams to apply assets consistently. A common language facilitates collaboration across different functional areas.
  • Flexibility
    This system is in continuous iteration, providing an up-to-date source of truth for the team.
  • Speed
    When your building blocks are readily available, everything is easier to construct. Collaboration is also accelerated as individuals get a fundamental understanding of how others’ work contributes to the brand experience.
  • Ethos
    Documenting the brand’s ethos will motivate the team to preserve, protect, and extend it. That level of care is perceived and appreciated by users.

To accomplish the above most effectively, the Brand System must remain accessible, empowering, holistic, extensible, flexible, and iterative. Let’s take a closer look at each of these traits and some examples of how they can be put in practice.


Open to all team members, regardless of their level of technical expertise or direct involvement with each element. Systems that perpetuate divisions within organizations can be visually mesmerizing, but end up fragmenting the brand experience.

Help Scout provides a visual example of what the concepts of illustration scale and grid mean for those who may not be familiar with them. (Large preview) Empowering

Full of examples that encourage continuous application. Some aspects of the brand experience can be hard to grasp for those who don’t interact with them daily, but a Brand System should empower everyone to recognize what is fundamentally on and off-brand — regardless of the touchpoint involved. Does the company’s support team feel confident about how the brand is visually represented? Does the design team have a general idea of how the brand responds to customers’ requests?

Webflow provides clear examples and instructions to empower different team members to write for the product, even if they’re not used to it. (Large preview) Holistic

No aspect of the brand’s execution is too foreign to include. Brand Systems surface the tools and frameworks various teams are using to clarify the bigger picture. Too often the customer’s experience appears disjointed because we’ve compartmentalized it. The brand experience “belongs” to marketing, or design, or some kind of executive-level team, so resources like UI components or support scripts are dealt with separately. As the unifying backbone of all business functions, the brand experience informs execution at every level.

For WeWork, physical spaces are a key part of the entire experience. Their brand system includes guidelines in this respect. (Large preview) Extensible

Individual teams can develop specific subsections within the system to fit their needs. Regardless of how specialized these different areas get, the Brand System remains accessible to all. Team members decide how deeply they want to dive into each element, but the information is readily available.

Atlassian makes use of its Confluence platform to host guidelines related to different parts of the brand experience. Sections have varying levels of access and are regularly maintained by different teams. (Large preview) Flexible

There can be alternative versions of the Brand System for external audiences, including media and partners. While we’d like the brand experience to unfold in owned channels, the reality is that sometimes customers interact with it through earned channels controlled by third parties. In those cases, a minimized version of the Brand System can help preserve the story, voice, and visual style.

Instagram, for example, offers a special set of guidelines for users broadcasting content about the brand. (Large preview) Iterative

The Brand System should evolve and be continuously updated over time. To that end, host and serve the content in a way that makes it easy to access and edit as things change.

Salesforce surfaces ongoing updates to its Lightning system in a section called Release Notes. (Large preview) What Does A Brand System Contain?

Brand Systems solve a fundamental disconnect in teams. Nobody outside of marketing feels empowered to market the product, nobody outside of design feels like they have a solid grasp of the brand’s style guidelines, nobody outside of support feels confident responding to a customer. Sounds familiar? That’s why it’s crucial to build a Brand System that is as all-encompassing and transparent as possible.

While Design Systems are the closest implementation of a resource like this, a Brand System is centered around the brand story, understanding symbols and strategy as necessary layers in its communication. It is informed by product and design teams, but also functional areas like support, marketing, and executive leadership that are key to shaping the entire brand experience. In Brand Systems, visual components are presented in the context of a business model, a company mission, positioning, and other strategic guidelines that must be equally internalized by the team.

Comet, a Design System by Discovery Education. (Large preview)

A Brand Style Guide is another commonly used tool to align teams around a set of principles. While useful, these guides focus heavily on marketing and design specifications. Their main objective is to impart a shared visual language for the brand so that it is applied cohesively across the board. That resolves part of the problem but doesn’t reveal how other functional areas contribute to the overall brand experience. Therefore, these guidelines could be considered as part of the larger Brand System.

Brand Guidelines for the Wildlife Conservation Society (Designed by Pentagram) (Large preview)

That said, these are some of the sections and components you should consider including in your Brand System:


If the brand experience is embroidery, the story is the thread weaving all the touchpoints together. It reveals what has been and will continue to be important, who the brand is trying to serve, and how it plans to do so most effectively. Start your Brand System by answering questions like:

  • What is this brand’s core value proposition?
  • What does its history look like? Include a timeline and key milestones.
  • How do you summarize both of the above in an “About Us” blurb?
  • What are the brand’s core values? What propels this team forward?
  • Who is the audience? Who are the main personas being addressed and what are these individuals trying to get done?
(Large preview) The Smithsonian Institution included a section called Audience Segments in the strategy section of their branding website. (Large preview)
  • What does their journey with us look like? If known, what is their sentiment towards the brand?
  • What is the brand’s mission as it relates to its target customers? How about the team itself and society at large?
  • How does this business model work, in general terms? (Specifics will be included in the “Strategy” section).
  • Who are the brand’s direct competitors? What sets it apart from them?
  • How does this brand define product/service quality? Are there any values around that?
  • What is the brand’s ultimate vision?
Shopify summarizes the brand’s Product Experience Principles in their Polaris design system. (Large preview) Symbols

You know what drives the brand and the narrative it brings to the table. This part of the Brand System is about actually representing that. Symbols are sensory: they define what the brand looks, sounds, and feels like. Because they help us convey the story across multiple touchpoints, it’s vital for the entire team to have a grasp of what they stand for and how they can be properly deployed.

Here are some examples of building blocks you’ll want to define in this section:

  • Main and alternative versions of the brand’s logo
  • Color palette
  • Typography scheme
  • Icons, photography, and illustration style
  • Patterns, lines, and textures
  • Layout and spacing
  • Slide deck styling
  • Stationery and merchandising applications
  • Motion & sound, including audiobranding
  • Packaging (if applicable)
  • Scent (if applicable).

For brands built around digital products:

  • User Interface components
  • Interaction patterns
  • Key user views & states
  • User Experience guidelines
  • Code standards
  • Tech stack overview.
IBM includes patterns for common actions like “Next” in its Carbon design system. (Large preview)

Bear in mind that the nature of your product will determine how you complete the section above. A tech-based company might list elements like interaction patterns, but a retail brand might look at aspects like store layout.


Once you’ve clarified the brand’s story, and the symbols that will represent it, define how you go about growing it. This part of the Brand System addresses both messaging and method, narrative and tactics.

It’s not enough for the team to be aware of why this brand is being built: the goal is to get everyone familiar with how it is sustained, grown, and communicated.

Just like customer support can feel alienated from the design function, these growth-related tenets are often not surfaced beyond marketing, acquisition, or executive conversations. However, those kinds of strategic ideas do impact customers at every touchpoint. A Brand System is a crash course that makes high-level perspective accessible to all, unlocking innovation across the entire team.

Here are some guiding questions and components to include:

  • How does this brand define success? What growth metric does the team focus on to track performance? (GMV, revenue, EBITDA, sales, etc).
  • What does the conversion funnel look like? How does this brand acquire, activate and retain customers?
    • What is the average Customer Acquisition Cost (CAC)?
    • What is the retention rate?
    • What is the Customer’s Lifetime Value (LTV)?
    • Which channels drive the most revenue? Traffic?
    • Which products and categories drive the most revenue? Traffic?
    • Which of the buyer personas defined in the “Story” section bring the most revenue? Traffic?
  • What are the brand’s key objectives for this year (to be updated)? These are company-wide goals.
  • What initiatives or themes is the team focusing on to meet those objectives this year?
  • How is the team organized to meet those objectives?
  • What channels does this brand use to communicate with its target audience? Name them and specify how big they are in terms of reach and/or traffic.
    • Owned
      • Website, blog, or other web properties
      • Social channels
      • Email
    • Earned
      • Ongoing brand partnerships
      • Referrals
    • Paid
      • Specific ad platforms
      • Influencers
      • Affiliates
  • What is this brand’s personality like?
  • What defines the brand’s voice? How does it adopt different tones in specific situations?
  • How does the brand’s voice come to life in owned, earned, and paid channels?
    • Company website and landing pages
    • Social channels. Clarify if tone varies
    • Email
    • Ads
    • Sales collateral
    • Press releases
    • Careers page & job sites
  • How does the brand’s voice come to life in the customer’s experience with the product, before, during, and after purchase?
    • Call to action
    • Navigation
    • Promotion
    • Education
    • Success/error
    • Apology/regret
    • Reassurance/support
  • How does the brand’s voice come to life internally (within the team)?
    • Employee handbooks
    • Onboarding process.
  • What topics should this brand aim to be a thought leader at?
UC Berkeley defines the themes and key messages to highlight when speaking to different audiences. (Large preview)
  • Grammar and spelling-wise, does this brand adhere to a specific style manual?
  • What are some common words and expressions users can expect from this brand?
Mailchimp’s Content Style Guide (Source) (Large preview) How To Get Started With Your Own Brand System

If you’re feeling ready to shape your own Brand System, here are some steps you can take to approach the challenge as a team:

1. Kickoff

Set up a company-wide planning session. If you can’t have everyone attend, make sure there’s someone representing product, design, marketing, support, and the executive team. Lead a conversation with two goals:

  • Brand audit
    How is the brand represented in various contexts? Is there brand debt to account for? Consider the brand’s story, symbols, and strategy.
  • Brand definition
    Discuss how this brand:
    • sounds,
    • looks,
    • speaks,
    • feels,
    • interacts,
    • introduces itself in a few words.
2. Production

After having that open discussion, delegate the various sections described above (Story, Symbols, Strategy) to the teams that interact most closely with each of them. Ask specific individuals to document the brand’s point of view regarding each system component (listed in point 2).

3. Publication

Upload the full Brand System to a central location where it is readily available and editable. Schedule a team-wide presentation to get everyone on the same page.

4. Summary

Condense the main guidelines in a one-page document called Brand-At-a-Glance. Here are some of the key points you could include:

  • Brand mission, vision, and values
  • Visual identity: color palette, main logo versions, type scheme, illustration style
  • About Us blurb.
5. Revision

Establish a periodic cross-functional meeting where the brand is protected and defined. Frequency is up to you and your team. This is also where the Brand System is formally updated, if needed. In my experience, unless this space is scheduled, the revisions simply won’t happen. Time will pass, customers’ needs will change, the brand experience will shift, and there won’t be a common space to document and discuss it all.

Brand Systems: Aligning Teams Around A Common Story

When customers interact with your brand, they’re not aware of what’s going on backstage. And there is no reason they should. All they perceive is the play you’re presenting, the story you’re sharing, and the solution it represents for them. When the individual actors go off script, as great as they might sound solo, the brand experience breaks.

Enter the Brand System: a shared library that defines the brand’s story, symbols, and strategy. In doing so, this tool aligns all actors around the multi-faceted experience customers truly perceive. Within teams, Brand Systems help avoid fragmentation, confusion, and exclusion. Externally, they’re a script to deliver the most compelling brand experience possible — at every touchpoint, every single time.

(ah, yk, il)
Categories: Web Design

What I Learned From Designing AR Apps

Mon, 06/24/2019 - 03:00
What I Learned From Designing AR Apps What I Learned From Designing AR Apps Gleb Kuznetsov 2019-06-24T12:00:59+02:00 2019-07-01T12:46:47+00:00

The digital and technological landscape is constantly changing — new products and technologies are popping up every day. Designers have to keep track of what is trending and where creative opportunities are. A great designer has the vision to analyze new technology, identify its potential, and use it to design better products or services.

Among the various technologies that we have today, there’s one that gets a lot of attention: Augmented Reality. Companies like Apple and Google realize the potential of AR and invest significant amounts of resources into this technology. But when it comes to creating an AR experience, many designers find themselves in unfamiliar territory. Does AR require a different kind of UX and design process?

As for me, I’m a big fan of learning-by-doing, and I was lucky enough to work on the Airbus mobile app as well as the Rokid AR glasses OS product design. I’ve established a few practical rules that will help designers to get started creating compelling AR experiences. The rules work both for mobile augmented reality (MAR) and AR glasses experiences.

Rokid Glasses motion design exploration by Gleb Kuznetsov Glossary

Let’s quickly define the key terms that we will use in the article:

  • Mobile Augmented Reality (MAR) is delivering augmented reality experienced on mobile devices (smartphones and tablets);
  • AR Glasses are a wearable smart display with a see-through viewing an augmented reality experience.
1. Get Buy-In From Stakeholders

Similar to any other project you work for, it is vital that you get support from stakeholders as early in the process as is possible. Despite being buzzed about for years, many stakeholders have never used AR products. As a result, they can question the technology just because they don’t understand the value it delivers. Our objective is to get an agreement from them.

“Why do we want to use AR? What problem does it solve?” are questions that stakeholders ask when they evaluate the design. It’s vital to connect your design decisions to the goals and objectives of the business. Before reaching stakeholders, you need to evaluate your product for AR potential. Here are three areas where AR can bring a lot of value:

  • Business Goals
    Understand the business goals you're trying to solve for using AR. Stakeholders always appreciate connecting design solutions to the goals of the business. A lot of time business will respond to quantifiable numbers. Thus, be ready to provide an explanation off how your design is intended to help the company make more money or save more money.
  • Helpfulness For Users
    AR will provide a better user experience and make the user journey a lot easier. Stakeholders appreciate technologies that improve the main use of the app. Think about the specific value that AR brings to users.
  • Creativity
    AR is excellent when it comes to creating a more memorable experience and improving the design language of a product. Businesses often have a specific image they are trying to portrait, and product design has to reflect this.

Only when you have a clear answer to the question “Why is this better with AR?”, you will need to share your thoughts with stakeholders. Invest your time in preparing a presentation. Seeing is believing, and you’ll have better chances of buy-in from management when you show a demo for them. The demo should make it clear what are you proposing.

2. Discovery And Ideation Explore And Use Solutions From Other Fields

No matter what product you design, you have to spend enough time researching the subject. When it comes to designing for AR, look for innovations and successful examples with similar solutions from other industries. For example, when my team was designing audio output for AR glasses, we learned a lot from headphones and speakers on mobile phones.

Design User Journey Using “As A User I Want” Technique

One of the fundamental things you should remember when designing AR experiences is that AR exists outside of the phone or glasses. AR technology is just a medium that people use to receive information. The tasks that users want to accomplish using this technology are what is really important.

“How to define a key feature set and be sure it will be valuable for our users?” is a crucial question you need to answer before designing your product. Since the core idea of user-centered design is to keep the user in the center, your design must be based on the understanding of users, their goals and contexts of use. In other words, we need to embrace the user journey.

When I work on a new project, I use a simple technique “As a [type of user], I want [goal] because [reason].” I put myself in the user's shoes and think about what will be valuable for them. This technique is handy during brainstorming sessions. Used together with storyboarding, it allows you to explore various scenarios of interaction.

In the article “Designing Tomorrow Today: the Airbus iflyA380 App,” I’ve described in detail the process that my team followed when we created the app. The critical element of the design process was getting into the passenger’s mind, looking for insights into what the best user experience would be before, during and after their flight.

To understand what travelers like and dislike about the travel experience, we held a lot of brainstorming sessions together with Airbus. Those sessions revealed a lot of valuable insights. For example, we found that visiting the cabin (from home) before flying on the A380 was one of the common things users want to do. The app uses augmented reality so people can explore the cabin and virtually visit the upper deck, the cockpit, the lounges — wherever they want to go — even before boarding the plane.

IFLY A380 iOS app design by Gleb Kuznetsov. (Large preview)

App also accompanies passengers from the beginning to the end of their journey — basically, everything a traveler wants to do with the trip is wrapped up in a single app. Finding your seat is one of the features we implemented. This feature uses AR to show your seat in a plane. As a frequent traveler, I love that feature; you don’t need to search for the place at the time when you enter the cabin, you can do it beforehand — from the comfort of your couch. Users can access this feature right from the boarding pass — by tapping on ‘glass’ icon.

IFLY A380 app users can access the AR feature by tapping on the ‘glass’ icon. (Large preview) Narrow Down Use Cases

It might be tempting to use AR to solve a few different problems for users. But in many cases, it’s better to resist this temptation. Why? Because by adding too many features in your product, you make it not only more complex but also more expensive. This rule is even more critical for AR experience that generally requires more effort. It’s always better to start with simple but well-designed AR experience rather than multiple complex but loose designed AR experiences.

Here are two simple rules to follow:

  • Prioritize the problems and focus on the critical ones.
  • Use storyboarding to understand exactly how users will interact with your app.
  • Remember to be realistic. Being realistic means that you need to strike a balance between creativity and technical capabilities.
Use Prototypes To Assess Ideas

When we design traditional apps, we often use static sketches to assess ideas. But this approach won’t work for AR apps.

Understanding whether a particular idea is good or bad cannot be captured from a static sketch; quite often the ideas that look great on paper don’t work in a real-life context.

Thus, we need to interact with a prototype to get this understanding. That’s why it’s essential to get to prototyping state as soon as possible.

It’s important to mention that when I say ‘prototyping state’ I don’t mean a state when you create a polished high-fidelity prototype of your product that looks and work as a real product. What I mean is using a technique of rapid prototyping and building a prototype that helps you experience the interaction. You need to make prototypes really fast — remember that the goal of rapid prototyping is in evaluating your ideas, not in demonstrating your skills as a visual designer.

3. Design

Similar to any other product you design, when you work on AR product, your ultimate goal is to create intuitive, engaging, and clean interface. But it can be challenging since the interface in AR apps accounts both for input and output.

Physical Environment

AR is inherently an environmental medium. That’s why the first step in designing AR experience is defining where the user will be using your app. It’s vital to select the environment up front. And when I say ‘environment’, I mean a physical environment where the user will experience the app — it could be indoors or outdoors.

Here are three crucial moments that you should consider:

  1. How much space users need to experience AR? Users should have a clear understanding of the amount of space they’ll need for your app. Help users understand the ideal conditions for using the app before they start the experience.
  2. Anticipate that people will use your app in environments that aren’t optimal for AR. Most physical environments can have limitations. For example, your app is AR table tennis game but your users might not have a large horizontal surface. In this case, you might want to use a virtual table generated based on your device orientation.
  3. Light estimation is essential. Your app should analyze the environment automatically and provide contextual guidance if the environment is not good enough. If the environment is too dark or too bright for your app, tell the user that they should find a better place to use your app. ARCore and ARKit have a built-in system for light estimation.

When my team designed Airbus i380 mobile AR experience, we took the available physical space into account. Also, we’ve considered the other aspects of interaction, such as the speed at which the user should make decisions. For instance, the user who wants to find her seat during the boarding won’t have too much time.

We sketched the environment (in our case, it was a plane inside and outside) and put AR objects in our sketch. By making our ideas tangible, we got an understanding of how the user will want to interact with our app and how our app will adapt to the constraints of the environment.

AR Realism And AR Objects Aesthetics

After you define the environment and required properties, you will need to design AR objects. One of the goals behind creating AR experience is to blend virtual with real. The objects you design should fit into the environment — people should believe that AR objects are real. That’s why it’s important to render digital content in context with the highest levels of realism.

Here are a few rules to follow:

  • Focus on the level of details and design 3D assets with lifelike textures. I recommend using multi-layer texture model such as PBR (Physically Based Rendering model). Most AR development tools support it, and this is the most cost-effective solution to achieve an advanced degree of detail for your AR objects.
  • Get the lighting right. Lighting is a very crucial factor for creating realism — the wrong light instantly breaks the immersion. Use dynamic lighting, reflect environmental lighting conditions on virtual objects, cast object shadows, and reflections on real-world surfaces to create more realistic objects. Also, your app should react to real-world changing of lighting.
  • Minimize the size of textures. Mobile devices are generally less powerful than desktops. Thus, to let your scene load faster, don’t make textures too large. Strive to use 2k resolution at most.
  • Add visual noise to AR textures. Flat-colored surfaces will look fake to the user's eye. Textures will appear more lifelike when you introduce rips, pattern disruptions, and other forms of visual noise.
  • Prevent flickering. Update the scene 60 times per second to prevent flickering of AR objects.
Design For Safety And Comfort

AR usually accompanied by the word ‘immersive.’ Creating immersive experience is a great goal, but AR immersion can be dangerous — people can be so immersed in smartphones/glasses, so they forget what is happening around them, and this can cause problems. Users might not notice hazards around them and bump into objects. This phenomenon is known as cognitive tunneling. And it caused a lot of physical traumas.

  • Avoid users from doing anything uncomfortable — for example, physically demanding actions or rapid/expansive motion.
  • Keep the user safe. Avoid situations when users have to walk backward.
  • Avoid long play AR sessions. Users can get fatigued using AR for extended periods. Design stop points and in-app notifications that they should take a break. For instance, if you design an AR game, let users pause or save their progress.
Placement For Virtual Objects

There are two ways of placing virtual objects — on the screen or in the world. Depending on the needs of your project and device capabilities, you can follow either the first or second approach. Generally, virtual elements should be placed in world space if they suppose to act like real objects (e.g., a virtual statue in AR space), and should be placed as an on-screen overlay if they intended to be UI controls or information messages (e.g., notification).

Rokid Glasses. (Large preview)

‘Should every object in AR space be 3D?’ is a common question among designers who work on AR experiences. The answer is no. Not everything in the AR space should be 3D. In fact, in some cases like in-app notifications, it's preferable to use flat 2D objects because they will be less visually distracting.

Rokid Glasses motion design exploration by Gleb Kuznetsov. (Large preview) Avoid Using Haptic Feedback

Phone vibrations are frequently used to send feedback in mobile apps. But using the same approach in AR can cause a lot of problems — haptic feedback introduces extra noise and makes the experience less enjoyable (especially for AR Glasses users). In most cases, it’s better to use sound effect for feedback.

Make A Clear Transition Into AR

Both for MAR and AR glass experiences, you should let users know they’re about to transition into AR. Design a transition state. For the ifly380 app, we used an animated transition — a simple animated effect that user sees when taps on the AR mode icon.

Trim all the fat.

Devote as much of the screen as possible to viewing the physical world and your app's virtual objects:

  • Reduce the total number of interactable elements on the screen available for the user at one moment of time.
  • Avoid placing visible UI controls and text messages in your viewport unless they are necessary for the interaction. A visually clean UI lends itself seamlessly to the immersive experience you’re building.
  • Prevent distractions. Limit the number of times when objects appear on the user screen out of the blue. Anything that appears out of the blue instantly kills realism and make the user focus on the object.
AR Object Manipulation And Delineating Boundaries Between The ‘Augment’ And The ‘Reality’

When it comes to designing a mechanism of interaction with virtual objects, favor direct manipulation for virtual objects — the user should be able to touch an object on the screen and interact with it using standard, familiar gestures, rather than interact with separate visible UI controls.

Also, users should have a clear understanding of what elements they can interact with and what elements are static. Make it easy for users to spot interactive objects and then interact with them by providing visual signifiers for interactive objects. Use glowing outlines or other visual highlights to let users know what’s interactive.

Scan object effect for outdoor MAR by Gleb Kuznetsov. (Large preview)

When the user interacts with an object, you need to communicate that the object is selected visually. Design a selection state — use either highlight the entire object or space underneath it to give the user a clear indication that it’s selected.

Last but not least, follows the rules of physics for objects. Just like real objects, AR objects should react to the real-world environment.

Design For Freedom Of Camera

AR invites movement and motion from the user. One of the significant challenges when designing or AR is giving users the ability to control the camera. When you give users the ability to control the view, they will swing device around in an attempt to find the points of interest. And not all apps are designed to help the user to control the viewfinder.

Google identifies four different ways that a user can move in AR space:

  1. Seated, with hands fixed.
  2. Seated, with hands moving.
  3. Standing still, with hands fixed.
  4. Moving around in a real-world space.

The first three ways are common for mobile AR while the last one is common for AR glasses.

In some cases, MAR users want to rotate the device for ease of use. Don’t interrupt the camera with rotation animation.

Consider Accessibility When Designing AR

As with any other product we design, our goal is to make augmented reality technology accessible for people. Here are a few general recommendations on how to address real-world accessibility issues:

  • Blind users. Visual information is not accessible to blind users. To make AR accessible for blind users, you might want to use audio or haptic feedback to deliver navigation instructions and other important information.
  • Deaf or hard-hearing users. For AR experience that requires voice interaction, you can use visual signals as an input method (also known as speechreading). The app can learn to analyze lip movement and translate this data in commands.

If you're interested in learning more practical tips on how to create accessible AR apps, consider watching the video talk by Leah Findlater:

Encourage Users To Move

If your experience demands exploration, remind users they can move around. Many users have never experienced a 360-degree virtual environment before, and you need to motivate them to change the position of their device. You can use an interactive object to do that. For example, during I/0 2018, Google used an animated fox for Google Maps that guided users to the target destination.

This AR experience uses an animated bird to guide users. (Large preview) Remember That Animation Is A Designer’s Best Friend

Animation can be multipurpose. First, you can use a combination of visual cues and animation to teach users. For example, the animation of a moving phone around will make it clear what users have to do to initialize the app.

Second, you can use animation to create emotions.

One second of emotion can change the whole reality for people engaging with a product.

Well-designed animated effects help to create a connection between the user and the product — they make the object feel tangible. Even a simple object such as loading indicator can build a bridge of trust between users and the device.

Rokid Alien motion design by Gleb Kuznetsov. (Large preview)

A critical moment about animation — after discovering the elements of design and finding design solutions for the animation base, it’s essential to spend enough time on creating a proper animated effect. It took lots of iterations to finish a loading animation that you see above. You have to test every animation to be sure it works for your design and be ready to adjust color, positioning, etc. to give the best effect.

Prototype On The Actual Device

In the interview for Rokid team, Jeshua Nanthakumar mentioned that the most effective AR prototypes are always physical. That’s because when you prototype on the actual device, from the beginning, you make design work well on hardware and software that people actually use. When it comes to unique displays like on the Rokid Glasses, this methodology is especially important. By doing that you’ll ensure your design is implementable.

Motion design language exploration for AR Glasses Rokid by Gleb Kuznetsov. (Large preview)

My team was responsible for designing the AR motion design language and loading animation for AR glasses. We decided to use a 3D sphere that will be rotated during the loading and will have nice reflections on its edges. The design of the animated effect took two weeks of hard work of motion designers and it looked gorgeous on high-res monitors of our design team, but the final result wasn’t good enough because the animation caused motion sickness.

Motion sickness often caused by the discrepancies between the motion perceived from the screen of AR Glasses and the actual movement of the user's head. But in our case, the root cause of the motion sickness was different — since we put a lot of attention in polishing details like shapes, reflections, etc. unintentionally we made users focus on those details while the sphere was moving.

As a result, the motion happened in the periphery, and since humans are more sensitive to the moving objects in the periphery this caused motion sickness. We solved this problem by simplifying the animation. But it’s critical to mention that we won’t be able to find this problem without testing on the actual device.

If we compare the actual procedure of testing of AR apps with traditional GUI apps, it will be evident that testing AR apps require more manual interactions. A person who conducts testing should determine whether the app provides the correct output based on the current context.

Here are a few tips that I have for conducting efficient usability testing sessions:

  • Prepare a physical environment to test in. Try to create real-world conditions for your app — test it with various physical objects, in different scenes with different lighting. But the environment might not be limited to scene and lighting.
  • Don’t try to test everything all at once. Use a technique of chunking. Breaking down a complex flow into smaller pieces and testing them separately is always beneficial.
  • Always record your testing session. Record everything that you see in the AR glass. A session record will be beneficial during discussions with your team.
  • Testing for motion sickness.
  • Share your testing results with developers. Try to mitigate the gap between design and development. Make sure your engineering team knows what problem you face.

Similar to any other new technology, AR comes with many unknowns. Designers who work on AR projects have a role of explorers — they experiment and try various approaches in order to find the one that works best for their product and delivers the value for people who will use it.

Personally, I believe that it’s always great to explore new mediums and find new original ways of solving old problems. We are still at the beginning stages of the new technological revolution — the exciting time when technologies like AR will be an expected part of our daily routines — and it’s our opportunity to create a solid foundation for the future generation of designers.

(cc, yk, il)
Categories: Web Design

Design Your Mobile Emails To Increase On-Site Conversion

Fri, 06/21/2019 - 04:00
Design Your Mobile Emails To Increase On-Site Conversion Design Your Mobile Emails To Increase On-Site Conversion Suzanne Scacca 2019-06-21T13:00:59+02:00 2019-07-01T12:46:47+00:00

I find it interesting that Google has pushed so hard for web designers to shift from designing primarily for desktop to now designing primarily for mobile. Google’s right… but why only focus on designing websites to appeal to mobile users? After all, Gmail is a leader within the email client ranks, too.

Email can be an incredibly powerful driver of conversions for websites, according to a 2019 report from Barilliance.

On average, emails convert at a rate of 1.48%. That includes all sent emails though — which includes the ones that go unopened as well as the ones that bounce. If you look at emails that are opened by recipients, however, the average conversion rate jumps to 17.75%.

Let’s go even further with this:

Recent data from Litmus reveals that more emails are opened on mobile than on any other device:

Litmus data reveals that 43% of email opens occur on mobile devices. (Source: Litmus) (Large preview)

Many sources even put the average mobile open rate at well over 50%. But whether it’s 43% or 50%+, it’s clear that mobile is most commonly the first device people reach for to check their emails.

Which brings us to the following conclusion:

If users are more likely to open email on mobile and we know that opened emails convert at a higher rate than those that go unopened, wouldn’t it make sense for designers to prioritize the mobile experience when designing emails?

Mobile Email Design Tips to Increase Conversions

Let’s explore what the latest research says about designing emails for mobile users and how that can be used to increase opens, clicks and, later, your website’s conversion rates (on mobile and desktop).

Design the Same Email for Mobile and Desktop

Although email is often ranked as the most effective marketing channel for acquiring and retaining customers, that’s not really an accurate picture of what’s going on.

According to Campaign Monitor, here’s what’s actually happening with mobile email subscribers:

Campaign Monitor charts the progression from mobile email opens to click-through rate. (Source: Campaign Monitor) (Large preview)

The open rates on mobile are somewhat on par with the Litmus data earlier.

However, it can take multiple opens before the email recipient actually clicks on a link or offer within an email. And guess what? About a third of them make their way over to desktop — where they convert at a higher rate than those that stay on mobile.

As the report states:

Data from nearly 6 million email marketing campaigns suggests the shift to mobile has made it more difficult to get readers to engage with your content, unless you can drive subsequent opens in a different environment.

I’ve reconstructed the graphic above and filled it with the number of people who would take action from an email list of 1,000 recipients:

An example of how Campaign Monitor’s data translates into real-world numbers. (Source: Campaign Monitor) (Large preview)

At first glance, it looks as though mobile is the clear winner — at least in terms of driving traffic to the website. After the initial mobile open, 32 subscribers go straight to the website. After a few more opens on mobile, 5 more head over there.

Without a breakdown of what the user journey looks like when opened on desktop, though, the calculation of additional clicks you’d get from that portion of the list isn’t so cut-and-dried.

However, let’s assume that Litmus’s estimate of 18% desktop opens is accurate and that Campaign Monitor’s 12.9% click-through rate holds true whether they open the email first on mobile or desktop. I think it’s safe to say that 23 desktop-only email opens can be added to the total.

So, that brings it to:

37 clicks on mobile vs 26 on desktop.

Bottom line: while mobile certainly gets more email subscribers over to a website, the conversion-friendliness of desktop cannot be ignored.

Which is why you don’t want to segment your lists based on device. If you want to maximize the number of conversions you get from a campaign, enable subscribers to seamlessly move from one device to the other as they decide what action to take with your emails.

In other words, design the same exact email for desktop and mobile. But assume that the majority of subscribers will open the email on their mobile device (unless historical data of your campaigns says otherwise). Then, use mobile-first design and marketing tips to create an email that’s suitable for all subscribers, regardless of device.

Factor in Dark Mode When Choosing Your Colors

You don’t want there to be anything that stands in your users’ way when it comes to moving from email to website. That’s why you have to consider how their choice of color and brightness for their mobile screen affects the readability or general appearance of your email design.

There are a number of ways in which this can become an issue.

As we hear more and more about how harmful blue light from our devices can be, it’s no surprise that Dark Mode options are beginning to roll out. While it’s prevalent on desktops right now, it’s mostly in beta for mobile. The same goes for email apps.

That said, smartphone users can hack their own “Dark Mode” of sorts. This type of color inversion can be enabled through the iPhone’s “Accessibility” settings.

Gadget Hacks shows how iPhone users can hack their own 'Dark Mode'. (Source: Gadget Hacks) (Large preview)

Essentially, what this does is invert all of the colors on the screen from light to dark and vice versa.

Unfortunately, the screenshotting tool on my iPhone won’t allow me to capture the colors exactly as they appear. However, what I can show you is how the inversion tool alters the color of your email design.

This is an email I received from Amtrak last week. It’s pretty standard with its branded color palette and brightly colored notices and CTA buttons:

What a promotional email from Amtrak looks like on the Gmail mobile app. (Source: Amtrak) (Large preview)

Now, here is what that same email looks like when viewed through my iPhone’s “Smart Invert” setting:

What a promotional email from Amtrak looks like in Gmail when colors are inverted. (Source: Amtrak) (Large preview)

The clean design of the original with the white font on the deep blue brand colors is gone. Now, there’s a harsh mix of colors and a hard-to-read Amtrak logo in its place.

You can imagine how this kind of inconsistent and disjointed color display would create an off-putting experience for mobile users.

But what do you expect them to do? If they’re struggling with the glare from their mobile device, Dark Mode (or some other brightness adjustment) will make it easier for them to open and read emails in the first place. Even if it means compromising the appearance of the email you so carefully designed.

One bright spot in all this is that the official “Dark Mode” being rolled out to iPhone (and, hopefully, other smartphones) soon won’t alter the look of HTML emails. Only plain-text messages will be affected.

However, it’s important to still be mindful of how the design choices you make may clash with a surrounding black background. Brightly colored backgrounds, in particular, are likely to clash with the surrounding black of your email app.

How do you solve this issue? Unfortunately, you can’t serve different versions of your email to users based on whether they’re viewing it in Dark Mode or otherwise. You’ll just have to rely on your own tests to confirm that potential views in Dark Mode don’t interfere with your design or message.

In addition to the standard testing you do, set your own smartphone up with Dark Mode (or its hack counterpart). Then, run your test email through the filter and see what happens to the colors. It won’t take long to determine what sort of colors you can and cannot design with for email.

Design the Subject Line

The subject line is the very first thing your email subscribers are going to see, whether it shows up as a push notification or they first encounter it in their inbox. What do you think affects their initial decision to click open an email rather than throw it in the Trash or Spam box immediately? Recognizing the Sender will help, but so will the attractiveness of the subject line.

As for how exactly you go about “designing” a subject line, there are a few things to think about. The first is the length.

Marketo conducted a study across 200+ email campaigns and 2 million emails sent to subscribers. Here is what the test revealed about subject line length:

Marketo tested over 2 million sent emails to determine the ideal subject line length. (Source: Marketo) (Large preview)

Although the 4-word subject line resulted in the highest open rate, it had a poor showing in terms of clicks. It was actually the 7-word subject line that seemed to have struck the perfect balance with subscribers, leading 15.2% of them to open the email and then 10.8% of them to click on it.

While you should still test this with your own email list, it appears that seven words is the ideal length for a subject line.

Next, you have to think about the buzzwords used in the subject line.

To start, keep this list of Yesware’s Spam Trigger Words out of it:

Yesware’s analysis and list of the top spam-trigger words. (Source: Yesware) (Large preview)

If you want to increase the chance the email will be opened, read, clicked on and eventually convert on-site, you have to be savvy about which words will appear within the subject line.

What I’d suggest you do is bookmark CoSchedule's Email Subject Line Tester tool.

CoSchedule tests and scores your email subject lines with one click. (Source: CoSchedule) (Large preview)

Here’s an example of how CoSchedule analyzes your subject lines and clues you in to what increases and decreases your open rates:

The first part of CoSchedule’s subject line analysis and scoring tool. (Source: CoSchedule) (Large preview)

As you can see, CoSchedule tells you which kinds of words increase open rates as well as those that don’t. Do enough of these subject line tests and you should be able to compile a good set of wording guidelines for your writers and marketers.

Further down, you’ll get more insight into what makes for a strongly worded and designed subject line:

The second part of CoSchedule’s subject line assessment and recommendations. (Source: CoSchedule) (Large preview)

CoSchedule will provide recommendations on how to shorten or lengthen the character and word counts based on best practices and results.

Finally, at the very bottom of your subject line test you’ll see this:

The final part of CoSchedule’s subject line tester includes an email client preview. (Source: CoSchedule) (Large preview)

This gives you (or, rather, your writer) a chance to see how the subject line will appear within the “design” of an email client. It’s not a problem if the words get cut off on mobile. It’s bound to happen. However, you still want everything that does appear to be appealing enough to click on.

Also, don’t forget about dressing up your subject lines with emoji.

When you think about it, emoji in mobile email subject lines make a lot of sense. Text messaging and social media are ripe with them. It’s only natural to use this fun and truncated form of language in email, too.

Campaign Monitor makes a good point about this:

If you replace words with recognizable emoji, you’ll create shorter subject lines for mobile users. Even if it doesn’t shorten your subject line enough to fit on a mobile screen, it’s still an awesome way to make it stand out from the rest of your subscribers’ cluttered inboxes.

The CoSchedule test will actually score you based on how (or if) you used emoji, too:

CoSchedule suggests that the use of emoji in subject lines will give you an edge. (Source: CoSchedule) (Large preview)

As you can see, CoSchedule considers this a competitive advantage in marketing.

Even just looking at my own email client, my eye is instantly drawn to the subject line from Sephora which contains a “NEW” emoji:

A Sephora email containing an emoji stands out from others in the inbox. (Source: Sephora) (Large preview)

Just be careful with which emoji you use. For starters, emoji are displayed differently from device to device, so it may not have the same effect on some of your subscribers if it’s a more obscure choice.

There’s also the localization aspect to think about. Not every emoji is perceived the same way around the globe. As Day Translations points out, the fire symbol is one that could cause confusion as some countries interpret it as a literal fire whereas some may view it as a symbol for attraction.

That said, emoji have proven to increase both open rates and read rates of emails. Find the right mobile-friendly emoji to include in your subject line and you could effectively increase the number of subscribers who visit your website as a result.


There are so many different kinds of emails that go out from websites:

  • Welcome message
  • Post-purchase transaction email
  • Abandoned cart reminder
  • Promotional news
  • Product featurette
  • New content available
  • Account /rewards points
  • And more.

In other words, there are plenty of ways to get in front of email subscribers.

Just remember that the majority of them will first open your email on mobile. And some will reopen it on mobile over and over again until they’re compelled to click on it or trash it. It’s up to you to design the email in a way that motivates them to visit your website and, consequently, convert.

Further Reading on SmashingMag: (ra, yk, il)
Categories: Web Design

JAMstack Fundamentals: What, What And How

Thu, 06/20/2019 - 05:30
JAMstack Fundamentals: What, What And How JAMstack Fundamentals: What, What And How Vitaly Friedman 2019-06-20T14:30:59+02:00 2019-07-01T12:46:47+00:00

We love pushing the boundaries on the web, and so we’ve decided to try something new. You probably have heard of JAMstack — the new web stack based on JavaScript, APIs, and Markup — but what does it mean for your workflow and when does it make sense in your projects?

As a part of our Smashing Membership, we run Smashing TV, a series of live webinars, every week. No fluff — just practical, actionable webinars with a live Q&A, run by well-respected practitioners from the industry. Indeed, the Smashing TV schedule looks pretty dense already, and it’s free for Smashing Members, along with recordings — obviously.

We’ve kindly asked Phil Hawksworth to run a webinar explaining what JAMStack actually means and when it makes sense, as well as how it affects tooling and front-end architecture. The one hour-long webinar is now available as well. We couldn’t be happier to welcome Phil to co-MC our upcoming SmashingConf Toronto (June 25-26) and run JAMStack_conf London, which we co-organize on July 9-10 this year as well. So, let’s get into it!

Phil Hawksworth: Excellent, okay, well let’s get into it then. Just by way of a very quick hello, I mean I’ve said hello already, Scott’s given me a nice introduction. But yes, I currently work at Netlify, I work in the developer experience team there. We are hopefully going to have plenty of time for Q&A but, as Scott mentioned, if you don’t get a chance to ask questions there, or if you just rather, you can ping them directly at me on Twitter, so my Twitter handle is my names, it’s Phil Hawksworth, so any time you can certainly ask me questions about JAMstack or indeed anything on Twitter.

Phil Hawksworth: But I want to start today just by kind of going back in time a little bit to this quote which really resonates very, very strongly with me. This is a quote from the wonderful Aaron Schwartz who, of course, contributed so much to the Creative Commons and the open web and he wrote this on his blog way back in 2002, and he said, “I care about not having to maintain cranky AOL server, Postgres and Oracle installs.” AOL server, I had to look up to remind myself was an open source web server at the time.

Phil Hawksworth: But this chimes really strongly with me. I also don’t want to be maintaining infrastructure to keep a blog alive, and that’s what he was talking about. And it was in this blog post on his own blog and it was titled “Bake, Don’t Fry”. He was picking on a term that someone who’d built a CMS recently had started to use, and he kind of popularized this term about baking (Bake, Don’t Fry); what he’s talking about there is pre-rendering rather than rendering on demand, so baking the content ahead of time, rather than frying it on demand when people come and ask for it — getting things away from request time and into kind of build time.

Phil Hawksworth: And when we’re talking about pre-rendering and rendering, what we mean by that is we’re talking about generating markup. I feel a bit self-conscious sometimes talking about kind of server render or isomorphic rendering or lots of these kind of buzzwordy terms; I got called out a few years ago at a conference, Frontiers Conference in Amsterdam when I was talking about rendering on the server and someone said to me, “You mean generating HTML? Just something that outputs HTML?” And that’s, of course, what I mean.

Phil Hawksworth: But all of this kind of goes a long way towards simplifying the stack. When we think about the stack that we serve websites from; I’m all about trying to simplify things, I’m super keen on trying to simplify the stack. And that’s kind of at heart of this thing called “JAMstack” and I want to try and explain this a little bit. The “JAM” in JAMstack stands for JavaScript, APIs and Markup. But that’s not enough really to help us understand what it means — what on earth does that really mean?

Phil Hawksworth: Well, what I want to try and do in the next half hour or so, is I want to kind of expand on that definition and give more of a description of what JAMstack is. I want to talk a bit about the impact and the implications of JAMstack, and, you know, think about what that can give us as to why we might choose it. Along the way, I’m going to try to mention some of the tools and services that will be useful, and hopefully, I’ll wrap up with some resources that you might want to dig into and perhaps mention some first steps to get you under way.

Phil Hawksworth: So, that’s the plan for the next half-hour. But, I want to, kind of, come back to this notion about simplifying the stack, because, hopefully, people who join this or have come to watch this video later on, maybe you’ve got a notion of what JAMstack is, or maybe it’s a completely new term, and you’re just curious. But, ultimately, there are a lot of stacks out there, already. There are lots of ways that you can deliver a website. It feels like we’ve been building different types of infrastructure for a really long time, whether that’s a LAMP stack or the MAMP stack, or the — I don’t know — the MEAN stack. There’s a bunch of them floating by on the screen here. There are lots and lots of them.

Phil Hawksworth: So, why on earth would we need another one? Well, JAMstack is, as I mentioned, is JavaScript/API/Markup, but if we try and be a tiny bit more descriptive, JAMstack is intended to be a modern architecture, to help create fast and secure sites and dynamic apps with JavaScript/APIs and pre-rendered markup, served without web servers, and it’s this last point which is, kind of, something that sets it apart and maybe, makes it a little bit more, kind of, interesting and unusual.

Phil Hawksworth: This notion of serving something without web servers, that sounds either magical or ridiculous, and hopefully, we’ll figure out what along the way. But to try and shed some light over this and describe it in a little bit more detail, it’s sometimes useful to compare it to what we might think of as a traditional stack, or a traditional way of serving things on the web. So, let’s do that just for a second. Let’s just walkthrough, perhaps, what a request might look like as it gets serviced in a traditional stack.

Phil Hawksworth: So, in this scenario, we got someone opening up a web browser and making a request to see a page. And maybe that request hits a CDN, but probably, more likely, it hit some other infrastructure that we are hosting — as the people who own this site. Maybe we tried to make sure that this is going to scale under lots of load because we, obviously, want a very popular and successful sight. So, perhaps we got a load balancer, that has some logic in it, which will service that request to one of a number of web servers that we’ve provisioned and configured and deployed to. There might be a number of those servers.

Phil Hawksworth: And those servers will execute some logic to say, “Okay, here’s our template, we need to populate that with some data.” We might get our data from one of a number of database servers that will perform some logic to look up some data, return that to the web server, create a view that we then pass back through the load balancer. Perhaps, along the way, calling off to CDN, stashing some assets in the CDN, and I should clarify, a CDN is a Content Delivery Network, so a network of machines distributed around the Internet to try and get request service as close to possible to the user and add things, like caching.

Phil Hawksworth: So, we might stash some assets there, and ultimately, return a view into the browser, into the eyeballs of the user, who gets to then experience the site that we built. So, obviously, that’s, either, an oversimplification or a very general view of how we might service a request in a traditional stack. If we compare that to the JAMstack, which is servicing things in a slightly different way, this is how it might look.

Phil Hawksworth: So, again, same scenario, we’re starting in a web browser. We’re making a request for a view of the page, and that page is already in a CDN. It serves statically from there, so it’s returned to the user, into the browser, and we’re done. So, obviously, a very simplified view, but straight away, you can start to see the differences here in terms of complexity. In terms of places that we need to manage code, deeply code, all of those different things. So, for me, one of the core attributes one of a JAMstack, is that it means that you’re building a site that’s capable of being served directly from a CDN, or even from a static file server. CDN is something that we might want to put in place to handle load, but ultimately, this could be served directly from any kind of static file server, kind of static hosting infrastructure.

Phil Hawksworth: JAMstack, kind of, offers an opportunity to reduce complexity. Just comparing those two parts of the diagram that we’ll come back to a few times, over the course of the next half hour, you can see that it’s an opportunity to reduce complexity and reduce risk. And so, it means that we can start to enjoy some of the benefits of serving static assets, and I’m going to talk about what those are a little bit later on. But you might be looking at this and thinking, “Well, great, but isn’t this just the new name for static websites?” That’s a reasonable thing to level at me when I’m saying, “We’re going to serve things statically.”

Phil Hawksworth: But I want to come back to that. I want to talk about that a little bit more, but first of all, I want to, kind of, talk about this notion of stacks and what on earth is a stack, anyway? And I think of a stack as the layers of technology, which deliver your website or application. And we’re not talking about the build pipeline, or the development process, but certainly the way we serve sites can have a big impact on how we develop and how we deploy things, and so on.

Phil Hawksworth: But here, we’re talking about the technology stack, the layers of technology, that actually deliver your website and your application to the users. So, let’s do another little comparison. Let’s talk about the LAMP stack for a second.

Phil Hawksworth: The LAMP stack, you may remember, is made up of an apache web server, for doing things like the HCP routing and the serving of static assets. PHP, for some pre-processing, so pretty hyper-text processing; applying the logic, maybe building the views for the templates and what have you. And has some access to your data, by my NISQL, and then LINUX is the operating system that sits beneath all of that, keeps that all breathing. We can wrap that up together notionally as this web server. And we may have many of these servers, kind of, sitting together to serve a website.

Phil Hawksworth: That’s a, kind of, traditional look at the LAMP stack, and if we compare that to the JAMstack, well, here, there’s a critical change. Here, we’re actually moving up level, rather than thinking about the operating system and thinking about how we run the logic to deliver a website. Here we’re making an assumption that we’re going to be serving these things statically. So, we’re doing the ACP routing, and the serving of assets from a static server. That can be reasonably done. We got very good at this, over the years, building ways to deliver static websites, or static assets.

Phil Hawksworth: This might be a CDN, and again, we’ll talk about that in a moment. But the area of interest for us, is happening more in the browser. So, here, this is where our markup is delivered and is parsed. This is where JavaScript can execute, and this is happening in the browser. In many ways, the browser has become the runtime for the modern web. Rather than having the runtime in the server infrastructure, itself, now we’ve moved that up a level, closer to the user, and into the browser.

Phil Hawksworth: When it comes to accessing data, well, that’s happening through, possibly, external APIs, making calls via JavaScripts to these external APIs to get server access, or we can think APIs as the browser APIs, being able to interact with JavaScript with capabilities right there in your browser.

Phil Hawksworth: Either way, the key here about the JAMstack is that, we’re talking about things that are pre-rendered: they’re served statically and then, they maybe progressively enhanced in the browser to make use of browser APIs, JavaScripts, and what have you.

Phil Hawksworth: So, let’s just do this little side-by-side comparison here. Again, I just want to kind of reiterate that the JAMstack has moved up a level to the browser. And if we see the two sides of this diagram, with the LAMP stack on the left and effectively, the JAMstack on the right, you might even think that, well, even when we were building things with the LAMP stack, we’re still outputting mark-up. We’re still outputting JavaScript. We might still be accessing APIs. So, in many ways, the JAMstack is almost like a subset of what we were building before.

Phil Hawksworth: I used to sometimes talk about JAMstack as the assured stack, because it’s assures a set of tools and technologies that we need to deliver a site. But, either way, it’s a much simplified way of delivering a site that, kind of, does away with the need for things to execute and perform logic at the server at request time.

Phil Hawksworth: So, this can do a lot of things. This can, kind of, simplify deployments and again, I’m going to call back to this diagram from time-to-time. If we think about how we deploy our code and our site, for every deploy, from the very first one, through the whole development lifecycle, all the way through the life of the website. On the traditional stack, we might be having to change the logic and the content for every box on that diagram.

Phil Hawksworth: Whereas, in the JAMstack, when we’re talking about deploying, we’re talking at getting things to the CDN, getting things to the static server, and that’s what the deployment entails. The build, the kind of logic that runs the build — that can run anywhere. That doesn’t need to run in the same environment that’s hosting the web server. In fact, it doesn’t! It starts the key to the JAMstack. We put the separation at what happens at request time, serving these static assets, versus what happens at build time, which can be your logic that you run to build and then to the deployment.

Phil Hawksworth: So, this kind of decoupling is a key thing, and I’m going to come back to that later on. We’ve got very good at serving static files, and getting things to a CDN or getting things to the file system (the file server) is somewhere that we’ve seen huge, kind of, advancement over the last few years. There are a lot of tools and processes, now, that can help us do this really well. Just to call out a few services that can serve static assets well and give workflows to getting your build to that environment, they’re the usual suspects that you might imagine the big clouds infrastructure providers, like Azure, AWS, and Google Cloud.

Phil Hawksworth: But then, there are others. So, the top one on the right is a service called Surge, which has been around for a few years. It allows you to run a command in your build environment and deploy your assets through to their hosting environment. Netlify, the next one down, is where I work and we do very much the same thing but we have different automation as well. I could go into it another time. And the one on the bottom, another static hosting environment site, called Now.

Phil Hawksworth: So, there’s a bunch of different options for doing this, and all of these spaces provide different tooling for getting to the CDN, as quickly as possible. Getting your sites deployed in the most seamless way that we can. And they all have something in common where they’re building on the principal of running something locally. I often think of a static site generator as something that we might run in a build which when we run that, it takes things like content and templates and maybe, data from different services and it outputs something which can be served statically.

Phil Hawksworth: We can preview that locally in our static server. Something that is kind of simple to do on any local development environment, and then the process of deploying that is getting that to the hosting environment and ideally, out to a CDN in order to get, kind of, scale. So, with that kind of foundation laid out, I want to address a bit of a common misconception when it comes to JAMstack sites. And I didn’t do myself any favors by opening this up as describing JAMstack sites as being JavaScript, APIs, and Markup. Because the common misconception is that every JAMstack site has to be JavaScript and APIs, and Markup, but this kind of thing that we’ve overlooked is that we don’t have to use all three — every one one of these is, kind of, optional. We can use as much, or as little of these as we like. In the same way that a LAMP stack site wouldn’t necessarily need to be hitting a data base. Now, I’ve built things in the past that are served by an apache server, on a Linux machine, and I’ve been using PHP, but I haven’t been hitting a database and I wouldn’t start to rename a stack necessarily for that.

Phil Hawksworth: So, if we think about what is a JAMstack site, then it could be a bunch of different things. It might be something that’s built out with a static site generator, like Jekyll, pulling content from YAML files to build a site that has no JavaScript, doesn’t hit APIs at all, and we serve it on something, like GitHub Pages. Or, that would be a JAMstack site. Or maybe we’re using a static site generator, like Gatsby, which is, rather in a Ruby environment for Jekyll, now this is a JavaScript static site generator built in the React ecosystem.

Phil Hawksworth: That might be pulling content again, and it’s organizing Markdown files. It might be enriching that with calls to APIs, GraphQL’s APIs. It might be doing things in the browser, like doing JavaScript hydration of populating templates right there in the browser. And it might be served on Amazon S3. Is that a JAMStack site? Yeah, absolutely!

Phil Hawksworth: Moving on to a different static site generator, Hugo, which is built with Go! Again, we might be organizing content in Markdown files, adding interactions in the browser using JavaScript. Maybe not calling any external APIs and maybe hosting that on Google Cloud. Is it JAMstack? Absolutely! You see, I’m building to a theme here. Using something like Nuxt, another static site generator, now built in the View ecosystem. Maybe that’s pulling content from different adjacent files? Again, we might be using JavaScript interactions in the browser, perhaps calling APIs to do things like e-Commerce, serving it another static site. Another hosting infrastructure like Netlify, is it a JAMstack? Yes, it is!

Phil Hawksworth: But we might even go, you know, go off to this side end of the scale, as well. And think about a handmade, progressive web app that we’ve built artisanally, hand-rolled, JavaScript that we built ourselves. We’re packaging it up with webpack. We’re maybe using JavaScript web tokens and calling out to APIs to do authentication, interacting with different browser APIs, hosting it on Azure. Yes, that’s JAMstack as well!

Phil Hawksworth: And, you know, all of these things, and many more, can be considered JAMstack, because they all share one attribute in common and that is none of them are served with an origin server. None of them have to hit a server that performs logic at request time. These are being served as static assets, and then enriched with JavaScript and calls to APIs, afterwards.

Phil Hawksworth: So, again, I just want to reiterate that a JAMstack means it’s capable of being served directly from the CDN. So, I want to just call out some of the impacts and implications of this, because why would we want to do this? Well, the first notion is about security, and we’ve got a greatly reduced surface area for attack, here. If we think about (coming back to this old diagram again), the places where we might have to deal with an attack, we have to secure things like the load balancer, the webservers, the database servers. All of these things, we have to make sure aren’t able to be penetrated by any kind of an attack and, indeed, the CDN.

Phil Hawksworth: If the more pieces we can take out of this puzzle, the fewer places that can be attacked and the fewer places we have to secure. Having few moving parts to attack is really very valuable. At Netlify, we operate our own CDNs, so we get the luxury of being able to monitor the traffic that comes across it, and even though all of the sites hosted on Netlify, all of the JAMstack sites that you might imagine, none of them have a WordPress admin page on them because it’s completely decoupled. There is no WordPress admin, but we see a huge volume of traffic, probing for things like WP Admin, looking for ways in, looking for attack vectors.

Phil Hawksworth: I really love some of the things that Kent C. Dodds has done. I don’t know if you are familiar with the React community, you’ve probably encountered Kent C. Dodds in the past. He doesn’t use WordPress, but he still routes this URL, the WPAdmin. I think he used to route it through to a Rick Roll video on YouTube. He’s certainly been trolling people who have gone probing for it. But, the point is, by decoupling things in that way and, kind of, moving things that happen, build time from what happens in request time, we can just drastically reduce our exposure. We’ve got no moving parts at request time. The moving parts are all completely decoupled at build time. Potentially, on completely, well, necessarily on completely different infrastructure.

Phil Hawksworth: This, of course, also has an impact on performance, as well. Going back to our old friend here, the places we might want to try and improve performance across the stack here, when there’s logic that needs to be executed at these different places. The way that this often happens in traditional stacks is, they start to add layers, add static layers, in order to improve performance. So, in other words, try and find ways that we can start to behave as if it’s static. Not have to perform that logic at each level of the stack in order to speed things up. So, we’re starting to introduce things like caching all over the infrastructure and obvious places we might find to do that is in the web server, rather than perform that logic, we want to serve something immediately without performing that logic.

Phil Hawksworth: So, it’s kind of like a step towards, kind of, being pseudo-static. Likewise in database servers, we want to add caching layers to cache-com queries. Even in the low balance, the whole CDN, you can think of as a cache. But on the traditional stack, we need to figure out how to manage that cache, because not everything will be cached. So, there’s going to some logic about. What needs to be dynamically populated versus what can be cached. And the JAMstack model, everything is cached. Everything is cached from the point that the deployment is done, so we can think about it completely differently.

Phil Hawksworth: This, then, starts to, kind of, hint through to scaling, as well. And by scale, I’m talking about, how do we handle large loads of traffic? Traditional stacks will start to add infrastructure in order to scale. So, yes, to caching. We’re starting to put in place in our traditional stack. That will help — to a degree. What typically happens is, in order to handle large loads of traffic, we’ll start expanding the infrastructure and starting to add more servers, more pieces to handle these requests, costing these things out and estimating the load is a big overhead and it can be a headache for anyone doing technical architecture. It certainly was for me, which is why I was starting to lean much more towards doing the JAMstack approach where I just know that everything is served from the CDN, which is designed by default to handle scale, to handle performance right out of the gate.

Phil Hawksworth: So, I also want to give a nod to developer experience, and the impact this can have there. Now, developer experience should never be seen as something which trumps user experience, but I believe that a good developer experience can reduce friction, can allow for developers to do a much better job of building up to great user experiences!

Phil Hawksworth: So, when we think about where the developer experience lives, and where the areas of concern for a developer are here: well, in a traditional stack, we might need to think about how we get the code to all of these different parts of the infrastructure, and how they all play together. In the JAMstack world, really, what we’re talking about is this box here at the bottom. You know, how do we ran the build and them, how do we automate a deployment to get something served in the first place? And the nice thing is, that in the JAMstack model, what you do in that build is completely up to you.

Phil Hawksworth: That’s a really well-defined problem space, because ultimately, you’re trying to build something you can serve directly from a CDN. You want to pre-render something, using whatever tools you like: whether it’s a static site generator built in Ruby or Python or JavaScript or Go or PHP, you have the freedom to make that choice. And so, that can create a much nicer environment for you to work in. And also, it creates an opportunity to have real developer confidence because a real attribute of JAMstack sites is that they can be much more easily served as immutable and atomic deployment.

Phil Hawksworth: And I want to, kind of, jump away from the slides just for a moment, to describe what that means, because an immutable deployment and an atomic deployment can… (that can just sound a little bit like marketing speak) but what I’m going to do, is I’m going to jump into my browser. Now … actually, I’m going to go back for a second. Let me… just do this.

Phil Hawksworth: Here we are. This will be easier. Jumping right into the page. Now, Scott, you will tell me, Scott, if you can’t see my browser, I’m hoping. Now, assuming everyone can see my browser.

Scott: Everything looks good.

Phil Hawksworth: Excellent! Thank you very much!

Phil Hawksworth: So, what I’m doing here, is I’m using Netlify as an example, as an example of the service. But, this is an attribute which is common to sites that can be hosted, statically. So, when we talk about an immutable deployment, what we mean is, that rather each deployment of code having to touch lots of different parts of the infrastructure, and change lots of things, here we’re not mutating the state of the site on the server. We’re creating an entirely new instance of the site for every deployment that’s happened. And we can do that because the site is a collection of static assets.

Phil Hawksworth: Here, I’m looking at the deployment that have happened from my own website. I’ll give you a treat. There you are, that’s what it looks like. It’s just a blog, it doesn’t look like anything particularly remarkable or exciting. It’s a statically generated blog, but what I have here is every deployment that’s ever happened, lives on in perpetuity, because it’s a collection of static assets that are served from a CDN. Now, I could go back as far as my history can carry me and go and look at the site, as it was back in… when was this? This was August, 2016. And by virtue of it being a set of static assets, we’re able to host this on its own URL that lives on in perpetuity and if I even wanted to, I could decide to go in and publish that deployment.

Phil Hawksworth: So, now, anyone’s who’s looking at my website, if I go back to my website here, if I refresh that page, now that’s being served directly from the CDN with the assets that were there before. Now, I can navigate around again. Here, you can see. Look, I was banging on about this, I was using these terrible terms like isomorphic rendering and talking about the JAMstack back in 2016. So, this is now what’s being served live on my site. Again, because there are mutual deployments that just live on forever. I’m going to just put my own, kind of, peace of mind, I’m going to — is this the first page? Yeah. I’m going to go back to my latest deployment. I’ll have to shut again, and get me back into the real world. Let me just make sure this is okay.

Phil Hawksworth: Okay! Great! So, then now, this is back to serving my previous version, or my latest version of the site. I’ll hop back to keynote. So, this is possible because things are immutable and atomic. The atomic part of that means, again, that the deployment is completely contained. So, you never get the point where some of the assets are available on the web server, but some of them won’t. Only when everything is there in context and everything is there, complete, do we toggle the serving of the site to the new version. Again, this is the kind of thing you can do much more easily if you’re building things out as a JAMstack site that serves directly from the CDN as a bunch of assets.

Phil Hawksworth: I noticed that my timer has reset, after going back and forward from keynote, so I think I have about six or seven minutes left. Tell me, Scott, if—

Scott: So, yeah, we’re still good for about ten minutes.

Phil Hawksworth: Ten minutes? Okay, wonderful!

Scott: There’s no rush.

Phil Hawksworth: Thank you, that should be good!

Phil Hawksworth: So, just switching gear a tiny bit and talking about APIs and services (since APIs is part of JAMstack), the kind of services that we then might be able to use is mostly JAMstack. You know, we might be using services that we built in-house, or we might be using bought-services. There are lots of different providers who can do things for us, and that’s because that’s their expertise. Through APIs, we might be pulling in content from content management systems as a service, and there’s a bunch of different providers for this, who specialize in giving a great content management experience and then, exposing the content through API, so you used to be able to pull them in.

Phil Hawksworth: Likewise, there are different ways that you can serve assets. People like Cloudary are great at this, for doing image optimization, serving assets directly to your sites, again, through APIs. Or what about e-Commerce? You know, there are places like Stripe or Snipcart that can provide us API, so that we don’t have to build these services ourselves and get into the very complex issues that come with trying to build an e-Commerce engine. Likewise, identity, from people like Auth0 who are using Oauth. There are lots of services that are available and we can consume these things through APIs, either in the browser or at build time, or sometimes, a combination of both.

Phil Hawksworth: Now, some people might think, “Well, that’s fine, but I don’t want to give the keys to the kingdom away. I don’t want to risk giving these services over to external providers,” and to that, I say, well, you know, vendors who provide a single service really depend on its success. If there’s a company that’s core business, or entire business, is in building-out an e-Commerce engine, an e-Commerce service for you, they’re doing that for all of their clients, all of their customers, so they really depend on its success and they have the specialist skills to do that.

Phil Hawksworth: So, that kind of de-risks it from you a great deal. Especially when you start to factor in the fact that you can have your technical and service-level contracts to give you that extra security. But it’s not all about bought services, it’s also about services you can build yourselves. Now, there’s a number of ways that this can happen, but sometimes, you absolutely need a little bit of logic on the server. And so far, I’ve just been talking about taking the server out of the equation. So, how do we do that?

Phil Hawksworth: Well, this is where serverless can really come to the rescue. Serverless and JAMstack, they just fit together really beautifully. And when I’m talking about serverless, I’m talking about no functions as a service. I know that serverless can be a bit of a loaded term, but here, I’m talking about functions as a service. Because functions as a service can start to enable a real micro-services architecture. Using things like AWS Lambda or Google Cloud functions or similar functions as a service, can allow you to build out server infrastructure without a server. Now, you can start deploying JavaScript logic to something that just runs on demand.

Phil Hawksworth: And that means, you can start supplementing some of these other services with, maybe, very targeted small services you build yourselves that can run the serverless functions. These kind of smaller services are easier to reason about, understand, build out and they create much greater agility. I want to just mention a few examples and results from JAMstack sites. I’m not going to go down the server list avenue too much, right now. We can, maybe, come back to that in the questions. I really just kind of want to switch gear and, thinking about time a little bit, talk about some examples and results.

Phil Hawksworth: Because there are some types of sites that lend themselves in a very obvious way to a JAMstack site. Things like the documentation for React, or Vuejs, those [inaudible 00:32:40], pre-rendered JAMstacks sites. As do sites for large companies, such as Citrix, this is a great example of Citrix multi-language documentation. You can actually view the video from the JAMstack conference that happened in New York, where Beth Pollock had worked on this project, talked about the change that went on in that project. From building on traditional, non-enterprised infrastructure to a JAMstack approach and building with Jekyll, which is not necessarily the fastest generating static site generator, but still, they saw a huge improvement.

Phil Hawksworth: Beth talked about the turnaround time for updates went from weeks to minutes. Maybe people are kind of frowning at the idea of weeks for updates to sites, but sometimes in big complex infrastructure, with lots of stakeholders and lots of moving parts, this really is the situation we’re often finding ourselves in. Beth also talked about estimating the annual cost savings for this move to a JAMstack site. To get the site running properly, estimated their savings of around 65%. That’s huge kind of savings. Changing gear to a slightly different type of site, something a little closer to home, Smashing Magazine itself is a JAMstack site, which might be a little bit surprising, because on one hand, yes, there’s lots of articles and it’s also content, which is published regularly, but not every minute of the day, for sure.

Phil Hawksworth: So, that might lend itself, perhaps, for something that’s pre-generated, but of course, there’s also a membership area and an event section, and a job board, and e-Commerce, and all of these things. This is all possible on the JAMstack because not only are we pre-rendering, but we’re also enriching things with JavaScript and the front end to call out to APIs, which let some of these things happen. The project that I think I saw Vitaly arrive in the call, so that’s going to be good, we might be able to come back to this in a few minutes.

Phil Hawksworth: But the project that migrated, Smashing Magazine onto a JAMstack approach, I believe, simplified the number of platforms from five, effectively down to one. And I’m using Vitaly’s words directly here: Vitaly talked about having some caching issues, trying to make the site go quickly, using probably every single WordPress caching plug-in out there, and goodness knows, there are a few of them! So, Smashing Magazine saw an improvement in performance, time to first load went from 800 milliseconds to 80 milliseconds. Again, I’m simplifying the infrastructure that served the site up in the first place. So, it’s kind of interesting to see the performance gains that can happen there.

Phil Hawksworth: Another totally different type of site. This is from the Google Chrome team, who built this out to demonstrate at Google I/O this year. This very much feels like an application. This is Minesweeper in a browser. I apologize if you’re watching me play this. I’m not playing it while talking to you; I recorded this sometime ago and it’s agony to see how terrible I seem to be at Minesweeper while trying to record. That’s not a mine, that can’t be!

Phil Hawksworth: Anyway, we’ll move on.

Phil Hawksworth: The point of that is, this is something that feels very much more like an app, and it was built in a way to be very responsible about the way it used JavaScript. The payload to interactive was 25KB. This progressively would download and use other resources along the way, but it meant that the time to interact was under five seconds on a very slow 3G network. So, you can be very responsible with the way you use JavaScript and still package up JavaScript, as part of the experience for a JAMstack site.

Phil Hawksworth: So, I’m kind of mindful of time. We’re almost out of time, so what is the JAMstack? Well, it’s kind of where we started from. JAMstack sites are rendered in advance: they’re not dependent on an origin server (that’s kind of key), and they may be progressively enhanced in the browser with JavaScript. But as we’ve shown, you don’t have to use JavaScript at all. You might just be serving that statically, ready to go, without that. It’s an option available to you.

Phil Hawksworth: This key tenant, I think of, JAMstack sites is they’re served without web service. They’re pre-rendered and done in advance.

Phil Hawksworth: If you’re interested in more, it’s already been mentioned a little bit, there is a conference in London in July — July 9th and 10th. The speakers are going to be talking about all kinds of things to do with performance in the browser, things that you can do in the browser, results of building on the JAMstack and things to do with serverless.

Phil Hawksworth: There’s also a bunch of links in this deck that I will share, after this presentation, including various bits and pieces to do with static site generation, things like headless CMS, the jamstack.org site itself, and a great set of resources on a website called “The New Dynamic” which is just always full of latest information on JAMstack. We’re out of time, so I’ll wrap it up there, and then head back across to questions. So, thanks very much for joining and I’d love to take questions.

Scott: Thanks, Phil. That was amazing, thank you. You made me feel quite old when you pulled up the Minesweeper reference, so—

Phil Hawksworth: (laughs) Yeah, I can’t take any credit for that, but it’s kind of fascinating to see that as well.

Scott: So, I do think Vitaly is here.

Vitaly: Yes, always in the back.

Phil Hawksworth: I see Vitaly’s smiling face.

Vitaly: Hello everyone!

Phil Hawksworth: So, I’m going to hand it over to Vitaly for the Q&A, because I seem to have a bit of a lag on my end, so I don’t want to hold you guys up. Vitaly, I’ll hand it over to you.

Scott: Okay. Thanks, Scott.

Vitaly: Thanks, Scott.

Vitaly: Hello—

Vitaly: Oh, no, I’m back. Hello everyone. Now Scott is back but Phil is gone.

Scott: I’m still here! Still waiting for everything.

Vitaly: Phil is talking. Aw, Phil, I’ve been missing you! I haven’t seen you, for what, for days, now? It’s like, “How unbelievable!” Phil, I have questions!

Vitaly: So, yeah. It’s been interesting for us, actually, to move from WordPress to JAMstack — it was quite a journey. It was quite a project, and the remaining moving parts and all. So, it was actually quite an undertaking. So, I’m wondering, though, what would you say, like if we look at the state of things and if we look in the complexes, itself, that applications have. Especially if you might deal with a lot of legacy, imagine you have to deal with five platforms, maybe seven platforms here, and different things. Maybe, you have an old legacy project in Ruby, you have something lying on PHP, and it’s all kind of connected, but in a hacky way. Right? It might seem like an incredible effort to move to JAMstack. So, what would be the first step?

Scott: So … I mean, I think you’re absolutely right, first of all. Re-platforming any site is a big effort, for sure. Particularly if there’s lots of legacy. Now, the thing that I think is kind of interesting is an approach that I’ve seen getting more popular, is in identifying attributes of the site, parts of the site, that might lend themself more immediately to being pre-generated and served statically than others. You don’t necessarily have to everything as a big bang. You don’t have to do the entire experience in one go. So, one of the examples I shared, kind of, briefly was the Citrix documentations site.

Scott: They didn’t migrate all of Citrix.com across to being JAMstack. They identified a particular part that made sense to be pre-rendered, and they built that part out. And then, what they did was they started to put routing in front of all the requests that would come into their infrastructure. So, it would say, “Okay, well, if it’s in this part of the past the domain, either in the sub-domain or maybe, through to a path, route that through something which is static, then the rest of it, pass that through to the rest of the infrastructure.

Scott: And I’ve seen that happen, time and time again, where with some intelligent redirects, which, thankfully, is something that you can do reasonably simply on the JAMstack. You can start to put fairly expressive redirect engines in front of the site. It means that you can pass things through just that section of the site that you tried to take on as a JAMstack project. So, choosing something and focusing on that first, rather than trying to do a big bang, where you do all of the legacy and migration in one. I think that’s key, because, yeah, trying to do everything at once is pretty tough.

Vitaly: It’s interesting, because just, I think, two days, maybe even today, Chris Coyier wrote an article renaming JAMstack to SHAMstack where, essentially, it’s all about JavaScript in which we need think about steady coasting, because JavaScript could be hosted steadily as well. And it’s interesting, because he was saying exactly that. He actually — when we think about JAMstack, very often, we kind of tend to stay in camps. It’s either, fully rendered and it lives a static-thing. Somewhere there, in a box and it’s served from a city and that’s it, or it’s fully-expressive and reactive and everything you ever wanted. And actually, he was really right about a few things, like identifying some of the things that you can off-load, to aesthetic-side, generated assets, so to say, to that area.

Vitaly: And, JAMstackify, if you might, say some of the fragments of your architecture. Well, that’s a new term, I’m just going to coin, right there! JAMstackify.

Phil Hawksworth: I’m going to register the domain quickly, before anybody else.

Phil Hawksworth: And it’s a nice approach. I think, it kind of makes my eye twitch a little bit when I hear that Chris Coyier has been redubbing it the SHAMstack, because it makes it sound like he thinks it’s a shambles. But I know that he’s really talking about static-hosting and markup, which I—

Vitaly: Yes, that’s right.

Phil Hawksworth: I really like, because the term JAMstack can be really misleading, because it’s trying to cover so many different things and the point I was trying to, I probably hammered it many times in that slide, is that it can be all kinds of things. It’s so broad, but the key is pre-rendering and hosting the core of the sites statically. It’s very easy for us to get into religious wars about where it needs to be a React site. It has to be a React app, in order to be a JAMstack site, or it’s a React app, so it can’t be JAMstack. But, really, the crux of it is, whether you use JavaScript or not, whether you’re calling APIs or not, if you pre-render and get things into a static host that can be very performant, that’s the core of JAMstack.

Vitaly: Yes, absolutely.

Phil Hawksworth: We’re very fortunate that browser’s are getting so much more capable, and the APIs that are there within browser’s themselves can allow us to do much more as well. So, that kind of opens the doors even further, but it doesn’t mean that everything that we build as a JAMstack site has to make use of everything. Depending on what we’re trying to deliver, that’s how we should start to choose the tools that we’re playing with to deploy those things.

Vitaly: Absolutely. We have Doran here. Doran, I think I know, Doran. I have a feeling that I know Doran. He’s asking, “Do you expect serverless to be gravitating towards seamless integration with JAMstack from [inaudible 00:44:36]? What is referred to as the A in JAM.

Phil Hawksworth: That’s a great question, because I think, serverless functions are — they just go so well with JAMstack sites, because in many ways, in fact, I think someone once asked me if JAMstack sites are serverless, and so I squirmed about that question, because serverless is such a loaded term. But, in many ways, it’s bang-on because I was talking, time and time again, about there’s no origin server. There’s no server infrastructure for you to manage. In fact, I once wrote a blog post called “Web Serverless,” because the world needs another buzz term, doesn’t it?

Phil Hawksworth: And really, the kind of point of that was, yes, we’re building things without servers. We don’t want to have to manage these servers, and serverless functions, or functions as a service, just fits into that perfectly. So, in the instances that you do need an API that you want to make a request to, where really it’s not sensible for you to make that request directly from the browser. So, for instance, if you’ve got secrets, or keys, in that request, you might not want those requests — that information — ever exposed in the client. But we can certainly proxy those things, and typically, traditionally, what we need to do then, is spin-up a server, have some infrastructure that was effectively doing little more than handling requests, adding security authentication to it and passing those requests on, proxying them back.

Phil Hawksworth: Serverless functions are perfect for that. They’re absolutely ideal for that. So, I sometimes think of serverless functions, or functions of a service, almost as like an escape hatch, where you just need some logic on a server, but you don’t want to have to create an entire infrastructure. And you can do more and more with that, and stipe the development pipelines for, development workflows, for functions as a service is maturing. It’s getting more accessible for JavaScript developers to be able to build these things out. So, yeah, I really think those two things go together very nicely.

Vitaly: All right, that’s a very comprehensive answer. Actually, I attended a talk just recently, where a front-end engineer from Amazon was speaking about serverless and Lamda functions they’re using — I was almost gone. He was always speaking about Docker, and Kubernetes, and all those things, Devox World, I was sitting there, thinking, “How did he end up there. I don’t understand what’s going on!” I had no idea what’s going on.

Phil Hawksworth: Exactly, but the thing is, it used to be the… I was… I accepted that I didn’t understand any of that world, but I didn’t have any desire to, since that was for an entirely different discipline. And that discipline is still really important. You know, people who are designing infrastructure — that’s still really key. But, it just feels, now, that I’m tempted. As someone with a front-end development background, as a JavaScript developer, I’m much more tempted to want to play in that world, because the tools are coming, kind of, closer to me.

Phil Hawksworth: It’s much more likely that I might be able to use some of these things, and deliver things kind of safely, rather than just as an experiment of my own, which is where I used to be dappling. So, it feels like we’re becoming more powerful as web developers, which is exciting to me.

Vitaly: Like Power Rangers, huh?

Vitaly: One thing I do want to ask you, though, and this is actually something we discussed already, maybe, a week ago, but I still wanted to bring it up, because the one thing that you mentioned in the session was the notion of having a stand-alone instance of every single deploy, which is really cool. The question, though, is if you have a large assignment, with tens of thousands of pages, you really don’t want to redeploy every thing, every single time. So, essentially, if you have, like, if you’re mostly using the static side of things. So, we had this idea for a while and I know this is actually something that you brought up last time. The idea of atomic deployments.

Vitaly: Where you actually, literally, were served some sort of div between two different versions of snapshots of the set-up. So, if you say, change the header everywhere, then, of course, every single page has to be redeployed. But if you change, maybe, a component, like let’s say, carousel, that maybe effects only a 1000 pages, then it would make sense to redeploy 15000 pages. But only this 1000. So, can we get there? Is it a magical idea that’s out there, or is it something that’s quite tangible, at this point?

Phil Hawksworth: I think that is, probably, the Holy Grail for static site generators and this kind of model because, certainly, you’ve identified probably the biggest hurdle to overcome. Or the biggest ceiling that you bump into. And that is websites that have many, tens of thousands or hundreds of thousands, or millions of URLs — the notion that the build can become very long. Being able to detect which URL’s will change, based on a code change, is a challenge. It’s not insurmountable, but it’s a big challenge. Understanding what the dependency graph is across your entire site and then, intelligently deploying that — that’s really tough to do.

Phil Hawksworth: Because as you mentioned, a component change might have very far-reaching implications but you — it’s difficult, always, to know how that’s going to work. So, there are a number of static site generators, the projects that are putting some weight behind that challenge, and trying to figure out how they do partial-regeneration and incremental builds. I’m very excited that the prospect that that might get solved day, but at the moment, it’s definitely a big challenge. You can start to do things like try to logically sharred your site, and think about, again, kind of similar to the migration issue. Well, this section I know is independent in terms of its, kind of, some of the assets that it uses, or the type of content that lives there, so I can deploy them individually.

Phil Hawksworth: But that’s not ideal to me. That’s not really the perfect scenario. One of the approaches that I’ve explored a little bit, just as a proof of concept, is thinking about how you do things, like, making intelligent use of 404s. So, for instance, a big use case for very large signs, maybe news sites is, when they need a URL when a breaking news story happens, they need to be first to get it deploy out there. They need to get a URL up there. Things like the BBC News, you’ll see that the news story will arrive on the website, and then overtime, they’ll add to it, incrementally, but getting there first is key. So, having a build that takes 10 minutes, 20 minutes, whatever it’s going to be, that could be a problem.

Phil Hawksworth: But, if they’re content is abstracted and maybe used to have been called from an API. I mentioned content management systems that are abstracted, like Contentful, or Sanity, or a bunch of those. Anything that has a content API changes to that content structure that will trigger a build and we’ll go through the run, but the other thing that could happen is that, well, if you publish your URL for that, and then publicize that URL, even if the build hasn’t run, if someone hicks that URL, if the first stop on its 404 is instead of saying, “We haven’t got it,” is actually to hit that API directly, then, you can say, “Well, the build hasn’t finished to populate that yet, but I can do it in the client.” I can go directly to the API, get that, populate it in the client.

Vitaly: Hmm, interesting.

Phil Hawksworth: So, even while the build is still happening, you can start populating those things. And then, once the build’s finished, of course it wouldn’t hit a 404. You would hit that statically running page. So, there are techniques and there are strategies to tackle it, but still, it’s a very long, rambling answer, I’m sorry, but my conclusion is, yeah, that’s a challenge. Fingers crossed we’ll get better strategies.

Vitaly: Yeah, that’s great. So, I’m wondering, so, at this point, we really aren’t thinking, not just what the performance in terms of the content delivering, but those in performance in terms of the build speed. Like building deployment. So, this is also something that we’ve been looking into for, quite a bit of time now, as well.

Vitaly: One more thing I wanted to ask you. So, this is interesting, like this technique that you mentioned. How do you learn about this? This is just something people tend to publish on their own blogs or, is it some medium or is there a central repository where you can get some sort of case studios, of how JAMstack—how companies moved while unloading, or have failed to move to JAMstack.

Phil Hawksworth: So, it’s kind of maturing this landscape a little bit, at the moment. I mean, some of these examples, I think, I’m in a very fortunate position, I work somewhere that I’m in a role that I’m playing with the toys, coming up with interesting ways to use it and start experimenting with them. So, these proofs of concepts are, kind of, things that I get to experiment with and try to address these challenges. But the, I kind of mentioned earlier, a case study that was shown at the JAMstack conference in New York, and certainly, events like that, we’re starting to see best practices or industry practices and industry approaches being talked about at those kind of events. And certainly, I want to see more and work on more case studies to get in places like on Smashing Magazines, so that we can share this information much more readily.

Phil Hawksworth: I think, large companies and the enterprise space, is gradually adopting JAMstack, in different places, in different ways, but the world is still sloped to get out there, so I think, each time a company adopts it and shares their experience, we all get to learn from that. But I really want to see more and more of these case studies get published, so that we can lean particularly about how these kind of challenges are overcome.

Vitaly: Alright, so, then, maybe just the last question from me, because I always like to read questions. So, the JAMstack land, if you could change something, maybe there is something that you desperately would love to see, beyond deployments. Anything else that would be really making you very happy? That would make your day? What would that be? What’s on your wishlist, for JAMstack?

Phil Hawksworth: What a question. I mean, had we not talked about incremental builds, that would be—

Vitaly: We did. That’s too late, now. This card has been passed, already. We need something else.

Phil Hawksworth: So—

Vitaly: What I mean, like on a platform, if you looked at the back platform, there are so many exciting things happening. We have Houdini, we have web components coming, and everything, since you could be changing the entire landscape of all the right components. On the other side, we have all this magical, fancy world with SS NGS, and, of course, obviously, we also have single-page applications and all. What are you most excited about?

Phil Hawksworth: I’m going to be obtuse here, because there is so much stuff that’s going on, it’s exciting, and there is so many new capabilities that you can make use of in the browser. The thing that I really get excited about is people showing restraint (laughs) and as I said, dull answer, but I love seeing great executions that are done with restraint, in a thoughtful — about the wider audience. It’s really good fun, and gratifying to build with the shiniest new JavaScript library or the new browser API that does, I don’t know, scratch and sniff capabilities in the browser, which we desperately need, any day now.

Phil Hawksworth: But I really like seeing things that I know are going to work in many, many places. They’re going to be really performant, are going to be sympathetic to the browsers that exist — not just on the desks of CEOs and CTOs who got the snazzy toys, but also people who have got much lower-powered devices, or they’ve got challenging network conditions and those kinds of things. I like seeing interesting experiences, and rich experiences, delivered in a way that are sympathetic to the platform, and kind of, compassionate for the wider audience, because I think the web reaches much further than us, the developers, who build things for it. And I get excited by seeing interesting things done, in ways that reach more people.

Phil Hawksworth: That’s probably not the answer you were necessarily—

Vitaly: Oh, that’s a nice ending. Thank you so much. No, that’s perfect, that really is. All right, I felt everything went good! Thank you so much for being with us! I’m handing out to Scott!

Phil Hawksworth: Great!

Vitaly: I’m just here to play questions and answers. So, thank you so much, Phil! I’m still here, but Scott, the stage is yours, now! Maybe you can share with us what’s coming up next on Smashing TV?

Scott: I will, but first, Phil, I can’t wait to see how the implementation of scratch-and-sniff API work. Sounds very interesting. And, Vitaly, JAMstackify is already taken.

Vitaly: (dejected) Taken?! Can we buy it?

Scott: No, it exists!

Vitaly: Well, that’s too late. I’m always late.

Phil Hawksworth: That’s exciting in its own way.

Vitaly: That’s the story of my life. I’m always late.

Scott: Members coming up next, I believe, Thursday, the 13th, we have my ol’ pa, Zach Leatherman, talking about what he talks about best, which is fonts. So, he’s talking about the Five Y’s of Font Implementations. And then, I’m also very interested in the one we have coming up on the 19th, which is editing video, with JavaScript and CSS, with Eva Faria. So, stay tuned for both of those.

Scott: So, that is again, next Thursday, with Zach Leatherman, and then on the 19th, with Eva, who will be talking about editing video in JavaScript and CSS. So, on that note, Phil, I can’t see you anymore, are you still there?

Phil Hawksworth: I’m here!

Scott: On that note, thank you very much everyone! Also, is anybody in the, kind of, close to Toronto area? Or anybody that’s ever wanted to visit Toronto? We have a conference coming up at the end of June, and there’s still a few tickets left. So, maybe we’ll see some of you there.

Vitaly: Thank you so much, everyone else!

Vitaly: Oh, by the way, just one more thing! Maybe Phil mentioned it, but we also have the JAMstack Conference in London, in July. So, that’s something to watch out for, as well. But I’m signing off and going to get my salad! Not sure what you—

Scott: Okay, goodbye, everybody!

Vitaly: All right, bye-bye, everyone.

That’s A Wrap!

We kindly thank Smashing Members from the very bottom of our hearts for their continuous and kind support — and we can’t wait to host more webinars in the future.

Also, Phil will be MCing at SmashingConf Toronto 2019 next week and at JAMstack_conf — we’d love to see you there as well!

Please do let us know if you find this series of interviews useful, and whom you’d love us to interview, or what topics you’d like us to cover and we’ll get right to it.

(ra, il)
Categories: Web Design

Optimizing Google Fonts Performance

Thu, 06/20/2019 - 02:00
Optimizing Google Fonts Performance Optimizing Google Fonts Performance Danny Cooper 2019-06-20T11:00:16+02:00 2019-07-01T12:46:47+00:00

It’s fair to say Google Fonts are popular. As of writing, they have been viewed over 29 trillion times across the web and it’s easy to understand why — the collection gives you access to over 900 beautiful fonts you can use on your website for free. Without Google Fonts you would be limited to the handful of “system fonts” installed on your user’s device.

System fonts or ‘Web Safe Fonts’ are the fonts most commonly pre-installed across operating systems. For example, Arial and Georgia are packaged with Windows, macOS and Linux distributions.

Like all good things, Google Fonts do come with a cost. Each font carries a weight that the web browser needs to download before they can be displayed. With the correct setup, the additional load time isn’t noticeable. However, get it wrong and your users could be waiting up to a few seconds before any text is displayed.

Google Fonts Are Already Optimized

The Google Fonts API does more than just provide the font files to the browser, it also performs a smart check to see how it can deliver the files in the most optimized format.

Let’s look at Roboto, GitHub tells us that the regular variant weighs 168kb.

168kb for a single font variant. (Large preview)

However, if I request the same font variant from the API, I’m provided with this file. Which is only 11kb. How can that be?

When the browser makes a request to the API, Google first checks which file types the browser supports. I’m using the latest version of Chrome, which like most browsers supports WOFF2, so the font is served to me in that highly compressed format.

If I change my user-agent to Internet Explorer 11, I’m served the font in the WOFF format instead.

Finally, if I change my user agent to IE8 then I get the font in the EOT (Embedded OpenType) format.

Google Fonts maintains 30+ optimized variants for each font and automatically detects and delivers the optimal variant for each platform and browser.

— Ilya Grigorik, Web Font Optimization

This is a great feature of Google Fonts, by checking the user-agent they are able to serve the most performant formats to browsers that support those, while still displaying the fonts consistently on older browsers.

Browser Caching

Another built-in optimization of Google Fonts is browser caching.

Due to the ubiquitous nature of Google Fonts, the browser doesn’t always need to download the full font files. SmashingMagazine, for example, uses a font called ‘Mija’, if this is the first time your browser has seen that font, it will need to download it completely before the text is displayed, but the next time you visit a website using that font, the browser will use the cached version.

As the Google Fonts API becomes more widely used, it is likely visitors to your site or page will already have any Google fonts used in your design in their browser cache.

— FAQ, Google Fonts

The Google Fonts browser cache is set to expire after one year unless the cache is cleared sooner.

Note: Mija isn’t a Google Font, but the principles of caching aren’t vendor-specific.

Further Optimization Is Possible

While Google invests great effort in optimizing the delivery of the font files, there are still optimizations you can make in your implementation to reduce the impact on page load times.

1. Limit Font Families

The easiest optimization is to simply use fewer font families. Each font can add up to 400kb to your page weight, multiply that by a few different font families and suddenly your fonts weigh more than your entire page.

I recommend using no more than two fonts, one for headings and another for content is usually sufficient. With the right use of font-size, weight, and color you can achieve a great look with even one font.

Three weights of a single font family (Source Sans Pro). (Large preview) 2. Exclude Variants

Due to the high-quality standard of Google Fonts, many of the font families contain the full spectrum of available font-weights:

  • Thin (100)
  • Thin Italic (100i)
  • Light (300)
  • Light Italic (300i)
  • Regular (400)
  • Regular Italic (400i)
  • Medium (600)
  • Medium Italic (600i)
  • Bold (700)
  • Bold Italic (700i)
  • Black (800)
  • Black Italic (800i)

That’s great for advanced use-cases which might require all 12 variants, but for a regular website, it means downloading all 12 variants when you might only need 3 or 4.

For example, the Roboto font family weighs ~144kb. If however you only use the Regular, Regular Italic and Bold variants, that number comes down to ~36kb. A 75% saving!

The default code for implementing Google Fonts looks like this:

<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">

If you do that, it will load only the ‘regular 400’ variant. Which means all light, bold and italic text will not be displayed correctly.

To instead load all the font variants, we need to specify the weights in the URL like this:

<link href="https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,500,500i,700,700i,900,900i" rel="stylesheet">

It’s rare that a website will use all variants of a font from Thin (100) to Black (900), the optimal strategy is to specify just the weights you plan to use:

<link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,600" rel="stylesheet">

This is especially important when using multiple font families. For example, if you are using Lato for headings, it makes sense to only request the bold variant (and possibly bold italic):

<link href="https://fonts.googleapis.com/css?family=Lato:700,700i" rel="stylesheet"> 3. Combine Requests

The code snippet we worked with above makes a call to Google’s servers (fonts.googleapis.com), that’s called an HTTP request. Generally speaking, the more HTTP requests your web page needs to make, the longer it will take to load.

If you wanted to load two fonts, you might do something like this:

<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">

That would work, but it would result in the browser making two requests. We can optimize that by combining them into a single request like this:

<link href="https://fonts.googleapis.com/css?family=Roboto|Open+Sans:400,400i,600" rel="stylesheet">

There is no limit to how many fonts and variants a single request can hold.

4. Resource Hints

Resource hints are a feature supported by modern browsers which can boost website performance. We are going to take a look at two types of resource hint: ‘DNS Prefetching’ and ‘Preconnect’.

Note: If a browser doesn’t support a modern feature, it will simply ignore it. So your web page will still load normally.

DNS Prefetching

DNS prefetching allows the browser to start the connection to Google’s Fonts API (fonts.googleapis.com) as soon as the page begins to load. This means that by the time the browser is ready to make a request, some of the work is already done.

To implement DNS prefetching for Google Fonts, you simply add this one-liner to your web pages <head>:

<link rel="dns-prefetch" href="//fonts.googleapis.com"> Preconnect

If you look at the Google Fonts embed code it appears to be a single HTTP request:

<link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700" rel="stylesheet">

However, if we visit that URL we can see there are three more requests to a different URL, https://fonts.gstatic.com. One additional request for each font variant.

(View source) (Large preview)

The problem with these additional requests is that the browser won’t begin the processes to make them until the first request to https://fonts.googleapis.com/css is complete. This is where Preconnect comes in.

Preconnect could be described as an enhanced version of prefetch. It is set on the specific URL the browser is going to load. Instead of just performing a DNS lookup, it also completes the TLS negotiation and TCP handshake too.

Just like DNS Prefetching, it can be implemented with one line of code:

<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>

Just adding this line of code can reduce your page load time by 100ms. This is made possible by starting the connection alongside the initial request, rather than waiting for it to complete first.

5. Host Fonts Locally

Google Fonts are licensed under a ‘Libre’ or ‘free software’ license, which gives you the freedom to use, change and distribute the fonts without requesting permission. That means you don’t need to use Google’s hosting if you don’t want to — you can self-host the fonts!

All of the fonts files are available on Github. A zip file containing all of the fonts is also available (387MB).

Lastly, there is a helper service that enables you to choose which fonts you want to use, then it provides the files and CSS needed to do so.

There is a downside to hosting fonts locally. When you download the fonts, you are saving them as they are at that moment. If they are improved or updated, you won’t receive those changes. In comparison, when requesting fonts from the Google Fonts API, you are always served the most up-to-date version.

Google Fonts API Request. (Large preview)

Note the lastModified parameter in the API. The fonts are regularly modified and improved.

6. Font Display

We know that it takes time for the browser to download Google Fonts, but what happens to the text before they are ready? For a long time, the browser would show blank space where the text should be, also known as the "FOIT” (Flash of Invisible Text).

Recommended Reading: FOUT, FOIT, FOFT” by Chris Coyier

Showing nothing at all can be a jarring experience to the end user, a better experience would be to initially show a system font as a fallback and then “swap” the fonts once they are ready. This is possible using the CSS font-display property.

By adding font-display: swap; to the @font-face declaration, we tell the browser to show the fallback font until the Google Font is available.

@font-face { font-family: 'Roboto'; src: local('Roboto Thin Italic'), url(https://fonts.gstatic.com/s/roboto/v19/KFOiCnqEu92Fr1Mu51QrEz0dL-vwnYh2eg.woff2) format('woff2'); font-display: swap; }

In 2019 Google, announced they would add support for font-display: swap. You can begin implementing this right away by adding an extra parameter to the fonts URL:

https://fonts.googleapis.com/css?family=Roboto&display=swap 7. Use the Text Parameter

A little known feature of the Google Fonts API is the text parameter. This rarely-used parameter allows you to only load the characters you need.

For example, if you have a text-logo that needs to be a unique font, you could use the text parameter to only load the characters used in the logo.

It works like this:


Obviously, this technique is very specific and only has a few realistic applications. However, if you can use it, it can cut down the font weight by up to 90%.

Note: When using the text parameter, only the “normal” font-weight is loaded by default. To use another weight you must explicitly specify it in the URL.

https://fonts.googleapis.com/css?family=Roboto:700&text=CompanyName Wrapping Up

With an estimated 53% of the top 1 million websites using Google Fonts, implementing these optimizations can have a huge impact.

How many of the above have you tried? Let me know in the comments section.

(dm, yk, il)
Categories: Web Design

How To Create A PDF From Your Web Application

Wed, 06/19/2019 - 05:00
How To Create A PDF From Your Web Application How To Create A PDF From Your Web Application Rachel Andrew 2019-06-19T14:00:59+02:00 2019-07-01T12:46:47+00:00

Many web applications have the requirement of giving the user the ability to download something in PDF format. In the case of applications (such as e-commerce stores), those PDFs have to be created using dynamic data, and be available immediately to the user.

In this article, I’ll explore ways in which we can generate a PDF directly from a web application on the fly. It isn’t a comprehensive list of tools, but instead I am aiming to demonstrate the different approaches. If you have a favorite tool or any experiences of your own to share, please add them to the comments below.

Starting With HTML And CSS

Our web application is likely to be already creating an HTML document using the information that will be added to our PDF. In the case of an invoice, the user might be able to view the information online, then click to download a PDF for their records. You might be creating packing slips; once again, the information is already held within the system. You want to format that in a nice way for download and printing. Therefore, a good place to start would be to consider if it is possible to use that HTML and CSS to generate a PDF version.

CSS does have a specification which deals with CSS for print, and this is the Paged Media module. I have an overview of this specification in my article “Designing For Print With CSS”, and CSS is used by many book publishers for all of their print output. Therefore, as CSS itself has specifications for printed materials, surely we should be able to use it?

The simplest way a user can generate a PDF is via their browser. By choosing to print to PDF rather than a printer, a PDF will be generated. Sadly, this PDF is usually not altogether satisfactory! To start with, it will have the headers and footers which are automatically added when you print something from a webpage. It will also be formatted according to your print stylesheet — assuming you have one.

The problem we run into here is the poor support of the fragmentation specification in browsers; this may mean that the content of your pages breaks in unusual ways. Support for fragmentation is patchy, as I discovered when I researched my article, “Breaking Boxes With CSS Fragmentation”. This means that you may be unable to prevent suboptimal breaking of content, with headers being left as the last item on the page, and so on.

In addition, we have no ability to control the content in the page margin boxes, e.g. adding a header of our choosing to each page or page numbering to show how many pages a complex invoice has. These things are part of the Paged Media spec, but have not been implemented in any browser.

My article “A Guide To The State Of Print Stylesheets In 2018” is still accurate in terms of the type of support that browsers have for printing directly from the browser, using a print stylesheet.

Printing Using Browser Rendering Engines

There are ways to print to PDF using browser rendering engines, without going through the print menu in the browser, and ending up with headers and footers as if you had printed the document. The most popular options in response to my tweet were wkhtmltopdf, and printing using headless Chrome and Puppeteer.


A solution that was mentioned a number of times on Twitter is a commandline tool called wkhtmltopdf. This tool takes an HTML file or multiple files, along with a stylesheet and turns them into a PDF. It does this by using the WebKit rendering engine.

We use wkhtmltopdf. It’s not perfect, although that was probably user error, but easily good enough for a production application.

— Paul Cardno (@pcardno) February 15, 2019

Essentially, therefore, this tool does the same thing as printing from the browser, however, you will not get the automatically added headers and footers. On this positive side, if you have a working print stylesheet for your content then it should also nicely output to PDF using this tool, and so a simple layout may well print very nicely.

Unfortunately, however, you will still run into the same problems as when printing directly from the web browser in terms of lack of support for the Paged Media specification and fragmentation properties, as you are still printing using a browser rendering engine. There are some flags that you can pass into wkhtmltopdf in order to add back some of the missing features that you would have by default using the Paged Media specification. However, this does require some extra work on top of writing good HTML and CSS.

Headless Chrome

Another interesting possibility is that of using Headless Chrome and Puppeteer to print to PDF.

Puppeteer. It's amazing for this.

— Alex Russell (@slightlylate) February 15, 2019

However once again you are limited by browser support for Paged Media and fragmentation. There are some options which can be passed into the page.pdf() function. As with wkhtmltopdf, these add in some of the functionality that would be possible from CSS should there be browser support.

It may well be that one of these solutions will do all that you need, however, if you find that you are fighting something of a battle, it is probable that you are hitting the limits of what is possible with current browser rendering engines, and will need to look for a better solution.

JavaScript Polyfills For Paged Media

There are a few attempts to essentially reproduce the Paged Media specification in the browser using JavaScript — essentially creating a Paged Media Polyfill. This could give you Paged Media support when using Puppeteer. Take a look at paged.js and Vivliostyle.

Yes. For simple docs, like course certificates, we can use Chrome, which has minimal @ page support. For anything else, we use PrinceXML or the paged.js polyfill in Chrome. Here's a WIP proof-of-concept using paged.js for books: https://t.co/AZ9fO94PT2

— Electric Book Works (@electricbook) February 15, 2019

Using A Print User Agent

If you want to stay with an HTML and CSS solution then you need to look to a User Agent (UA) designed for printing from HTML and CSS, which has an API for generating the PDF from your files. These User Agents implement the Paged Media specification and have far better support for the CSS Fragmentation properties; this will give you greater control over the output. Leading choices include:

A print UA will format documents using CSS — just as a web browser does. As with browser support for CSS, you need to check the documentation of these UAs to find out what they support. For example, Prince (which I am most familiar with) supports Flexbox but not CSS Grid Layout at the time of writing. When sending your pages to the tool that you are using, typically this would be with a specific stylesheet for print. As with a regular print stylesheet, the CSS you use on your site will not all be appropriate for the PDF version.

Creating a stylesheet for these tools is very similar to creating a regular print stylesheet, making the kind of decisions in terms of what to display or hide, perhaps using a different font size or colors. You would then be able to take advantage of the features in the Paged Media specification, adding footnotes, page numbers, and so on.

In terms of using these tools from your web application, you would need to install them on your server (having bought a license to do so, of course). The main problem with these tools is that they are expensive. That said, given the ease with which you can then produce printed documents with them, they may well pay for themselves in developer time saved.

It is possible to use Prince via an API, on a pay per document basis, via a service called DocRaptor. This would certainly be a good place for many applications to start as if it looked as if it would become more cost effective to host your own, the development cost of switching would be minimal.

A free alternative, which is not quite as comprehensive as the above tools but may well achieve the results you need, is WeasyPrint. It doesn’t fully implement all of Paged Media, however, it implements more than a browser engine does. Definitely, one to try!

Other tools which claim to support conversion from HTML and CSS include PDFCrowd, which boldly claims to support HTML5, CSS3 and JavaScript. I couldn’t, however, find any detail on exactly what was supported, and if any of the Paged Media specification was. Also receiving a mention in the responses to my tweet was mPDF.

Moving Away From HTML And CSS

There are a number of other solutions, which move away from using HTML and CSS and require you to create specific output for the tool. A couple of JavaScript contenders are as follows:

Headless browser + saving to PDF was once my first choice but always produced subpar results for anything other than a single page document. We switched over to https://t.co/3o8Ce23F1t for multi-page reports which took quite a lot more effort but well worth it in the end!

— JimmyJoy (@jimle_uk) February 15, 2019


Other than the JavaScript-based approaches, which would require you to create a completely different representation of your content for print, the beauty of many of these solutions is that they are interchangeable. If your solution is based on calling a commandline tool, and passing that tool your HTML, CSS, and possibly some JavaScript, it is fairly straightforward to switch between tools.

In the course of writing this article, I also discovered a Python wrapper which can run a number of different tools. (Note that you need to already have the tools themselves installed, however, this could be a good way to test out the various tools on a sample document.)

For support of Paged Media and fragmentation, Prince, Antenna House, and PDFReactor are going to come out top. As commercial products, they also come with support. If you have a budget, complex pages to print to PDF, and your limitation is developer time, then you would most likely find these to be the quickest route to have your PDF creation working well.

However, in many cases, the free tools will work well for you. If your requirements are very straightforward then wkhtmltopdf, or a basic headless Chrome and Puppeteer solution may do the trick. It certainly seemed to work for many of the people who replied to my original tweet.

If you find yourself struggling to get the output you want, however, be aware that it may be a limitation of browser printing, and not anything you are doing wrong. In the case that you would like more Paged Media support, but are not in a position to go for a commercial product, perhaps take a look at WeasyPrint.

I hope this is a useful roundup of the tools available for creating PDFs from your web application. If nothing else, it demonstrates that there are a wide variety of choices, if your initial choice isn’t working well.

Please add your own experiences and suggestions in the comments, this is one of those things that a lot of us end up dealing with, and personal experience shared can be incredibly helpful.

Further Reading

A roundup of the various resources and tools mentioned in this article, along with some other useful resources for working with PDF files from web applications.

Specifications Articles and Resources Tools (il)
Categories: Web Design

Unleash The Power Of Path Animations With SVGator

Tue, 06/18/2019 - 04:30
Unleash The Power Of Path Animations With SVGator Unleash The Power Of Path Animations With SVGator Mikołaj Dobrucki 2019-06-18T13:30:59+02:00 2019-07-01T12:46:47+00:00

(This is a sponsored article.) Last year, a comprehensive introduction to the basic use of SVGator was published here on Smashing Magazine. If you’d like to learn about the fundamentals of SVGator, setting up your first projects, and creating your first animations, we strongly recommended you read it before continuing with this article.

Today, we’ll take a second look to explore some of the new features that have been added to it over the last few months, including the brand new Path Animator.

Note: Path Animator is a premium feature of SVGator and it’s not available to trial users. During a seven-day trial, you can see how Path Animator works in the sample project you’ll find in the app, but you won’t be able to apply it to your own SVGs unless you’re opted-in for a paid plan. SVGator is a subscription-based service. Currently, you can choose between a monthly plan ($18USD/month) and a yearly plan ($144USD total, $12USD/month). For longer projects, we recommend you consider the yearly option.

Path Animator is just the first of the premium features that SVGator plans to release in the upcoming months. All the new features will be available to all paid users, no matter when they subscribed.

The Charm Of Path Animations

SVG path animations are by no means a new thing. In the last few years, this way of enriching vector graphics has been heavily used all across the web:

Animation by Codrops (Original demo) (Large preview)

Path animations gained popularity mostly because of their relative simplicity: even though they might look impressive and complex at first glance, the underlying rule is in fact very simple.

How Do Path Animations Work?

You might think that SVG path animations require some extremely complicated drawing and transform functions. But it’s much simpler than it looks. To achieve effects similar to the example above, you don’t need to generate, draw, or animate the actual paths — you just animate their strokes. This brilliant concept allows you to create seemingly complex animations by animating a single SVG attribute: stroke-dashoffset.

Animating this one little property is responsible for the entire effect. Once you have a dashed line, you can play with the position of dashes and gaps. Combine it with the right settings and it will give you the desired effect of a self-drawing SVG path.

If this still sounds rather mysterious or you’d just like to learn about how path animations are made in more detail, you will find some useful resources on this topic at the end of the article.

No matter how simple path animations are compared with what they look like, don’t think coding them is always straightforward. As your files get more complicated, so does animating them. And this is where SVGator comes to the rescue.

Furthermore, sometimes you might prefer not to touch raw SVG files. Or maybe you’re not really fond of writing code altogether. Then SVGator has got you covered. With the new Path Animator, you can create even the most complex SVG path animations without touching a line of code. You can also combine coding with using SVGator.

To better understand the possibilities that Path Animator gives us, we will cover three separate examples presenting different use cases of path animations.

Example #1: Animated Text

In the first example, we will animate text, creating the impression of self-writing letters.

Final result of the first example (Large preview)

Often used for lettering, this cute effect can also be applied to other elements, such as drawings and illustrations. There’s a catch, though: the animated element must be styled with strokes rather than fills. Which means, for our text, that we can’t use any existing font.

Outlining fonts, no matter how thin, always results in closed shapes rather than open paths. There are no regular fonts based on lines and strokes.

Outlined fonts are not suitable for self-drawing effects with Path Animator. (Large preview) Path animations require strokes. These paths would work great with Path Animator. (Large preview)

Therefore, if we want to animate text using path animations we need to draw it ourselves (or find some ready-made vector letters suitable for this purpose). When drawing your letters, feel free to use some existing font or typography as a reference — don’t violate any copyright, though! Just keep in mind it’s not possible to use fonts out of the box.

Preparing The File

Rather than starting with an existing typeface, we’ll begin with a simple hand-drawn sketch:

A rough sketch for the animation (pardon my calligraphy skills!) (Large preview)

Now it’s time to redraw the sketch in a design tool. I used Figma, but you can use any app that supports SVG exports, such as Sketch, Adobe XD, or Adobe Illustrator.

Usually, I start with the Pen tool and roughly follow the sketch imported as a layer underneath:

Once done, I remove the sketch from the background and refine the paths until I’m happy with the result. No matter what tools you use, nor technique, the most important thing is to prepare the drawing as lines and to use just strokes, no fills.

These paths can be successfully animated with Path Animator as they are created with strokes. (Large preview)

In this example, we have four such paths. The first is the letter “H”; the second is the three middle letters “ell”; and “o” is the third. The fourth path is the line of the exclamation mark.

The dot of “!” is an exception — it’s the only layer we will style with a fill, rather than a stroke. It will be animated in a different way than the other layers, without using Path Animator.

Note that all the paths we’re going to animate with Path Animator are open, except for the “o,” which is an ellipse. Although animating closed paths (such as ellipses or polygons) with Path Animator is utterly fine and doable, it’s worth making it an open path as well, because this is the easiest way to control exactly where the animation starts. For this example, I added a tiny gap in the ellipse just by the end of the letter “l” as that’s where you’d usually start writing “o” in handwriting.

A small gap in the letter ‘o’ controls the starting point of the animation. (Large preview)

Before importing our layers to SVGator, it’s best to clean up the layers’ structure and rename them in a descriptive way. This will help you quickly find your way around your file once working in SVGator.

If you’d like to learn more about preparing your shapes for path animations, I would recommend you check out this tutorial by SVGator.

It’s worth preparing your layers carefully and thinking ahead as much as possible. At the time of writing, in SVGator you can’t reimport the file to an already existing animation. While animating, if you discover an issue that requires some change to the original file, you will have to import it into SVGator again as a new project and start working on your animation from scratch.

Creating An Animation

Once you’re happy with the structure and naming of your layers, import them to SVGator. Then add the first path to the timeline and apply Path Animator to it by choosing it from the Animators list or by pressing Shift + T.

To achieve a self-drawing effect, our goal is to turn the path’s stroke into a dashed line. The length of a dash and a gap should be equal to the length of the entire path. This allows us to cover the entire path with a gap to make it disappear. Once hidden, change stroke-dashoffset to the point where the entire path is covered by a dash.

SVGator makes it very convenient for us by automatically providing the length of the path. All we need to do is to copy it with a click, and paste it into the two parameters that SVGator requires: Dashes and Offset. Pasting the value in Dashes turns the stroke into a dashed line. You can’t see it straightaway as the first dash of the line covers the whole path. Setting the Offset will change stroke-dashoffset so the gap then covers the path.

Once done, let’s create an animation by adding a new keyframe further along the timeline. Bring Offset back to zero and… ta-da! You’ve just created a self-drawing letter animation.

Creating a self-writing text animation in SVGator: Part 1

There’s one little issue with our animation, though. The letter is animated — but back-to-front. That is, the animation starts at the wrong end of the path. There are, at least, a few ways to fix it. First, rather than animating the offset from a positive value to zero, we can start with a negative offset and bring it to zero. Unfortunately, this may not work as expected in some browsers (for example, Safari does not accept negative stroke offsets). While we wait for this bug to be fixed, let’s choose a different approach.

Let’s change the Dashes value so the path starts with a gap followed by a dash (by default, dashed lines always start with a dash). Then reverse the values of the Offset animation. This will animate the line in the opposite direction.

Reversing the direction of self-writing animation

Now that we’re done with “H” we can move on to animating all the other paths in the same way. Eventually, we finish by animating the dot of the exclamation mark. As it’s a circle with a fill, not an outline, we won’t use Path Animator. Instead, we use Scale Animator to the make dot pop in at the end of the animation.

Creating a self-writing text animation in SVGator: Part 2

Always remember to check the position of an element’s transform origin when playing with scale animations. In SVG, all elements have their transform origin in the top-left corner of the canvas by default. This often makes coding transform functions a very hard and tedious task. Fortunately, SVGator saves us from all this hassle by calculating all the transforms in relation to the object, rather than the canvas. By default, SVGator sets the transform origin of each element in its own top-left corner. You can change its position from the timeline, using a button next to the layer’s name.

Transform origin control in SVGator’s Timeline panel (Large preview)

Let’s add the final touch to the animation and adjust the timing functions. Timing functions define the speed over time of objects being animated, allowing us to manipulate their dynamics and make the animation look more natural.

In this case, we want to give the impression of the text being written by a single continuous movement of a hand. Therefore, I applied an Ease-in function to the first letter and an Ease-out function to the last letter, leaving the middle letters with a default Linear function. In SVGator, timing functions can be applied from the timeline, next to the Animator’s parameters:

Timing function control in SVGator’s Timeline panel (Large preview)

After applying the same logic to the exclamation mark, our animation is done and ready to be exported!

Final result of the first example Example #2: Animated Icon

Now let’s analyze a more UI-focused example. Here, we’re going to use SVGator to replicate a popular icon animation: turning a hamburger menu into a close button.

Final result of the second example (Large preview)

The goal of the animation is to smoothly transform the icon so the middle bar of the hamburger becomes a circle, and the surrounding bars cross each other creating a close icon.

Preparing The File

To better understand what we’re building and how to prepare a file for such an animation, it’s useful to start with a rough sketch representing the key states of the animation.

It’s helpful to plan your animation ahead and start with a sketch. (Large preview)

Once we have a general idea of what our animation consists of, we can draw the shapes that will allow us to create it. Let’s start with the circle. As we’re going to use path animation, we need to create a path that covers the whole journey of the line, starting as a straight bar in the middle of the hamburger menu, and finishing as a circle around it.

Complete path of the middle bar animation turning into a circle. (Large preview)

The other two bars of the menu icon have an easier task — we’re just going to rotate them and align to the centre of the circle. Once we combine all the shapes together we’re ready to export the file as SVG and import it to SVGator.

Our icon, ready to be animated in SVGator. (Large preview) Creating An Animation

Let’s start by adding the first shape to the timeline and applying Path Animator to it. For the initial state, we want only the horizontal line in the middle to be visible, while the rest of the path stays hidden. To achieve it, set the length of the dash to be equal to the length of the hamburger’s lines. This will make our straight middle line of the menu icon. To find the correct value, you can use the length of one of the other lines of the hamburger. You can copy it from the timeline or from the Properties panel in the right sidebar of the app.

Then set the length of the following gap to a value greater than the remaining length of the path so it becomes transparent.

Creating an icon animation in SVGator: Part 1

The initial state of our animation is now ready. What happens next is that we turn this line into a circle. To do that, two things need to happen simultaneously. First, we use Offset to move the line along the path. Second, we change the width of the dash to make the line longer and cover the entire circle.

Creating an icon animation in SVGator: Part 2

With the circle ready, let’s take care of the close icon. Just as before, we need to add two animations at the same time. First, we want the top line to lean down (45 degrees) and the bottom line to move up (-45 degrees) until they cross each other symmetrically. Second, we need to move the lines slightly to the right so they stay aligned with the circle.

As you might remember from the previous example, in SVGator, transform origins are located in the top-left corner by default. That’s very convenient to us as, in this case, that is exactly where we want them to be. All we need to do is to apply the correct rotation angles.

When it comes to aligning the lines with the circle, note that we don’t have to move them separately. Rather than adding Animators to both of the lines, we can add a group containing both of them to the timeline, and animate them together with a single Position Animator. That’s one of those moments when a nice, clean file structure pays off.

Creating an icon animation in SVGator: Part 3

Next thing to do is add a reverse animation that turns the close button back into a hamburger menu. To achieve that, we can basically follow the previous steps in reverse order. To speed things up a bit, copy and paste the existing keyframes on the timeline — that’s yet another improvement SVGator introduced in the past few months.

Reversing icon animation: back to the hamburger menu.

Once done, don’t forget to adjust the timing functions. Here, I’ve decided to go with an Ease-in-out effect on all elements. Our icon is ready for action.

Final result of the second example Implementation

Even though implementing microinteractions goes far beyond the scope of this article, let me take a moment to briefly describe how such animation can be brought to life in a real project.

Illustrations and decorative animation are usually more straightforward. Quite often, you can use SVG files generated by SVGator out of the box. We can’t say that about our icon, though. We want the first part of the animation to be triggered when users click the button to open the menu drawer, and the second part of the animation to play once they click it for the second time to close the menu.

To do that, we need to slice our animation into a few separate pieces. We won’t discuss here the technical details of implementing such animation, as it depends very much on the environment and tech stack you’re working with; but let’s at least inspect the generated SVG file to extract the crucial animation states.

We’ll start by hiding the background and adjusting the size of the canvas to match the dimensions of the icon. In SVGator, we can do this at any time, and there are no restrictions to the size of our canvas. We can also edit the styles of the icon, such as color and width of the stroke, and test what your graphic will look like on a dark background using a switch in the top-right corner.

Preparing icon animation for development

When we’re ready, we can export the icon to SVG and open it in a text editor.

Elements you see in the body of the document are the components of your graphic. You should also notice that the first line of code is exceptionally long. Straight after the opening <svg> tag, there’s a <style> element with plenty of minified CSS inside. That’s where all the animation happens.

<svg viewBox="0 0 600 450" fill="none" xmlns="http://www.w3.org/2000/svg" id="el_vNqlglrYK"><style>@-webkit-keyframes kf_el_VqluQuq4la_an_DAlSHvvzUV… </style> <!-- a very long line of code that contains all the animations --> <g id="el_SZQ_No_bd6"> <g id="el_BVAiy-eRZ3_an_biAmTPyDq" data-animator-group="true" data-animator-type="0"><g id="el_BVAiy-eRZ3"> <g id="el_Cnv4q4_Zb-_an_6WWQiIK_0" data-animator-group="true" data-animator-type="1"><path id="el_Cnv4q4_Zb-" d="M244 263H356" stroke-linecap="round"/></g> <g id="el_aGYDsRE4sf_an_xRd24ELq3" data-animator-group="true" data-animator-type="1"><path id="el_aGYDsRE4sf" d="M244 187H356" stroke-linecap="round"/></g> </g></g> <path id="el_VqluQuq4la" d="M244 225H355.5C369 225 387.5 216.4 387.5 192C387.5 161.5 352 137 300 137C251.399 137 212 176.399 212 225C212 273.601 251.399 313 300 313C348.601 313 388 273.601 388 225C388 176.399 349.601 137 301 137" stroke-linecap="round"/> </g> </svg>

It’s really nice of SVGator to minify the code for us. However, we’ll have to undo it. Once the CSS code is written out in full (you can do this in your browser’s development tools, or in one of many online code formatters), you’ll see that it’s a long list of @keyframes followed by a list of id rules using the @keyframes in their animation properties.

The code may look unreadable (even when nicely formatted) but, rather, it’s very repetitive. Once you understand the underlying rule, following it is no longer that hard. First, we’ve got the @keyframes. Each animated element has its own @keyframes @-rule. They’re sorted in the same order as elements in SVGator. Therefore, in our case, the first @-rule applies to the middle bar of the hamburger icon, the second one to the top bar, and so on. The keyframes inside also match the order of keyframes created in SVGator:

@keyframes kf_el_VqluQuq4la_an_DAlSHvvzUV{ /* middle bar animation */ 0%{ stroke-dasharray: 112, 2000; /* initial state */ } 25%{ stroke-dasharray: 112, 2000; } 50%{ stroke-dasharray: 600, 2000; /* turns into a circle */ } 75%{ stroke-dasharray: 600, 2000; /* back at initial state */ } 100%{ stroke-dasharray: 112, 2000; } }

All you need to do now is use these values from the keyframes to code your interaction. It’s still a lot of work up ahead, but thanks to SVGator the crucial part is already done.

What happens next is another story. However, if you’re curious to see an example of how this animation could work in practice, here’s a little CodePen for you:

See the Pen [Hamburger icon path animation](https://codepen.io/smashingmag/pen/ewNdJo) by Mikołaj.

See the Pen Hamburger icon path animation by Mikołaj.

The example is built with React and uses states to switch CSS classes and trigger transitions between the respective CSS values. Therefore, there’s no need for animation properties and @keyframes @-rules.

You can use a set of CSS custom priorities listed at the top of the SCSS code to control the styling of the icon as well as duration of the transitions.

Example #3: Animated Illustration

For the third and final example of this article, we’re going to create an animated illustration of an atom with orbiting particles.

Final result of the third example (Large preview) Dashed Lines And Dotted Lines

In the two previous examples, we’ve taken advantage of dashed SVG paths. Dashed lines are cool but did you know that SVG also supports dotted lines? A dotted line in SVG is no more, no less than a dashed line with round caps, and the length of the dashes is equal to zero.

If we can have a path with lots of dots, who said we can’t have a path with a single dot? Animate the stroke’s offset and you’ve got an animation of a circle following any path you want. In this example, the path will be an ellipse, and a circle will represent an orbiting particle.

Preparing The File

As no SVG element can have two strokes at the same time, for each of the particles we need two ellipses. The first of them will be an orbit, the second will be for the particle. Multiply it by three, combine with another circle in the middle for the nucleus and here it is: a simple atom illustration, ready to be animated.

Our illustration, ready to be imported to SVGator. (Large preview)

Note: At the time of writing, creating dotted lines in Figma is a hard task. Not only can’t you set a dash’s length to zero, but neither can you create a gap between the dashes long enough to cover the entire path. And when it comes to export, all your settings are gone anyway. Nonetheless, if you’re working with Figma, don’t get discouraged. We’ll fix all of these issues easily in SVGator. And if you’re working in Sketch, Illustrator, or similar, you shouldn’t experience these problems at all.

Creating An Animation

Once you have imported the SVG file into SVGator, we’ll start by fixing the dotted lines. As mentioned above, to achieve a perfect circular dot, we need a dash length set to zero. We also set the length of the gap equal to the length of the path (copied from above). This will make our dot the only one visible.

Creating an illustration animation in SVGator: Part 1

With all three particles ready, we can add new keyframes and animate the offsets by one full length of the path. Finally, we play a bit with the Offset values to make the dots’ positions feel a bit more random.

Creating an illustration animation in SVGator: Part 2.

Remember that if you find your animation too fast or too slow you can always change its duration in the settings. Right now, SVGator supports animations up to 30 seconds long.

As a final touch, I’ve added a bit of a bounce to the whole graphic.

Creating an illustration animation in SVGator: Part 3

Now the animation is ready and can be used, perhaps as a loader graphic.

Final result of the third example A Quick Word On Accessibility

As you can see, there’s hardly a limit to what can be achieved with SVG. And path animations are a very important part of its tool kit. But as a wise man once said, with great power comes great responsibility. Please refrain from overusing them. Animation can add life to your product and delight users, but too many animations can ruin the whole experience as well.

Also, consider allowing users to disable animations. People suffering from motion sickness and other related conditions will find such an option very helpful.


That’s it for today. I hope you enjoyed this journey through the possibilities of path animations. To try them out yourself, just visit SVGator’s website where you can also learn about its other features and pricing. If you have any remarks or questions, please don’t hesitate to add them in the comments. And stay tuned for the next updates about SVGator — there are lots of other amazing new features already on the way!

Further Reading Useful Resources (og, yk, il)
Categories: Web Design

Building A Component Library Using Figma

Mon, 06/17/2019 - 05:00
Building A Component Library Using Figma Building A Component Library Using Figma Emiliano Cicero 2019-06-17T14:00:16+02:00 2019-07-01T12:46:47+00:00

I’ve been working on the creation and maintenance of the main library of our design system, Lexicon. We used the Sketch app for the first year and then we moved to Figma where the library management was different in certain aspects, making the change quite challenging for us.

To be honest, as with any library construction, it requires time, effort, and planning, but it is worth the effort because it will help with providing detailed components for your team. It will also help increase the overall design consistency and will make the maintenance easier in the long run. I hope the tips that I’ll provide in this article will make the process smoother for you as well.

This article will outline the steps needed for building a component library with Figma, by using styles and a master component. (A master component will allow you to apply multiple changes all at once.) I’ll also cover in detail the components’ organization and will give you a possible solution if you have a large number of icons in the library.

Note: To make it easier to use, update and maintain, we found that it is best to use a separate Figma file for the library and then publish it as a team ‘library’ instead of publishing the components individually.

Getting Started

This guide was created from a designer’s perspective, and if you have at least some basic knowledge of Figma (or Sketch), it should help you get started with creating, organizing and maintaining a component library for your design team.

If you are new to Figma, check the following tutorials before proceeding with the article:


Before starting, there are some requirements that we have to cover to define the styles for the library.

Typography Scale

The first step to do is to define the typography scale; it helps to focus on how the text size and line height grow in your system, allowing you to define the visual hierarchy of your texts.

Typography scales are useful to improve the hierarchy of the elements, as managing the sizes and weights of the fonts can really guide the user through the content. (Large preview)

The type of scale depends on what you’re designing. It’s common to use a bigger ratio for website designs and a smaller ratio when designing digital products.

The reason for this is behind the design’s goal — a website is usually designed to communicate and convert so it gives you one or two direct actions. It’s easier in that context to have 36px for a main title, 24px for a secondary title, and 16px for a description text.

Related resource: “8-Point Grid: Typography On The Web” by Elliot Dahl.

On the other hand, digital products or services are designed to provide a solution to a specific problem, usually with multiple actions and possible flows. It means more information, more content and more components, all in the same space.

For this case, I personally find it rare to use more than 24px for texts. It’s more common to use small sizes for components — usually from 12 to 18 pixels depending on the text’s importance.

If you’re designing a digital product, it is useful to talk to the developers first. It’s easier to maintain a typography scale based on EM/REM more than actual pixels. The creation of a rule to convert pixels into EM/REM multiples is always recommended.

Related resource: “Defining A Modular Type Scale For Web UI” by Kelly Dern.

Color Scheme

Second, we need to define the color scheme. I think it’s best if you to divide this task into two parts.

  1. First, you need to define the main colors of the system. I recommend keeping it simple and using a maximum of four or five colors (including validation colors) because the more colors you include here, the more stuff you’ll have to maintain in the future.
  2. Next, generate more color values using the Sass functions such as “Lighten” and “Darken” — this works really well for user interfaces. The main benefit of this technique is to use the same hue for the different variants and obtain a mathematical rule that can be automated in the code. You can’t do it directly with Figma, but any Sass color generator will work just fine — for example, SassMe by Jim Nielsen. I like to increase the functions by 1% to have more color selection.
Once you have your main colors (in our case, blue and grey), you can generate gradients using lighten and darken functions. (Large preview)

Tip: In order to be able to apply future changes without having to rename the variables, avoid using the color as part of the color name. E.g., instead of $blue, use $primary.

Recommended reading: What Do You Name Color Variables?” by Chris Coyier

Figma Styles

Once we have the typography scale and the color scheme set, we can use them to define the Library styles.

This is the first actual step into the library creation. This feature lets you use a single set of properties in multiple elements.

Styles are the way to control all the basic details in your library. (Large preview) Concrete Example

Let’s say you define your brand color as a style, it’s a soft-blue and you originally apply it to 500 different elements. If it is later decided that you need to change it to a darker blue with more contrast, thanks to the styles you can update all the 500 styled elements at once, so you won’t have to do it manually, element by element.

We can define styles for the following:

If you have variations of the same style, to make it easier to find them later, you can name the single styles and arrange them inside the panel as groups. To do so, just use this formula:

Group Name/Style Name

I’ve included a suggestion of how to name texts and colors styles below.

Text Styles

Properties that you can define within a text style:

  • Font size
  • Font weight
  • Line-height
  • Letter spacing

Tip: Figma drastically reduces the number of styles that we need to define in the library, as alignments and colors are independent of the style. You can combine a text style with a color style in the same text element.

You can apply all the typography scale we’ve seen before as text styles. (Large preview)

Text Styles Naming

I recommend using a naming rule such as “Size/Weight”
(eg: 16/Regular, 16/SemiBold, 16/Bold).

Figma only allows one level of indentation, if you need to include the font you can always add a prefix before the size:
FontFamily Size/Weight or FF Size/Weight
*(eg: SourceSansPro 16/Regular or SSP 16/Regular).*

Color Styles

The color style uses its hex value (#FFF) and the opacity as properties.

Tip: Figma allows you to set a color style for the fill and a different one for the border within the same element, making them independent of each other.

You can apply color styles to fills, borders, backgrounds, and texts. (Large preview)

Color Styles Naming

For a better organization I recommend using this rule “Color/Variant”. We named our color styles using “Primary/Default” for the starter color, “Primary/L1”, “Primary/L2” for lighten variants, and “Primary/D1”, “Primary/D2” for darken variants.


When designing an interface you might also need to create elements that use some effects such as drop shadows (the drag&drop could be an example of a pattern that uses drop shadows effects). To have control over these graphic details, you can include effect styles such as shadows or layer blurs to the library, and also divide them by groups if necessary.

Define shadows and blurs to manage special interaction effects such as drag-n-drop. (Large preview) Grids

To provide something very useful for your team, include the grid styles. You can define the 8px grid, 12 columns grid, flexible grids so your team won’t need to recreate them.

There’s no need to memorize the grid sizes anymore. (Large preview)

Tip: Taking advantage of this feature, you can provide all the different breakpoints as ‘grid styles’.

Master Component

Figma lets you generate multiple instances of the same component and update them through a single master component. It’s easier than you might think, you can start with some small elements and then use them to evolve your library.

One master component to rule them all! (Large preview)

To explain this workflow better, I will use one of the basic components all the libraries have: the buttons.


Every system has different types of buttons to represent the importance of the actions. You can start having both primary and secondary buttons with only texts and one size, but the reality is that you’ll probably end up having to maintain something like this:

  • 2 color types (Primary | Secondary)
  • 2 sizes of buttons (Regular | Small)
  • 4 content types (Text Only | Icon Only | Text + Icon right | Icon Left + Text)
  • 5 states (Default | Hover | Active | Disabled | Focus)

This would give us up to 88 different components to maintain only with the set of buttons mentioned above!

Thanks to how Figma is built, you can easily manage a lot of button instances all at once. (Large preview) Let’s Start Step By Step

The first step is to include all the variations together in the same place. For the buttons we’re going to use:

  • A single shape for the background of the button so that we can then place the color styles for the fill and the border;
  • The single text that will have both text and color styles;
  • Three icon components (positioned to the right, center and left) filled in with the color style (you will be able to easily swap the icons).
A shape, a text, and an icon walk into a Figma bar... (Large preview)

The second step is to create the master component (use the shortcut Cmd + Alt + K on Mac, or Ctrl + Alt + K on Windows) with all of the variations as instances. I suggest using a different and neutral style for the elements inside the master component and use the real styles on the sub-components, this trick will help the team use only sub-components.

You can see the visual difference between a master component and a sub-component in the next step:

The more elements, the more instances you can control. (Large preview)

In the third step you need to duplicate the master component to generate an instance, now you can use that instance to create a sub-component, and from now on every change you make to the master component will also change the sub-component you’ve created.

You can now start applying the different styles we’ve seen before to the elements inside the sub-component and, of course, you can hide the elements you don’t need in that sub-component.

Thanks to the color styles you can generate different components using the same shape. In this example, primary and secondary styles are generated from the same master component. (Large preview) Text Alignment

As I’ve shown you in the styles, the alignments are independent of the style. So if you want to change the text alignment, just select it by hitting Cmd/Ctrl and changing it. Left, center or right: it will all work and you can define different sub-components as I did with the buttons.

Tip: To help you work faster without having to find the exact element layer, if you delete an element inside the instance, it will hide the element instead of actually deleting it.

Component Organization

If you’re coming from Sketch, you could be having trouble with the organization of the components in Figma as there are a few key differences between these two tools. This is a brief guide to help you organize the components well so that the instance menu doesn’t negatively affect your team’s effectiveness.

As you can see here, our library had so many sub-menus that as a result the navigation was going off the screen on MacBooks, that was a big problem for our library. We were able to find a workaround for this issue. (Large preview) This was the result after improving the library order following the rules for pages and frames, now it’s way more usable and organized for our teams. (Large preview)

We’ve all been there, the solution is easier than you think!

Here’s what I have learned about how to organize the components.

Figma Naming

While in Sketch all the organization depends only on the single component name, in Figma it depends on the Page name, the Frame name, and the single Component name — exactly in that order.

In order to provide a well-organized library, you need to think of it as a visual organization. As long as you respect the order, you can customize the naming to fit your needs.

Here’s how I’ve divided it:

  • File Name = Library Name (e.g. Lexicon);
  • Page Name = Component Group (e.g. Cards);
  • Frame Name = Component Type (e.g. Image Card, User Card, Folder Card, etc);
  • Component Name = Component State (e.g. Default, Hover, Active, Selected, etc).
This structure is the equivalent to the Sketch naming of ‘Cards/Image Card/Card Hover’. (Large preview) Adding Indentation Levels

When creating the Lexicon library, I found that I actually needed more than three levels of indentation for some of the components, such as the buttons that we saw before.

For these cases, you can extend the naming using the same method as Sketch for nested symbols (using the slashes in the component name, e.g. “Component/Sub-Component”), under the condition that you do it only after the third level of indentation, respecting the structural order of the first three levels as explained in the previous point.

This is how I organized our buttons:

  • Page name = Component Group (e.g. Buttons);
  • Frame name = Component Size (e.g. Regular or Small);
  • Component name = Style/Type/State (e.g. Primary/Text/Hover).
This structure is the equivalent to the Sketch naming of '*Buttons/Buttons Regular/Primary/Text/Button Hover*'. (Large preview)

Tip: You can include the component name (or a prefix of the name) in the last level, this will help your team to better identify the layers when they import the components from the library.

Icons Organization

Organizing the icons in Figma can be challenging when including a large number of icons.

As opposed to Sketch which uses a scroll functionality, Figma uses the sub-menus to divide the components. The problem is that if you have a large number of icons grouped in sub-menus, at some point they might go off screen (my experience with Figma on a MacBook Pro).

An example of how the components are organized inside a single scrollable sub-menu. (Large preview) As you can see, using a Macbook Pro the result was the menus going outside the screen. (Large preview)

Here are two possible solutions:

  • Solution 1
    Create a page named “Icons” and then a frame for each letter of the alphabet, then place each icon in the frame based on the icon’s name. For example, if you have an icon named “Plus”, then it will go in the “P” frame.
  • Solution 2
    Create a page named “Icons” and then divide by frames based on the icon categories. For example, if you have icons that represent a boat, a car, and a motorcycle, you can place them inside a frame named “vehicles”.
I, personally, applied solution 1. As you can see in this example, we had a huge number of icons so this was the better fit. (Large preview) Conclusion

Now that you know what’s exactly behind a team’s library construction in Figma, you can start building one yourself! Figma has a free subscription plan that will help you to get started and experiment with this methodology in a single file (however, if you want to share a team library, you will need to subscribe to the “Professional” option).

Try it, create and organize some advanced components, and then present the library to your team members so you could amaze them — or possibly convince them to add Figma to their toolset.

Finally, let me mention that here in Liferay, we love open-source projects and so we’re sharing a copy of our Lexicon library along with some other resources. You can use the Lexicon library components and the other resources for free, and your feedback is always welcome (including as Figma comments, if you prefer).

Lexicon is the design language of Liferay, used to provide a Design System and a Figma Library for the different product teams. (Large preview)

If you have questions or need help with your first component library in Figma, ask me in the comments below, or drop me a line on Twitter.

Further Resources (mb, yk, il)
Categories: Web Design

Monthly Web Development Update 6/2019: Rethinking Privacy And User Engagement

Fri, 06/14/2019 - 05:30
Monthly Web Development Update 6/2019: Rethinking Privacy And User Engagement Monthly Web Development Update 6/2019: Rethinking Privacy And User Engagement Anselm Hannemann 2019-06-14T14:30:00+02:00 2019-07-01T12:46:47+00:00

Last week I read about the web turning into a dark forest. This made me think, and I’m convinced that there’s hope in the dark forest. Let’s stay positive about how we can contribute to making the web a better place and stick to the principle that each one of us is able to make an impact with small actions. Whether it’s you adding Webmentions, removing tracking scripts from a website, recycling plastic, picking up trash from the street to throw it into a bin, or cycling instead of driving to work for a week, we all can make things better for ourselves and the people around us. We just have to do it.

  • Safari went ahead by introducing their new Intelligent Tracking Protection and making it the new default. Now Firefox followed, enabling their Enhanced Tracking Protection by default, too.
  • Chrome 75 brings support for the Web Share API which is already implemented in Safari. Latency on canvas contexts has also been improved.
  • The Safari Technology Preview Release 84 introduced Safari 13 features: warnings for weak passwords, dark mode support for iOS, support for aborting Fetch requests, FIDO2-compliant USB security keys with the Web Authentication standard, support for “Sign In with Apple” (for Safari and WKWebView). The Visual Viewport API, ApplePay in WKWebView, screen sharing via WebRTC, and an API for loading ES6 modules are also supported from now on.
  • There’s an important update to Apple’s AppStore review guidelines that requires developers to offer “Sign In with Apple” in their apps in case they support third-party sign-in once the service is available to the public later this year.
  • Firefox 67 is out now with the Dark Mode CSS media query, WebRender, and side-by-side profiles that allow you to run multiple instances parallelly. Furthermore, enhanced privacy controls are built in against crypto miners and fingerprinting, as well as support for AV1 on Windows, Linux, and macOS for videos, String.prototype.matchAll(), and dynamic imports.
  • The web relies on so many open-source projects, and, yet, here’s what it looks like to live off an open-source budget. Most authors are below the poverty line, forced to live in cheaper countries or not able to make a living at all from their public service of providing reliable, open software for others who then use it commercially.
  • We all know that annoying client who ignores your knowledge and gets creative on their own. As a developer, Holger Bartel experienced it dozens of times; now he found himself in the same position, having ordered a fine drink and then messed it up.
  • With so many dark patterns built into the software and websites we use daily, Fabricio Teixeira and Caio Braga call for a tech diet for users.
“Dark patterns try to manipulate users to engage further, deeper, or longer on a site or app. The world needs a tech diet, and designers can help make it a reality. (Image credit) CSS
  • The CSS feature for truncating multi-line text has been implemented in Firefox. -webkit-line-clamp: 3;, for example, will truncate text at the end of line three.
Security Privacy
  • Anil Dash tries to find an answer to the question if we can trust a company in 2019.
  • Kevin Litman-Navarro analyzed over 150 privacy policies and shares his findings in a visual story. Not only does it take about 15 minutes on average to read a privacy policy, but most of them require a college degree or even professional career to understand them.
  • Our view on privacy hasn’t changed much since the 18th century, but the circumstances are different today: Companies have a wild appetite to store more and more data about more people in a central place — data that was once exclusively accessible by state authorities. We should redefine what privacy, personal data, and consent are, as Maciej Cegłowski argues in “The new wilderness.”
  • The people at WebKit are very active when it comes to developing clever solutions to protect users without compromising too much on usability and keeping the interests of publishers and vendors in mind at the same time. Now they introduced “privacy preserving ad click attribution for the web,” a technique that limits the data which is sent to third parties while still providing useful attribution metrics to advertisers.
Most privacy policies on the web are harder to read than Stephen Hawking’s “A Brief History Of Time,” as Kevin Litman-Navarro found out by examining 150 privacy policies. (Image credit) Accessibility
  • Brad Frost describes a great way to reduce motion on websites (of animated GIFs, for example), using the picture element and its media query feature.
  • The IP Geolocation API is an open-source real-time IP to Geolocation JSON API with detailed countries data integration that is based on the Maxmind Geolite2 database.
  • Pascal Landau wrote a step-by-step tutorial on how to build a Docker development setup for PHP projects, and yes, it contains everything you might need to apply it to your own projects.
Work & Life
  • Roman Imankulov from Doist shares insights into decision-making in a flat organization.
  • As a society, we’re overworked, have too many belongings, yet crave for more, and companies only exist to grow indefinitely. This is how we kick-started climate change in the past century and this is how we got more people than ever into burn-outs, depressions, and various other health issues, including work-related suicides. Philipp Frey has a bold theory that breaks with our current system: A research by Nässén and Larsson suggests that a 1% decrease in working hours could lead to a 0.8% decrease in GHG emissions. Taking it further, the paper suggests that working 12 hours a week would allow us to easily achieve climate goals, if we’re also changing the economy to not entirely focus on growth anymore. An interesting study as it explores new ways of working, living, and consuming.
  • Leo Babauta shares a method that helps you acknowledge when you’re tired. It’s hard to accept, but we are humans and not machines, so there are times when we feel tired and our batteries are low. The best way to recover is realizing that this is happening and focusing on it to regain some energy.
  • Many of us are trying to achieve some minutes or hours of “deep work” a day. Fadeke Adegbuyi’s “The Complete Guide to Deep Work” shares valuable tips to master it.
Going Beyond…
  • People who live a “zero waste” life are often seen as extreme, but this is only one point of view. Here’s the other side where one of the “extreme” persons reminds us that it used to be normal to go to a farmer’s market to buy things that aren’t packed in plastic, to ride a bike, and drink water from a public fountain. Instead, our consumerism has become quite extreme and needs to change if we want to survive and stay healthy.
  • Sweden wants to become climate neutral by 2045, and now they presented an interesting visualization of the plan. It’s designed to help policymakers identify and fill in gaps to ensure that the goal will be achieved. The visualization is open to the public, so anyone can hold the government accountable.
  • Everybody loves them, many have them: AirPods. However, they are an environmental disaster, as this article shows.
  • The North Face tricking Wikipedia is advertising’s dark side.
  • The New York Times published a guide which helps us understand our impact on climate change based on the food we eat. This is not about going vegan but how changing eating habits can make a difference, both to the environment and our own health.
Categories: Web Design

Inspired Design Decisions: Avaunt Magazine

Thu, 06/13/2019 - 03:30
Inspired Design Decisions: Avaunt Magazine Inspired Design Decisions: Avaunt Magazine Andrew Clarke 2019-06-13T12:30:16+02:00 2019-07-01T12:46:47+00:00

I hate to admit it, but five or six years ago my interest in web design started to wane. Of course, owning a business meant I had to keep working, but staying motivated and offering my best thinking to clients became a daily struggle.

Looking at the web didn’t improve my motivation. Web design had stagnated, predictability had replaced creativity, and ideas seemed less important than data.

The reasons why I’d enjoyed working on the web no longer seemed relevant. Design had lost its joyfulness. Complex sets of build tools and processors had even supplanted the simple pleasure of writing HTML and CSS.

When I began working with the legendary newspaper and magazine designer Mark Porter, I became fascinated by art direction and editorial design. As someone who hadn’t studied either at art school, everything about this area of design was exciting and new. I read all the books about influential art directors I could find and started collecting magazines from the places I visited around the world.

The more inspired I became by mag- azine design, the faster my enthusiasm for web design bounced back. I wondered why many web designers think that print design is old-fashioned and irrelevant to their work. I thought about why so little of what makes print design special is being transferred to the web.

My goal became to hunt for inspiring examples of editorial design, study what makes them unique, and find ways to adapt what I’d learned to create more compelling, engaging, and imaginative designs for the web.

My bookcases are now chock full of magazine design inspiration, but my collection is still growing. I have limited space, so I’m picky about what I pick up. I buy a varied selection, and rarely collect more than one issue of the same title.

I look for exciting page layouts, inspiring typography, and innovative ways to combine text with images. When a magazine has plenty of interesting design elements, I buy it. However, if a magazine includes only a few pieces of inspiration, I admit I’m not above photographing them before putting it back on the shelf.

I buy new magazines as regularly as I can, and a week before Christmas, a few friends and I met in London. No trip to the “Smoke” is complete without a stop at Magma, and I bought several new magazines. After I explained my inspiration addition, one friend suggested I write about why I find magazine design so inspiring and how magazines influence my work.

Avaunt magazine. (Large preview)

That conversation sparked the idea for a series on making inspired design decisions. Every month, I’ll choose a publication, discuss what makes its design distinctive, and how we might learn lessons which will help us to do better work for the web.

As an enthusiastic user of HTML and CSS, I’ll also explain how to implement new ideas using the latest technologies; CSS Grid, Flexbox, and Shapes.

I’m happy to tell you that I’m inspired and motivated again to design for the web and I hope this series can inspire you too.

Andy Clarke
April 2019

Avaunt Magazine: Documenting The Extraordinary What struck me most about Avaunt was the way its art director has colour, layout, and type in diverse ways while maintaining a consistent feel throughout the magazine. (Large preview)

One look at me is going to tell you I’m not much of an adventurer. I don’t consider myself particularly cultured and my wife jokes regularly about what she says is my lack of style.

So what drew me to Avaunt magazine and its coverage of “adventure,” “culture,” and “style” when there are so many competing and varied magazines?

It often takes only a few page turns for me to decide if a magazine offers the inspiration I look for. Something needs to stand out in those first few seconds for me to look closer, be it an exciting page layout, an inspiring typographic treatment, or an innovative combination of images with text.

Avaunt has all of those, but what struck me most was the way its art director has used colour, layout, and type in diverse ways while maintaining a consistent feel throughout the magazine. There are distinctive design threads which run through Avaunt’s pages. The bold uses of a stencil serif and geometric sans-serif typeface are particularly striking, as is the repetition of black, white, a red which Avaunt’s designers use in a variety of ways. Many of Avaunt’s creative choices are as adventurous as the stories it tells.

© Avaunt magazine. (Large preview)

Plenty of magazines devote their first few spreads to glossy advertising, and Avaunt does the same. Flipping past those ads finds Avaunt’s contents page and its fascinating four-column modular grid.

This layout keeps content ordered within spacial zones but maintains energy by making each zone a different size. This layout could be adapted to many kinds of online content and should be easy to implement using CSS Grid. I’m itching to try that out.

For sans-serif headlines, standfirsts, and other type elements which pack a punch, Avaunt uses MFred, designed initially for Elephant magazine by Matt Willey in 2011. Matt went on to art direct the launch of Avaunt and commissioned a stencil serif typeface for the magazine’s bold headlines and distinctive numerals.

Avaunt Stencil was designed in 2014 by London based studio A2-TYPE who have since made it available to license. There are many stencil fonts available, but it can be tricky to find one which combines boldness and elegance — looking for a stencil serif hosted on Google Fonts? Stardos would be a good choice for display size type. Need something more unique, try Caslon Stencil from URW.

Avaunt’s use of a modular grid doesn’t end with the contents page and is the basis for a spread on Moscow’s Polytechnic Museum of Cold War curiosities which first drew me to the magazine. This spread uses a three-column modular grid and spacial zones of various sizes.

What fascinates me about this Cold War spread is how modules in the verso page combine to form a single column for text content. Even with this column, the proportions of the module grid still inform the position and size of the elements inside.

© Avaunt magazine. (Large preview)

While the design of many of Avaunt’s pages is devoted to a fabulous reading experience, many others push the grid and pull their foundation typography styles in different directions. White text on dark backgrounds, brightly coloured spreads where objects are cut away to blend with the background. Giant initial caps which fill the width of a column, and large stencilled drop caps which dominate the page.

Avaunt’s playful designs add interest, and the arrangement of pages creates a rhythm which I very rarely see online. These variations in design are held together by the consistent use of Antwerp — also designed by A2-TYPE — as a typeface for running text, and a black, white, and red colour theme which runs throughout the magazine.

© Avaunt magazine. (Large preview)

Studying the design of Avaunt magazine can teach and inspire. How a modular grid can help structure content in creative ways without it feeling static. (I’ll teach you more about modular grids later.)

How a well-defined set of styles can become the foundation for distinctive and diverse designs, and finally how creating a rhythm throughout a series of pages can help readers stay engaged.

Next time you’re passing your nearest magazine store, pop in a pick up a copy of Avaunt Magazine. It’s about adventure, but I bet it can help inspire your designs to be more adventurous too.

Say Hello To Skinny Columns

For what feels like an eternity, there’s been very little innovation in grid design for the web. I had hoped the challenges of responsive design would result in creative approaches to layout, but sadly the opposite seems to be true.

Top: Squeezing an image into one column reduces its visual weight and upsets the balance of my composition. Middle: Making the image fill two standard columns also upsets that delicate balance. Bottom: Splitting the final column, then add- ing half its width to another, creates the perfect space for my image, and a more pleasing overall result. (Large preview)

Instead of original grid designs, one, two, three, or four block arrangements of content became the norm. Framework grids, like those included with Bootstrap, remain the starting point for many designers, whether they use those frameworks or not.

It’s true that there’s more to why so much of the web looks the same as web designers using the same grid. After all, there have been similar conventions for magazines and newspapers for decades, but somehow magazines haven’t lost their personality in the way many websites have.

I’m always searching for layout inspiration and magazines are a rich source. Reading Avaunt reminded me of a technique I came across years ago but hadn’t tried. This technique adds one extra narrow column to an otherwise conventional column grid. In print design, this narrow column is often referred to as a “bastard column or measure” and describes a block of content which doesn’t conform to the rest of a grid. (This being a family friendly publication, I’ll call it a “skinny column.”)

In these first examples, squeezing an image into one column reduces its visual weight and upsets the balance of my composition. Making the image fill two standard columns also upsets that delicate balance.

Splitting the final column, then adding half its width to another, creates the perfect space for my image, and a more pleasing overall result.

(Large preview)

I might use a skinny column to inform the width of design elements. This Mini Cooper logo matches the width of my skinny column, and its size feels balanced with the rest of my composition.

(Large preview)

Sometimes, content won’t fit into a single column comfortably, but by combining the widths of standard and skinny columns, I create more space and a better measure for running text. I can place a skinny column anywhere within a layout to wherever I need my content.

(Large preview)

An empty skinny column adds whitespace which allows the eye to roam around a design. The asymmetry created by placing a skinny column between two standard columns also makes a structured layout feel more dynamic and energetic.

(Large preview)

Another empty skinny column carves a wide gutter into this design and confines my running text to a single column, so that its height reflects the image’s vertical format. I can also use a skinny column to turn typographic elements into exciting design elements.

Developing With Skinny Columns

Designs like these are surprisingly simple to implement using today’s CSS. I need just four structural elements; a logo, header, figure, plus an article to contain my running text:

<body> <img src="logo.svg" alt="Mini Cooper"> <header>…</header> <figure>…</figure> <article>…</article> </body>

I start with a design for medium size screens by applying CSS Grid to the body element within my first media query. At this size, I don’t need a skinny column so instead am developing a symmetrical three-column grid which expands evenly to fill the viewport width:

@media screen and (min-width : 48em) { body { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-column-gap: 2vw; } }

I use line numbers to place items into my grid columns and rows. I place my logo into the skinny first column and the first row using a substring matching attribute selector. This targets an image with “logo” anywhere in its source value:

[src*="logo"] { grid-column: 1; grid-row: 1; }

Next, I place the header element — containing my headline and standfirst paragraph — into the second row. Using line numbers from 1 to -1 spreads this header across all columns:

header { grid-column: 1 / -1; grid-row: 2; }

With display:grid; applied, all direct descendants of a grid-container become grid-items, which I can place using areas, line numbers, or names.

This design includes a figure element with a large Mini image, plus caption text about the original Cooper model design. This figure is crucial because it describes a relationship between the img and figcaption. However, while this figure makes my markup more meaningful, I lose the ability to place the img and figcaption using CSS Grid, because by neither are direct descendants of the body where I defined my grid.

Luckily, there’s a CSS property which — when used thoughtfully — can overcome this problem. I don’t need to style the figure, I only need to style its img and figcaption. By applying display:contents; to my figure, I effectively remove it from the DOM for styling purposes, so its descendants take its place:

figure { display: contents; }

It’s worth noting that although display effectively removes my figure from the DOM for styling purposes, any properties which inherit — including font sizes and styles — are still inherited:

figure img { grid-column: 2/-1; grid-row: 4; } figcaption { grid-column: 1; grid-row: 4; align-self: end; }

I place my article and style its text over three columns using Multi-column Layout, one of my favourite CSS properties:

article { grid-column: 1 / -1; grid-row: 3; column-count: 3; column-gap: 2vw; }

It’s time to implement a design which includes a skinny column for larger screens. I use a media query to isolate these new styles, then I create a five-column grid which starts with a 1fr wide skinny column:

@media screen and (min-width : 64em) { body { grid-template-columns: 1fr repeat(4, 2fr); } } (Large preview)

Then I add values to reposition the header, img and figcaption, and article, remembering to reset the column-count to match its new width:

header { grid-column: 3/-1; grid-row: 1; } figure img { grid-column: 4 / -1; grid-row: 2; } figcaption { grid-column: 2; grid-row: 2; align-self: start; } article { grid-column: 3; grid-row: 2; column-count: 1; }

Radically changing how a design looks using CSS alone, without making changes to the structure of HTML makes me smile, even after almost two decades. I also smile when I change the composition to create a dramatically different layout without changing the grid. For this alternative design, I’m aiming for a more structured look.

To improve the readability of my running text, I divide into three columns. Then, to separate this block of content from other text elements, I place my skinny column between the first two standard columns. There’s no need to change the structure of my HTML. All I need are minor changes to grid values in my stylesheet. This time, my 1fr wide skinny column value comes between two standard column widths:

@media screen and (min-width : 64em) { body { grid-template-columns: 2fr 1fr 2fr 2fr 2fr; } }

I place my header in the second row and the article in a row directly underneath:

header { grid-column: 3 / -1; grid-row: 2; } article { grid-column: 3 / -1; grid-row: 3; column-count: 3; column-gap: 2vw; }

Because neither the img and figcaption are direct descendants of the body element where I defined my grid, to place them I need the display:contents; property again:

figure { display: contents; } figure img { grid-column: 3/5; grid-row: 1; } figcaption { grid-column: 5/-1; grid-row: 1; align-self: start; }

Depending on how you use them, introducing skinny columns into your designs can make content more readable or transform a static layout into one which feels dynamic and energetic.

Skinny columns are just one example of learning a technique from print and using it to improve a design for the web. I was itching to try out skinny columns and I haven’t been disappointed.

(Large preview)

Adding a skinny column to your designs can often be an inspired decision. It gives you extra flexibility and can transform an otherwise static layout into one which is filled with energy.

Designing Modular Grids

Avaunt magazine contains plenty of inspiring layouts, but I want to focus on two pages in particular. This spread contains ‘Cold War Design’ objects within a design which could be applied to a wide variety of content types.

‘Cold War Design’ from Avaunt magazine issue 7, January 2019. (Large preview)

On first glance, modular grids can look complicated, however, they’re easy to work with. It surprises me that so few web designers use them. I want to change that.

When you use modular grids thoughtfully, they can fill your designs with energy. They’re excellent for bringing order to large amounts of varied content, but can also create visually appealing layouts when there’s very little content.

For this design — inspired by Avaunt — I base my modular grid on six symmetrical columns and four evenly spaced rows. Grid modules define the placement and size of my content.

Modular grid design inspired by Avaunt. (Large preview)

I bind several modules together to create spacial zones for large images and running text in a single-column on the left. Boundary lines help emphasise the visual structure of the page.

This type of layout might seem complicated at first, but in reality, it’s beautifully simple to implement. Instead of basing my markup on the visual layout, I start by using the most appropriate elements to describe my content. In the past, I would’ve used table elements to implement modular grids. Fast forward a few years, and divisions replaced those table cells. Incredibly, now I need just two structural HTML elements to accomplish this design; one article followed by an ordered list:

<body> <article>…</article> <ol>…</ol> </body>

That article contains a headline, paragraphs, and a table for tabular information:

<article> <p class="standfirst">…</p> <h1>…</h1> <p>…</p> <table>…</table> </article>

The modular grid of Mini blueprints is the most complicated visual aspect of my design, but the markup which describes it is simple. The blueprints are in date order, so an ordered list seems the most appropriate HTML element:

<ol class="items"> <li> <h2>1969</h2> <img src="front.svg" alt=""> </li> <li> <h2>1969</h2> <img src="back.svg" alt=""> </li> </ol>

My HTML weighs in at only 2Kb and is under sixty lines. It’s a good idea to validate that markup as a little time spent validating early will save plenty more time on debugging CSS later. I also open the unstyled page in a browser as I always need to ensure my content’s accessible without a stylesheet.

I begin developing a symmetrical three-column layout for medium size screens by isolating grid styles using a media query:

@media screen and (min-width : 48em) { body { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-column-gap: 2vw; } }

The article and ordered list are the only direct descendants of body, but it’s what they contain which I want to place as grid-items. I use display:contents; to enable me to place their contents anywhere on my grid:

article, ol { display: contents; }

Every element in my article should span all three columns, so I place them using line numbers, starting with the first line (1), and ending with the final line (-1):

.standfirst, section, table { grid-column: 1 / -1; }

The items in my ordered list are evenly placed into the three-column grid grid. However, my design demands that some items span two columns and one spans two rows. nth-of-type selectors are perfect tools for targetting elements without resorting to adding classes into my markup. I use them, the span keyword, and the quantity of columns or rows I want the items to span:

li:nth-of-type(4), li:nth-of-type(5), li:nth-of-type(6), li:nth-of-type(14) { grid-column: span 2; } li:nth-of-type(6) { grid-row: span 2; } When elements don’t fit into the available space in a grid, the CSS Grid placement algorithm leaves a module empty. (Large preview)

Previewing my design in a browser, I can see it’s not appearing precisely as planned because some grid modules are empty. By default, the normal flow of any document arranges elements from left to right and top to bottom, just like western languages. When elements don’t fit the space available in a grid, the CSS Grid placement algorithm leaves spaces empty and places elements on the following line.

A browser fills any empty module with the next element which can fit into that space without altering the source order. This may have implications for accessibility. (Large preview)

I can override the algorithm’s default by applying the grid-auto-flow property and a value of dense to my grid-container, in this case the body:

body { grid-auto-flow: dense; }

Row is the default grid-auto-flow value, but you can also choose column, column dense, and row dense. Use grid-auto-flow wisely because a browser fills any empty module with the next element in the document flow which can fit into that space. This behaviour changes the visual order without altering the source which may have implications for accessibility.

My medium size design now looks just like I’d planned, so now it’s time to adapt it for larger screens. I need to make only minor changes to the grid styles to first turn my article into a sidebar — which spans the full height of my layout — then place specific list items into modules on a larger six-column grid:

@media screen and (min-width : 64em) { body { grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; } article { grid-column: 1; grid-row: 1 / -1; } li:nth-of-type(4) { grid-column: 5 / span 2; } li:nth-of-type(5) { grid-column: 2 / span 2; } li:nth-of-type(6) { grid-column: 4 / span 2; grid-row: 2 / span 2; } li:nth-of-type(14) { grid-column: 5 / 7; } }

Keeping track of grid placement lines can sometimes be difficult, but fortunately, CSS Grid offers more than one way to accomplish a modular grid design. Using grid-template-areas is an alternative approach and one I feel doesn’t get enough attention.

Using grid-template-areas, I first define each module by giving it a name, then place elements into either one module or several adjacent modules known as spacial zones. This process may sound complicated, but it’s actually one of the easiest and most obvious ways to use CSS Grid.

I give each element a grid-area value to place it in my grid, starting with the logo and article:

[src*="logo"] { grid-area: logo; } article { grid-area: article; }

Next, I assign a grid-area to each of my list items. I chose a simple i+n value, but could choose any value including words or even letters like a, b, c, or d.

li:nth-of-type(1) { grid-area: i1; } … li:nth-of-type(14) { grid-area: i14; }

My grid has six explicit columns, and four implicit rows, the height of which are being defined by the height of the content inside them. I draw my grid in CSS using the grid-template-areas property, where each period (.) represents a grid module:

body { grid-template-columns: repeat(6, 1fr); grid-template-areas: ". . . . ". . . . ".. .. ".. .. . ." . ." . ." . ."; }

Then, I place elements into that grid using the grid-area values I defined earlier. If I repeat values across multiple adjacent modules — across either columns or rows — that element expands to create a spacial zone. Leaving a period (.) creates an empty module:

body { grid-template-columns: repeat(6, 1fr); grid-template-areas: "article logo i1 i2 i3 i3" "article i4 i4 i5 i5 "article i7 i8 i5 i5 "article i10 i11 i12 i14 i14"; }

In every example so far, I isolated layout styles for different screen sizes using media query breakpoints. This technique has become the standard way of dealing with the complexities of responsive web design. However, there’s a technique for developing responsive modular grids without using media queries. This technique takes advantage of a browser’s ability to reflow content.

I need make only minor changes to my grid styles to adapt this layout for larger screens. The sidebar article on the left and each list item are placed into my grid. (Large preview)

Before going further, it’s worth remembering that my design requires just two structural HTML elements; one ordered list for the content and an article which I transform into a sidebar when there’s enough width available for both elements to stand side-by-side. When there’s insufficient width, those elements stack vertically in the order of the content:

<body> <article>…</article> <ol>…</ol> </body>

The ordered list forms the most important part of my design and should always occupy a minimum 60% of a viewport’s width. To ensure this happens, I use a min-width declaration:

ol { min-width: 60%; }

While I normally recommend using CSS Grid for overall page layout and Flexbox for flexible components, to implement this design I turn that advice on its head.

I make the body element into a flex-container, then ensure my article grows to fill all the horizontal space by using the flex-grow property with a value of 1:

body { display: flex; } article { flex-grow: 1; }

To make sure my ordered list also occupies all available space whenever the two elements stand side-by-side, I give it a ridiculously high flex-grow value of 999:

article { flex-grow: 999; }

Using flex-basis provides an ideal starting width for the article. By setting the flex container’s wrapping to wrap, I ensure the two elements stack when the list’s minimum width is reached, and there’s insufficient space for them to stand side-by-side:

body { flex-wrap: wrap; } article { flex-basis: 20rem; }

I want to create a flexible modular grid which allows for any number of modules. Rather than specifying the number of columns or rows, using repeat allows a browser to create as many modules as it needs. autofill fills all available space, wrapping the content where necessary. minmax gives each module a minimum and maximum width, in this case 10rem and 1fr:

ol { grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); grid-column-gap: 2vw; }

To avoid modules staying empty, I use grid-auto-flow again with a value of dense. The browser’s algorithm will reflows my content to fill any empty modules:

ol { grid-auto-flow: dense; }

Just like before, some list items span two columns, and one spans two rows. Again, I use nth-of-type selectors to target specific list items, then grid-column or grid-row with the span keyword followed by the number of columns or rows I want to span:

li:nth-of-type(4), li:nth-of-type(5), li:nth-of-type(14) { grid-column: span 2; } li:nth-of-type(6) { grid-column: span 2; grid-row: span 2; }

This simple CSS creates a responsive design which adapts to its environment without needing multiple media queries or separate sets of styles.

(Large preview)

By using of modern CSS including Grid and Flexbox, relying on browsers’ ability to reflow content, plus a few smart choices on minimum and maximum sizes, this approach comes closest to achieving the goals of a truly responsive web.

(ra, yk, il)
Categories: Web Design

UX Optimizations For Keyboard-Only And Assistive Technology Users

Tue, 06/11/2019 - 05:00
UX Optimizations For Keyboard-Only And Assistive Technology Users UX Optimizations For Keyboard-Only And Assistive Technology Users Aaron Pearlman 2019-06-11T14:00:59+02:00 2019-06-20T10:35:05+00:00

(This is a sponsored article.) One of the cool things about accessibility is that it forces you to see and think about your application beyond the typical sighted, mouse-based user experience. Users who navigate via keyboard only (KO) and/or assistive technology (AT) are heavily dependent not only on your application’s information architecture being thoughtful, but the affordances your application makes for keeping the experience as straightforward as possible for all types of users.

In this article, we’re going to go over a few of those affordances that can make your KO/AT user experiences better without really changing the experience for anyone else.

Additions To Your Application’s UX

These are features that you can add to your application to improve the UX for KO/AT users.

Skip Links

A skip link is a navigation feature that invisibly sits at the top of websites or applications. When it is present, it is evoked and becomes visible on your application’s first tab stop.

A skip link allows your user to “skip” to various sections of interest within the application without having to tab-cycle to it. The skip link can have multiple links to it if your application has multiple areas of interest you feel your users should have quick access to your application’s point of entry.

For KO/AT users, this is a helpful tool to both allow them to rapidly traverse your app and can help orient them to your application’s information architecture. For all other users, they likely will never even know this feature exists.

Here’s an example with how we handle skip links. After you click the link, hit Tab ⇥ and look in the upper-left corner. The skip link has two links: Main Content and Code Samples. You can use Tab ⇥ to move between them, hit Enter to navigate to the link.

Shortcuts/Hotkey Menus

This is a feature that I think everyone is familiar with: shortcuts and hotkeys. You’ve likely used them from time to time, they are very popular amongst power users of an application, and come in a variety of incarnations.

For KO/AT users, shortcuts/hotkeys are invaluable. They allow them to use the applications, as intended, without having to visually target anything or tab through the application to get to an element or content. While frequent actions and content are always appreciated when represented in a shortcut/hotkey menu, you may also want to consider some slightly less frequent actions that may be buried in your UI (for good reason) but are still something that a user would want to be able to access.

Making shortcuts for those functions will be extremely helpful to KO/AT users. You can make the command a bit more involved, such as using (3) keystrokes to evoke it, to imply it’s a less frequently used piece of functionality. If you have a shortcut/hotkey menu make sure to find a way to promote it in your applications so your users, especially your KO/AT users, can find it and use it effectively.

User Education

User education refers to a piece of functionality that directs the users on what to do, where to go, or what to expect. Tooltips, point outs, info bubbles, etc. are all examples of user education.

One thing you should ask yourself when designing, placing, and/or writing copy for your user education is:

“If I couldn't see this, would it still be valuable to understand ______?”

Many times it’s just reorienting the user education through that lens that can lead to a much better experience for everyone. For example, rather than saying “Next, click on the button below,” you may want to write, “To get started, click the START button.” The second method removes the visual orientation and instead focus on the common information both a sighted and KO/AT user would have at their disposal.

Note: I should mention it’s perfectly OK to use user education features, like point outs, to visually point out things on the application just make sure the companion text lets your KO/AT users understand the same things which are referred to visually.

See the Pen ftpo demo by Harris Schneiderman.

See the Pen ftpo demo by Harris Schneiderman. Augmentations To Your Application’s UX

There are changes or tweaks you can make to common components/features to improve the UX for KO/AT users.

Modal Focusing

Now we’re getting into the nitty-gritty. One of the great things about accessibility is how it opens the doorway to novel ways to solve problems you may have not considered before. You can make something fully WCAG 2.0 AA accessible and solve the problem with very different approaches. For modals, we at Deque came up with an interesting approach that would be totally invisible to most sighted-users but would be noticed by KO/AT users almost immediately.

For a modal to be accessible it needs to announce itself when evoked. Two common ways to do this are: focus the modal’s body after the modal is open or focus the modal’s header (if it has one) after the modal is open. You do this so the user’s AT can read out the modal’s intent like “Edit profile” or “Create new subscription”.

After you focus the body or header, hitting Tab ⇥ will send focus to the next focusable element in the modal — commonly a field or, if it’s in the header, sometimes it’s the close button (X). Continuing to tab will move you through all the focusable elements in the modal, typically finishing with terminal buttons like SAVE and/or CANCEL.

Now we get to the interesting part. After you focus the final element in the modal, hitting Tab ⇥ again will “cycle” you back to the first tab stop, which in the case of the modal will be either the body or the header because that’s where we started. However, in our modals we “skip” that initial tab stop and take you to the second stop (which in our modals is the close (X) in the upper corner. We do this because the modal doesn’t need to keep announcing itself over and over each cycle. It only needs to do it on the initial evocation not on any subsequent trips through, so we have a special programmatic stop which skips itself after the first time.

This is a small (but appreciated) usability improvement we came up with exclusively for KO/AT users which would be completely unknown to everyone else.

See the Pen modal demo by Harris Schneiderman.

See the Pen modal demo by Harris Schneiderman. Navigation Menus Traversing And Focus/Selected Management

Navigation menus are tricky. They can be structured in a multitude of ways, tiered, nested, and have countless mechanisms of evocation, disclosure, and traversing. This makes it important to consider how they are interacted with and represented for KO/AT users during the design phase. Good menus should be “entered” and “exited”, meaning you tab into a menu to use it and tab out of it to exit it (if you don’t use it).

This idea is best illustrated with a literal example, so let’s take a look at our 2-tier, vertical navigation from Cauldron.

  1. Go to https://pattern-library.dequelabs.com/;
  2. Hit Tab ⇥ three times. The first tab stop is the skip link (which we went over previously), the second is the logo which acts as “return to home” link, and the third tab enters the menu;
  3. Now that you are in the menu, use the arrow keys (→ and ↓) to move and open sections of the menu;
  4. Hitting Tab ⇥ at any point will exit you from the menu and send you to the content of the page.

Navigation menus can also work in conjunction with some of the previous topics such as shortcut/hotkey menus to make using the menu even more efficient.

Logical Focus Retention (I.E. Deleting Row, Returning Back To A Page)

Focus retention is very important. Most people are familiar, at least in concept, with focusing elements in their logical intended order on the page; however, it can get murky when an element or content changes/appears/disappears.

  • Where does focus go when then field you are on is deleted?
  • What about when you’re sent to another tab where the application has a new context?
  • What about after a modal is closed due to a terminal action like SAVE?

For a sighted user there are visual cues which can inform them of what happened.

Here’s an example: You have an Edit Recipe modal which lets your user add and remove any ingredients. There is one ingredient field with an “Add another ingredient” button below it. (Yes, it’s styled as a link but that’s a topic for another day.) Your focus is on the button. You click the button and a new field appears between the button and the first field. Where should the focus go? Most likely your user added another ingredient to engage with it so the focus should shift from the button into the newly added field.

See the Pen focus retention by Harris Schneiderman.

See the Pen focus retention by Harris Schneiderman.

The big takeaway from all this isn’t so much the specific examples but the mentality which supports them — consider the UX for your application through the lens of the KO/AT user as well sighted, mouse-only user. Some of the best and most clever ideas come from the most interesting and important challenges.

If you need help ensuring that your features are accessible, all of the examples above plus countless more can be tested using Deque’s free web accessibility testing application: axe pro. It’s free and you can sign up here.

(ra, il)
Categories: Web Design

Styling In Modern Web Apps

Mon, 06/10/2019 - 05:00
Styling In Modern Web Apps Styling In Modern Web Apps Ajay NS 2019-06-10T14:00:59+02:00 2019-06-20T10:35:05+00:00

If you search for how to style apps for the web, you’ll come across many different approaches and libraries, some even changing day by day. Block Element Modifier (BEM); preprocessors such as Less and SCSS; CSS-in-JS libraries, including JSS and styled-components; and, lately, design systems. You come across all of these in articles and blogs, tutorials and talks, and — of course — debates on Twitter.

How do we choose between them? Why do so many approaches exist in the first place? If you’re already comfortable with one method, why even consider moving to another?

In this article, I’m going to take a look at the tools I have used for production apps and sites I’ve worked on, comparing features from what I’ve actually encountered rather than summarizing the content from their readmes. This is my journey through BEM, SCSS, styled-components, and design systems in particular; but note that even if you use different libraries, the basic principles and approach remain the same for each of them.

CSS Back In The Day

When websites were just getting popular, CSS was primarily used to add funky designs to catch the user’s attention, such as neon billboards on a busy street:

Microsoft’s first site (left) and MTV’s site from the early 2000s. (Large preview)

Its use wasn’t for layout, sizing, or any of the basic needs we routinely use CSS for today, but as an optional add-on to make things fancy and eye-catching. As features were added to CSS, newer browsers supporting a whole new range of functionality and features appeared, and the standard for websites and user interfaces evolved — CSS became an essential part of web development.

It’s rare to find websites without a minimum of a couple hundred lines of custom styling or a CSS framework (at least, sites that don’t look generic or out of date):

Wired’s modern responsive site from InVision’s responsive web design examples post. (Large preview)

What came next is quite predictable. The complexity of user interfaces kept on increasing, along with the use of CSS; but without any guidelines suggested and with a lot of flexibility, styling became complicated and dirty. Developers had their own ways of doing things, with it all coming down to somehow getting things to look the way the design said it was supposed to be.

This, in turn, led to a number of common issues that many developers faced, like managing big teams on a project, or maintaining a project over a long period of time, while having no clear guides. One of the main reasons this happens even now, sadly, is that CSS is still often dismissed as unimportant and not worth paying much attention to.

CSS Is Not Easy To Manage

There’s nothing built into CSS for maintenance and management when it comes to large projects with teams, and so the common problems faced with CSS are:

  • Lack of code structure or standards greatly reduces readability;
  • Maintainability as project size increases;
  • Specificity issues due to code not being readable in the first place.

If you’ve worked with Bootstrap, you’ll have noticed you’re unable to override the default styles and you might have fixed this by adding !important or considering the specificity of selectors. Think of a big project’s style sheets, with their large number of classes and styles applied to each element. Working with Bootstrap would be fine because it has great documentation and it aims to be used as a solid framework for styling. This obviously won’t be the case for most internal style sheets, and you’ll be lost in a world of cascaded styles.

In projects, this would be like a couple thousand lines of CSS in a single file, with comments if you’re lucky. You could also see a couple of !important used to finally get certain styles to work overriding others.

!important does not fix bad CSS. (Large preview)

You may have faced specificity issues but not understood how specificity works. Let’s take a look.

(Large preview)

Which of the styles applied to the same element would be applied to the image on the right, assuming they both point to it?

What is the order of weight of selectors such as inline styles, IDs, classes, attributes, and elements? Okay, I made it easy there; they’re in order of weight:

Start at 0; add 1,000 for a style attribute; add 100 for each id; add 10 for each attribute, class or pseudo-class; add 1 for each element name or pseudo-element.

This is a simplified way of calculating and representing specificity which works in usual cases, but do note that the real representation would look like: (0,0,0,0). Here, the first number signifies the style attribute, second the ID, and so on. Each selector can actually have a value greater than 9 and it’s only when there is an equal number of selectors of highest weight that selectors of lower weight are considered.

So, for instance, taking the above example:

(Large preview) (Large preview)

Do you see why the second example was the correct answer? The id selector clearly has far more weight than element selectors. This is essentially the reason why your CSS rule sometimes doesn’t seem to apply. You can read about this in detail in Vitaly Friedman’s article, “CSS Specificity: Things You Should Know”.

The larger the codebase, the greater the number of classes. These might even apply to or override different styles based on specificity, so you can see how quickly it can become difficult to deal with. Over and above this we deal with code structure and maintainability: it’s the same as the code in any language. We have atomic design, web components, templating engines; there’s a need for the same in CSS, and so we’ve got a couple of different approaches that attempt to solve these different problems.

Block Element Modifier (BEM) “BEM is a design methodology that helps you to create reusable components and code sharing in front-end development.”

— getbem.com

The idea behind BEM is to create components out of parts of apps that are reused or are independent. Diving in, the design process is similar to atomic design: modularize things and think of each of them as a reusable component.

I chose to start out managing styles with BEM as it was very similar the way React (that I was already familiar with) breaks down apps into reusable components.

(Large preview) Using BEM

BEM is nothing more than a guide: no new framework or language to learn, just CSS with a naming convention to organize things better. Following this methodology, you can implement the patterns you’ve already been using, but in a more structured manner. You can also quite easily do progressive enhancements to your existing codebase as it requires no additional tooling configuration or any other complexities.

  • At its heart BEM manages reusable components, preventing random global styles overriding others. In the end, we have more predictable code, which solves a lot of our specificity problems.
  • There’s not much of a learning curve; it is just the same old CSS with a couple of guides to improve maintainability. It is an easy way of making code modular by using CSS itself.
  • While promoting reusability and maintainability, a side effect of the BEM naming principle is making naming the classes difficult and time-consuming.
  • The more nested your component is in the block, the longer and more unreadable the class names become. Deeply nested or grandchild selectors often face this issue.
<div class="card__body"> <p class="card__body__content">Lorem ipsum lorem</p> <div class="card__body__links"> <!-- Grandchild elements --> <a href="#" class="card__body__links__link--active">Link</a> </div> </div>

That was just a quick intro to BEM and how it solves our problems. If you’d like to take a deeper look into its implementation, check out “BEM For Beginners” published here in Smashing Magazine.

Sassy CSS (SCSS)

Put blandly, SCSS is CSS on steroids. Additional functionality such as variables, nesting selectors, reusable mixins, and imports help SCSS make CSS more of a programming language. For me, SCSS was fairly easy to pick up (go through the docs if you haven’t already) and once I got to grips with the additional features, I’d always prefer to use it over CSS just for the convenience it provided. SCSS is a preprocessor, meaning the compiled result is a plain old CSS file; the only thing you need to set up is tooling to compile down to CSS in the build process.

Super handy features
  • Imports help you split style sheets into multiple files for each component/section, or whichever makes readability easier.
// main.scss @import "_variables.scss"; @import "_mixins.scss"; @import "_global.scss"; @import "_navbar.scss"; @import "_hero.scss";
  • Mixins, loops, and variables help with the DRY principle and also make the process of writing CSS easier.
@mixin flex-center($direction) { display: flex; align-items: center; justify-content: center; flex-direction: $direction; } .box { @include flex-center(row); }

Note: SCSS mixin: Check out more handy SCSS features over here.

  • Nesting of selectors improves readability as it works the same way HTML elements are arranged: in a nested fashion. This approach helps you recognize hierarchy at a glance.

It is possible to group the code for components into blocks, and this greatly improves readability and helps in ease of writing BEM with SCSS:

This code is relatively less heavy and complicated as opposed to nesting multiple layers. (Large preview)

Note: For further reading on how this would work, check out Victor Jeman’s “BEM with Sass” tutorial.


This is one of the most widely used CSS-in-JS libraries. Without endorsing this particular library, it has worked well for me, and I’ve found its features quite useful for my requirements. Take your time in exploring other libraries out there and pick the one that best matches your needs.

I figured a good way to get to know styled-components was to compare the code to plain CSS. Here’s a quick look at how to use styled-components and what it’s all about:

Instead of adding classes to elements, each element with a class is made into a component. The code does look neater than the long class names we have with BEM.

Interestingly, what styled-components does under the hood is take up the job of adding relevant classes to elements as per what’s specified. This is essentially what we do in style sheets (note that it is in no way related to inline styling).

import styled from 'styled-components'; const Button = styled.button` background-color: palevioletred; color: papayawhip; `; // Output <style> .dRUXBm { background-color: palevioletred; color: papayawhip; } </style> <button class="dRUXBm" />

Note: Styled-components under the hood: read more about inline styling vs CSS-in-JS in “Writing your styles in JS ≠ writing inline styles” by Max Stoiber.

Why Are Styled-Components One Of The Widely Used CSS-In-JS Libraries?

For styling, here we’re just using template literals with normal CSS syntax. This allows you to use the full power of JavaScript to handle the styling for you: conditionals, properties passed in as arguments (using an approach similar to React), and essentially all the functionality that can be implemented by JavaScript.

While SCSS has variables, mixins, nesting, and other features, styled-components only adds on, making it even more powerful. Its approach, based heavily on components, might seem daunting at first since it’s different from traditional CSS. But as you get used to the principles and techniques, you’ll notice that everything possible with SCSS can be done in styled-components, as well as a lot more. You just use JavaScript instead.

const getDimensions = size => { switch(size) { case 'small': return 32; case 'large': return 64; default: return 48; } } const Avatar = styled.img` border-radius: 50%; width: ${props => getDimensions(props.size)}px; height: ${props => getDimensions(props.size)}px; `; const AvatarComponent = ({ src }) => ( <Avatar src={src} size="large" /> );

Note: Template literals in styled-components allow you to use JS directly for conditional styling and more.

Another thing to note is how perfectly this fits into the world of web components. A React component has its own functionality with JavaScript, JSX template, and now CSS-in-JS for styling: it’s fully functional all by itself and handles everything required internally.

Without us realizing, that was the answer to a problem we’ve been talking about for too long: specificity. While BEM was a guideline to enforce component-based structure for elements and styles but still relying on classes, styled-components impose it for you.

Styled-components has a couple of additional features I’ve found especially useful: themes, which can configure a global prop (variable) passed down to each styled-component; automatic vendor prefixing; and automatic clean-up of unused code. The amazingly supportive and active community is just the icing on the cake.

Note: There’s a lot more to check out and take advantage of. Read more in the styled-components docs.

Quick Recap On Features
  • Template literals are used for syntax, the same as traditional CSS.
  • It imposes modular design.
  • It solves specificity issues by handling class names for you.
  • Everything that can be done with SCSS and more, implemented with JS.
Why It Might Not Be For You
  • It obviously relies on JavaScript, which means without it the styles don’t load, resulting in a cluttered mess.
  • Previously readable class names are replaced with hashes that really have no meaning.
  • The concept of components rather than cascading classes might be a bit hard to wrap your head around, especially since this affects the way you arrange things a lot.
Design Systems

As usage of web components increases, as well as the need for atomic design (basically breaking down UI into basic building blocks), many companies are choosing to create component libraries and design systems. Unlike the technologies or approaches on how to handle styling mentioned above, design systems represent an organizational approach to handling components and consistent design across whole platforms or apps.

It’s possible to use an approach we’ve discussed within a design system to organize styles, while the design system itself focuses on the building blocks of the apps rather than internal implementations.

“Design systems are essentially collections of rules, constraints, and principles implemented in design and code.”

Design systems and component libraries are aimed at whole ecosystems spanning different platforms and media, and can determine the overall outlook of the company itself.

“A design system is an amalgamation of style, components, and voice.” IBM’s Carbon design system (Large preview)

Once they gain momentum, tech businesses sometimes have to scale up extremely fast, and it can be hard for the design and development teams to keep up. Different apps, new features and flows, constant reevaluation, changes, and enhancements are to be shipped as rapidly as possible when the business requires them.

Take the case of a simple modal; for instance, one screen has a confirmation modal which simply accepts a negative or positive action. This is worked on by Developer A. Then the design team ships another screen that has a modal comprising a small form with a few inputs — Developer B takes this up. Developers A and B work separately and have no idea that both of them are working on the same pattern, building two different components that are essentially the same at base level. If different developers worked on the different screens we might even see UI inconsistencies committed to the codebase.

Now imagine a large company of multiple designers and developers — you could end up with a whole collection of components and flows that are supposed to be consistent, but instead are distinct components existing independently.

The main principle of design systems is to help meet business requirements: build and ship new features, functionality, and even full apps while maintaining standards, quality, and consistency of design.

Here are some examples of popular design systems:

When talking about styling in particular, we’d be specifically interested in the component library part, although the design system itself is far more than just a collection of components. A component handles its functionality, template, and styling internally. A developer working on the app needn’t be aware of all of the internal working of the components, but would just need to know how to put them together within the app.

Now imagine a couple of these components that are further made reusable and maintainable, and then organized into a library. Developing apps could be almost as simple as drag-and-drop (well, not exactly, but a component could be pulled in without worrying about any internal aspects of its working). That’s essentially what a component library does.

(Large preview) (Large preview) Why You Might Want To Think About Building A Design System
  • As mentioned earlier, it helps the engineering and design teams keep up with rapidly changing business needs while maintaining standards and quality.
  • It ensures consistency of design and code throughout, helping considerably with maintainability over a long period of time.
  • One of the greatest features of design systems is that they bring the design and development teams closer, making work more of a continuous collaboration. Rather than whole pages of mock-ups given to developers to work on from scratch, components and their behaviors are well-defined first. It’s a whole different approach, but a better and faster way to develop consistent interfaces.
Why It Might Not Be The Best Fit For You
  • Design systems require a lot of time and effort up front to plan things out and organize from scratch — both code- and design-wise. Unless really required, it might not be worth delaying the development process to focus on building the design system at first.
  • If a project is relatively small, a design system can add unnecessary complexity and end up a waste of effort when what was actually required was just a couple of standards or guidelines to ensure consistency. Because several high-profile companies have adopted design systems, the hype can influence developers into thinking this is the always best approach, without analyzing the requirements and ensuring this could actually be practical.
Different appearances of a button (Large preview) Conclusion

Styling applications is a world in itself, one not often given the importance and attention it deserves. With complex modern user interfaces, it’s only matter of time before your app becomes a mess of unordered styles, reducing consistency and making it harder for new code to be added or changes made to the existing codebase.

Distilling what we’ve discussed so far: BEM, along with SCSS, could help you organize your style sheets better, take a programming approach to CSS, and create meaningful structured class names for cleaner code with minimal configuration. Building over a front-end framework like React or Vue, you might it find it convenient to hand class naming to a CSS-in-JS library if you’re comfortable with a component-based approach, putting an end to all your specificity issues, along with a couple of other benefits. For larger applications and multiple platforms, you might even consider building a design system in combination with one of the other methods, to boost development speeds while maintaining consistency.

Essentially, depending on your requirements and the size and scale of your software, it’s important to spend time determining your best approach to styling.

(dm, og, yk, il)
Categories: Web Design