Creating Authentic Human Connections Within A Remote Team

dreamt up by webguru in Uncategorized | Comments Off on Creating Authentic Human Connections Within A Remote Team

Creating Authentic Human Connections Within A Remote Team

Creating Authentic Human Connections Within A Remote Team

Randy Tolentino

On any given day, walk into your local coffee shop and you’ll likely see someone situated at a table, staring into a computer screen. Without knowing any details, one thing’s for sure, it’s obvious they’re ‘at work’. Many of us have been there at some point in our careers—all we need is a power outlet, internet access, and we’re good to go.

As a software developer for a global company, I have the benefit of collaborating with people from all over the world. Here, from the IBM Design Studio in Austin, Texas, approximately 4,500 miles and at least a fifteen-hour flight separate myself from the nearest developers on our product team. If we consider the furthest members, try 18 hours away by plane, literally on the other side of the planet.

In this current role, I’m a part of a multi-site team where most of the technical people are based out of two primary locations: Cork, Ireland and Kassel, Germany. On this product team, I happen to be the only satellite developer based in Austin, although I do have the benefit of sitting alongside our design team.

Scenarios like these are common nowadays. In 2018, Owl Labs found that 56% of the participating companies in their study adopted or allowed for some form of remote arrangement for its employees. While this organizational approach has revolutionized the way we perform our job functions, it’s also paved the way for new patterns to emerge in the way we interact with each other across the distance.

A map of the world showing main locations where our teams are based out of

Our product dev team is spread across the globe. (Large preview)

Connecting With People

I’ve always found that the most fascinating aspect of a distributed team is its people. The ‘diversity of people’, in itself, deserves emphasis. In my view, this mix of skills, knowledge, and perspectives make up the heart of the experience. Being able to integrate with people from various backgrounds is eye-opening. Hearing different accents, discovering new ways to look at problems, and learning about world cultures all within the normal flow of the day is simply refreshing.

At the same time, one of the biggest hurdles for those on remote teams is forming a relationship with your colleagues, that genuine human connection. In a 2018 study by And Co and Remote Year, 30% of the respondents reported lack of community as the number one factor impacting their happiness at work, understandably so. Having virtual colleagues makes it easy to fall into the trap of thinking ‘we all have individual assignments, we only need to interact when our work crosses paths, and all we’re here to do is deliver’.

It’s just not enough.

Throughout my career, almost every project I’ve worked on involved others that were remote in some capacity. In this context, I’ve learned plenty about what it takes to build meaningful partnerships with people across varying distances and multiple time zones. My hope is that the following list of suggestions and ideas can help others out there who are navigating through the challenge of building actual human connections with their teammates.

  1. People, Not Resources
  2. Building A Continuous Improvement Culture
  3. Reading Emotions Across The Distance
  4. A Little Extra Effort Can Bridge The Gap
  5. Staying Thankful At The Core

1. People, Not Resources

Problem: Sometimes, remote team members can be mistakenly reduced or perceived as ‘contributors only’. In some cases, people are actually referred to as ‘resources’, literally.

About a year ago, I was on a kick-off call for a project where the client was headquartered in another city. At one point during the virtual meeting, I politely asked one of the client-stakeholders about credentials and ownership of a third-party app that they used. It was a fair question, I was simply gathering requirements. But his response towards me was belittling and unprofessional, making it seem as if I were questioning his knowledge or authority. From then on, it’s been a personal goal of mine to always acknowledge remote colleagues as people, not just resources.

At the very minimum, great collaborations are comprised of individuals who respect and care about one another on a holistic level. Sure, we collectively share the same objectives, but we’re also more than just workers. The very idea of ‘having a genuine connection with people you work with’, is a proven motivator for many when it comes to job satisfaction. It makes sense because as human beings, we have an innate need to connect with one another—this is especially true on remote teams.

These are some ways to remind us that people are the foundation of your team:

  • Proactively introduce yourself to as many teammates as possible.
  • Learn about each other, share cultures, stories, and professional backgrounds.
  • Be mindful of your audible and legible tone (on calls and chats), keep it friendly and respectful.

2. Building A Continuous Improvement Culture

Problem: As remote team members, we can find ourselves stranded on an island if we don’t ask for help sooner than later.

Oftentimes, we make the mistake of believing that in order to bring value to the team, we must know everything (all the time). This ‘rugged individualist’ mentality is a one-way ticket to imposter syndrome. The next thing you know, a significant amount of time passes, your progress remains stagnant, and by the time someone extends a hand you’re already underwater. Remember, no one knows everything, and more importantly, teams thrive off of collaboration. We learn together.

The best functioning teams that I’ve been on all had a healthy continuous learning culture. On these teams, failure is okay, especially when our mistakes are transformed into learning opportunities. When working on a remote team, instead of running or hiding from our mistakes, I personally recommend that we fail in “public”. This lets the team know that you hired a human, one who’ll run into stumbling blocks and will inevitably produce errors. By doing so, this gives others the opportunity to either offer assistance, or learn.

A GitHub pull request including a comment seeking for help and clarity

Asking for help and admitting mistakes allow you to improve your craft. (Large preview)

You can contribute to the team’s improvement culture in the following ways:

  • Leverage public channels to show when you’re stuck, this allows the group to help or point you in the right direction.
  • Share what you’ve learned in public channels, retrospectives, or through documentation.
  • Spend time listening and scanning for ways to help others.
  • When you do help your team, remind them that everyone asks for help and how you are all on this journey together.

3. Reading Emotions Across The Distance

Problem: Understanding someone’s emotional state is already difficult when you’re in the same office. When it comes to communicating online, getting a good read on someone’s tone, feelings, or intent, becomes even more challenging.

In person, it’s relatively easier to exercise soft-skills because you’re in the same physical space as your colleagues. From laughter to frustration, there’s an advantage we gain from being co-located when it comes to interpreting how someone is feeling. We can gauge these emotions based off of vocal inflections, facial expressions, and gestures.

However, when we’re far from teammates, we have to be more creative when trying to convey or pick-up on these sentiments. When I breakdown how I communicate with my team throughout the day, about 90% of it occurs in chats; the remaining 10% is split between in conference calls, email, and any other tool that allows for commenting. In each of these modes, we have to clearly convey not only what we say, but what we mean and how we feel.

A conversation in Slack showing how emoji helps convey feelings

Using the appropriate emoji can allow others to have a better grasp of how you might feel. (Large preview)

We can improve our team’s collective ability to read and convey emotions in the following ways:

  • Video calls provide a visual and audible opportunity to pick up on our expressions; turn on the camera and smile at each other.
  • Instead of just focusing on business objectives, develop the habit of paying particular attention to tone and feelings when communicating with your team.
  • Use the appropriate emoji to supplement your thoughts or reactions; these fun and effective special characters can help to surface your feelings.

4. A Little Extra Effort Can Bridge The Gap

Problem: The physical mileage between team members and multiple time-zones can cause a strain in our effort to connect with our colleagues.

With Germany being 7 hours ahead and Ireland being 6, I am constantly reminded how the time difference is an issue. On most occasions, when I have questions or run into some sort of blocker anytime after lunch, all of our dev team is offline.

If I worked the typical 9-to-5 schedule, I’d only have about 3 to 4 hours of an overlap with my remote team. It took me a few weeks to fully realize how much the time difference was a factor, but once I did, I decided to flex my schedule.

When I learned that our Ireland team had daily standups at 10:30 AM, (4:30 AM our time), I asked to be invited to those meetings. Most people might think: that’s way too early! But, for a couple of weeks, I joined their call and found it to be incredibly helpful from an alignment and tracking perspective. More importantly, the team understood that I was here to be as helpful as possible and was willing to sacrifice my own conveniences for the sake of the team.

While we can’t do much about the distance, there are a few strategies to potentially improving the overlap:

  • Find creative ways to extend yourself for the interest of the team; these gestures show good faith and the willingness to make things better for the group.
  • Be equally accommodating towards others and reciprocate the flexibility your colleagues show towards one another.
  • Take the most advantage of the overlapping time, ask critical questions, and ensure no one is blocked from making progress.

5. Staying Thankful At The Core

Problem: In our work, we spend almost every minute of every day focusing our attention on solving some sort of problem.

Deeply embedded into my personal culture is an appreciation mindset; practicing gratitude allows me to maintain a fairly good mood throughout the day. I regularly think about how blessed I am to work in the tech industry, helping to solve some of the world’s most challenging problems. I can never take this for granted. Being able to listen to my favorite hip hop playlists, writing code all day, and having access to learning from a wealth of individuals, this is a dream come true. This thankful mentality stays with me no matter what and it’s something I aim to emit when interacting with my team.

It’s not always easy though. In the tech industry, we spend nearly every minute of the day, using our skills and creativity to find our way out of a problem. Sometimes we’re focused on business problems, maybe we’re solving a user pain point, or maybe we’re managing an internal team issue. This repetition, over time, this can take a toll on us, and we could forget why we even chose to do this.

Keeping a positive attitude can help lift team morale and has been known to make you a better collaborator. Even though you may be far from your teammates, your attitude comes through in your work and communications. Here are some pointers to keep in mind when showing appreciation towards your team:

  • Use company tools to acknowledge a teammate.
  • Ask teammates how they’d like to be recognized, and thank them accordingly.
  • Relay positive feedback to a colleague’s lead or manager.

A thank you note using the digital recognition tool at IBM

At IBM, we use the Recognition platform to acknowledge our peers. (Large preview)

Remember To Be Human

You see them on various social media platforms, posts or photos of a team retreat where employees step away from their projects for a few days to focus on team-building. Some organizations intentionally design these events into their annual schedules; it’s an excellent way to bridge the gaps and facilitate bonding. Many teams return home from these retreats and experience improved alignment and productivity.

For other organizations, having the ability to meet face-to-face with your remote counterparts isn’t an option. In these cases, we have to make the best of our circumstances by depending on our soft-skills and creativity to help form the alliances we need. I’m confident that by caring for one another as people first, we collectively become better at what we do.

Behind every @username, profile picture, and direct message is a person, one who probably cries and rejoices for the same reasons you might. As technology continues to influence new social behaviors that shape the way we work, it’s important to remember that phenomenal teams are composed of individuals who understand each other and care for one another.

People make products, it’s not the other way around. No matter how far the distance between you and your teammates, I encourage you to make a conscious effort to connect with one another, invest in long-lasting friendships, and last but not least, remember to be human.


Smashing Editorial
(ra, il)

Source: Smashing Magazine, Creating Authentic Human Connections Within A Remote Team

Handling Unused CSS In SASS To Improve Performance

dreamt up by webguru in Uncategorized | Comments Off on Handling Unused CSS In SASS To Improve Performance

Handling Unused CSS In SASS To Improve Performance

Handling Unused CSS In SASS To Improve Performance

Luke Harrison

In modern front-end development, developers should aim to write CSS which is scalable and maintainable. Otherwise, they risk losing control over specifics such as the cascade and selector specificity as the codebase grows and more developers contribute.

One way this can be achieved is through the use of methodologies such as Object-Oriented CSS (OOCSS), which rather than organizing CSS around page context, encourages separating structure (grid systems, spacing, widths, etc.) from decoration (fonts, brand, colors, etc.).

So CSS class names such as:

  • .blog-right-column
  • .latest_topics_list
  • .job-vacancy-ad

Are replaced with more reusable alternatives, which apply the same CSS styles, but aren’t tied to any particular context:

  • .col-md-4
  • .list-group
  • .card

This approach is commonly implemented with the help of a SASS framework such as Bootstrap, Foundation, or increasingly more often, a bespoke framework which can be shaped to better fit the project.

So now we’re using CSS classes cherry-picked from a framework of patterns, UI components and utility classes. The below example illustrates a common grid system built using Bootstrap, which stacks vertically, then once the md breakpoint is reached, switches to a 3 column layout.

Column 1
Column 2
Column 3
</div> </div>

Programmatically generated classes such as .col-12 and .col-md-4 are used here to create this pattern. But what about .col-1 through .col-11, .col-lg-4, .col-md-6 or .col-sm-12? These are all examples of classes which will be included in the compiled CSS stylesheet, downloaded and parsed by the browser, despite not being in use.

In this article, we’ll start by exploring the impact unused CSS can have on page load speeds. We’ll then touch upon some existing solution for removing it from stylesheets, following up with my own SASS oriented solution.

Measuring The Impact Of Unused CSS Classes

Whilst I adore Sheffield United, the mighty blades, their website’s CSS is bundled into a single 568kb minified file, which comes to 105kb even when gzipped. That seems like a lot.

This is Sheffield United’s website, my local Football team (that’s Soccer for you lot over in the colonies 🇺🇸). (Large preview)

Shall we see how much of this CSS is actually used by on their homepage? A quick Google search reveals plenty of online tools up to the job, but I prefer to use the coverage tool in Chrome, which can be run straight from Chrome’s DevTools. Let’s give it a whirl.

The quickest way to access the coverage tool in Developer Tools is to use the keyboard shortcut Control+Shift+P or Command+Shift+P (Mac) to open the command menu. In it, type coverage, and select the ‘Show Coverage’ option. (Large preview)

The results show that only 30kb of CSS from the 568kb stylesheet is used by the homepage, with the remaining 538kb relating to the styles required for the rest of the website. This means a whopping 94.8% of the CSS is unused.

You can see timings like these for any asset in Chrome in Developer Tools via Network -> Click on your asset -> Timing tab. (Large preview)

CSS is part of a webpage’s critical rendering path, which involves all the different steps a browser must complete before it can begin page render. This makes CSS a render-blocking asset.

So with this in mind, when loading Sheffield United’s website using a good 3G connection, it takes a whole 1.15s before the CSS is downloaded and page rendering can begin. This is a problem.

Google has recognized this as well. When running a Lighthouse audit, online or via your browser, any potential load time and filesize savings which could be made by removing unused CSS are highlighted.

In Chrome (and Chromium Edge), you can right Google Lighthouse audits by clicking on the Audit tab in developer tools. (Large preview)

Existing Solutions

The goal is to determine which CSS classes aren’t required and remove them from the stylesheet. Existing solutions are available which attempt to automate this process. They can typically be used via a Node.js build script, or via task runners such as Gulp. These include:

These generally work in a similar way:

  1. On bulld, the website is accessed via a headless browser (Eg: puppeteer) or DOM emulation (Eg: jsdom).
  2. Based on the page’s HTML elements, any unused CSS is identified.
  3. This is removed from the stylesheet, leaving only what is needed.

Whilst these automated tools are perfectly valid and I’ve used many of them across a number of commercial projects successfully, I’ve encountered a few drawbacks along the way which are worth sharing:

  • If class names contain special characters such as ‘@’ or ‘/’, these may not be recognized without writing some custom code. I use BEM-IT by Harry Roberts, which involves structuring class names with responsive suffixes like: u-width-6/12@lg, so I’ve hit this issue before.
  • If the website uses automated deployment, it can slow down the build process, especially if you have lots of pages and lots of CSS.
  • Knowledge about these tools needs to be shared across the team, otherwise there may be confusion and frustration when CSS is mysteriously absent in production stylesheets.
  • If your website has many 3rd party scripts running, sometimes when opened in a headless browser, these don’t play nicely and can cause errors with the filtering process. So typically you have to write custom code to exclude any 3rd party scripts when a headless browser is detected, which depending on your setup, may be tricky.
  • Generally, these kind of tools are complicated and introduce a lot of extra dependencies to the build process. As is the case with all 3rd party dependencies, this means relying on somebody else’s code.

With these points in mind, I posed myself a question:

Using just SASS, is it possible to better handle the SASS we compile so any unused CSS can be excluded, without resorting to just crudely deleting the source classes in the SASS outright?

Spoiler alert: The answer is yes. Here’s what I’ve come up with.

SASS Oriented Solution

The solution needs to provide a quick and easy way to cherry-pick what SASS ought to be compiled, whilst being simple enough that it doesn’t add any more complexity to the development process or prevent developers from taking advantage of things like programmatically generated CSS classes.

To get started, there’s a repo with build scripts and a few sample styles which you can clone from here.

Tip: If you get stuck, you can always cross-reference with the completed version on master branch.

cd into the repo, run npm install and then npm run build to compile any SASS into CSS as required. This should create a 55kb css file in the dist directory.

If you then open /dist/index.html in your web browser, you should see a fairly standard component, which on click expands to reveal some content. You can also view this here, where real network conditions will be applied, so you can run your own tests.

We’ll use this expander UI component as our test subject when developing the SASS-oriented solution for handling unused CSS. (Large preview)

Filtering At The Partials Level

In a typical SCSS setup, you’re likely going to have a single manifest file (eg: main.scss in the repo), or one per page (eg: index.scss, products.scss, contact.scss) where framework partials are imported. Following OOCSS principles, those imports may look something like this:

Example 1
Undecorated design patterns

@import 'objects/box';
@import 'objects/container';
@import 'objects/layout';

UI components

@import 'components/button';
@import 'components/expander';
@import 'components/typography';

Highly specific helper classes

@import 'utilities/alignments';
@import 'utilities/widths';

If any of these partials aren’t in use, then the natural way of filtering this unused CSS would be to just disable the import, which would prevent it from being compiled.

For example, if only using the expander component, the manifest would typically look like the below:

Example 2
Undecorated design patterns
// @import 'objects/box';
// @import 'objects/container';
// @import 'objects/layout';

UI components
// @import 'components/button';
@import 'components/expander';
// @import 'components/typography';

Highly specific helper classes
// @import 'utilities/alignments';
// @import 'utilities/widths';

However, as per OOCSS, we’re separating decoration from structure to allow for maximum reusability, so it’s possible the expander could require CSS from other objects, component or utility classes to render correctly. Unless the developer is aware of these relationships by inspecting the HTML, they may not know to import these partials, so not all of the required classes would be compiled.

In the repo, if you look at the expander’s HTML in dist/index.html, this appears to be the case. It uses styles from the box and layout objects, the typography component, and width and alignment utilities.


Toggle Expander

</div> </div> </div>
Lorum ipsum

</div> </div>

Let’s tackle this problem waiting to happen by making these relationships official within the SASS itself, so once a component is imported, any dependencies will also be imported automatically. This way, the developer no longer has the extra overhead of having to audit the HTML to learn what else they need to import.

Programmatic Imports Map

For this dependency system to work, rather than simply commenting in @import statements in the manifest file, SASS logic will need to dictate if partials will be compiled or not.

In src/scss/settings, create a new partial called _imports.scss, @import it in settings/_core.scss, and then create the following SCSS map:

@import 'breakpoints';
@import 'spacing';
@import 'imports';
$imports: (
   object: (
   component: (
   utility: (

This map will have the same role as the import manifest back in example 1.

Example 4
$imports: (
   object: (
   component: (
   utility: (

It should behave like a standard set of @imports would, in that if certain partials are commented out (like the above), then that code shouldn’t be compiled on build.

But as we’re wanting to import dependencies automatically, we should also be able to ignore this map under the right circumstances.

Render Mixin

Let’s start to add some SASS logic. Create _render.scss in src/scss/tools, and then add its @import to tools/_core.scss.

In the file, create an empty mixin called render().

@mixin render() {


In the mixin, we need to write SASS which does the following:

  • render()
    “Hey there $imports, fine weather isn’t it? Say, do you have the container object in your map?”
  • $imports
  • render()
    “That’s a shame, looks like its won’t be compiled then. How about the button component?”
  • $imports
  • render()
    “Nice! That’s the button being compiled then. Say hi to the wife for me.”

In SASS, this translates to the following:

@mixin render($name, $layer) {
   @if(index(map-get($imports, $layer), $name)) {

Basically, check if the partial is included in the $imports variable, and if so, render it using SASS’s @content directive, which allows us to pass a content block into the mixin.

We would use it like so:

Example 5
@include render('button', 'component') {
   .c-button {
      // styles et al

   // any other class declarations

Before using this mixin, there’s a small improvement which we can make to it. The layer name (object, component, utility, etc.) is something we can safely predict, so we have an opportunity to streamline things a little.

Before the render mixin declaration, create a variable called $layer, and remove the identically named variable from the mixins parameters. Like so:

$layer: null !default;
@mixin render($name) {
   @if(index(map-get($imports, $layer), $name)) {

Now, in the _core.scss partials where objects, components and utility @imports are located, redeclare these variables to the following values; representing the type of CSS classes being imported.

$layer: 'object';

@import 'box';
@import 'container';
@import 'layout';
$layer: 'component';

@import 'button';
@import 'expander';
@import 'typography';
$layer: 'utility';

@import 'alignments';
@import 'widths';

This way, when we use the render() mixin, all we have to do is declare the partial name.

Wrap the render() mixin around each object, component and utility class declaration, as per the below. This will give you one render mixin usage per partial.

For example:

@include render('button') {
   .c-button {
      // styles et al

   // any other class declarations
@include render('button') {
   .c-button {
      // styles et al

   // any other class declarations

Note: For utilities/_widths.scss, wrapping the render() function around the entire partial will error on compile, as in SASS you can’t nest mixin declarations within mixin calls. Instead, just wrap the render() mixin around the create-widths() calls, like below:

@include render('widths') {


// Example: .u-width-1/3
@include create-widths($utility-widths-sets);


// Create responsive variants using settings.breakpoints
// Changes width when breakpoint is hit
// Example: .u-width-1/3@md

@each $bp-name, $bp-value in $mq-breakpoints {
   @include mq(#{$bp-name}) {
      @include create-widths($utility-widths-sets, @, #{$bp-name});

// End render

With this in place, on build, only the partials referenced in $imports will be compiled.

Mix and match what components are commented out in $imports and run npm run build in the terminal to give it a try.

Dependencies Map

Now we’re programmatically importing partials, we can start to implement the dependency logic.

In src/scss/settings, create a new partial called _dependencies.scss, @import it in settings/_core.scss, but make sure it’s after _imports.scss. Then in it, create the following SCSS map:

$dependencies: (
   expander: (
      object: (
    component: (
    utility: (

Here, we declare dependencies for the expander component as it requires styles from other partials to render correctly, as seen in dist/index.html.

Using this list, we can write logic which would mean these dependencies would always be compiled along with their dependent components, no matter the state of the $imports variable.

Below $dependencies, create a mixin called dependency-setup(). In here, we’ll do the following actions:

1. Loop through the dependencies map.
@mixin dependency-setup() {
   @each $componentKey, $componentValue in $dependencies {
2. If the component can be found in $imports, loop through its list of dependencies.
@mixin dependency-setup() {
   $components: map-get($imports, component);
   @each $componentKey, $componentValue in $dependencies {
      @if(index($components, $componentKey)) {
         @each $layerKey, $layerValue in $componentValue {

3. If the dependency isn’t in $imports, add it.
@mixin dependency-setup() {
   $components: map-get($imports, component);
   @each $componentKey, $componentValue in $dependencies {
       @if(index($components, $componentKey)) {
           @each $layerKey, $layerValue in $componentValue {
               @each $partKey, $partValue in $layerValue {
                   @if not index(map-get($imports, $layerKey), $partKey) {
                       $imports: map-merge($imports, (
                           $layerKey: append(map-get($imports,  $layerKey), '#{$partKey}')
                       )) !global;

Including the !global flag tells SASS to look for the $imports variable in the global scope, rather than the mixin’s local scope.

4. Then it’s just a matter of calling the mixin.
@mixin dependency-setup() {
@include dependency-setup();

So what we have now is an enhanced partial import system, where if a component is imported, a developer doesn’t then have to manually import each of its various dependency partials as well.

Configure the $imports variable so only the expander component is imported and then run npm run build. You should see in the compiled CSS the expander classes along with all of its dependencies.

However, this doesn’t really bring anything new to the table in terms of filtering out unused CSS, as the same amount of SASS is still being imported, programmatic or not. Let’s improve on this.

Improved Dependency Importing

A component may require only a single class from a dependency, so to then go on and import all of that dependency’s classes just leads to the same unnecessary bloat we’re trying to avoid.

We can refine the system to allow for more granular filtering on a class by class basis, to make sure components are compiled with only the dependency classes they require.

With most design patterns, decorated or not, there exists a minimum amount of classes which need to be present in the stylesheet for the pattern to display correctly.

For class names using an established naming convention such as BEM, typically the “Block” and “Element” named classes are required as a minimum, with “Modifiers” typically being optional.

Note: Utility classes wouldn’t typically follow the BEM route, as they’re isolated in nature due to their narrow focus.

For example, take a look at this media object, which is probably the most well-known example of object-oriented CSS:


If a component has this set as a dependency, it makes sense to always compile .o-media, .o-media__image and .o-media__text, as that’s the minimum amount of CSS required to make the pattern work. However with .o-media--spacing-small being an optional modifier, it ought to only be compiled if we explicitly say so, as its usage may not be consistent across all media object instances.

We’ll modify the structure of the $dependencies map to allow us to import these optional classes, whilst including a way to import only the block and element in case no modifiers are required.

To get started, check the expander HTML in dist/index.html and make a note of any dependency classes in use. Record these in the $dependencies map, as per below:

$dependencies: (
   expander: (
       object: (
           box: (
           layout: (
       component: (
           button: true,
           typography: (
       utility: (
           alignments: (
           widths: (

Where a value is set to true, we’ll translate this into “Only compile block and element level classes, no modifiers!”.

The next step involves creating a whitelist variable to store these classes, and any other (non-dependency) classes we wish to manually import. In /src/scss/settings/imports.scss, after $imports, create a new SASS list called $global-filter.

$global-filter: ();

The basic premise behind $global-filter is that any classes stored here will be compiled on build as long as the partial they belong to is imported via $imports.

These class names could be added programmatically if they’re a component dependency, or could be added manually when the variable is declared, like in the example below:

Global filter example
$global-filter: (

Next, we need to add a bit more logic to the @dependency-setup mixin, so any classes referenced in $dependencies are automatically added to our $global-filter whitelist.

Below this block:

@if not index(map-get($imports, $layerKey), $partKey) {


…add the following snippet.

@each $class in $partValue {
   $global-filter: append($global-filter, '#{$class}', 'comma') !global;

This loops through any dependency classes and adds them to the $global-filter whitelist.

At this point, if you add a @debug statement below the dependency-setup() mixin to print out the contents of $global-filter in the terminal:

@debug $global-filter;

…you should see something like this on build:

DEBUG: "o-box--spacing-small", "o-layout--fit", "c-box--rounded", "true", "true", "u-flex-middle", "u-align-center", "u-width-grow", "u-width-shrink"

Now we’ve got a class whitelist, we need to enforce this across all of the different object, component and utility partials.

Create a new partial called _filter.scss in src/scss/tools and add an @import to tools layer’s _core.scss file.

In this new partial, we’ll create a mixin called filter(). We’ll use this to apply logic which means classes will only be compiled if included in the $global-filter variable.

Starting off simple, create a mixin which accepts a single parameter — the $class which the filter controls. Next, if the $class is included in the $global-filter whitelist, allow it to be compiled.

@mixin filter($class) {
   @if(index($global-filter, $class)) {

In a partial, we would wrap the mixin around an optional class, like so:

@include filter('o-myobject--modifier') {
   .o-myobject--modifier {
      color: yellow;

This means the .o-myobject--modifier class would only be compiled if its included in $global-filter, which can either be set directly, or indirectly through what’s set in $dependencies.

Go through the repo and apply the filter() mixin to all optional modifier classes across object and component layers. When handling the typography component or the utilities layer, as each class is independent from the next, it’d make sense to make them all optional, so we can then just enable classes as we need them.

Here’s a few examples:

@include filter('o-layout__item--fit-height') {
    .o-layout__item--fit-height {
        align-self: stretch;
// Changes alignment when breakpoint is hit
// Example: .u-align-left@md
@each $bp-name, $bp-value in $mq-breakpoints {
    @include mq(#{$bp-name}) {
        @include filter('u-align-left@#{$bp-name}') {
            .u-align-left@#{$bp-name} {
                text-align: left !important;

        @include filter('u-align-center@#{$bp-name}') {
            .u-align-center@#{$bp-name} {
                text-align: center !important;

        @include filter('u-align-right@#{$bp-name}') {
            .u-align-right@#{$bp-name} {
                text-align: right !important;

Note: When adding the responsive suffix classnames to the filter() mixin, you don’t have to escape the ‘@’ symbol with a ”.

During this process, whilst applying the filter() mixin to partials, you may (or may not) have noticed a few things.

Grouped Classes

Some classes in the codebase are grouped together and share the same styles, for example:

.o-box--spacing-horizontal {
    padding-left: 0;

As the filter only accepts a single class, it doesn’t account for the possibility that one style declaration block may be for more than one class.

To account for this, we’ll expand the filter() mixin so in addition to a single class, it’s able to accept a SASS arglist containing many classes. Like so:

@include filter('o-box--spacing-disable-left', 'o-box--spacing-horizontal') {
    .o-box--spacing-horizontal {
        padding-left: 0;

So we need to tell the filter() mixin that if either of these classes are in the $global-filter, you are allowed to compile the classes.

This will involve additional logic to type check the mixin’s $class argument, responding with a loop if an arglist is passed to check if each item is in the $global-filter variable.

@mixin filter($class...) {
    @if(type-of($class) == 'arglist') {
        @each $item in $class {
            @if(index($global-filter, $item)) {
    @else if(index($global-filter, $class)) {

Then it’s just a matter of going back to the following partials to correctly apply the filter() mixin:

  • objects/_box.scss
  • objects/_layout.scss
  • utilities/_alignments.scss

At this point, go back to $imports and enable just the expander component. In the compiled stylesheet, besides the styles from the generic and elements layers, you should only see the following:

  • The block and element classes belonging to the expander component, but not its modifier.
  • The block and element classes belonging to the expander’s dependencies.
  • Any modifier classes belonging to the expander’s dependencies which are explicitly declared in the $dependencies variable.

Theoretically, if you decided you wanted to include more classes in the compiled stylesheet, such as the expander components modifier, it’s just a matter of adding it to the $global-filter variable at the point of declaration, or appending it at some other point in the codebase (As long as it’s before the point where the modifier itself is declared).

Enabling Everything

So we now have a pretty complete system, which lets you import objects, components and utilities down to the individual classes within these partials.

During development, for whatever reason, you may just want to enable everything in one go. To allow for this, we’ll create a new variable called $enable-all-classes, and then add in some additional logic so if this is set to true, everything is compiled no matter the state of the $imports and $global-filter variables.

First, declare the variable in our main manifest file:

$enable-all-classes: false;

@import 'settings/core';
@import 'tools/core';
@import 'generic/core';
@import 'elements/core';
@import 'objects/core';
@import 'components/core';
@import 'utilities/core';

Then we just need to make a few minor edits to our filter() and render() mixins to add some override logic for when the $enable-all-classes variable is set to true.

First up, the filter() mixin. Before any existing checks, we’ll add an @if statement to see if $enable-all-classes is set to true, and if so, render the @content, no questions asked.

@mixin filter($class...) {
    @if($enable-all-classes) {
    @else if(type-of($class) == 'arglist') {
        @each $item in $class {
            @if(index($global-filter, $item)) {
    @else if(index($global-filter, $class)) {

Next in the render() mixin, we just need to do a check to see if the $enable-all-classes variable is truthy, and if so, skip any further checks.

$layer: null !default;
@mixin render($name) {
    @if($enable-all-classes or index(map-get($imports, $layer), $name)) {

So now, if you were to set the $enable-all-classes variable to true and rebuild, every optional class would be compiled, saving you quite a bit of time in the process.


To see what type of gains this technique is giving us, let’s run some comparisons and see what the filesize differences are.

To make sure the comparison is a fair one, we ought to add the box and container objects in $imports, and then add the box’s o-box--spacing-regular modifier to the $global-filter, like so:

$imports: (
     object: (
        // 'layout'
     component: (
        // 'button',
        // 'typography'
     utility: (
        // 'alignments',
        // 'widths'

$global-filter: (

This makes sure styles for the expander’s parent elements are being compiled like they would be if there were no filtering taking place.

Original vs Filtered Stylesheets

Let’s compare the original stylesheet with all classes compiled, against the filtered stylesheet where only CSS required by the expander component has been compiled.

Stylesheet Size (kb) Size (gzip)
Original 54.6kb 6.98kb
Filtered 15.34kb (72% smaller) 4.91kb (29% smaller)

You may think that the gzip percentage savings mean this isn’t worth the effort, as there’s not much difference between the original and filtered stylesheets.

It’s worth highlighting that gzip compression works better with larger and more repetitive files. Because the filtered stylesheet is the only proof-of-concept, and only contains CSS for the expander component, there isn’t as much to compress as there would be in a real-life project.

If we were to scale up each stylesheet by a factor of 10 to sizes more typical of a website’s CSS bundle size, the difference in gzip file sizes are much more impressive.

10x Size
Stylesheet Size (kb) Size (gzip)
Original (10x) 892.07kb 75.70kb
Filtered (10x) 209.45kb (77% smaller) 19.47kb (74% smaller)

Filtered Stylesheet vs UNCSS

Here’s a comparison between the filtered stylesheet and a stylesheet which has been run through the UNCSS tool.

Filtered vs UNCSS
Stylesheet Size (kb) Size (gzip)
Filtered 15.34kb 4.91kb
UNCSS 12.89kb (16% smaller) 4.25kb (13% smaller)

The UNCSS tool wins here marginally, as it’s filtering out CSS in the generic and elements directories.

It’s possible that on a real website, with a larger variety of HTML elements in use, the difference between the 2 methods would be negligible.

Wrapping Up

So we’ve seen how — using just SASS — you are able to gain more control over what CSS classes are being compiled on build. This reduces the amount of unused CSS in the final stylesheet and speeds up the critical rendering path.

At the start of the article, I listed some drawbacks of existing solutions such as UNCSS. It’s only fair to critique this SASS-oriented solution in the same way, so all the facts are on the table before you decide which approach is better for you:


  • No additional dependencies required, so you don’t have to rely on somebody else’s code.
  • Less build time required than Node.js based alternatives, as you don’t have to run headless browsers to audit your code. This is especially useful with continuous integration as you may be less likely to see a queue of builds.
  • Results in similar file size when compared to automated tools.
  • Out of the box, you have complete control over what code is being filtered, regardless of how those CSS classes are used in your code. With Node.js based alternatives, you often have to maintain a separate whitelist so CSS classes belonging to dynamically injected HTML aren’t filtered out.


  • The SASS-oriented solution is definitely more hands-on, in the sense that you have to keep on top of the $imports and $global-filter variables. Beyond the initial setup, the Node.js alternatives we’ve looked at are largely automated.
  • If you add CSS classes to $global-filter and then later remove them from your HTML, you need to remember to update the variable, otherwise you’ll be compiling CSS you don’t need. With large projects being worked on by multiple devs at any one time, this may not be easy to manage unless you properly plan for it.
  • I wouldn’t recommend bolting this system onto any existing CSS codebase, as you’d have to spend quite a bit of time piecing together dependencies and applying the render() mixin to a LOT of classes. It’s a system much easier to implement with new builds, where you don’t have existing code to contend with.

Hopefully you’ve found this as interesting to read as I’ve found it interesting to put together. If you have any suggestions, ideas to improve this approach, or want to point out some fatal flaw that I’ve missed entirely, be sure to post in the comments below.

Smashing Editorial
(dm, yk, il)

Source: Smashing Magazine, Handling Unused CSS In SASS To Improve Performance

Collective #539

dreamt up by webguru in Uncategorized | Comments Off on Collective #539


The case study factory

A well made and eye-opening presentation on how the formulaic approach to UX case studies is numbing the critical thinking of designers, and how to bring a unique point of view to one’s work.

Check it out


A Contact Picker for the Web

Read all about the new Contact Picker API, an on-demand picker that allows users to select entries from their contact list and share limited details of the selected entries with a website.

Read it

Meet Dimension

Read about Dimension, a fascinating open-source plan to adapt fully-featured design tools like Figma from desktop to tablet. By Theo Strauss.

Read it


Artificial Intelligence Driven Design

A free Brain food ebook series where Joël van Bodegraven and other guest authors delve deep into how Artificial Intelligence will impact UX design, and how to design meaningful experiences in an era with AI-driven products and services.

Check it out


Predictably Random

Remy Sharp gives some insight to random functions in JavaScript and shares a tool that can visualize them.

Read it


Monica Dinculescu shares her latest creation called MidiMe: a small magenta.js model that you can train in your browser with your music to output variations. Read more about it in this article.

Check it out


Eighth annual js13kGames challenge

Read the details about the eighth annual js13kGames competition, a game jam for web developers, game developers, and anyone who wants to challenge themselves to create something fun using JavaScript.

Read it


Avant UI

Based on the Bootstrap Framework, this UI kit provides a fresh look and adds new features and components.

Get it

Collective #539 was written by Pedro Botelho and published on Codrops.

Source: Codrops, Collective #539

Now Live: Your SmashingConf Toronto Playlist

dreamt up by webguru in Uncategorized | Comments Off on Now Live: Your SmashingConf Toronto Playlist

Now Live: Your SmashingConf Toronto Playlist

Now Live: Your SmashingConf Toronto Playlist

Rachel Andrew

We have edited and prepared the video from SmashingConf Toronto, and it is all now live for you to watch and learn from. To get a feel for the event, watch our compilation. We think that it really captures the atmosphere of a SmashingConf!

Day One

The Day One Collaborative Doc created by attendees is full of takeaways from the first day of the conference. You might find some of those notes helpful as you watch the video linked below.

Speaker Name Talk Title
Brad Frost “Let’s Build A Design System” (Video)
Sarah Drasner “Let’s Write A Vue App From Scratch” (Video)
Phil Hawksworth “JAMStack: Silly Name. Serious Stuff.” (Video)
Jenny Shen “Build Bridges, Not Walls: Design For Users Across Cultures” (Video)
Chris Gannon “Make It Move! Create A Web Animation From Scratch” (Video)
Kristina Podnar “Help! I’m Your Ailing Website. The Digital Policy & Standards Rehab Hour” (Video)
Steven Hoober “Authentic Digital Design By The Numbers” (Video)

Day Two

Check out the Day Two Collaborative Doc for more resources and thoughts shared by our attendees and speakers on the second day of the conference.

Speaker Name Talk Title
Phil Nash “Diving Into Service Workers, Live” (Video)
Dan Rose “Seeing The Pages For The Components” (Video)
Diana Mounter “The Secret Lives of Color Systems” (Video)

Some of the speakers shared additional resources, or GitHub repos to go with their talks. You can find all of the relevant links here.

You can also find all of the video in the Vimeo showcase for SmashingConf Toronto 2019, and we have a lot of videos from previous events for you to explore.

If you would like to be part of the SmashingConf fun next year, we already have tickets on sale for SmashingConf San Francisco 2020. The rest of this year’s events (New York and Freiburg) are already sold out! There are a few workshop-only tickets available for New York 2019, but be quick!

Related Resources on SmashingMag:

Smashing Editorial

Source: Smashing Magazine, Now Live: Your SmashingConf Toronto Playlist

Inspired Design Decisions: Ernest Journal

dreamt up by webguru in Uncategorized | Comments Off on Inspired Design Decisions: Ernest Journal

Inspired Design Decisions: Ernest Journal

Inspired Design Decisions: Ernest Journal

Andrew Clarke

When you work in design for any length of time, forming habits is natural. It’s not unusual to follow a predictable process or use familiar patterns. This repetition can be fabulous for your productivity, but when each design looks much like your last, you can quickly begin to feel jaded. Staying curious is the best remedy for that feeling.

After running a small studio for eighteen years, my fatigue had become overwhelming. I dreaded each and every new email notification and phone call. While client projects offered opportunities to be creative, they also depleted my energy reserves and any capacity I had to come up with ideas.

For someone whose business — and self-esteem — relies on what I dream up, this was devastating. I admitted to my wife that I was exhausted, had no more to give, and couldn’t carry on because the business we’d started together had become a burden. I needed to recharge, reconnect with my creativity, and rekindle my enthusiasm for working in design.

When a company in Sydney offered me an interim role, I didn’t hesitate. They seemed welcoming, work was interesting, and living in Australia was something I wanted to experience. More importantly, time away allowed me to explore aspects of design which were new to me, away from the crushing pressures I’d felt building up while running my business.

Working in Australia meant finding creative ways to sell the company’s products and services, as well as exploring new approaches to the design of the products themselves. I was curious about whether graphic design and visual storytelling could make a digital product more compelling.

As I’d studied Fine Art and not art direction or graphic design, I knew very little about its principles, famous names, or history. I was eager to learn, and with the pressure of running my business lifted, I had the energy and the time for studying. I started a magazine collection, studied books on art direction and graphic design, and discovered art directors, including Alexey Brodovitch, Neville Brody, Bea Feitler, and Tom Wolsey. Their work fascinated me, and I was curious why we see so little like it online.

This curiosity took me in unexpected directions, and my head was soon bursting with ideas. I learned how to combine images and text in more exciting ways from Alexey Brodovitch and Bea Feitler. I picked up tips on how to give my typographic designs more impact from Neville Brody, and Tom Wolsey taught me how to make even the smallest design element more interesting. I studied editorial and magazine layout principles, and instead of merely copying them, I found ways to adapt them for the web to make product and website layouts more compelling.

Time away helped me rediscover my enthusiasm for design. While falling into predictable patterns — in behaviour and design — is still tempting, since coming home, I’ve realised how important it is to stay curious, study other media, and keep my mind open to the lessons we can learn from them.

Ernest Journal magazine covers

Ernest Journal. (Large preview)

Curiosity keeps a creative mind open to new possibilities, and that’s what Ernest Journal magazine — the inspiration for this issue — is all about.

Andy Clarke
July 2019

  1. Inspired Design Decisions: Avaunt Magazine
  2. Inspired Design Decisions: Pressing Matters
  3. Inspired Design Decisions: Ernest Journal

 Andy Clarke reading Pressing Matters magazine

The design of Ernest Journal is simple, but not minimal. (Large preview)

Ernest Journal: Curiosity And Adventure

Despite its smaller format, on my latest visit to my favourite magazine shop, I was drawn to Ernest Journal. Ernest is “a journal for enquiring minds. It’s made for those who value surprising and meandering journeys, fuelled by curiosity rather than adrenaline, and guided by chance encounters.”

When you open Ernest Journal for the first time, you’re immediately drawn to its content, rather than its design. There are beautiful photographs and striking graphic designs which are often presented large enough to spread from one page to the next.

The design of Ernest Journal is simple, but not minimal. It gets maximum value from only a small number of assets, in particular, its dominant two typefaces, Freight Big Pro and Gill Sans Nova.

Ernest Journal magazine spreads

© Ernest Journal. (Large preview)

Freight Big Pro is a high contrast serif typeface by Joshua Darden — the founder of type foundry Darden Studio — who also designed Jubilat and Omnes, two fonts I use regularly. Freight Big Pro is a family of twelve styles and comes with a host of OpenType features including beautiful ligatures, a feature used by Ernest Journal for headlines and even its logotype. While Gill Sans has never been a particular favourite of mine, the designers of Ernest Journal put it to good use in contemporary looking headlines and other typographic details.

Ernest Journal’s layout consists mainly of two and three columns, but it’s their thoughtful use, which helps the overall design feel connected, despite the variety of content and styles in the magazine. I’ll teach you how to create varied yet connected designs later in this issue.

Ernest Journal is an excellent example of how to use colour and typography to create consistency across an entire publication. At the same time, by picking colours from graphics and photographs to use for headlines, pull-quotes, and other details, their designers connect this overall design to individual stories. This adds variety and makes the stories Ernest Journal tells even more engaging.

Magazine Anatomy

The not-so-snappily named Web Hypertext Application Technology Working Group (WHATWG) surveyed thousands of websites before settling on names for new elements including header and footer. Magazines have their own terminology for parts of a page which you can use to name product or website components:

Anatomy of a magazine page

Anatomy of a magazine page. (Large preview)
Running head <header> [role="banner"]
Folio <footer> [role="contentinfo"]
Headline <h1> .type-headline
Byline/credits <small> .type-credits
Standfirst (deck, intro, or kicker) <p> .type-standfirst
Lede <p> .type-lede
Image caption <figcaption>
Pull quote <blockquote>
Body copy <article>
Sub-head <hx>

Next time you’re passing a magazine store, drop in and look for a copy of Ernest Journal. It might be small, but you’ll find it packed with ideas to use on your next project.

Inspired By Ernest Journal

Many people blame frameworks including Bootstrap for the homogenous layouts we see all too often on the web, but the problem comes from our thinking, not the framework. The cold, hard truth is that Bootstrap doesn’t create unimaginative designs. Lazy designers do.

An unambitious design based on a framework grid

Bootstrap doesn’t create unimaginative designs. Lazy designers do. (Large preview)

The majority of Ernest Journal’s content is placed using a symmetrical grid which can easily be reproduced for the web using a framework’s twelve columns. Content is simply laid out using a mix of two and three columns. Yet unlike many websites built using a framework, Ernest Journal’s pages are exciting and varied. There’s no reason why frameworks can’t be used to create layouts as engaging as Ernest Journal. All it takes is an understanding of layout design and imagination.

Variety is a crucial part of the success of Ernest Journal’s design, and it’s a lesson we can apply to products and websites. Single columns have been used by book designers for generations and designs based on them look classical. Grids with two symmetrical columns feel orderly. They can hold a tremendous amount of content without becoming overwhelming. Combine white space with three or more columns and your designs immediately take on an editorial feel, reminiscent of a quality print publication, like Ernest Journal.

Designing With Frameworks

The original Fiat 500 was a tiny car which made a big impression on the motor industry. It was enormously popular and became the template for a generation of small cars. For this design about the rise of this iconic little car, I want to make a similarly big impression by filling a large panel with a headline and image. This panel occupies two-thirds the width of my page — eight of my twelve columns. The running text on the right occupies four columns, and its width is matched by the standfirst paragraph opposite, bringing this asymmetric composition into balance.

A design inspired by Ernest Journal

Panels like this one will have more impact when you allow them to bleed off the edges of the page. (Large preview)

By using a variety of connected but diverse layouts, you can make stories more engaging and keep readers interested. My next design is based on that same twelve column grid but looks completely different. Here, the large image occupies six columns, half the width, and the full height of my page. Text runs down two columns in the centre, and supporting information — including a timeline of Fiat 500 models — matches its width, even though I place it within a much wider panel.

A design inspired by Ernest Journal

I reinforce the distinction between content types by using a sans-serif typeface for supporting information. The box also has a different background colour to emphasise this difference. (Large preview)

Now, I know some of you will be wondering how to adapt designs like this to smaller screens. Proportionately narrow columns of text don’t make sense when space is limited, so I use the entire screen width. Instead of asking people to flick past a tall image, I place the Fiat 500 on its side within a horizontal scrolling panel.

A design inspired by Ernest Journal

It’s just as important to create a connected experience across screen sizes as it is across media. (Large preview)

Even when using just two or three symmetrical columns, you can create a surprising variety of layouts. So that your design feels connected and familiar across all its pages, develop a system for how to use those columns. You might use three columns for running text, giving your design an editorial feel, and twin-columns for images.

A design inspired by Ernest Journal

The placement of these images suggests movement in this otherwise highly structured composition. (Large preview)

Alternatively, use twin-columns of text for an orderly feeling and three columns for images. This increased repetition of shapes helps a composition to feel more dynamic.

A design inspired by Ernest Journal

If you have plenty of running text, twin-columns solidify it into blocks, giving your page visible structure. (Large preview)

Changing how you place images in three columns is a simple way to vary the look and feel of a design. My next design sets one large image across two-thirds of the page, and a small picture in the remaining third. But image proportions are not nearly as interesting as the position of the gutter between images, and how it offsets the gutter between running text columns below.

A design inspired by Ernest Journal

Negative and positive space are equally important. The margins around, and gutters between, this content help to lead someone’s eye to where they should start reading. (Large preview)

There’s still space on medium-size screens for an exciting juxtaposition of two and three columns. But what about small screens?

Twin-columns of running text would make no sense in such a narrow width, but you needn’t sacrifice the benefits of white space, even when it’s limited. For this small-screen design, I place images into a horizontally scrolling panel. Then, I use a narrow column to indent the running text.

A design inspired by Ernest Journal

There’s no need to fall back on predictable, single-column designs for small screens. Use your imagination and be experiment with ways to use positive and negative space. (Large preview)

Designing Connected Layouts

In the last issue, I introduced you to Swiss artist and typographer Karl Gerstner and the “mobile grid” he designed to lay out content in Capital magazine consistently and without restrictions. Those same principles apply when placing content inspired by Ernest Journal.

Example based on Karl Gerstner’s mobile grid

(Large preview)

A single module — filling the entire width of the page — slows people down and encourages them to linger on its content. It isn’t necessary to use every pixel, and I devote a quarter of this composition to white space to give this design a feeling of luxury.

Example based on Karl Gerstner’s mobile grid

(Large preview)

Something is reassuring about the structure of a twin-column layout, so for this design, I give equal space to these classic cars. To prevent this design from becoming predictable, I utilise extra columns for larger cars and use gutters to stagger the start of my headlines and paragraphs.

Example based on Karl Gerstner’s mobile grid

(Large preview)

It’s possible to pump energy into the structure of a symmetrical three-column design. For this next design, I use those three columns in two different ways, first with a top-down view of the Fiat 500, then a smaller module for each of the remaining cars.

Example based on Karl Gerstner’s mobile grid

(Large preview)

Designs which use odd numbers of columns and rows can be compelling, especially when arranged in a modular grid. This design demands attention not only because it‘s interesting visually, but also because it’s so different from other pages. It’s an excellent choice for interrupting the rhythm of reading to make someone focus on a particular piece of content.

Controlling Reading Rhythm

The pace in which someone moves through a product or website is an essential factor in their experience. This principle is as useful on a mobile’s smaller screen as it is on a larger one.


Controlling reading rhythm

Larger modules which fill a small screen make an immediate impact and give someone time to pause. (Large preview)


Controlling reading rhythm

Two evenly sized modules feel balanced as the pace starts to pick up. (Large preview)


Controlling reading rhythm

Three smaller modules speed up the pace, even though they contain more content than before. (Large preview)


Controlling reading rhythm

Small modules encourage people to glance briefly at your content before making a choice about which direction to take. (Large preview)


Controlling reading rhythm

With five modules visible, people can race through your content. (Large preview)


Controlling reading rhythm

A large number of tiny modules is the fastest yet and is ideal for mobile navigation. (Large preview)

Creating Connections

One of the most attractive features of Ernest Journal, and a technique you can quickly adapt to the websites you design is using an accent colour picked from images. You can use accents for headlines, pull quotes, and other typographic and details to connect them with graphics and photographs.

Choose which elements to apply this accent colour and then style them throughout your website to create continuity. Use just one accent — or tints of that colour — per article to give each its own distinctive style.

Creating connections

Pick an accent colour from a graphic and use it on typographic and other details to connect them to your image. (Large preview)

On this first article, I pick a dark pink from the lights on the Fiat 500 and use it for my headline, standfirst, and dates in my timeline. For the second article, I sample a warm light brown from the suitcase in a photograph of another Fiat 500. There are plenty of tools available online to help you sample colours from images, but my favourite is still Adobe Color.

Creating connections

Sample accent colours from dominant areas in photographs using a tool like Adobe Color to help you. (Large preview)

Using large blocks of colour can help you distinguish between content types, and choosing the same colour for panel backgrounds and typographic elements such as drop caps will maintain a subtle connection between them.

I use a warm dark brown for my drop cap, headline, and pull quote, and in the background of the panel which dominates these pages. The yellow outlines in the illustration, borders, and titles in the timeline is a colour I use to connect multiple pages.

For the second page, I also use the same light brown as before to create a palette of colours and consistency across all my designs.

Creating connections

Remember accessibility when you reduce the contrast between background and foreground colours. Lea Verou’s Contrast Ratio is the tool I use most often. (Large preview)

Foundation Styles

Colours help create a signature style that can make a design memorable. Colour connects content to a brand, creates connections between images and text. They define the personality of a product or website, and ultimately an entire company, so it’s crucial to develop a suite of colours to use throughout your designs.

But colour isn’t the only aspect of a design which can help maintain that all-important consistency. You can create signature typographic elements, including block quotes, dates, and drop caps, as well as border styles, and image treatments which repeat across pages.

With these styles forming the foundation to your design, you’ll then be free to use colour and type variations to give each article its own unique look.

Creating connections

Colour isn’t the only aspect of a design which helps maintain that consistency, so create signature typographic elements, border styles, and image treatments too. (Large preview)

In this design, a background colour covers the entire page. Simply changing that colour between articles, while maintaining layout and typography styles, adds variety and creates a series of pages which, while different, feel like they belong together.

Creating connections

Combine changes in colour and pace to make different content types clear to your readers. (Large preview)

Using a tool like Adobe Color, experiment with analogous and complementary colours. Creating a colour family sampled from graphics and photographs, and using them in several combinations, is a simple way to create a variety of designs for sections across your website.

Creating connections

Combine colours in different and interesting ways to add variety while maintaining a unified look and feel. (Large preview)

Ernest Journal’s design is successful because although each article has its own distinctive elements which connect the visual style with the content, those articles use a consistent grid system and foundation styles. This consistency helps Ernest Journal feel like a unified whole and not a collection of separate pieces.

NB: Smashing members have access to a beautifully designed PDF of Andy’s Inspired Design Decisions magazine and full code examples from this article.

  1. Inspired Design Decisions: Avaunt Magazine
  2. Inspired Design Decisions: Pressing Matters
  3. Inspired Design Decisions: Ernest Journal
Smashing Editorial
(ra, yk, il)

Source: Smashing Magazine, Inspired Design Decisions: Ernest Journal

Building Mobile Apps With Ionic And React

dreamt up by webguru in Uncategorized | Comments Off on Building Mobile Apps With Ionic And React

Building Mobile Apps With Ionic And React

Building Mobile Apps With Ionic And React

Ahmed Bouchefra

Ionic has recently added support for React; so now, React developers can get the advantages of Ionic to build hybrid mobile apps and progressive web apps (PWAs). In this post, we’ll show you how to get started using Ionic with React by building a simple demo app from scratch.


In order to properly follow this tutorial, you’ll need the following prerequisites:

  • recent versions of Node.js and npm installed on your system,
  • working knowledge of TypeScript and React.

You can check that you have the latest Node.js version (v10) installed by running the following command:

$ node -v

Introducing React And Ionic

Let’s start with brief introductions to both React and Ionic.

According to the official website:

“React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called ‘components’.”

React focuses on building UIs and doesn’t provide any built-in tools for the common tasks required in web development, such as fetching remote data and routing, so you’ll need to use some existing third-party libraries for these tasks.

According to the Ionic website:

“Ionic Framework is the free, open-source mobile UI toolkit for developing high-quality cross-platform apps for native iOS, Android, and the web — all from a single codebase.”

Basically, it’s a set of UI components that you can use with plain JavaScript or any popular front-end framework or library, such as Angular, React or Vue, to build a hybrid mobile app and PWA.

In this tutorial, we’ll see and use some Ionic UI components such as the following:

  • IonMenu: With this, a navigation drawer will slide in from the side of the current view.
  • IonToolbar: These top bars are positioned above or below the content.
  • IonHeader: This parent component holds the toolbar component.
  • IonContent: This component provides a content area, with methods to control the scrollable area and other things. You need only one content component inside a single view.
  • IonList: This component contains items with similar data content, such as images and text. It’s made up of IonItem objects.
  • IonItem: This component may contain text, icons, avatars, images, inputs and any other native or custom element.
  • IonButton: This component provides a clickable element, which can be used in a form or anywhere that needs simple, standard button functionality.

Installing Ionic CLI v5

Ionic’s command line interface (CLI), version 5, has support for creating Ionic projects based on React. So, let’s get started by installing the tool from npm.

Open a CLI, and run the following command:

$ npm install -g ionic

At the time of writing, Ionic’s CLI v5.2.3 is the latest.

Note: *According to how you installed Node.js in your system, you may need to add sudo before your command in macOS or Linux or run the command prompt as administrator in Windows if you get any permission errors. You can also simply fix your npm permissions or use a tool such as nvm.*

Next, install Cordova Resources (which is used to generate Cordova resources locally) and Native Run (used to deploy app binaries to devices):

$ npm install -g cordova-res native-run

These are required only if you want to test your application on a real mobile device or emulator.

Creating An Ionic And React Project

Now, let’s create a project based on React. Go back to your terminal, make sure you are in your working directory, and run the following command:

$ ionic start myApp --type=react

We use --type=react to generate a project based on React. You’ll next need to choose a starter template from the available ones. Let’s pick sidemenu for a starter template with a side menu and navigation.

After generating the project and installing the dependencies, you can serve your app locally using the following commands:

$ cd ./myApp
$ ionic serve

Your app will be available from the http://localhost:8100 address, and you can actually use your web browser to start playing with it.

Ionic is called a hybrid mobile framework because it makes use of web technologies that were originally designed to create web apps, along with a native container (Cordova or Capacitor), to build mobile apps without using native technologies for the target platforms, such as Java or Kotlin for Android or Swift for iOS.

Because your mobile app is actually a web application, you can do most development by testing in a web browser without using an emulator or a real mobile device, except for testing native device features such as the camera or the SQLite storage, in case you’ve used them in your app. In fact, it’s even possible to use certain techniques to mimic the plugins that provide the native features and do the entire testing during development in your web browser.

Cleaning Our Project

We have the app’s basic structure, with two pages (home and list) and a menu. Let’s remove the list page since it’s just boilerplate code.

First, remove the src/pages/List.tsx file, then open the src/App.tsx file, and remove the entry for the list page from the appPages array:

const appPages: AppPage[] = [
    title: 'Home',
    url: '/home',
    icon: home

Also, remove the import of the list page from the file:

import  List  from  './pages/List';

Next, remove <Route path="/:tab(home)/list" component={List} exact={true} /> from the App component:

const App: React.FunctionComponent = () => (
      <IonSplitPane contentId="main">
        <Menu appPages={appPages} />
        <IonPage id="main">
            <Route path="/:tab(home)" component={Home} exact={true} />
            <Route exact path="/" render={() => <Redirect to="/home" />} />

export default App;

The App component is the root component that gets rendered by our application. If you open the src/index.tsx file, you’ll find the following code:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

The render() method is used to render a React element into the DOM in the supplied root element.

Theming The App

Having created, served and cleaned our Ionic project, let’s now see how we can change the colors of the UI so that it looks more professional.

Let’s get started with the side menu. Open the src/components/Menu.tsx file, and add a color attribute with a primary value to the IonToolbar, IonContent, IonList and IonItem UI components:

const Menu: React.FunctionComponent = ({ appPages }) => (
  <IonMenu contentId="main">
      <IonToolbar color="primary">
    <IonContent color="primary">
      <IonList style= {{ background : '#3880ff'}} color="primary">
        {, index) => {
          return (
            <IonMenuToggle key={index} auto-hide="false">
              <IonItem color="primary" href={appPage.url}>
                <IonIcon slot="start" icon={appPage.icon} />

Ionic provides some default colors (primary, secondary, tertiary, success, warning, danger, light, medium and dark) that can be used to change the color of UI components. A color can be applied to an Ionic component in order to change the default colors using the color attribute. See “Colors” for more information.

These colors have default values, but you can customize them via some predefined CSS variables. See “Modifying Colors“.

This is a screenshot of our menu:

Ionic menu
Ionic menu. (Large preview)

Next, let’s change the color of the Home page. Open the src/pages/Home.tsx file, and set the color attribute of the IonToolbar and IonContent components to primary:

const HomePage: React.FunctionComponent = () => {
  return (
        <IonToolbar color="primary">
          <IonButtons slot="start">
            <IonMenuButton />
      <IonContent color="primary" >


This is a screenshot of the page:

Ionic home
Ionic home. (Large preview)

Installing Axios And Consuming A REST API

We’ll see how to install Axios and consume a third-party RESTful API in our application, and we’ll also see how to display the fetched data using Ionic card and list components.

Having themed our application, let’s now see how to fetch data using Axios. We’ll use the third-party API available from

First, we need to grab an API key, so that we can communicate with the API. Go to the registration page, enter your information, and register an account. You’ll be given an API key; note it, and let’s continue.

Head back to your terminal, and run the following command to install Axios:

$ npm install axios --save

Next, open the src/pages/Home.tsx file, and start by importing Axios and IonButton:

import {
} from '@ionic/react';

import axios from 'axios';

Next, define the API_KEY and URL constant variables:

const  API_KEY  =  "<YOUR_API_KEY_HERE>";
const  URL  =  `${API_KEY}`;

In the URL variable, we’ll add an endpoint to get the top headlines from our source, TechCrunch. You can use any source you want from the available sources.

Note: Make sure to put your own API key in the API_KEY variable.

Next, define the fetchArticles() method as follows:

const fetchArticles = () => {

  return axios({
    url: URL,
    method: 'get'
  }).then(response => {


We simply call the axios() method to send a GET request to the news endpoint, and the result from the method is a promise that needs to be resolved in order to get the news data.

Next, update the HomePage component as follows to call the fetchArticles() method and resolve the returned promise:

const HomePage: React.FunctionComponent = () => {

  const [articles, setArticles] = React.useState([]);
  const items: any[] = [];

  React.useEffect(() => {

    fetchArticles().then(data => setArticles(data.articles));

  }, []);

  return (
        <IonToolbar color="primary">
          <IonButtons slot="start">
            <IonMenuButton />
      <IonContent color="primary" >
        <IonList color="primary">

   => {

              return (
                  <IonButton href={a['url']} color="primary" slot="end">Read</IonButton>


In our function component, we first call the useState() hook of React to create the articles state variable, which will hold the news articles after we fetch them from the API.

useState() returns the state variable, which has the empty array as its initial value and a function that we can use to change the value of the variable. We use destructuring assignment to unpack the values from the returned pair into distinct variables (i.e. articles and setArticles()).

Next, we call the useEffect() hook to perform a side effect in our component. In our case, the side effect is to fetch data from the news API using the fetchArticles() method, which returns a promise. Once the promise is resolved, we call the setArticles() method to assign the news data to the articles variable.

Both useState() and useEffect() are built-in React hooks that were introduced in React 16.8; they simply let you use state and other React features without having to write a class. The useEffect() hook is equivalent to calling the componentDidMount, componentDidUpdate and componentWillUnmount lifecycle methods combined in class-based components.

Finally, in the view template, we iterate over the articles array using the map() method, and we display the title of each news article inside an IonItem element of the IonList component, and also a button that takes us to the page of the full article.

This is a screenshot of the page:

Ionic news app
Ionic news app (Large preview)

You can find the source code in this GitHub repository.


In this tutorial, we have started using both Ionic and React and used them to build a simple mobile application that fetches and displays news data from a third-party API using the Axios client. We have also seen how to use hooks in React — namely, the useState() and useEffect() hooks — to create state and perform side effects inside React function components. With Ionic, we’ve seen how easy it is to generate a project based on React and how we can theme the application using the color attributes of components.

Smashing Editorial
(dm, al, yk, ra, il)

Source: Smashing Magazine, Building Mobile Apps With Ionic And React

Writing Modes And CSS Layout

dreamt up by webguru in Uncategorized | Comments Off on Writing Modes And CSS Layout

Writing Modes And CSS Layout

Writing Modes And CSS Layout

Rachel Andrew

In this article I am going to take a look at the CSS writing-mode property. However this is not an article about the practical or creative application of this property. Instead, I want to demonstrate why understanding writing modes is so important, even to those of us who rarely need to change the writing mode of a page or component. The support of multiple writing modes is key to the way that our new layout methods of Flexbox and Grid Layout have been designed. Understanding this can unlock a better understanding of how these layout methods work.

What Are Writing Modes?

The writing mode of a document or a component refers to the direction that text flows. In CSS, to work with writing modes we use the writing-mode property. This property can take the following values:

  • horizontal-tb
  • vertical-rl
  • vertical-lr
  • sideways-rl
  • sideways-lr

If you are reading this article on Smashing Magazine in English then the writing mode of this document is horizontal-tb, or Horizontal Top To Bottom. In English sentences are written horizontally, the first letter of each line starting on the left.

A language such as Arabic also has a horizontal-tb writing mode. It is written horizontally, top to bottom, however Arabic script is written right to left, and so sentences in Arabic start on the right.

Chinese, Japanese and Korean are written vertically, with the first character of the first sentence being top right. Following sentences being added to the left. Therefore the writing mode used is vertical-rl. A vertical writing mode running from right to left.

Mongolian is also written vertically, but from left to right. Therefore, should you want to typeset Mongolian script you would use the writing mode vertical-lr.

The other two values of writing-mode are designed more for creative purposes than for typesetting vertical scripts. Using sideways-lr and sideways-rl turns text sideways – even characters normally written vertically and upright. The values unfortunately are only supported in Firefox at the moment. The following CodePen shows all of the different values of writing-mode, you will need to use Firefox if you want to see the sideways-* ones in action.

See the Pen [Writing Mode demo]( by Rachel Andrew.

See the Pen Writing Mode demo by Rachel Andrew.

Writing Modes can be used when creating a document that uses a language written using that writing mode. They can also be used creatively, for example to set a heading vertically down the side of some content. In this article however, I want to take a look at the impact that supporting vertical languages, and the possibility of vertical text, has on CSS layout, and across CSS in general.

Before I do so, if you are interested in the use of writing modes for vertical text, here are some useful resources.

The Block And Inline Dimensions

When we change the writing mode of a document, what we are doing is switching the direction of the block flow. Therefore it quickly becomes very useful for us to understand what is meant by block and inline.

One of the first things we learn about CSS is that some elements are block elements, for example a paragraph. These elements display one after the other in the block direction. Inline elements, such as a word in a sentence display one after the other in the inline direction. Working in a horizontal writing mode, we become used to the fact that the block dimension runs top to bottom vertically, and the inline dimension left to right horizontally.

As block and inline elements relate to the writing mode of our document however, the inline dimension is horizontal only if we are in a horizontal writing mode. It doesn’t relate to width, but instead to inline size. The block dimension is only vertical when in a horizontal writing mode. Therefore it doesn’t relate to height, but to block size.

Logical, Flow-relative Properties

These terms, inline size and block size are also used as the names of new CSS properties designed to reflect our new writing mode aware world. If, in a horizontal writing mode you use the property inline-size instead of width, it will act in exactly the same way as width – until you switch the writing mode of your component. If you use width that will always be a physical dimension, it will always be the size of the component horizontally. If you use inline-size, that will be the size in the inline dimension, as the below example shows.

See the Pen [width vs. inline-size]( by Rachel Andrew.

See the Pen width vs. inline-size by Rachel Andrew.

The same is true for height. The height property will always be the size vertically. It relates to how tall the item is. The block-size property however gives the size in the block dimension, vertically if we are in a horizontal writing mode and horizontal in a vertical one.

As I described in my article “Understanding Logical Properties And Values”, there are mappings for all of the physical properties, those which are tied to the dimensions of the screen. Once you start to think about it, so much of CSS is specified in relation to the physical layout of a screen. We set positioning, margins, padding and borders using top, right, bottom, and left. We float things left and right. Sometimes tying things to the physical dimension will be what we want, however increasingly we are thinking about our layouts without reference to physical location. The Logical Properties and Values specification rolls out this writing mode agnostic way of working right across CSS.

Writing Modes, Grid and Flexbox

When our new layout methods landed on the scene, they brought with them an agnostic way of looking at the writing mode of the component being laid out as a flex or grid layout. For the first time people were being asked to think about start and end, rather than left and right, top and bottom.

When I first started to present on the subject of CSS Grid, my early presentations were a rundown of all of the properties in the specification. I mentioned that the grid-area property could be used to set all four lines to place a grid item. The order of those lines was not however the familiar top, right, bottom and left we use to set all four margins. Instead, we need to use top, left, bottom, right – the reverse of that order! Until I understood the connection between grid and writing modes, this seemed a very odd decision. I came to realise that what we are doing is setting both start lines, then both end lines. Using top, right, bottom and left would work fine if we were in a horizontal writing mode, turn the grid on its side however and that makes no sense. If we use grid-area: 1 / 2 / 3 / 5; as in the pen below the lines are set as follows:

  • grid-row-start: 1; – block start
  • grid-column-start: 2 – inline start
  • grid-row-end: 3 – block end
  • grid-column-end: 5 – inline end

See the Pen [grid-area]( by Rachel Andrew.

See the Pen grid-area by Rachel Andrew.

Flexbox Rows And Columns

If you use flexbox, and add display: flex to a container, your items will display as a row as the intial value of the flex-direction property is row. A row will follow the inline dimension of the writing mode in use. Therefore if your writing mode is horizontal-tb a row runs horizontally. If the text direction of the current script is left to right then items will line up starting from the left, if it is right to left they will line up starting on the right.

Use a vertical writing mode however, such as vertical-rl and flex-direction: row will cause the items to lay out vertically, as the inline direction is vertical. In this next CodePen all of the examples have flex-direction: row, only the writing mode or direction has changed.

See the Pen [flex-direction: row]( by Rachel Andrew.

See the Pen flex-direction: row by Rachel Andrew.

Add flex-direction: column, and the items layout in the block dimension of your writing mode. In a horizontal writing mode the block dimension is top to bottom, so a column is vertical. With a writing mode of vertical-rl a column is horizontal. As with the previous example, the only difference between the below flex layouts, is the writing mode being used.

See the Pen [flex-direction: column]( by Rachel Andrew.

See the Pen flex-direction: column by Rachel Andrew.

Grid Auto-placement

When using auto-placement in grid, you will see similar behavior to that in flex layout. Grid items auto-place according to the writing mode of the document. The default is to place items in rows, which will be the inline direction – horizontally in a horizontal writing mode and vertically in a vertical one.

See the Pen [Grid auto-placement row]( by Rachel Andrew.

See the Pen Grid auto-placement row by Rachel Andrew.

Try changing the flow of items to column as in the example below. The items will now flow in the block dimension – vertically in a horizontal writing mode and horizontally in a vertical one.

See the Pen [Grid auto-placement column]( by Rachel Andrew.

See the Pen Grid auto-placement column by Rachel Andrew.

Grid Line-placed Placement

Line-based placement also respects writing mode. The lines of our grid start at 1, both for rows and columns. If we position an item from column line 1 to column line 3, and are in a horizontal writing mode with a left to right direction, that item will stretch from the left-most column line across two grid tracks horizontally. Thus spanning two columns.

Change the writing mode to vertical-rl and column line 1 will be at the top of the grid, the item spanning two tracks vertically. Still spanning two columns, but the columns are now running horizontally.

See the Pen [Margins: adjacent siblings]( by Rachel Andrew.

See the Pen Margins: adjacent siblings by Rachel Andrew.

Alignment In Grid And Flexbox

One of the first places many people will have come into contact with the way Flexbox dealt with writing modes, would be when aligning items in a flex layout. If we take the flex-direction: row example above, and use the justify-content property to align all of the items to flex-end the items move to the end of their row. This means that in a horizontal writing mode with left to right direct the items all move to the right, as the end of that row is on the right. If the direction is right to left they all move to the left.

In the vertical writing mode they move to the bottom, assuming there is space for them to do so. I have set an inline-size on the components in this example to ensure that we have spare space in our flex containers to see the alignment in action.

Alignment is a little easier to understand in grid layout, as we always have the two axes to play with. Grid is two-dimensional, those two dimensions are block and inline. Therefore, you can remember one rule if you want to know whether to use the properties that begin with align- or those which begin with justify-. In grid layout the align- properties:- align-content, align-items, align-self are used to do block axis alignment. In a horizontal writing mode that means vertically, and in a vertical writing mode horizontally.

Once again we don’t use left and right or top and bottom, as we want our grid layout to work in exactly the same way no matter what the writing mode. So we align using start and end. If we align to start on the block dimension, that will be top when in horizontal-tb, but will be right when in vertical-rl. Take a look in the example below, the alignment values are identical in both grids, the only difference is the writing mode used.

See the Pen [Margins: adjacent siblings]( by Rachel Andrew.

See the Pen Margins: adjacent siblings by Rachel Andrew.

The properties justify-content, justify-items,justify-self are always used for inline alignment in grid layout. That will be horizontal in a horizontal writing mode and vertical in a vertical writing mode.

See the Pen [Margins: adjacent siblings]( by Rachel Andrew.

See the Pen Margins: adjacent siblings by Rachel Andrew.

Flexbox alignment is complicated somewhat by the fact that the main axis can be switched from row to column. Therefore in flexbox we need to think about the alignment method as main axis versus cross axis. The align- properties are used on the cross axis. On the main axis all you have is justify-content due to the fact that in flexbox we deal with items as a group. On the cross axis you can use align-content in cases where you have multiple flex lines AND space in the flex container to space them out. You can also use align-items and align-self to move the flex items on the cross axis in relationship to each other and their flex line.

See the Pen [Flexbox alignment]( by Rachel Andrew.

See the Pen Flexbox alignment by Rachel Andrew.

For more on alignment in CSS layout see my previous Smashing Magazine articles:

Writing Mode Awareness And Older CSS

Not all of CSS has fully caught up with this flow-relative, writing mode agnostic way of working. The places where it has not start to stand out as unusual the more you think of things in terms of block and inline, start and end. For example in multi-column layout we specify column-width, which really means column inline-size, as it isn’t mapped to the physical width when working in a vertical writing mode.

See the Pen [Multicol and writing-mode]( by Rachel Andrew.

See the Pen Multicol and writing-mode by Rachel Andrew.

As you can see, writing modes underpin much of what we do in CSS, even if we never use a writing mode other than horizontal-tb.

I find it incredibly helpful to think about CSS layout in this writing mode agnostic way. While it is perhaps a little early to be switching all of our properties and values to logical ones, we are already in a flow-relative world when dealing with new layout methods. Having your mental model be one of block and inline, start and end, rather than tied to the four corners of your screen, clarifies many of the things we come across when using flexbox and grid.

Smashing Editorial

Source: Smashing Magazine, Writing Modes And CSS Layout

Which Is Best: A Loyalty Program PWA or Mobile App?

dreamt up by webguru in Uncategorized | Comments Off on Which Is Best: A Loyalty Program PWA or Mobile App?

Which Is Best: A Loyalty Program PWA or Mobile App?

Which Is Best: A Loyalty Program PWA or Mobile App?

Suzanne Scacca

Customer loyalty is a critical component in the success of any business. In some cases, loyalty can be earned by providing a high-quality service and dedicated support. In other cases, customers expect more from a business than just the products or services they put before them.

So, don’t be surprised when clients ask you to design a loyalty app for them.

Loyalty programs are a great way to dish out rewards to the most loyal base of customers while also giving them a reason to stay engaged with a brand. This isn’t superficial engagement like views or clicks either. If the rewards are valuable enough, customers will stay committed to a business for longer (even when faced with a negative experience) and also spend more money than one-time customers.

There’s a lot of value in creating a loyalty program. Now, it’s up to you to determine the best way to design it for your clients:

Should it be a PWA or mobile app?

Why Is Mobile The Key To Loyalty?

Using the 2018 Loyalty Program Consumer Survey from CodeBroker, let’s shed some light on why mobile is where you need to design your clients’ loyalty apps.

To start, there are a number of businesses that would benefit from loyalty programs. For example:

  • Retailers
  • e-Commerce
  • Restaurants
  • Hotels
  • Airlines and other travel providers
  • Credit card companies

With many of these options, there’s an in-person component at play, which is why it’s important to give users access to their loyalty program and rewards on mobile.

But be careful. Of the top concerns expressed by CodeBroker’s survey respondents, 54% said it was too difficult to access rewards information from their mobile devices.

CodeBroker survey stat

CodeBroker’s 2018 Loyal Consumer Survey and report. (Source: CodeBroker) (Large preview)

What’s more, many consumers were frustrated with having to install a mobile app in order to get rewards updates. And, yet, 75% indicated they’d be more likely to sign up for a rewards program if it were convenient to use from their mobile device.

Now, the main gripe from this report is that consumers want communications about rewards points and other program details sent via text and email. They don’t want to have to log into a mobile app to get them.

It’s a valid argument to make. If a brand were proactive in emailing Jane Doe to say, “Hey! You have 2,500 points to use by the end of the month!”, that would be a much better experience than Jane Doe having to take the initiative to check on her points standing.

However, this ignores the fact that customer loyalty is more than just the act of counting how many points one has to spend.

True customer loyalty comes about when brands can anticipate their customers’ needs and provide a more personalized, fast and convenient experience.

Which is why we have to look beyond mobile communications and look at how to actually design the program’s experience for mobile.

Designing Loyalty Programs For Mobile

While mobile apps and PWAs can both provide a good experience, consumers have already expressed a disinterest in installing mobile apps to manage their loyalty programs. That said, I don’t think it’s fair to throw native mobile apps out of the race solely based on that feedback. If you make a mobile app worthwhile, consumers will use it.

Plus, PWAs can work offline… but will only display cached content. Which means that customers who want to use their loyalty app to place orders on the go, pay in store from their app or do something else when they’re out of service range won’t be able to do so with a PWA.

That’s why I’m going to argue that you should design your loyalty program as a PWA only if there’s no in-person counterpart. So, basically, e-commerce companies can skip the mobile app. Those in the credit card space might be able to get away with it, too, though security will need to be extra tight.

Everyone else, will need to build a mobile app. And, based on what I’m seeing, you should create a matching PWA, too.

For example, this is the Starbucks rewards app as a PWA:

Starbucks rewards PWA

The home page of the Starbucks rewards PWA. (Source: Starbucks) (Large preview)

And this is the Starbucks loyalty program as a mobile app:

Starbucks loyalty mobile app

The home screen of the Starbucks loyalty mobile app. (Source: Starbucks) (Large preview)

There are a number of discrepancies between the two, but, for the most part, it’s an identical experience. I’d even argue that the PWA looks a lot cleaner and more welcoming to users. However, the mobile app is necessary for customers that want to order while they’re on the road or to pay from their phone at the counter or drive-through.

With that out of the way, I’d like to quickly review some strategies for designing loyalty program apps for your mobile users. I’ll use both PWAs and native apps in these examples, just so you can see that there isn’t a whole lot of difference in how you design them:

1. Ask Your Users for More Than a Username and Password

Unlike something like an email subscription form or a free SaaS signup, you should be collecting more than just a username and password from your users. And they should be happy to give it to you.

It’s up to you to decide where and when it’s best to ask for this information though:

Do you want to ask for it on the login screen? Or do you want them to provide personal details and preferences later on?

Let’s look at how The North Face’s VIPeak program handles it:

VIPeak rewards signup

The North Face’s VIPeak rewards signup form. (Source: The North Face) (Large preview)

This signup screen asks for four things:

  • First Name
  • Last Name
  • Email
  • Password

It’s a couple extra fields to fill in, but I don’t think many customers will take issue with it. Plus, signing up doesn’t just let them start collecting rewards immediately. They automatically get 10% off their first purchase from the website.

Now, what I like about how this one is handled is that users aren’t pestered with extra questions at signup. Instead, they have the ability to customize what sort of promotions they receive at a time when it’s more convenient for them.

The North Face email preferences

The North Face asks loyalty members what kinds of interests they want offers for. (Source: The North Face) (Large preview)

This is just one way to make the signup process go more smoothly on mobile. You can use this post-signup customization for more than just email preferences, too. You can plant a number of additional fields or questions in their account settings.

For instance, you could ask for their mailing address if the loyalty app also does order-and-delivery services. Or if you want to go old school with your marketing and send them a mailer.

You could also ask for their birthday. This would work in your favor two-fold. First, a birthday discount or free gift offer is a great way to re-engage a user who’s potentially lost interest or forgotten about the brand. Plus, everyone loves a birthday gift, so that “free” bonus would be useful in holding onto their loyalty.

2. Always Lead with Points

There’s a reason why the CodeBroker report focuses heavily on the points aspect of loyalty programs.

Even if the brand offers other rewards with memberships, customers first and foremost want to know how much “free” money they have to play with.

So, when you design your loyalty PWA or mobile app, don’t be coy with that data. Put it front and center.

This is the Chick-fil-A One app:

Chick-fil-A One points counter

The Chick-fil-A One app displays the total points available to redeem. (Source: Chick-fil-A One) (Large preview)

As you can see, the main focus in the “Rewards” tab is on how many points are available to redeem.

This is a good idea for two reasons:

  1. If someone comes to the app wanting to spend their points, there’s no need to hunt them down. This makes the experience better for them and speeds up the time to conversion.
  2. If someone comes to the app to do something else, that big red number might be enough to get them thinking, “Hmmm… maybe I should deal with those points while I’m here.”

Either way, the prioritization of points available gives them a reason to re-engage and spend.

Plus, it’s really easy to redeem available points.

If users click the “Redeem my points” button under their points counter or they click on the “Redeem” tab at the top, they’ll be taken to this page:

Chick-fil-A Redeem

Chick-fil-A One makes it easy to see what you can buy with points earned. (Source: Chick-fil-A One) (Large preview)

Items that are unavailable (based on the user’s point total) will be greyed out. The ones they do have enough points to spend on will appear in full color.

It’s a smart design strategy as it simplifies the redemption process while also motivating users to open their wallets and spent a little more to get the items they can’t afford with points just yet.

3. Motivate Them to Spend More By Using FOMO

Feature comparison tables aren’t just a great way to upsell product tiers to customers. You can use them to communicate the value of spending more money through a loyalty program.

Sephora’s Beauty Insider program uses this technique:

Sephora points explainer

Sephora briefly explains how much points can be earned in its loyalty program. (Source: Sephora) (Large preview)

First, it simply explains that users earn 1 point for every $1.00 spent. But the comparison table below reveals that there’s more to the program than that:

Sephora points comparison table

Sephora’s points comparison table helps convince loyalty members to spend more. (Source: Sephora) (Large preview)

As Beauty Insider members reach certain spending tiers, even more benefits become available. For instance, after they’ve spent their first $350, they’ll start getting 1.25 points for every $1.00 spent. New rewards become available, too, like full-size beauty product samples and celebration gifts.

If you want to motivate users to install your loyalty app and keep spending money through it, clearly show them what they’re missing.

4. Simplify Future Purchases

The whole point in creating a loyalty program is to retain a customer’s business for the long run. To do that, you have to find ways to make them buy again and again.

Now, a lot of that rests on your client’s shoulders as they’re the ones who will shape the offers that entice them back to the app. However, you have a part to play as well.

Let’s use World of Hyatt to demonstrate how you might do this.

World of Hyatt points counter

The Account tab in World of Hyatt shows points accumulation. (Source: World of Hyatt) (Large preview)

This is Hyatt Hotels’ loyalty program app. Users can view points accumulation, manage account preferences and book new hotel stays.

Users can also quickly rebook previous reservations:

World of Hyatt Rebook feature

World of Hyatt includes a quick Rebook feature for repeat stays. (Source: World of Hyatt) (Large preview)

And if that isn’t helpful enough, users can set custom room preferences from their account settings:

World of Hyatt room settings

World of Hyatt lets users define room settings for more personalized search results. (Source: World of Hyatt) (Large preview)

This way, the World of Hyatt app won’t waste their time showing rooms that don’t fit their ideal specifications as they try to book something new.

While the simplification of preferences and setting up repeat or recurring purchases will look differently from app to app, it’s an important feature to build in whenever you can. If you can show your users that you understand how tedious it is to enter the same details every time or to repeat a process even though nothing has changed, they’ll be more likely to return.


There’s one other thing I want to add here and it’s this:

When your client asks you to build a loyalty app, make sure it’s the right thing to do. Because if their business is new and they have absolutely no brand name recognition or long-term trust to leverage, it might be difficult to get people to subscribe to the program. No matter how beautifully you design the app experience.

And because loyalty members want access to their rewards on mobile, that’s going to leave you with two costlier choices than a website.

It might be best to explain the risks of creating a loyalty program without a huge demand for one. And, instead, recommend creating on-site promotions and offers they can share through email to start.

Then, when they’re ready, you can sit down with them and explain how a PWA or mobile app loyalty program will help them attract a better quality of customer and hold onto them for longer.

Smashing Editorial
(yk, ra)

Source: Smashing Magazine, Which Is Best: A Loyalty Program PWA or Mobile App?

Making Peace With The Feast Or Famine Of Freelancing

dreamt up by webguru in Uncategorized | Comments Off on Making Peace With The Feast Or Famine Of Freelancing

Making Peace With The Feast Or Famine Of Freelancing

Making Peace With The Feast Or Famine Of Freelancing

Liz Elcoate

It’s embarrassing to admit — particularly as I host a podcast about this very subject — but I dramatically dropped the ball when it came to booking in projects for this past spring. It just suddenly happened. I was finishing up two major contracts and had the next one in the pipeline. Then out of the blue that client postponed indefinitely and my two big contracts finished and I was left with no work — nothing, zip, zilch.

I’ve been here before for a week or two at a time so the panic didn’t kick in immediately. A week passed and I caught up on a few things and wrote a bit. I updated my portfolio and recorded some podcast episodes. When week two rolled around with no enquiries I put out a lazy tweet saying I was looking for work at the same time as contacting some previous clients and colleagues to see if they had anything that they might need me on. Still nothing. Then week three and week four came and went rapidly and by the end of the first month I was feeling physically ill with panic and worry.

The Panic

The worry wasn’t just financial – financially I was okay for a little while – it was also centred around what this lack of work said about my abilities and my worth.

By the beginning of month two I’d stopped sleeping. I was round robin-ing friends and colleagues in wild eyed desperation hoping that they might miraculously have an answer for me. I felt isolated and scared. I was also scattergun-ing job advertisements for anything — full time, contract, part time, freelance — something that would end the worry. And that was the strangest thing of all. The worry wasn’t just financial — financially I was okay for a little while — it was also centred around what this lack of work said about my abilities and my worth.

I just kept wondering why this had happened. I blamed Brexit, the patriarchy, my sex, my age, but more than anything I blamed myself and my obvious huge lack of talent. Why hadn’t I realised it before, why had no one else realised it before?

The Shame

While this inner turmoil was going on I was maintaining an aura of calm to the outside world as I didn’t want anyone to realise I had spectacularly failed. I didn’t want anyone to know how I’d gone from being a relatively successful designer — who’d worked on some brilliant projects with some brilliant people, who wrote about brand design, who hosted a successful podcast, who got asked to speak regularly on the subject of design — to being found out as a talentless fake. I can’t put into words how isolating this was. Feeling it was impossible to be honest about the position I was in to the majority of the people I cared about. I think a few people guessed and I was honest with others close to me but I was in a downward spiral of shame.

The Truth

As I always do when things are tough I decided honesty was the best policy. I thought I would write an article about the position I’d found myself in and the impact it was having on my mental health. I didn’t want to write a how-to-find work piece — there are a million of those — but a piece on the mental implications quiet times can have. Firstly though I needed to talk to other freelancers about their experiences and what better place to do that than on Twitter.

So I asked the question:

It’s fair to say the answers took me by surprise. Not only had other freelancers been through this but they had also had significant periods of time without work, it was far more common than I had realised.

Times varied from one month to six months to two years without paid work. Most common was around two to three months. But quite a few people also mentioned that they had sustained periods where they had work but it wasn’t enough to pay the bills (something I had definitely experienced). It was also suggested that the quiet times are seasonal which seemed obvious when mentioned but not something I’d really thought about until then.

One person who replied had had to go on benefits, a few others had taken full time roles (of course with the result being that the minute they accepted the position they had a deluge of enquiries from new clients). There were others who had had to use tax money to live on.

Some freelancers had taken on alternative types of creative work such as writing, journalism or creating their own courses.

The Fallout

It was clear that I was not alone and that this was a common pattern for a lot of people. The thing I was most concerned about though was how people coped with this from a mental health stand point. Did it affect other people as dramatically as it effected me?

So I asked Twitter, “What did you do to stay on top of the anxiety and worry when work was dead? Did you manage or did it impact your mental health?”

This to me was the most important question of all. Until this point I hadn’t realised that my self esteem is utterly tied up in my work, so when I’m busy I think “Brilliant, I must be pretty good at this” and when it went quiet I immediately thought “Everybody has realised I’m a talentless idiot”.

Worryingly it seems that I am not alone and this is an all too common feeling. Pavithra Muthalagan replied saying that

Sometimes I feel unemployed even when my bank account is telling me things are fine.


… There’s some ingrained mentality defining “success” in a extremely limited/limiting way… imposter syndrome is always hovering over my shoulder

I get this on all levels, it was exactly my experience. My bank account was okay but I felt profoundly unemployed and unemployable. This was far more worrying to me than just the financial impact. I was deeply disappointed that my self esteem and identity were so tied up in how many projects I had on.

Katherine Cory replied to my question about the impact these quiet periods have had on her mental health:

This is a scenario I have also experienced in the past, taking on difficult clients for little money just to get some work in but then the whole project being a nightmare and ending up worse off financially and mentally.

The Positives

But it seems these difficult and stressful times can also be used for growth.

Ben Tallon wrote:

I love this idea and Ben’s attitude. Viewing these times philosophically and finding value in them is a great way to make peace with the up and down nature of freelancing.

Jon Hicks shared his experience:

This was a common theme. Getting outside in nature and pursuing your passions or just having a ramble. Running and upping the time you exercise in quiet times was another great suggestion that several people made. Anything that takes you out of your head and into your body and reminds you of the world outside.

My biggest problem was obsessing over the lack of work and how this defined me as a designer and person. Matt Essam who is a business coach said that he works with clients on this and refers to it as a “scarcity” mindset. He wrote:

I’ve found the only cure to be massive, consistent action. Picking up the phone, going networking etc.

I completely agree with this point however I need to acknowledge it is more easily said than done, especially when your confidence is already rock bottom and you’re riddled with anxiety.

There were other great ideas too. Several people suggested alternative unpaid work — maybe writing or volunteering. Others used their time to learn something new — a coding language or design technique.

One particular reply that really stood out came from Jesse Gardner:

Jesse started a project where he walked the streets of his neighbourhood photographing and interviewing people. There is a lot in this idea — not only does this kind of project keep you being creative and active, it also creates connection with other people, something fundamental to our mental well being. The completed project called Troy Stories: Stories from people of Troy, NY is inspiring and beautiful.

Screenshot of the Troy Stories website homepage

The Troy Stories Website (Source: Troy Stories) (Large preview)

The Why

It’s clear from the response I had to my Twitter questions that at times freelancing can be high risk both financially and for our overall well-being. Three months, six months or even two years without work is devastating. Being in a position where you have to claim benefits or you’re forced to use up all of your carefully saved tax money can lead to crippling anxiety and dramatic changes in circumstances. So it begs the question — why do we do it?

My particular reasons for freelancing were complex — family, commitments, location, flexibility. I’m a lone parent without financial support and I live in a location where there aren’t many design agencies — particularly ones who would let me work flexibly. But everyone has their own particular reasons that make the uncertainty of freelancing worthwhile.

Naomi Atkinson wrote:

This next reply could have been written by me. For many people being able to get outside and walk their dog, and spend time with them is vital to their health and well-being.

Steve Morgan makes an excellent point that freelance gives him the opportunity to work with the type of clients he wants to work with in a way that he choses and in the hours that suit him. They’re some pretty compelling reasons.

For many, employment just isn’t an option as Katie Cory and Adam Greenough confirmed in their replies.

Katie sums it up with one word: necessity. As someone who has ME or Chronic Fatigue Syndrome — Katie has to be able to look after her health, take days out and manage stress. Work when she can and rest when she needs to.

Adam’s reply shows that freelancing gives him the flexibility to be able to manage his mental health with ongoing treatment and operate his workload around that.

Personally, if I wanted to I am in a position to go back to being employed (my daughter is now at University) and I’d be lying if I said it wasn’t tempting after the last few months. The thought of a regular income and being able to focus on the creative side of my work without the worry sounds very appealing. But there are also all the things I love and take for granted about freelancing — having time to spend outside, structuring my day how I want, the feeling of accomplishment when a project launches, the autonomy — so for now I am still on this crazy freelance merry-go-round and I’ve learnt a lot over this difficult period.

The Feast Or Famine Toolkit

So what can we keep in our physical and mental tool kit for those inevitable times when work is quiet?

Don’t attach our value to our lack of work.

We must define success for ourselves. It is ludicrous to feel worthy when we have a lot of work on and unworthy when we don’t.

This is based on an outdated limiting model of what success should look like, created during and peddled since the industrial revolution. We are one of the first generations trying to do things differently and redefine “success”. Success that encompasses life and health as well as work, and we should be proud of ourselves for that.

Drop the scattergun approach to finding work.

Don’t do what I did and sit at your desk everyday for 12 hours applying for literally anything — full time jobs, contract, freelance, temping, dog walking. Whilst I think that action is important, it has to be structured. I had got to the point where I had lost direction and was just taking a “throw enough mud at the wall and something will stick” approach. I feel the only thing I was projecting to potential clients/employers at this point was an air of desperation.

I feel the only thing I was projecting to potential clients/employers at this point was an air of desperation.

Schedule a specific amount of time each day that is dedicated to finding work. Determine your desired market and then target them in a way that works best for you. One book I read during my time of quiet was Anti-Sell by Steve Morgan. It has some brilliant tips for finding work and generating sales for people who hate selling, like me.

Connect with people.

Kind people have saved my life and my sanity over this period. My mate Andy was always up for a dog walk and let me moan at him, my friends on Twitter were amazing (shout out to Dave Smyth and Naomi Atkinson). Try and attend events where you can meet up with other freelancers. Evenings like Design x Business are great because they remind you why you do what you do and are filled with other freelancers. Never underestimate the power of a good freelance podcast too, there are tons out there.

Keep learning and studying in your chosen field.

Use this time to read some of those design or CSS books you bought but never had time to look at. Think about doing a course — they don’t need to be expensive, places like Skillshare have an enormous choice of brilliant subjects.

Create time in your day to do the work you really want to do.

Set a design challenge (like we used to have in the old days). You could create a brief for a made up dream client and a problem they need solving. Then go to town! Enjoy it, be creative. Remember why you chose this career. It’ll be fun and you’ll have something of value to add to your portfolio.

The work you do while you procrastinate is probably the work you should be doing for the rest of your life.

— Jessica Hische

Get out in nature, it is life saving and it is free.

Studies have proven that nature-based activities have a direct and positive affect on mental health, anxiety and stress. Gardening, conservation and walking are all incredibly good for your mental and physical well-being. If you are able then exercising and running outside is also a great way to combat depression and help with sleeping.

Pursue your hobbies — creative or not.

This was a big one for me. I became locked into nothing but my inability to find work. Going back to the hobbies I enjoyed helped so much. They don’t have to be expensive. Films, cycling, painting, model making, knitting, woodwork, pottery, cooking — whatever takes your fancy. And never underestimate the joys of a good book for pure escapism.

Most importantly, don’t be ashamed.

As my conversation on twitter proved this happens to EVERYONE at some point or another. Even people who we assume are constantly over booked with work. Speak to people and be open and honest. It’s important to let people know you’re available for work. Constantly peddling this outward appearance of being super busy and successful can backfire and mean that people don’t approach you for a project as they assume you will be booked up. I know this has meant that I’ve missed out on exciting things in the past as potential clients assumed I’d be too busy.

Finally, try to grow a financial buffer.

I know, I know — easier said than done. If you’re reading this during a quiet period of work and you’re struggling financially then you may feel this is a case of closing the door after the horse has bolted. And if that is the case then try to focus on the points above and not too much on money. You’re more likely to get out of the dip sooner and with your mental health in better shape if you stay positive and don’t get in the scarcity mindset that I did. Money worries are so pervasive, I know whenever I experience them they can render me completely ineffectual.

With that in mind, when work has picked up again (which it will) start setting aside a little each month for a financial buffer. It is so easy to set up a savings account online. Sometimes you don’t even need to do that. Banks like Starling let you set up Goals on your current account which are like little individual pots that you can save money in and then just shift into your account when you need them. I was lucky I had some savings, other people tweeted stated that they used money they’d saved for tax (which can be a little risky depending on the time of year). The point is, that if you can have an account with a couple of months of money in then that will definitely ease the anxiety.

It is always worth remembering that a quiet period will pass, work will come back in — maybe even tomorrow. My biggest regret is that I let it affect my self esteem and self worth so much and made me doubt all of my accomplishments. It isn’t that your work is rubbish or everyone has finally found out you know nothing. Its just that at this particular moment in time you’ve not reached the people you need to reach or your services just aren’t needed. But rest assured they will be again very soon.

Smashing Editorial
(yk, ra)

Source: Smashing Magazine, Making Peace With The Feast Or Famine Of Freelancing

Collective #537

dreamt up by webguru in Uncategorized | Comments Off on Collective #537


Our Sponsor

The Ultimate WordPress Page Builder

You’ve never built a WordPress website like this before. Divi is more than just a WordPress theme, it’s a completely new website building platform that replaces the standard WordPress post editor with a vastly superior visual editor.

Try it


Components AI

An experimental platform for exploring generative design systems. You can cycle through generated designs one or many at a time until you find something inspiring.

Check it out



Nadieh Bremer shares a magnificent project that visualizes how Planet’s satellites create a full image of Earth’s landmass in one single day. Read more about it in this tweet.

Check it out



A tool for creating and downloading natural voices as mp3 audio files.

Check it out

Collective #537 was written by Pedro Botelho and published on Codrops.

Source: Codrops, Collective #537