Setting Up Tailwind CSS In A React Project

Setting Up Tailwind CSS In A React Project

Setting Up Tailwind CSS In A React Project

Blessing Krofegha

2020-02-24T11:00:00+00:00 2020-02-25T01:38:05+00:00

In the dispensation of CSS libraries and frameworks, a ton of awesome libraries have been built to simplify the work of a developer in the quest to create intuitive interfaces. However, quite a lot of them (Bootstrap, Foundation) impose design decisions that are difficult to undo; they come with predefined components, therefore, eliminating the need for dynamic customization. This is the reason why Tailwind CSS is considered to be a good choice for building 21st-century web interfaces.

With Tailwind CSS, you get to create the components that suit what you want or what you are working on. These components can be created by harnessing the power of the utility-first prowess of Tailwind CSS. If you are tired of making use of Bootstrap and its likes, you’ll find Tailwind CSS a good fit for working on beautiful interfaces as you implement the designs you need using the utility classes it provides.

In this tutorial, you will learn what Tailwind CSS is and how to work with it. In the end, you’ll have built a profile card that uses Tailwind CSS utility classes. After that, you can go on to build a portfolio website that showcases your skills and other things you have worked on.

Note: While we won’t be writing CSS in this tutorial, a good knowledge of CSS will come in handy as you work through what we will be covering.

Styling In Modern Web Apps

There are different ways of organizing styling in modern applications which often have complex interfaces and design patterns. Let’s walk through BEM, preprocessors, CSS-in-JS and even design systems to find out what works best for you. Learn more →

What Is Tailwind CSS?

Tailwind CSS is a utilitybased low-level CSS framework intended to ease building web applications with speed and less focus to writing custom CSS, without leaving the comfort zone of your HTML code, yet achieve awesome interfaces.

For example, you could style a button with just a few classes (instead of always having to declare a single big class separately from your HTML and writing a bunch of properties to make something):

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded ml-4 mt-4"> Button

Other CSS frameworks (such as Bootstrap, Foundation, Bulma, and so on) present you with diverse predefined components (such as modals, buttons, alerts, cards). But with Tailwind CSS, you get to make your own, or you’re forced to make your own depending on your project model. Another way to put it, you actually own the components, and you get to harness your customization power on any component of your choice. This means that there is no more need to fight against the framework, and trying to figure out which classes need to be overridden in order to get results you initially aimed for.

Why Use Tailwind CSS?

Maybe you’re not quite ready to betray other frameworks yet, or you haven’t been convinced to embrace the goodies that come with Tailwind CSS. Allow me to give you a few reasons why you may want to consider Tailwind CSS.

No Naming Conventions

One of the most stressful parts of writing custom CSS is having to name classes. At every point, you’re pondering which class should be generic or specific. How do you organize them and ensure they’re cascaded? Tailwind CSS solves those problems seamlessly by providing utility-based classes that can be used all the time.

However, cases may arise where you need to name some classes. Sometimes this tends to happen when you need to extract certain components and use them later in your design (with the help of the @apply directives).

Cache Benefits

When writing custom CSS (or using any other traditional CSS framework), you always have to make changes to your CSS files when making changes in your designs. With Tailwind CSS, you need not worry a bit about that since you’re using the same classes over and over again within the markup. This means that you do not have to bust your CSS cache everytime in order to make small changes to your design.

When Not To Use Tailwind CSS

Are you saying I should always use Tailwind CSS for every project? Of course not! There are a few use cases where you may not want to use Tailwind CSS.

If You’re Working On A Small Projects

When you need to get started with a mini-project that has a very short deadline (especially something a few users would be using or only yourself), then Tailwind CSS is not the best option. In those cases, I’d recommend using Bootstrap, Foundation or any other framework instead. That’s because they come with predefined ready-to-use components (themes to get started with). With Tailwind CSS, you have to creatively create your own.

If You’re A CSS Beginner

Before diving into Tailwind CSS for any project, its advisable to know CSS. Beginners that desire to use Tailwind CSS for web-based projects should first master CSS to a certain degree. It provides utility classes that are linked to the underlying CSS, therefore, only those with a solid knowledge of CSS can easily build with it.

If You Dislike Adding A Lot Of Classes To Your Elements

When writing Tailwind CSS, you always have to write lots of classes, which makes your codebase (HTML) look busy and sometimes difficult to read. If you prefer keeping your code neat, you may want to consider writing custom CSS or use any other CSS framework (such as Bootstrap).

With these reasons, it’s about time to move over to the business of the day: let’s set up Tailwind CSS in a React project together!

Getting Started

To set up our project, we’ll scaffold a new React app using create-react-app. If you have already done this, skip this process, otherwise, run the command below:

npx create-react-app react-tailwindcss && cd react-tailwindcss

Next, we install a few development dependencies. You can use any of the options that work for you.

Using npm

npm install tailwindcss postcss-cli autoprefixer -D

Using Yarn

yarn add tailwindcss postcss-cli autoprefixer -D

We need to initialize Tailwind CSS by creating the default configurations. Type the command below in your terminal:

npx tailwind init tailwind.js --full

This command creates a tailwind.js in your project’s base directory; the file contains the configuration, such as our colors, themes, media queries, and so on. It’s a useful file that helps with predefined sets of properties which will aid the need to re-brand certain conventions or properties if the need arises.

How To Configure PostCSS?

The PostCSS documentation states that:

“PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.”

Why Autoprefixer?

It’s necessary to install Autoprefixer alongside Tailwind CSS because Autoprefixer usually tracks to see which CSS properties need to be prefixed. Hence, Tailwind CSS does not provide any vendor prefixing. If you’re curious as a cat in regards to PostCSS navigate to their documentation.

Create a PostCSS configuration file in your base directory manually or using the command:

touch postcss.config.js

Add the following lines of code to your PostCSS file:

const tailwindcss = require('tailwindcss');
module.exports = { plugins: [ tailwindcss('./tailwind.js'), require('autoprefixer') ],

Because PostCSS is necessary to lint our CSS, hence this configuration.

Code Steps

  • We fetched the Tailwind CSS package and placed it in a variable.
  • We wrapped tailwind.js (our default base configuration) in our tailwindcss variable.
  • We fetched the autoprefixer package.

How To Inject Tailwind’s Components, Utilities And Base Styles To Your App

Inside your src folder create a folder, name it assets, this is where all your styles would be stored. In that folder, create a tailwind.css file and main.css file respectively. The tailwind.css file will be used by us to import Tailwind CSS styles, and for custom configurations and rules. The main.css will hold the styles that are generated as a result of what we have in the tailwind.css file.

Next, we need to import the base styles and configurations. We will do that in one of the CSS files we created above. Add the following to your tailwind.css file.

@tailwind base; @tailwind components; @tailwind utilities;

Note that we used the @tailwind directive to inject Tailwind’s base, components, and utilities styles into our CSS:

  • @tailwind base
    This injects Tailwind’s base styles, which is a combination of Normalize.css and some additional base styles.

    Note: If you’d like to get the complete references of all the styles applied by Preflight, see this stylesheet.

  • @tailwind components
    This injects any component (reusable styles like cards and form elements, etc.) classes registered by plugins based in our config file.
  • @tailwind utilities
    This injects all of Tailwind’s utility classes(including the default and your own utilities) they are generated based on our config file.

Tailwind CSS will swap these directives out at build time with all of its generated CSS. If you’re using postcss-import, use this instead:

@import "tailwindcss/base"; @import "tailwindcss/components"; @import "tailwindcss/utilities";

How To Configure Your App To Build Your CSS

Next, we need to configure our project to build our CSS styles each time we run either the npm start or yarn start command.

Open your package.json file and use the snippet below in place of the script part of your package.json file:

"scripts": { "start": "npm run watch:css && react-scripts start", "build": "npm run build:css && react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "build:css": "postcss src/assets/tailwind.css -o src/assets/main.css", "watch:css": "postcss src/assets/tailwind.css -o src/assets/main.css" },

Importing Our CSS

We need to import our CSS file appropriately to ensure that it’s properly watched and built when we run yarn start or npm start.

Open your index.js file and make the following changes:

  1. Import our main.css file and delete import './index.css';.
    import './assets/main.css'

    Your *index.js* should look like this after the changes:

    import React from "react";
    import ReactDOM from "react-dom";
    import './assets/main.css';
    import App from "./App";
    ReactDOM.render(<App />, document.getElementById("root"));
  2. Head over to App.js and delete import logo from './logo.svg'; leaving only import React from 'react';. Also delete everything inside the App component. (Don’t worry if our App.js looks barren now — we’ll add some code as we proceed in this post.)

Let’s Build A Profile Card Project

Now that our setup works well, and everything looks good, let’s build a Profile Card. However, I’d like to show you what the state of our app before we begin.

React app
React app (Large preview)

To start your app, type this command npm start or yarn start.

Command Prompt - Starting our app
Command Prompt – Starting our app (Large preview)

You’d observe that our Tailwind CSS is building the necessary files needed in main.css.

Let’s get started in our project.
Here’s what our code (App.js) looks like without implementing Tailwind CSS classes.

import React from 'react';
function App() { return ( <div className=""> <img className="" src={require('./profile.jpg')} alt="Display" /> <div className=""> <div className=""> Blessing Krofegha </div> <p className=""> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
export default App;

The outcome of the above code snippet is thus the following:

Our Project without Tailwind CSS
Our Project without Tailwind CSS (Large preview)

As you can see, all of the text has been aligned to the left by default. The image is pretty big because there is no styling. The App component has four main divs to which we’ll be adding classes to. This will then, of course, change the styling of the elements.

First div

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className=""> <div className=""> Blessing Krofegha </div> <p className=""> When I’m not coding, I switch to Netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
export default App;

Code Steps

We gave the div max-width with max-w-sm for small screens and have added border-radius using the rounded class. To prevent scrolling bars from showing up, we used overflow-hidden.

On the first div, we garnished our background with a shadow effect using box-shadow with the shadow-lg class. Using this means that we’d be having a box-shadow(shadow effect) of 0px from the top, 10px from the right, 15px from the bottom, and -3px from the left (with a faint black on the left axis).

On the right axis, we’ve got 0px from the top, 4px from right, 6px from the bottom and -2px from the bottom (with a lighter shade of black rgba(0,0,0, 0.05)).

Do you mean a simple class name such as max-w-sm rounded overflow-hidden shadow-lg is responsible for all of this awesomeness? Yes! That’s the awesomeness of Tailwind CSS!

Next, we gave img a width of 100% with w-full and an src attribute and, of course, an alt attribute.

Here’s how our new Profile card should look like:

The outcome of our first div
The outcome of our first div (Large preview)

Second div

Add this class px-6 py-4 to our second div:

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className="px-6 py-4"> <div className=""> Blessing Krofegha </div> <p className=""> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
export default App;

Code Steps

In our second div, we gave it a padding-right/left of 1rem representing px-6 in the x-axis and padding-top/bottom of 1.5rem which is py-4 in the y-axis.

The outcome of our second div
The outcome of our second div (Large preview)

Third div

Add the class font-bold text-purple-500 text-xl mb-2 to our second div:

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className="px-6 py-4"> <div className="font-bold text-purple-500 text-xl mb-2"> Blessing Krofegha </div> <p className="text-gray-700 text-base"> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className=""> <span className="">#Software Engineer</span> <span className="">#Writter</span> <span className="">#Public Speaker</span> </div> </div> );
export default App;

Code Steps

We set the font-weight to a value of 700 with font-bold class. Next, we gave our div a light purple color using text-purple-500 and made our font-size extra small by using text-xl. We gave our div a margin-bottom of 0.5rem by using mb-2. We also added a paragraph and made its color a darker shade of gray using text-gray-700.

We added a light text color to our paragraph with text-gray-700 and a font size of 1em using text-base. Therefore, text-base is equal font-size: 1rem and text-gray-700 is equal color: #4a5568;

Let’s see what changes were made with our 3rd div:

The outcome from our third div
The outcome from our third div (Large preview)

Fourth div

import React from 'react';
function App() { return ( <div className="max-w-sm rounded overflow-hidden shadow-lg"> <img className="w-full" src={require('./profile.jpg')} alt="Display" /> <div className="px-6 py-4"> <div className="font-bold text-purple-500 text-xl mb-2"> Blessing Krofegha </div> <p className="text-gray-700 text-base"> When i’m not coding i switch to netflix with biscuits and cold tea as my companion. <span></span>😜 </p> </div> <div className="px-6 py-4"> <span className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#Software Engineer</span> <span className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">#Writter</span> <span className="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mt-2 ml-20">#Public Speaker</span> </div> </div> );
export default App;

Code Steps

Like the previous div mentioned above, we added a padding-right/left of 1rem representing px-6 in the x-axis and padding-top/bottom of 1.5rem respectively representing py-4 in the y-axis.

Lastly, we added a few classes to our spans which include inline-block. What this does is sets the display of the span which means the element is treated like other inline elements but allows the use of block properties.

We added a background-color of gray using bg-gray-200 and created a border-radius of 9999px using the rounded-full class; px3 adds padding to the x-axis while py-1 adds padding in the y-axis. text-sm is added to make the font-size of the text small and text-gray-700 was used to add a dark shade of gray color to the text. We went on to add margin-right to the span element.

If you’ve been carefully following along, then you should have something similar:

Final outcome of our Profile Card
The final outcome of our Profile Card (Large preview)

Note: You can replace the image with an image of your choice (preferably yours) and also personalize the content any way you wish.


I hope you enjoyed this tutorial. Of course, you can take always take it a bit further by making this a little profile application that says much more about you beyond the little information we have above. For example, you could go on to share a list of skillsets that you have, or add a table to projects you have worked on and possibly a contact form. Let your creativity flow, and please do share your projects in the comments section below — I’d love to see what you come up with!

Smashing Editorial (ks, il)
Introducing 15 Best New Portfolios, February 2020

Each month we publish a roundup of the best new portfolios, launched in the previous four weeks, by freelancers, agencies, and other creative professionals.

This month’s edition is packed with color and animation. Almost every site in this list animates some part of its interface, and many are dependent on animation entirely. You’ll find tons of great interaction design, but the real trend in 2020 is that personality is making its way back into our sites.

Sarah Drasner

Sarah Drasner’s personal portfolio site is wonderful because it conveys the simple joy she feels in technology. It opens with large type stating, “I Make Things.” But hover over it and you’ll find that she also says, “I Break Things”. The coded flowers that burst open for the break animation are delightfully rebellious. The whole site is packed with personality.

Six N. Five

The interaction design, especially the light-dark transition on Six N. Five’s portfolio site is something to behold. Cursor to the left, or right, to switch from studio work to films. Scroll through some exceptional work, and hover over thumbnails to see a preview. What we really love is the simplest of touches: when you scroll past the bottom of a case study, it automatically returns you to the home screen.


We have two agencies called Franc/Frank this month. This time, it’s an animation studio with a uniquely engaging, linear style. Franc’s work includes cell animation, which appears to be increasingly rare these days. The contemporary edge is provided by the very 2020 color palette, with bold hues cutting into softer, ice-cream pastels.

Special Offer, Inc.

The portfolio for Special Offer, Inc. could be a prototype for the colorful brutalism trend that we’ve carried over from 2019. The red on orange typography is by most measures, a real no-no, but as a way of searing the site into your eyeballs it does an awesome job. The overwhelming amount of content is part of the confident attitude, a minimalist site just isn’t right for many agencies, and it’s great we have so many options in 2020.

Sandy Dauneau

Sandy Dauneau’s portfolio is centered around her beautifully emotive animation, with a slider that offers various projects to enjoy. It features some really expressive typography, but nothing here outshines her delicate, and expertly observed animation. Make sure you check out her showreel, which really convey’s the best of her current work.

David William Baum

It’s difficult for photographers to come up with new ways of presenting their work. There’s only so many ways you can present a grid of thumbnails. The portfolio of David William Baum does an excellent job of solving this, with a moving grid of photos that responds to your cursor, then a stack of images to scroll through when you click a set, which feels a lot like flicking through a collection of printed hand-held photos.


When we’re designing portfolios, it’s easy to get carried away with all kinds of different effects like liquid effects and hover states. Fancy effects help get you noticed by design agencies, but if you’re a design agency selling to business, what works is simplicity. Frank has done an amazing job of keeping its portfolio simple, not because simplicity like this is difficult, but because it’s brave.

Corey Haggard

Corey Haggard has taken more of a traditional single-pager approach to his portfolio. He’s hopped on the out-sized typography trend, and if you click on any of the thumbnails on his site you’ll be rewarded with a flag-style enlarge effect, but basically this is a no-nonsense portfolio that shows off some inspiring work, and is well-worth a few minutes browsing.

Victor Costa

Victor Work 20’ is the 2020 portfolio of Victor Costa, a Brazilian designer/developer based in Toronto. Scroll through and you’ll find some nice flag effects on the portfolio thumbnails. What we really like is the cool wavy line transitions as you scroll from one area of the site to the next — it’s an awesome way to section sites, without subjecting us to hard, horizontal lines.

Davide Baratta

Davide Baratta’s site is one of the new breed of portfolio sites that really only work well on touch screens. If you check it out on a tablet, or a large-screen mobile device, it’s awesome. The simple slide back and forth, with taps for further exploration, feels like a native experience. A lot of time and effort has gone into making this site feel effortless. There’s also some great lettering in there.

Pierre Mouchan

It’s all about generative art these days, and Pierre Mouchan’s site is no exception. With a nod towards out-sized typography, what really grabs your attention is the giant pulsing blob in the center of the screen; it’s enough to trouble Steve McQueen. Each blob on the site represents a project and you can click on each for more info. It even works surprisingly well on mobile.

A Color Bright

It’s all very well presenting beautiful animation if that’s your focus, but what if your focus is on user experience? A Color Bright is a Berlin-based design agency that provides UX/UI design, product development, brand growth, and other digital design. Its portfolio is all about the potential of the user, with a focus on the dynamics of the team you’ll be working with if you hire them.

The Mill

The Mill’s site is a visual overload of motion design, VR, animation, and video. It works as a collection precisely because the lack of hierarchy allows you to delve in on a whim. Each video thumbnail links through to a case study, and the quality of the clients (Nike, Jeep, HBO, Spotify…) means that wherever you click you’ll be rewarded with a high-profile project.

Oxana Bayra

Oxana Bayra’s portfolio opens with glitch-effect artwork that’s growing increasingly popular. Cursor over one of the crystalline objects — each of which features expertly coded artwork — and the glitch-effect grows stronger. Bayra’s won dozens of awards for her generative art and design work, and much of it is on display in her portfolio.

Kevin van der Wijst

Kevin van der Wijst is a digital designer based in Valencia, and you can feel the influence of that sunny Spanish city in his site. In recent decades Valencia has become known for some of the most extraordinary public architecture in the world, and the geometric shapes of van der Wijst’s portfolio echo the shapes of sunlight on buildings. If you cursor over it, you’ll see there’s a liquid mouse trail effect, as if the buildings were reflected in pooled water.

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

Popular Design News of the Week: February 17, 2020 – February 23, 2020

Every week users submit a lot of interesting stuff on our sister site Webdesigner News, highlighting great content from around the web that can be of interest to web designers. 

The best way to keep track of all the great stories and news being posted is simply to check out the Webdesigner News site, however, in case you missed some here’s a quick and useful compilation of the most popular designer news that we curated from the past week.

Note that this is only a very small selection of the links that were posted, so don’t miss out and subscribe to our newsletter and follow the site daily for all the news.

Free Vector Images for Commercial Use for Web Designers


5 Things I Wish I’d Known as a Young Web Designer


CSS Color Extractor


See the Logos AI Generated for Apple, Google, and Uber


8 Best Free Font Resources for Designers


Google Design Resources


20 Company Website Designs to Inspire your Small Business


What’s Coming in WordPress 5.4 (Features and Screenshots)


AI Songwriter – These Lyrics do not Exist


Plastic Humans – Just Another Illustration Set


What Designers Can Learn from Etsy’s Minimalist Icons


10+ Best Online Code Editors


Website SEO: How to Optimize your Content for Google


Web Design Best Practices for your Next Website Project


How to Design User Onboarding: Tips and Practices


13 Best Sites for Downloading Illustrations


Neumorphism - the Zombie Trend


Tips for Web Designers Who are Looking to Raise Brand Awareness


Earth View – Get 1000 Beautiful Google Earth Landscape Photos Free


3 Types of Feedback to Ignore


Page Builders Might not Be a Good Idea


Behavioural Science is a Powerful Design Tool


Consistency is Key – How to Build a Figma Design System


What is an “Aha!” Moment and How to Find It?


The Biggest Mistakes I Made as a New UX Designer


Want more? No problem! Keep track of top design news from around the web with Webdesigner News.

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

3 Strategies to Follow When Your Site is Failing

Here are 3 strategies you should consider if your website is struggling. We’ll cover:

  • Web analytics and split testing
  • In-person testing
  • Simplifying your sales process

If possible, implement these strategies ahead of time before you run into any issues. I’m going to cover why these strategies are effective and what they are good at resolving.

1. Analytics and Split Testing

If you don’t know when or where your users are leaving, then you’re missing ou; this is extremely unhelpful if you are selling something.

Analytics will let you see the average amount of time spent per page, and which page your customers are exiting your website from.

If a user views your website and leaves after visiting your homepage without going any further, then you know exactly what to change. If they are spending an excessive amount of time navigating through simple parts of your sales process, then you know something may be wrong, and you should address it.

AB split testing…is particularly good at resolving weak points on your website where visitors are…changing their minds

Depending on which page of your website they are on, you may want them spending more or less time on it. An abnormally high amount of users abandoning their shopping cart might mean your checkout isn’t providing the user with a positive experience.

AB split testing refers to displaying different versions of the same page to different visitors. It is particularly good at resolving weak points on your website where visitors are leaving or changing their minds about going ahead with what you want them to (e.g. buying a product).

Let’s say we have 2000 page visitors, and 70% are leaving immediately from the landing page, and 600 are proceeding forward (30% click-through rate). Instead of presenting one landing page to all visitors, we display two landing pages and show one landing page to half the visitors, and the second landing page to the other half.

We make some changes to the original landing page and send some of the users to the new version and some to the original version. We do this to see if the new landing page will have a better click-through than the original, 30%.

A quick example for a skydiving company: Group A visitors see ‘Book’ in a smaller sized button, whereas Group B visitors see ‘Skydive NOW!’ in a larger sized button. If the ‘Skydive NOW!’ button improves the number of bookings the site receives, we could consider using Group B as the new control and further work on optimising the booking page, perhaps by creating a modification in which ‘Skydive NOW!’ has a different color scheme or is placed in a different position on the page.

This could be a minor re-design, such as changing the color of a button, to something more enticing, or a major re-design.

You can also display more than two versions of a page simultaneously, making multiple modifications, displaying three or more versions to different users. In this case, we would have the original version, A, and two or more modified pages B, C … so on. This can make split testing quicker by immediately testing multiple possibilities but it adds complexity to the process.

2. In-Person Testing

In-person, or remote testing, is a strategy in which you recruit a user to test your website by undertaking various tasks e.g., Buy a specific product and ship it to your home, or find some specific information on your website.

This should be done regularly during the web building process as by doing so when you launch your website, you might uncover major or recurring problems that could have been prevented. If you do it in early development stages, you can use the information from the test to plan before you start building things that don’t work!

If your website is already live and you overlooked testing beforehand, it’s not too late

If your website is already live and you overlooked testing beforehand, it’s not too late. You can still employ a handful of individuals to test it now.

In-person testing is typically done where you supervise an individual and instruct them to carry out certain tasks and take note of how they are navigating your website by seeing the way they browse the page and/or move their mouse. Ask them to think out loud. You should also ask them why they selected that option over another, what they liked about a particular feature, etc. 

If you already know which areas of your website need to be worked on, but you’re unsure of how to improve on it, you could ask your tester for specific insight.

I typically choose three users for testing, as it’s quick, easy, cheap, and manages to uncover lots of flaws I may have overlooked. Having more users testing the website can be beneficial, but typically most users end up pointing out the same weaknesses.

This is an effective strategy because having a handful of people test your website is like having someone read over your writing. You may not pick up on your own mistakes, but someone else will. It’s also important to note that the way (you), a web-designer browses the web is different from how the average person browses the web. You may have a perfect understanding of what is happening on your website because you created it. Still, someone who is using it for the first time won’t have the same knowledge and experience as you and will try to undertake tasks in the simplest, most intuitive way.

Remote testing is the same principle as in-person testing but executed remotely. This may save you the hassle of meeting up, but might mean that you need to use software (such as a camcorder) to monitor their browsing, along with voice or video calling, to discuss the process with them.

3. Simplifying Your Sales Process

Are you taking care of your customers and guiding them through their purchases?

What happens after your user lands on your website? Is there a good value proposition (product, service, or information that is appealing) compelling them to purchase?

Excellent, now you need to make sure the process is transparent and straightforward.

Be upfront about any extra fees or shipping costs. Let them know how long shipping may take. Customers want to feel like they can trust you.

Customers want to feel like they can trust you

Write out an FAQ (Frequently Asked Questions) addressing common concerns a potential customer may have. E.g., Let’s say I’m buying a dual SIM mobile (two sim cards, one mobile), I want to know which country the product is from, I want to know about the warranty, I may especially want to know details about the phone will store numbers from different cards.

Have an FAQ section addressing general sales questions and a product-specific FAQ. Along with that, address the product specifications and show high-quality photos or videos.

When the customer is satisfied with what they’ve selected, make the checkout process easy. Allow guest checkout if it’s a suitable option for your website. 

Show your customers you care about them and create reasons for them to want to share your website and products. Once you’ve made your sale, send them a follow-up email or little thank you. This will lead to more engagement and a repeat customer. Remember, selling a product isn’t the end goal. Making someone become a lifelong customer is, and you need to facilitate that.


Featured image via Unsplash.

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

How To Build A Simple Cryptocurrency Blockchain In Node.js

How To Build A Simple Cryptocurrency Blockchain In Node.js

How To Build A Simple Cryptocurrency Blockchain In Node.js

Alfrick Opidi

2020-02-21T10:30:00+00:00 2020-02-22T01:36:04+00:00

The unprecedented rise of cryptocurrencies, and their underpinning blockchain technology, have taken the world by storm — from the humble beginnings of being an academic concept over a decade ago to current increased adoption in various industries.

The blockchain technology is receiving a lot of attention because of its ability to enhance security in trustless environments, enforce decentralization, and make processes efficient.

Traditionally, Python has been the de facto programming language for blockchain development. However, with the proliferation of this amazing technology, the development options have also increased — and Node.js has not been left behind.

In this tutorial, I’m going to talk about how to build a simple cryptocurrency blockchain in Node.js. It’s not going to be too fancy, but just sufficient to assist you to understand how a blockchain works.

I’ll call this simple cryptocurrency smashingCoin.

If you are a JavaScript developer who wants to take a leap into the burgeoning field of cryptocurrency, this article will equip you with the necessary skills to get started. Or, if you’re curious about how things work in the world of cryptocurrencies, then this tutorial may help in answering some of your questions.

Recommended reading: Understanding Subresource Integrity by Drew McLellan


To follow this tutorial successfully, you’ll need to have the following:

  • Node.js installed on your machine. You can download it from here;
  • A code editor, such as Visual Studio Code, Sublime Text, or any other.

Let’s get started…

What Is A Blockchain?

Blockchain is the technology that powers digital currencies, such as Bitcoin and Ethereum. It is an innovative distributed public ledger technology that maintains a continuously growing list of records, referred to as blocks, which are connected securely using cryptography.

The term blockchain has earned its name because of the manner it keeps transaction data, i.e. in blocks that are connected to each other to create a chain. The size of the blockchain grows with an increase in the number of transactions undertaken.

Any valid transaction data is logged into the blockchain network, which is governed by peer-to-peer rules that the participants stipulate. For example, this data could contain the “value” of the block such as in digital currencies, a record of transactions (such as when parties exchange goods and services), or entitlement privileges such as when the chain records ownership information.

Besides the transaction data, every block may contain its own cryptographic hash (a unique identifier or digital footprint), its own nonce value (an arbitrary random number used once in cryptographic computations), the hash of the previous block, and a timestamp of recent authenticated transactions.

Since every new block should point to the previous block, if a block is incorporated into the chain without containing the right hash of the last block, it could render the entire blockchain invalid. This immutability property is key to the security of blockchains.

Furthermore, various types of consensus protocols are often applied to maintain the authenticity of the blockchain. Consensus ensures that all participants agree to the network-validated transactions.

For example, a commonly used consensus protocol is proof of work, which aims to identify a number that finds a solution to a complicated mathematical problem after completing a certain amount of computing work.

The main idea of proof work is that any participant in the blockchain network should find this number difficult to identify but easily verifiable. Consequently, it discourages spamming and tampering with the structure of the blockchain.

In the case of most cryptocurrencies, adding a new block to the blockchain requires solving a complex mathematical equation, which increases in difficulty over time as the blockchain grows. Consequently, any person who proves that they’ve done work by solving this problem is compensated with a digital currency, in a process referred to as “mining”.

How To Create A Block

Now, after introducing the blockchain technology and how it works, let’s see how we can apply the concepts in creating a block. As earlier mentioned, blocks are what interlink to each other to form a blockchain.

To create the smashingCoin currency, I’ll use JavaScript classes, which were introduced in ES6.


Let’s get our hands dirty…

Here is the code for the CryptoBlock class:

const SHA256 = require('crypto-js/sha256');
class CryptoBlock{ constructor(index, timestamp, data, precedingHash=" "){ this.index = index; this.timestamp = timestamp; = data; this.precedingHash = precedingHash; this.hash = this.computeHash(); } computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(; } }

As you can see in the code above, I created the CryptoBlock class and added the constructor() method to it — just like it’s done in any other JavaScript class. Then, to initialize its properties, I assigned the following parameters to the constructor method:

indexIt’s a unique number that tracks the position of every block in the entire blockchain.
timestampIt keeps a record of the time of occurrence of each completed transaction.
dataIt provides data about the completed transactions, such as the sender details, recipient’s details, and quantity transacted.
precedingHashIt points to the hash of the preceding block in the blockchain, something important in maintaining the blockchain’s integrity.

Furthermore, I used the computeHash method to calculate the hash of the block based on its properties, as given in the data above.

As you can see, I imported the crypto-js JavaScript library and used its crypto-js/sha256 module to calculate the hash of each block. Since the module returns a number object, I used the toString() method to convert it into a string.

To add the crypto-js library to your project, go the terminal and run the following command to install it using npm:

npm install --save crypto-js

After running the above command, the node modules directory, which contains the library and other essential files, will be added to your project’s folder.

How To Create A Blockchain

As earlier explained, the blockchain technology is based on the concept that all the blocks are chained to one another. So, let’s create a CryptoBlockchain class that will be responsible for handling the operations of the entire chain. This is where the rubber is going to meet the road.

The CryptoBlockchain class will maintain the operations of the blockchain using helper methods that accomplish different tasks, such as creating new blocks and adding them to the chain.

Here is the code for the CryptoBlockchain class:

class CryptoBlockchain{ constructor(){ this.blockchain = [this.startGenesisBlock()]; } startGenesisBlock(){ return new CryptoBlock(0, "01/01/2020", "Initial Block in the Chain", "0"); } obtainLatestBlock(){ return this.blockchain[this.blockchain.length - 1]; } addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; newBlock.hash = newBlock.computeHash(); this.blockchain.push(newBlock); }

Let me talk about the roles of each of the helper methods that constitute the CryptoBlockchain class.

1. Constructor Method

This method instantiates the blockchain. Inside the constructor, I created the blockchain property, which refers to an array of blocks. Notice that I passed to it the startGenesisBlock() method, which creates the initial block in the chain.

2. Creating The Genesis Block

In a blockchain, the genesis block refers to the first-ever block created on the network. Whenever a block is integrated with the rest of the chain, it should reference the preceding block.

Conversely, in the case of this initial block, it does not have any preceding block to point to. Therefore, a genesis block is usually hardcoded into the blockchain. This way, subsequent blocks can be created on it. It usually has an index of 0.

I used the startGenesisBlock() method to create the genesis block. Notice that I created it using the afore-created CryptoBlock class and passed the index, timestamp, data, and precedingHash parameters.

3. Obtaining The Latest Block

Getting the latest block in the blockchain assists in ensuring the hash of the current block points to the hash of the previous block — thus maintaining the chain’s integrity.

I used the obtainLatestBlock() method to retrieve it.

4. Adding New Blocks

I used the addNewBlock() method to add a new block to the chain. To accomplish this, I set the previous hash of the new block to be equal to the hash of the last block in the chain — thus ensuring the chain is tamper-proof.

Since the properties of the new block get changed with every new calculation, it’s important to calculate its cryptographic hash again. After updating its hash, the new block is pushed into the blockchain array.

In reality, adding a new block to a blockchain is not that easy because of the several checks that have been placed. Nonetheless, for this simple cryptocurrency, it’s enough to demonstrate how a blockchain actually works.

Testing The Blockchain

Now, let’s test our simple blockchain and see if it works.

Here is the code:

let smashingCoin = new CryptoBlockchain();
smashingCoin.addNewBlock(new CryptoBlock(1, "01/06/2020", {sender: "Iris Ljesnjanin", recipient: "Cosima Mielke", quantity: 50}));
smashingCoin.addNewBlock(new CryptoBlock(2, "01/07/2020", {sender: "Vitaly Friedman", recipient: "Ricardo Gimenes", quantity: 100}) );
console.log(JSON.stringify(smashingCoin, null, 4));

As you can see in the code above, I created a new instance of the CryptoBlockchain class and named it as smashingCoin. Then, I added two blocks into the blockchain using some arbitrary values. In the data parameter, I used an object and added sender details, recipient’s details, and quantity transacted.

If I run the code on the terminal, here is the output I get:

How a blockchain looks like under the hood
Testing to see if our blockchain works. (Large preview)

That’s what the smashingCoin looks like!
It’s an object that contains the blockchain property, which is an array containing all the blocks in the chain. As you can see in the image above, each block references the hash of the previous block. For example, the second block references the hash of the first block.
After testing and seeing that our blockchain works, let’s add some more functionalities to enhance the features of the smashingCoin.

How To Verify The Blockchain’s Integrity

As earlier mentioned, a key characteristic of a blockchain is that once a block has been added to the chain, it cannot be changed without invalidating the integrity of the rest of the chain.

Therefore, to verify the integrity of the blockchain, I’ll add a checkChainValidity() method to the CryptoBlockchain class.

Hashes are critical for ensuring the validity and security of a blockchain because any change in the contents of a block will result in the production of an entirely new hash, and invalidating the blockchain.

As such, the checkChainValidity() method will make use of if statements to verify whether the hash of every block has been tampered with. Starting from the first created block, it’ll loop over the entire blockchain and check for its validity. Note that since the genesis block was hardcoded, it’ll not be checked.

Also, the method will verify whether the hashes of each two consecutive blocks are pointing to one another. If the integrity of the blockchain has not been compromised, it returns true; otherwise, in case of any anomalies, it returns false.

Here is the code:

checkChainValidity(){ for(let i = 1; i < this.blockchain.length; i++){ const currentBlock = this.blockchain[i]; const precedingBlock= this.blockchain[i-1]; if(currentBlock.hash !== currentBlock.computeHash()){ return false; } if(currentBlock.precedingHash !== precedingBlock.hash) return false; } return true; }

How To Add Proof Of Work

As earlier mentioned, proof of work is the concept applied to increase the difficulty entailed in mining or adding new blocks to the blockchain.

In the case of smashingCoin, I’ll employ a simple algorithm that deters people from generating new blocks easily or spamming the blockchain.

So, in the CryptoBlock class, I’ll add another method called proofOfWork().Essentially, this simple algorithm identifies a number, passed as a difficulty property, such that the hash of every block contains leading zeros that correspond to this difficulty level.

Ensuring the hash of every block begins with the number of zeros as set in the difficulty level requires a lot of computing power. The higher the difficulty level, the more time it takes to mine new blocks.

Furthermore, I’ll add a random nonce value to every hashed block such that, when rehashing takes place, the difficulty level restrictions can still be met.

Here is the code:

proofOfWork(difficulty){ while(this.hash.substring(0, difficulty) !==Array(difficulty + 1).join("0")){ this.nonce++; this.hash = this.computeHash(); } }

And, here is the updated computeHash() method with the nonce variable included:

computeHash(){ return SHA256(this.index + this.precedingHash + this.timestamp + JSON.stringify(; }

Additionally, to implement the proof of work mechanism in the generation of new blocks, I’ll include it in the addNewBlock() method:

addNewBlock(newBlock){ newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); }

Wrapping Up

Here is the entire code for building the smashingCoin cryptocurrency using Node.js:

const SHA256 = require("crypto-js/sha256");
class CryptoBlock { constructor(index, timestamp, data, precedingHash = " ") { this.index = index; this.timestamp = timestamp; = data; this.precedingHash = precedingHash; this.hash = this.computeHash(); this.nonce = 0; } computeHash() { return SHA256( this.index + this.precedingHash + this.timestamp + JSON.stringify( + this.nonce ).toString(); } proofOfWork(difficulty) { while ( this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0") ) { this.nonce++; this.hash = this.computeHash(); } }
} class CryptoBlockchain { constructor() { this.blockchain = [this.startGenesisBlock()]; this.difficulty = 4; } startGenesisBlock() { return new CryptoBlock(0, "01/01/2020", "Initial Block in the Chain", "0"); } obtainLatestBlock() { return this.blockchain[this.blockchain.length - 1]; } addNewBlock(newBlock) { newBlock.precedingHash = this.obtainLatestBlock().hash; //newBlock.hash = newBlock.computeHash(); newBlock.proofOfWork(this.difficulty); this.blockchain.push(newBlock); } checkChainValidity() { for (let i = 1; i < this.blockchain.length; i++) { const currentBlock = this.blockchain[i]; const precedingBlock = this.blockchain[i - 1]; if (currentBlock.hash !== currentBlock.computeHash()) { return false; } if (currentBlock.precedingHash !== precedingBlock.hash) return false; } return true; }
} let smashingCoin = new CryptoBlockchain(); console.log("smashingCoin mining in progress....");
smashingCoin.addNewBlock( new CryptoBlock(1, "01/06/2020", { sender: "Iris Ljesnjanin", recipient: "Cosima Mielke", quantity: 50 })
); smashingCoin.addNewBlock( new CryptoBlock(2, "01/07/2020", { sender: "Vitaly Friedman", recipient: "Ricardo Gimenes", quantity: 100 })
); console.log(JSON.stringify(smashingCoin, null, 4));

If I run the code on the terminal, here is the output I get:

Output of creating a simple cryptocurrency in Node.js
At last, our smashingCoin cryptocurrency! (Large preview)

As you can see on the image above, the hashes now start with four zeros, which correspond with the difficulty level set in the proof of work mechanism.


That’s it! That’s how you can build a simple cryptocurrency blockchain using Node.js.

Of course, the smashingCoin cryptocurrency is far from complete. In fact, if you release it without making more improvements, it is unlikely to meet the current market demands for a secure, reliable, and intuitive digital currency — making you the only one using it!

Nonetheless, I hope that this tutorial has equipped you with some basic skills to get your feet wet in the thrilling world of cryptos.

If you have any comments or questions, please post them below.

Further Resources

Smashing Editorial (dm, il)
How To Design Mobile Apps For One-Hand Usage

How To Design Mobile Apps For One-Hand Usage

How To Design Mobile Apps For One-Hand Usage

Maitrik Kataria

2020-02-20T11:00:00+00:00 2020-02-21T01:06:39+00:00

On Friday, January 2007 the world shrank into our palms as three revolutionary products — the iPod, a phone, and a breakthrough internet communicator — were unified to create the smartphones we know and love today.

Steve Jobs on One-Handed UX
The first iPhone introduced in 2007 marked the fall of Qwerty keypad and stylus. (Large preview)

iPhone was built to be comfortably used for one-handed operation, allowing for a smoother thumb movement across the screen.

Steve Jobs once said that the 3.5-inch screen is the “perfect size for consumers” and that larger screens are foolish.

Smartphone Shipments Worldwide by Screen Size from 2015 to 2021
(Large preview)

But it wasn’t until the turn of the last decade that phablets gained popularity owing to their bigger screens, so much so that less than 1% devices sold today had smaller than 4-inch screens.

90% of the smartphones sold today have bigger than 5-inch displays.

In the meantime, this goldrush for bigger-the-better presented app makers and designers with opportunities to utilize the screen real estate to serve more content and functions.

For instance, the CNN App was among the few who got early access to iPhone 5 introduced in 2012. The developers not only gave it an aesthetic transformation but also designed a reader-friendly, visually-appealing experience that made headlines stand out.

Evolution of Thumb Zone in UX UI Design
Adapted from Phil Schiller’s keynote at Apple’s Special Event 2012. (Large preview)

With Bigger Screens, The Ease Of Access And Reachability Suffer

While bigger screens are great for showing more content, the #1 design consideration of Steve Jobs for making 3.5-inch phones suffers — designing for one-handed usage.

In his 2-month-long research — at airports, streets, cafes, on buses and trains — Steven Hoober shed light on the three ways users hold their phones.

How People Hold and Interact with Mobile Phones
(Large preview)

49% of users hold their phones with one-hand specifically while they are on the go.

Making a strong case for designing apps for one-handed usage. Steven also found that users frequently alter their grip based on their comfort and situation.

Why Designing For One-Handed Usage Should Become The Top Priority For App Makers

We use our phones a great deal when we are preoccupied or in a hurry. This greatly impacts how users hold their phones and how they use the apps resulting in a lot more of one-handed-usage than the 49% number suggested above.

Research suggests that an average user checks their phones for as many as 58 times a day out of which 70% of mobile interaction lasts less than 2 minutes.

We use our phones in “distracted short-burst usage”.

Image Credit: Rescue Time. (Large preview)

A team of researchers at Simform observed usage and behavior of short-burst sporadic usage in multiple scenarios such as:

When Users Use Mobile Apps
Example cases of short-burst usage (Large preview)

Google’s Product Director, Luke Wrobleski, terms these short bursts as ‘one thumb, one eyeball’ mobile-usage experience. It reflects how a distracting environment forces users to engage in single-handed usage within short spans of partial attention. He further adds that the most optimal type of smartphone usage with a single hand is one where quick interaction is supported by smooth functionality.

How To Design For Keeping These One-Handed Short-Burst Usages In Mind?

The answer is rather simple. Do continuous usability testing and study different ways your users hold their phones in various situations.

If the users of your app tend to use the app a lot in distracting scenarios, then you should focus on designing patterns that target reachability and one-handed use.

Two Methods of Holding a Touchscreen Phone with One Hand
(Large preview)

Let’s take a look at the evolution of Spotify’s interface to get a perspective of the problem:

Thumb Zone for Mobile Hamburger Menu UI
Spotify’s Old Navigation — Hamburger Menu. (Large preview)

Spotify used the Hamburger Menu at the top-left which concealed these features and set the users on a treasure hunt of sorts. With the advent of bigger screens, however, another design challenge was added to the list — reachability.

Thumb Zone for Mobile Hamburger Menu UI
Spotify — A certain level of difficulty and discomfort was experienced as users tried to communicate with the app. (Large preview)

This compelled Spotify’s team to pull down the Hamburger Menu in 2016 and lay its core features — Home, Browse, Search, Radio, and Library — at the bottom that resulted in an increase of 9% clicks in general and 30% on menu items.

Use Established UX Patterns For Common App Usage Scenarios To Make One-Handed Usage Easy

Why reinvent the wheel? When you can use proven UX patterns that work. Many designers have already focused on one-handed usage as their designing principle.

We have gone through hundreds of apps and thousands of patterns to find the best patterns one-handed usage in mind. So let’s look at what works, what problems are solved, and what benefits you will get out of these.

We divide the most common user behaviors and UX patterns in six categories:

  1. Navigation UX Patterns
    e.g. menu bars, tab bars, and, gestures for easily moving between the most important sections of the app;
  2. Designing For Actions
    Creating, editing, posting, adding, removing, and other actions users take to utilize the core functionality of the app;
  3. Shopping, Transactional And Checkout Flow Design Patterns
  4. Searching, Sorting, And Filtering Patterns for when users want to quickly find or browse content;
  5. Input And Interaction Patterns
    Sliders, pickers, selectors, dropdowns, form fills, zooming, scrolling that make up the building blocks of any app;
  6. Miscellaneous Patterns
    Media playback, photo capture, photo editing, and map navigational patterns.

1. Designing App Navigation Keeping ‘One-Handed Usage’ In Mind

What Is It?

The foundation of a great app is a good navigation design. Good navigation helps users discover the features faster and find what’s important to them.

70% of users discover features of the app using navigation links compared to search or other ways. Navigation bars, menus, gestures, links, tabs, etc are the most common navigation UX patterns.

A good navigation design should have all the important sections right upfront and easily accessible.


Common UX patterns like Apple’s tab bar and Google’s swipeable menu have limitations. You can put only a limited number of features in the tab bar and to access all of the swipeable menu items is not easy.

Users shouldn’t have to struggle to reach an important part of the app by stretching to the top of the screen. That’s just bad usability. Specifically, if the users are on-the-go and are using the app in a short burst.


Facebook and many other apps solve this challenge by putting items in a tab icon called More or Menu from where users can access more features and sections of the app. This, however, is not ideal for reachability and one-handed use.

  • Use the flyout menu instead of a full-page menu for reachability and fitting in more than 5 items.
  • Expanded tab bar for when you have more content.
  • Personalized tab bar for power users to quickly access what they like.
  • Use gestures to imbibe ease-of-access in users’ habits.
  • Getting back and closing a page should be easy as well.
  • Quickly jumping to a section of the page with smart UX patterns

Facebook, for instance, conceals numerous features in a Hamburger Menu that declutters the main screen. Although this inclusion has a cleaner and more organized appeal, users suffer from one-handed reachability.

1.1 What makes the Hamburger Menu a REAL Problem?
Use Flyout Menu Instead Of A Full-Page Menu For Reachability

Thankfully, we have a way to resolve this challenge —

Full-page menus can be replaced with flyout menus, which like the name suggests ‘fly-out’ from the bottom. This allows for easier access to the options even with one hand.

1.2 Mobile UX Patterns for Flyout Menu Designs (Video Credit: Joox)
Expand The Tab Bar For When You Have More Content

Human Interface Guidelines recommend having no more than 5 features in the bottom navigation bar. This makes it tricky for app builders to present additional core functionalities at the forefront.

This is where the ‘More’ option (3 dots) comes in handy. Located at the bottom bar, it can conceal other functionalities and reveal them with a click.

1.3 Designing Bottom Navigation Bar with Expandable More Options.
Personalized Tab Bar For Power Users To Quickly Access What They Like

Every user is different and a feature that is important for one user may not be that important for the other. To make the most of your app, you can allow users to customize their tab bars with frequently used functionalities.

1.4 Personalized Bottom Tab Bar for Quick Feature-Accessibility.
Gestures Are Easy To Imbibe In Users’ Habits For Quick Navigation

Popularised by Tinder, Gesture-based navigation is a great technique to facilitate single-handed usage. Gestures if smartly used can help expand navigation for one-handed use.

1.5 Gesture-based Navigation to Access App Features.
From Designing “Getting To” To “Getting Back” Using Gestures And Accessibility

Navigation isn’t only about getting to a screen or section of the app. It is important to design for — going back to where the user came from, closing a screen, or jumping to a section on a page! Let’s look at how apps use gestures and UX patterns to do those things easily.

1.6 Using Gestures to Navigate Through Multiple Screens (Video Credit: Zenly)
Patterns For Quickly Jumping To Different Sections Of The App

Apps with many categories, subcategories, and sections such as books, wiki, restaurant menus, products may need more organization to ensure users don’t struggle with finding content.

These can be organized in a hierarchy and using UX patterns to increase accessibility and ease of use.

1.7 Floating Tab Bars and Gestures to Jump Between Sections.

2. One-Handed Patterns For Core Actions Like — Creating, Editing, Posting, Adding, Deleting And Others

What Is It?

Users spend about 50% of their mobile phone time in self-expression, social interaction, online shopping, managing finances, health and productivity, and planning upcoming events. These action-driven UX patterns include things like creating social posts, editing documents, editing, a few others.


When designing action-driven apps, we have to ensure they don’t take the backseat. Like, having a post or creating a button at the top instead of right next to your thumb.


There are three things to keep in mind when designing the user experience of these core actions.

  1. Core actions should grab users’ attention by the prominent placement of the icon or button. Don’t put them at the top right corner of the app where they can get buried. It should be easily reachable without needing to use second hand or overreaching.
  2. On top of that, users should be able to finish the entire creation and addition task flow with one hand. This includes things like canceling the task, typing with keyboard opening up, moving to the next step and so on.
  3. Designing for complex editing tasks with multi-level edit menus and controls.
  4. With reachability as a goal, you can make sharing and sending things easy and simple too.
The Button Or Icon For The Core Task Of The App Should Draw Users In

Apps’ core tasks center around things like capturing images, creating a post, adding files, sharing, etc. It becomes necessary to have users focus on these first and make it — reachable and discoverable.

For instance, Snapchat hides everything and only incentivizes users to capture photos and videos. Also, the ‘Send’ button immediately asks users to share their stories with others.

2.1 Making Core Tasks Easily Reachable with Gestures, Flyout Menus, and Floating Tab Bars.
Breaking Up Complex Editing Tasks With Menus And Controls Designed Specifically For Mobile

For many users, mobile phones are the most used computing devices. There is a generation of users who get real work done on their mobile phones. For example, document editing is no longer a computer-only affair since a host of mobile apps offer the service.

Microsoft Word and WPS Office offer a host of editing tools and multi-level menus within thumb’s reach. These intuitive menu systems are smart and powerful allowing users to do complex operations and multiple choices.

2.2 Placing Editing Tools on the Bottom Half of the Screen for Quicker Modifications.
With Reachability As A Goal, You Can Make Sharing And Sending Things Easy And Simple Too

What amplifies our experience with our favorite music these days is the super-quick shareability options for social media, often just a click away.

You can employ a share extension that slides up from the bottom and allows users to directly type messages.

2.3 UX Patterns for Single-handed Sharing of Photos, Videos, Music, and More.
Divide Creating Or Adding Tasks Into Multiple Steps

Creating boards, favorites, and wish lists can be a drag, especially when they are placed at the top extremes. Let’s look at the patterns that handle multi-step data inputs.

Flipboard and Airbnb keep everything at the bottom and within the reach of the thumb. From typing to selecting the next steps or canceling the action is very simple.

2.4 Placing ‘Create’ and ‘Add’ Icons within the Reach of the Thumb for Smooth One-handed Usage.

3. Designing Faster Checkout And Transactional Experiences For When You Are On-The-Go

What Is It?

According to Kaspersky Cybersecurity Index, 50% of eCommerce sales happen on mobile phones. Add to that commercial transaction like booking a ride, flight, hotel room, movie tickets, and concert tickets and you realize how important designing mobile checkout experience is. A report by Baymard Institute suggested that 23% of shoppers who abandon their cart abandon it because of the complicated checkout process. This is specifically true for mobile shoppers for whom checkout is a multi-step process where inputting data is not as easy.


The checkout process requires many inputs and careful attention from users.

  • Designing a one-handed checkout experience would mean users can complete the transaction with minimal thumb movement and fewer steps.
  • This is especially very important for users who are on the move or need to do the transaction immediately.


To design a one-handed checkout experience we have to minimize the information required from the users.

  • When choosing product variations like size, color, time/date and others, they should be easily accessible and discoverable.
  • We can use applications like Google and Apple wallet or autofill from things like Keychain, 1password, and LastPass to fill the information like names, credit cards, addresses, One-time-passwords.
  • We also must emphasize the simple and minimal thumb movements from the users.
Adding Items To Carts And Choosing Product Preferences At Thumb’s Reach

The logistics of shopping online can be simplified within three steps — adding items to carts, picking product variations, and completing the payment process.

As designers, it becomes essential for us to not only make these selections noticeable but also to place them within the reach of a thumb.

One way to achieve this goal is to display product variations in a tray that slides up when the user chooses an item.

Another way is to allow users to scroll through the page and quickly select variations of a product while the option to ‘Place the Order’ or ‘Buy’ stays static at the bottom.

3.1 Smooth Payment Checkout Flow With Options to Add Items and Choose Product Variations.
3.1 Adding Items to Cart for e-Commerce on On-Demand Delivery Apps. Video Credits: Shopping Choose | WE+AR TRBL | Tasty Hamburger App
Using e-Wallets And Password Managers For Swift Payment

The Payment Methods Report 2019 suggests that over 71% of online transactions are carried out via e-Wallets like Apple Pay, Google Pay, Alipay, Fitbit, Samsung Pay, YandexMoney, and others. These wallets are not only deemed to be faster but are also much safer and easier to access.

The checkout process can be made more efficient and straightforward. What’s more, you can also add a swipe-to-pay option for higher conversions.

3.2 UX Patterns for Payment Checkouts for e-Commerce Mobile Apps.
3.2 UX Patterns for Payment Checkouts for e-Commerce Mobile Apps. (Video Credits: SPACED Challenge (Travel + VR) | Checkout Promocode | Gamification Checkout)

4. Searching, Filtering, And Sorting Content With Reachability As The Main Goal

What Is It?

Without the right UX, finding just the right products or items can be a tedious challenge for the user. Searching, filtering, and sorting tools determine how easy or difficult it is for the user to browse the site’s product and item catalog.

Filters are a great tool to narrow down high volumes of content and to find the most relevant results.

In theory, they are different: sorting organizes the content according to a certain parameter, filtering removes it from view.

During Baymard’s Product Listings & Filtering study, it was observed that sites with an average product list usability saw abandonment rates of 67–90%. What’s more, there was about 17–33% abandonments from users trying to find the exact same types of product from e-Commerce sites with a slightly tweaked toolset. This resulted in approximately 4X increase in leads.


  • Searching on mobile should be easily accessible. For example, Youtube, Amazon Prime, Slack, Google Maps make it difficult for users to reach the search menu by having them reach the top right corner.
  • Organizing the information hierarchy of filters as there are too many parameters and categories so that users can find what they are looking for quickly.
  • Manage multi-level information in UI especially when there are many categories and each category has many items.
  • Changing UI based on different states like “Filter is applied” and what “Filters are applied”.
  • All this should be accomplished by users in the reach of users’ thumb.


  • Use gestures or easily accessible buttons for search. When users go to the search screen give suggestions as well as open the text box immediately.
  • Speak the language of the users and keep users intent in mind when organizing filters. Keep the filters/sorting button near the reach of users. Also, make accessing and closing the filters menu with one hand.
  • To solve information complexity use either a two-step filtering control or side by side filtering control.
  • Apply filters immediately. Make filters interactive based on actions users take. Allow users to choose multiple options. Change filter categories to match applied filters.
  • Show recommendations, recently used or most frequently used information first.

For many apps, Search is one of the top 5 features used. But many app designers make reaching the search icon difficult. See the comparison below for Apple Maps vs Google Maps and Netflix vs Youtube.

UX Search Patterns for Apple Maps and Google Maps
Comparing Search Bar Reachability – Apple Maps vs Google Maps. (Large preview)
UX Search Patterns for Netflix and YouTube
Comparing Search Bar Reachability – Netflix vs YouTube. (Large preview)

Some apps use the search screen as a content discovery screen. They recommend users what they’d like, what they searched before, what’s trending and so on.

4.1 Creating a Search Page for Users to Discover Content. (Large preview)
Remove Friction And Impending Steps From Searching And Filtering

To make things really quick for users, we can make it so that when they tap on the search icon on the tab bar the keyboard immediately pops up so that users can start typing their queries immediately. See the examples of Netflix and SpotHero.

Many apps like Amazon or Google Drive use the search bar prominently at the top of the home page. In such cases, we can use gestures (swipe down) like the Inshorts app to immediately start typing instead of having to reach the top and tap on the search bar.

4.2 Searching and Filtering Made Thumb-friendly.
Double-Tap On The Search Icon To Pull Up The Keyboard

If you want to use your search page to show information to users then you can also use double-tap to pull up the keyboard like Microsoft News, Spotify, and Reddit Apollo.

4.3 Accessing Keyboard Made Easy with a Double-tap on ‘Search’ Icon.
Thumb Reachable Filter Menu Should Let Users Find Information Faster

Online shopping, booking, on-demand and other apps alike can contain a laundry list of items for users to choose from.

The biggest consideration for designing a filtering menu for small devices is the information hierarchy. Let’s look at these examples to understand how filtering and sorting can be designed when options are aplenty. These show how you can handle information complexity without letting one-handed usage suffer.

Also, filters should be responsive and reactive to users’ choices and indicate when filters are applied.

To make this process more responsive, search results can be filtered in the background simultaneously as users select the choices.

4.4 Sorting and Filtering Items on e-Commerce and On-Demand Delivery Mobile Apps.
4.4 Sorting and Filtering Items on e-Commerce and On-Demand Delivery Mobile Apps. Video Credit: Filters | Car Sharing with Friends.

5. User Input Controls Such As Forms, Pickers, Selectors, Dropdowns, Sliders That Make Up The Building Blocks Of An App

What Is It?

With smaller screens comes smaller real estate. Fundamental user interactions have to be reimagined in order to increase the productivity of mobile users.

Things like filling up forms, typing up the password, choosing date/time, making a selection, popovers had to translate well to touch interface without abandoning the metaphors of PCs.


Inputting data on mobile devices is tedious, especially when there are a number of data fields to be filled.

Translating user interactions to smaller devices is not easy. The biggest challenges are:

  • Speed of user input should be very fast with minimal movement of users’ thumb.
  • Information should be gathered in a minimal number of steps.
  • The input control design should have an easily understood interface and metaphor.
  • The experience should be delightful and consistent.
  • Users must know their location and information must not be lost.

When done correctly, adding inputs in trackers, calendars, and others alike could become a short task.


  • Any user action like filling up forms or making choices should be closer to the bottom. The flow of actions and choices should be consistent without any jarring UI changes.
  • Information needed to move ahead should be in thumb’s reach.
  • Data input options including notifications should be clear and near to the bottom.
  • Bigger forms can be divided into multi-step and multi-screen forms. This multi-screen approach should have going forward and going back very easily.
Fixing Filling Up Forms Starting With Sign-Up Forms

We all hate filling up sign up forms. They are time-consuming and ask for unnecessary information.

Filling up forms can be less laborious by turning a lengthy form into multiple screens. Using things like auto-fill, thumb reachable buttons for next and previous steps, continuous keyboard presence, and no scrolling makes this approach faster and easier.

5.1 Best Practices for Multi-Screen Onboarding Flows (Video Credit: Zenly & AirBnB)
Get Quick Input From Users With Minimal Thumb Movement

Positioning the user-input controls towards the bottom of the screen allows for quicker data entry and prompt call-to-action responses.

Use pickers, dropdowns, scrollers, and sliders to supply information to users.

5.2 One-handed User Input Controls for Accurate Form Filling (Video Credit: Periscope)
Smart Mobile Patterns For User Input Controls

Let’s look at some more patterns that make getting input from users easier.

5.3 One-handed User Input Controls for Mobile App Forms (Video Credit: Peach | Zova Workout & Fitness | Square Order)

6. Miscellaneous Patterns For Media Playback, Photo Capture, Photo Editing, And Map Navigation Patterns

With over 2 million apps on Google Store and 1.83 million apps on the App Store, it has become imperative for designers to make their apps stand out. One way to do this is to make common functions fun and smooth for users, and this final section is a round-up of miscellaneous user interactions.

6.1 Forget Pinching; These Apps Lets Users Zoom In and Out with One Thumb.
6.1 Whether it’s Selecting Emojis, Sending Images, or Listening to Audio Clips, Gestures Can Add Ease such App Interactions.
6.1 Whether it’s Selecting Emojis, Sending Images, or Listening to Audio Clips, Gestures Can Add Ease such App Interactions (Video Credit: Composer Concept | Gamification + Checkout)


Although reachability is a big part of it designing for one-handed usage, it is not just about ensuring everything close to users’ reach. Apps that have good one-handed use also save the time of users, remove friction, take out unnecessary steps, and most importantly focus on quickening the “distracted short burst usage” of apps.

We looked at many patterns that designers can use to solve different UX challenges. For more, you can check these websites to find patterns that help you design for one-handed use.

Smashing Editorial (cc, yk, il)
How To Use The HTML Drag-And-Drop API In React

How To Use The HTML Drag-And-Drop API In React

How To Use The HTML Drag-And-Drop API In React

Chidi Orji

2020-02-19T11:00:00+00:00 2020-02-20T01:07:20+00:00

The drag-and-drop API is one of the coolest features of HTML. It helps us implement drag-and-drop features in web browsers.

In the current context, we will be dragging files from outside the browser. On dropping the file(s), we put them on a list and display their names. With the files in hand, we could then perform some other operation on the file(s), e.g. upload them to a cloud server.

In this tutorial, we’ll be focusing on how to implement the action of dragging and dropping in a React application. If what you need is a plain JavaScript implementation, perhaps you’d first like to read “How To Make A Drag-And-Drop File Uploader With Vanilla JavaScript,” an excellent tutorial written by Joseph Zimmerman not too long ago.

The dragenter, dragleave, dragover, And drop Events

There are eight different drag-and-drop events. Each one fires at a different stage of the drag-and-drop operation. In this tutorial, we’ll focus on the four that are fired when an item is dropped into a drop zone: dragenter, dragleave, dragover and drop.

  1. The dragenter event fires when a dragged item enters a valid drop target.
  2. The dragleave event fires when a dragged item leaves a valid drop target.
  3. The dragover event fires when a dragged item is being dragged over a valid drop target. (It fires every few hundred milliseconds.)
  4. The drop event fires when an item drops on a valid drop target, i.e dragged over and released.

We can turn any HTML element into a valid drop target by defining the ondragover and ondrop event handler attributes.

You can learn all about the eight events from the MDN web docs.

Drag-And-Drop Events In React

To get started, clone the tutorial repo from this URL:

Check out the 01-start branch. Make sure you have yarn installed as well. You can get it from

But if you prefer, create a new React project and replace the content of App.js with the code below:

import React from 'react';
import './App.css'; function App() { return ( <div className="App"> <h1>React drag-and-drop component</h1> </div> );
export default App;

Also, replace the content of App.css with the below CSS style:

.App { margin: 2rem; text-align: center;
h1 { color: #07F;
.drag-drop-zone { padding: 2rem; text-align: center; background: #07F; border-radius: 0.5rem; box-shadow: 5px 5px 10px #C0C0C0;
.drag-drop-zone p { color: #FFF;
.drag-drop-zone.inside-drag-area { opacity: 0.7;
.dropped-files li { color: #07F; padding: 3px; text-align: left; font-weight: bold;

If you cloned the repo, issue the following commands (in order) to start the app:

yarn # install dependencies
yarn start # start the app

The next step is to create a drag-and-drop component. Create a file DragAndDrop.js inside the src/ folder. Enter the following function inside the file:

import React from 'react'; const DragAndDrop = props => { const handleDragEnter = e => { e.preventDefault(); e.stopPropagation(); }; const handleDragLeave = e => { e.preventDefault(); e.stopPropagation(); }; const handleDragOver = e => { e.preventDefault(); e.stopPropagation(); }; const handleDrop = e => { e.preventDefault(); e.stopPropagation(); }; return ( <div className={'drag-drop-zone'} onDrop={e => handleDrop(e)} onDragOver={e => handleDragOver(e)} onDragEnter={e => handleDragEnter(e)} onDragLeave={e => handleDragLeave(e)} > <p>Drag files here to upload</p> </div> );
export default DragAndDrop;

In the return div, we have defined our focus HTML event handler attributes. You can see that the only difference from pure HTML is the camel-casing.

The div is now a valid drop target since we have defined the onDragOver and onDrop event handler attributes.

We also defined functions to handle those events. Each of these handler function receives the event object as its argument.

For each of the event handlers, we call preventDefault() to stop the browser from executing its default behavior. The default browser behavior is to open the dropped file. We also call stopPropagation() to make sure that the event is not propagated from child to parent elements.

Import the DragAndDrop component into the App component and render it below the heading.

<div className="App"> <h1>React drag-and-drop component</h1> <DragAndDrop />

Now view the component in the browser and you should see something like the image below.

Drop zone
div to be converted into a drop zone (Large preview)

If you’re following with the repo, the corresponding branch is 02-start-dragndrop

Managing State With The useReducer Hook

Our next step will be to write the logic for each of our event handlers. Before we do that, we have to consider how we intend to keep track of dropped files. This is where we begin to think about state management.

We will be keeping track of the following states during the drag-and-drop operation:

  1. dropDepth
    This will be an integer. We’ll use it to keep track of how many levels deep we are in the drop zone. Later on, I will explain this with an illustration. (Credits to Egor Egorov for shining a light on this one for me!)
  2. inDropZone
    This will be a boolean. We will use this to keep track of whether we’re inside the drop zone or not.
  3. FileList
    This will be a list. We’ll use it to keep track of files that have been dropped into the drop zone.

To handle states, React provides the useState and useReducer hooks. We’ll opt for the useReducer hook given that we will be dealing with situations where a state depends on the previous state.

The useReducer hook accepts a reducer of type (state, action) => newState, and returns the current state paired with a dispatch method.

You can read more about useReducer in the React docs.

Inside the App component (before the return statement), add the following code:

const reducer = (state, action) => { switch (action.type) { case 'SET_DROP_DEPTH': return { ...state, dropDepth: action.dropDepth } case 'SET_IN_DROP_ZONE': return { ...state, inDropZone: action.inDropZone }; case 'ADD_FILE_TO_LIST': return { ...state, fileList: state.fileList.concat(action.files) }; default: return state; }
const [data, dispatch] = React.useReducer( reducer, { dropDepth: 0, inDropZone: false, fileList: [] }

The useReducer hook accepts two arguments: a reducer and an initial state. It returns the current state and a dispatch function with which to update the state. The state is updated by dispatching an action that contains a type and an optional payload. The update made to the component’s state is dependent on what is returned from the case statement as a result of the action type. (Note here that our initial state is an object.)

For each of the state variables, we defined a corresponding case statement to update it. The update is performed by invoking the dispatch function returned by useReducer.

Now pass data and dispatch as props to the DragAndDrop component you have in your App.js file:

<DragAndDrop data={data} dispatch={dispatch} />

At the top of the DragAndDrop component, we can access both values from props.

const { data, dispatch } = props;

If you’re following with the repo, the corresponding branch is 03-define-reducers.

Let’s finish up the logic of our event handlers. Note that the ellipsis represents the two lines:

e.stopPropagation() const handleDragEnter = e => { ... dispatch({ type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth + 1 });
}; const handleDragLeave = e => { ... dispatch({ type: 'SET_DROP_DEPTH', dropDepth: data.dropDepth - 1 }); if (data.dropDepth > 0) return dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: false })

In the illustration that follows, we have nested drop zones A and B. A is our zone of interest. This is where we want to listen for drag-and-drop events.

An illustration of the ondragenter and ondragleave events
An illustration of the ondragenter and ondragleave events (Large preview)

When dragging into a drop zone, each time we hit a boundary, the ondragenter event is fired. This happens at boundaries A-in and B-in. Since we’re entering the zone, we increment dropDepth.

Likewise, when dragging out of a drop zone, each time we hit a boundary, the ondragleave event is fired. This happens at boundaries A-out and B-out. Since we’re leaving the zone, we decrement the value of dropDepth. Notice that we don’t set inDropZone to false at boundary B-out. That is why we have this line to check the dropDepth and return from the function dropDepth greater than 0.

if (data.dropDepth > 0) return

This is because even though the ondragleave event is fired, we’re still within zone A. It is only after we have hit A-out, and dropDepth is now 0 that we set inDropZone to false. At this point, we have left all drop zones.

const handleDragOver = e => { ... e.dataTransfer.dropEffect = 'copy'; dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: true });

Each time this event fires, we set inDropZone to true. This tells us that we’re inside the drop zone. We also set the dropEffect on the dataTransfer object to copy. On a Mac, this has the effect of showing a green plus sign as you drag an item around in the drop zone.

const handleDrop = e => { ... let files = [...e.dataTransfer.files]; if (files && files.length > 0) { const existingFiles = => files = files.filter(f => !existingFiles.includes( dispatch({ type: 'ADD_FILE_TO_LIST', files }); e.dataTransfer.clearData(); dispatch({ type: 'SET_DROP_DEPTH', dropDepth: 0 }); dispatch({ type: 'SET_IN_DROP_ZONE', inDropZone: false }); }

We can access the dropped files with e.dataTransfer.files. The value is an array-like object so we use the array spread syntax to convert it to a JavaScript array.

We now need to check if there is at least one file before attempting to add it to our array of files. We also make sure to not include files that are already on our fileList.
The dataTransfer object is cleared in preparation for the next drag-and-drop operation. We also reset the values of dropDepth and inDropZone.

Update the className of the div in the DragAndDrop component. This will conditionally change the className of the div depending on the value of data.inDropZone.

<div className={data.inDropZone ? 'drag-drop-zone inside-drag-area' : 'drag-drop-zone'} ... > <p>Drag files here to upload</p>

Render the list of files in App.js by mapping through data.fileList.

<div className="App"> <h1>React drag-and-drop component</h1> <DragAndDrop data={data} dispatch={dispatch} /> <ol className="dropped-files"> { => { return ( <li key={}>{}</li> ) })} </ol>

Now try dragging and dropping some files onto the drop zone. You’ll see that as we enter the drop zone, the background becomes less opaque because the inside-drag-area class is activated.

When you release the files inside the drop zone, you’ll see the file names listed under the drop zone:

Drop zone showing low opacity during dragover
Drop zone showing low opacity during dragover (Large preview)
A list of files dropped into the drop zone
A list of files dropped into the drop zone (Large preview)

The complete version of this tutorial is on the 04-finish-handlers branch.


We’ve seen how to handle file uploads in React using the HTML drag-and-drop API. We’ve also learned how to manage state with the useReducer hook. We could extend the file handleDrop function. For example, we could add another check to limit file sizes if we wanted. This can come before or after the check for existing files. We could also make the drop zone clickable without affecting the drag-and-drop functionality.


Smashing Editorial (ra, ks, il)
6 Best Browsers for Developers in 2020

On the surface, web browsers seem very similar. They all provide you with a relatively straightforward way to get online and search for the content that you need. 

However, the more time you spend building your skills as a designer/developer, the more you’ll recognize the need for a unique kind of browsing experience. Fortunately, we’ve found some of the best browsers for web developers, to get you started.

Let’s take a look at what each option can offer.

Firefox Developer Edition

Among developers, Firefox is probably the world’s most popular browser.

On it’s own, Firefox is a pretty powerful browser. Deemed a lot faster than the average web browser, Firefox helps you to track down information and create stunning websites in a fraction of the time of something like Edge. 

However, if you really want to get the next-level Firefox experience, then it’s worth upgrading to Firefox’s own developer edition. 

Like Google Chrome for Developers, Firefox’s Developer Edition comes built for the open web. 

Additionally, with Firefox Developer Edition, you get access to a next-generation CSS engine (written in RUST), an inactive CSS system that grays out CSS declarations that don’t impact the page, and more. There is also a host of “Firefox DevTools” to access. 

With your new browser, you can access a best-in-class JavaScript debugger, a Master CSS Grid, and various other features too. In fact, Firefox is the only browser that is specifically built with tools that help developers to build and design with their own CSS grid. These tools make it easier to visualize information, display area names, and preview transformations too.


Finally, Polypane is a unique kind of browser, specifically designed for developers and designers. This browser is a cross-platform solution and Devtool that experts can use to develop, test, and debug sites as quickly as possible. 

Created to help developers and designers increase both the quality of their work and their productivity, Polypane is packed full of useful features. What’s more, it works with any code editor and technology stack. 

In an age where user experience is more important than ever, Polypane helps companies to build higher-quality websites through everything from WordPress, to Drupal and Angular. 

Because tools for developing and debugging are built into the browser already, you don’t have to worry about finding and adding extra extensions.

For those who aren’t sure about using a new and proprietary browser experience, Polypane does come with a free trial. However, as with most specialist tools for web developers, you will need to pay if you want to continue accessing advanced features long-term. 

On the plus side, like Google Chrome’s developer edition, Polypane benefits from regular updates, so you know that you’re always going to be on the cutting edge of the web industry. 

What’s more, you can also access different packages depending on whether you’re using Polypane as an individual or an agency.

Google Chrome for Developers

Google Chrome stands out as one of the world’s most widely used browsers. 

Chrome has more than 58% of the market share, according to the latest estimates. With figures like that, it must have something special to offer. 

While Chrome might be particularly popular among everyday consumers, it also has something special to offer people in the web development and design world too. For instance, Google now has it’s own “Chrome browser for Developers” product. 

Created for the open web, Google Chrome for Developers helps professionals to design websites that are specifically optimized for the next version of the digital world. With Google Chrome, you can test cutting-edge APIs for web-based platforms in real-time.

What’s more, Google Chrome is packed with endless tools and add-ons that you can implement into your browser. That includes PHP consoles for WordPress, screenshot tools for collecting web design inspiration, and even LastPass for password control. 

Not only do you have endless opportunities to get creative with Google Chrome, but you also have access to updates that happen on a weekly basis, so you know you’re always on the cutting edge. 


Opera might not be as popular as Chrome or Firefox for developers, but it has a number of benefits to consider. If you’re not looking for too many advanced development features, then Opera could give you everything you need for a quick and effective experience online. 

Numerous stress and speed tests have placed this browsing solution right in the middle of the pack. You’re not going to get life-changing performance with Opera, but you will get a connection and browsing experience that you can rely on. 

Unlike Chrome and Firefox, Opera also relies more heavily on in-built features. That means that you don’t need to worry about adding extra functionality to your browser on your own. 

The Opera Developer browser gives today’s design experts a chance to get started with some of the latest tools and features as they roll out from Opera. 

If you want to be on the cutting edge of early experiments with web browsing, the developer stream is a perfect choice. However, it’s worth noting that some of the developer features you can access from this browser won’t be as stable as they should be.


Blisk is an interesting alternative to many of the major browsers on the web today. 

Compared to Opera, Chrome, and Firefox, Blisk doesn’t have nearly as much attention online. However, it may be worth consideration if you’re a growing developer. This browser is specifically designed to give designers a development-first workspace where they can develop and test modern applications as quickly as possible. 

Blisk is the only developer-focused web browser that allows you to access all of the functionality you need for creating sensational online experiences. You can view what your website or app is going to look like on virtually any phone design, from Google Pixel, to the iPhone. What’s more, there are viewing options in landscape or portrait mode too. 

Blisk also shows mobile and desktop designs side by side, so you can compare the UI that users will get whenever they approach a website – no matter where they’re connecting with you from. Other features include:

  • State of the art URL and scroll sync: Blisk automatically synchronizes scroll and URL positions for desktops and mobiles. 
  • Auto-refresh: Whenever you save code changes when working in a browser, Blisk will refresh your tabs and update CSS changes. 
  • DevTools: Blisk delivers DevTools similar to Chrome, you can launch separate DevTools for mobile and desktop and use them to simultaneously inspect the performance. 
  • Error notifications: Blisk automatically monitors potential page errors in JavaScript and resources that fail to load. 
  • Page inspector: Blisk delivers page inspector tools, powering quick inspection of any element on mobile or desktop.

Safari for Developers

Believe it or not, Safari for Developers is a very powerful tool – depending on the kind of websites and online experiences that you want to build. Although this browser option isn’t quite as broad or comprehensive as some of the other options we’ve mentioned so far – it has its benefits. 

For instance, Safari is the best way to make sure that your sites are going to perform amazingly on iPhone, Mac, and iPad technology. 

As Apple becomes an increasingly popular brand around the world, Safari will allow you to connect with viewers in a very specific landscape. Additionally, the Safari developer edition helps you to experiment with a host of advanced features too. 

With Safari for Developers, you can add things like Apple Pay to websites, giving customers more ways to check out online. This could be an excellent way to increase conversions for your ecommerce clients. 

Additionally, picture-in-picture functionality means that you can float a video window from Safari over your desktop or a full-screen app. This makes it easier to follow specific guidelines when you’re working in Safari. 

Safari even has it’s own tab on the Mac App store, where you can explore things like Xcode for creating unique Safari extensions that work specifically for Apple customers.

Exploring Different Development Browsers

As a developer, you’re going to need a very unique selection of tools within your browser to help you get the most out of your designs. 

The average browser simply won’t give you the advanced experience that you need online. That’s why it’s important to experiment with solutions ranging all the way from Google Chrome for developers, to modern solutions like Blisk. 

Whether you decide to go for something tried-and-tested, like Firefox, or something a little more innovative, you’re sure to find that a developer-focused browser helps you to accomplish more. 

p img {display:inline-block; margin-right:10px;}
.alignleft {float:left;}
p.showcase {clear:both;}
body#browserfriendly p, body#podcast p, div#emailbody p{margin:0;}

How To Make Cross-Browser Testing More Efficient With LambdaTest

How To Make Cross-Browser Testing More Efficient With LambdaTest

How To Make Cross-Browser Testing More Efficient With LambdaTest

Suzanne Scacca

2020-02-18T11:00:00+00:00 2020-02-19T01:07:38+00:00

Before consumers sat in front of mobile devices for hours every day, there were numerous browsers and operating systems web designers had to contend with. So, it’s not like the concept of cross-browser testing is new.

Because web browsers don’t always render websites the same way or process data in the manner originally intended, cross-browser testing has long been an important part of web design and development. It’s the only way to ensure that what’s built behind the scenes is properly implemented on the frontend of a website.

But it can quickly become a tedious undertaking if you attempt to review every browser, OS and device on your own.

Fortunately, we’re living in an era where automation is king and we now have a better way of conducting cross-browser tests (and more frequently, too). So, let’s talk about why you need to automate this process and how to do so with the help of LambdaTest.

An Improved Way To Handle Cross-Browser Testing

When you set out to build a website for your users, you account for who they are, what they need and what they will respond to along their journey. But how and when do you address the different outcomes your users might experience thanks to their browser choice?

Responsive design may help mitigate some of these differences, but it’s not a cure-all for the inherent display issues between browsers and devices.

To fully ensure that the code and design choices you’ve made for a website won’t negatively impact users, cross-browser testing throughout the web design process is essential.

And if you want to make sure extensive cross-browser testing doesn’t have a negative impact on your bottom line, then automating it is the way to go.

Here are some tips to help you build automated testing into your process:

Familiarize Yourself With Browser Support Differences

This is a roundup from Statista of the top web browsers by market share:

Statista - top web and mobile browsers 2020
Statista data on the top web and mobile browsers in 2020. (Source: Statista) (Large preview)

Now, the issue here isn’t necessarily that every browser processes your website data differently. What’s really mucking things up is the engine powering the browser behind the scenes.

For example, these are the engines the leading web browsers use:

  • Chrome uses Blink + V8;
  • Edge uses Blink;
  • Firefox uses Quantum/Gecko + SpiderMonkey;
  • Safari uses WebKit + Nitro;
  • Internet Explorer uses Trident + Chakra.

Many of these engines render the same piece of code differently. For example, look at this experiment created by LambdaTest:

LambdaTest Experiment - date time format in Chrome
A LambdaTest Experiment shows how the Chrome browser displays this code snippet. (Source: LambdaTest) (Large preview)

The date HTML tag is one of the most used tags and, yet, Chrome, Firefox and Opera are the only ones that fully support it — as indicated in the top blue bar above the test area. Even then, these browsers provide very different user experiences.

For example, the image above shows you what the date tag looks like in Chrome. Here’s how the same code displays in Edge:

LambdaTest Experiment - date time format in Edge
A LambdaTest Experiment shows how the Edge browser displays this code snippet. (Source: LambdaTest) (Large preview)

Not only does the font styling and sizing slightly different, but the way in which the date selection dropdown appears is vastly different.

So, before you start thinking about cross-browser testing and hammering out the kinks between these browsers and engines, familiarize yourself with the key differences.

A tool you can use as reference is Can I use….

You can look for discrepancies in the most commonly used components and technologies. Take, for instance, CSS grid layout:

Can I use… - CSS Grid Layout browser compatibility
Can I use… keeps track of cross-browser compatibility for CSS Grid Layout. (Source: Can I use…) (Large preview)

Most of the leading (and some not so leading) browsers support CSS grid layout (the ones in green). Internet Explorer (in blue) provides partial support and Opera Mini (in purple) provides none at all.

Or let’s say you’re trying to use more WebP images in your designs as they’re much better for performance and resolution. Here’s what Can I use… tells us about browser support for the image format:

Can I use… - WebP image format browser compatibility
Can I use… data on cross-browser support for the WebP image format. (Source: Can I use…) (Large preview)

The most recent versions of Internet Explorer and Safari (web and mobile) do not provide support for it. So, if you intend on designing with WebP images, you’ll have to create a workaround for these browsers.

Bottom line: Take the time now to understand what kind of content or code is supported, so you can more effectively build a website from the get-go.

Pro Tip: Create a Browser Matrix for Reference

You can see why it’s so important to understand the differences between browser renderings and support. The more you familiarize yourself with them, the less scrambling you’ll have to do when a new discrepancy is discovered.

To make it easier on yourself, it would be a good idea to create a browser matrix for all these differences now.

Here’s a simple one that LambdaTest has designed:

Web browser support matrix example
An example of how web designers can create their own browser support matrices. (Source: LambdaTest) (Large preview)

I’d recommend creating one of your own. You can leverage data from Can I use… as well as documenting support issues you’ve encountered in your own projects.

This will also help you set priorities when you’re designing. For example, you can decide which non-supported features are worth using based on what kind of impact they have on your website’s goals.

It would also be useful to have this spreadsheet on hand once a site has gone live. Using data from Google Analytics, you can start prioritizing design choices based on which web browsers your users primarily use.

Get Yourself A Cross-Browser Testing Tool That Does It All

It doesn’t matter the size of the websites you build. All public-facing sites would benefit from an automated cross-browser testing tool.

What’s especially nice about automating with LambdaTest is that it gives its users options. From fully automated tests that check how your code impacts the frontend to semi-automated tasks that ease the work in managing updates and bugs, there are so many ways to automate and optimize your process.

Here are some of the feature highlights you should know about:

Real Time Testing: Best for Bug Tracking

Real-time testing is useful when there’s something targeted you need to examine with your own two eyes. Like if you’ve shipped a design to the client for review and they insist something doesn’t look right on their end, you can review the website using their exact configuration. It would also be helpful for confirming bugs and sussing out which browsers are impacted.

From the Real-Time Testing panel, you’ll enter your site URL and then choose your viewing specifications.

It lets you get super specific, choosing from:

  • Mac vs. Android,
  • Device type,
  • Device version,
  • Operating system,
  • Web browser.
LambdaTest - Real Time Testing
This is the LambdaTest dashboard area for Real Time Testing. (Source: LambdaTest) (Large preview)

Once the test begins, this is what you’ll see (depending on the type of device you choose, of course):

Real Time Testing with LambdaTest
A Real Time Test conducted by LambdaTest. (Source: LambdaTest) (Large preview)

Above, you can see the first option in the sidebar enables you to quickly switch the device view. That way, if you have a couple of browser views you’re trying to compare or check errors on, you don’t have to backtrack.

As far as the other real-time testing options go, most of them are useful for identifying and reporting issues within the context that they actually happened.

LambdaTest bug tracking
LambdaTest’s Real Time Testing can be used for bug tracking and reporting. (Source: LambdaTest) (Large preview)

In the bug tracking tool above, you can pinpoint a spot on the page where an error has occurred. You can then mark it up using a number of tools on the sidebar.

Users can also use the screenshotting and video options to capture bigger errors — especially ones that occur when you move through or engage with the site.

Screenshot Testing: Best for Speeding Up Manual Testing

There’s no reason you or your QA can’t still review your website on your own. That said, why make the process take longer than it needs to? You can let LambdaTest’s Visual UI Testing tools speed up the process.

The Screenshot tool, for instance, enables you to select all of the devices and browsers you want to compare at once:

LambdaTest simultaneous screenshottin
LambdaTest Visual UI Testing comes with simultaneous cross-browser screenshotting. (Source: LambdaTest) (Large preview)

When the test completes, you’ll have all requested screenshots in one place:

Lambdatest screenshot check for inconsistencies
LambdaTest screenshots enable designers to quickly check for inconsistencies across browsers. (Source: LambdaTest) (Large preview)

You can view them here, download them to your computer or share them with others.

You can also organize your screenshots by project and version/round. That way, if you’re working through multiple rounds of revisions and want to refer back to a previous version, all copies of the previous iteration exist here. (You can also use screenshots in regression testing which I’ll explain shortly.)

Responsive Testing: Best for Confirming a Mobile-first Experience

If you need to see more than just a static screengrab, Responsive tests have you covered. All you need to do is select which OS and devices you want to compare and the tool will populate full working versions of the site in the mobile browser:

LambdaTest responsive testing
LambdaTest includes real-time responsive tests for all OS and devices. (Source: LambdaTest) (Large preview)

You can review your website’s design and interactivity not just in all possible browsers, but you can change the orientation of the site as well (in case issues appear when it goes landscape).

What’s nice about this testing tool is that, if anything appears wonky, you can mark the bug the second you detect it. There’s a button for you to do that directly above the interactive mobile browser. That’ll get those costly mobile errors reported and resolved more quickly.

Smart Testing: Best for Regression Testing

The eye can only detect so much, especially when you’ve been looking at the same section of a web page for weeks.

So, when you start implementing changes on your site — during development, just prior to launch and even afterwards — regression testing is going to be crucial for catching those potentially hard-to-spot issues.

This should take place any time something changes:

  • You manually update part of the design.
  • Code is tweaked on the backend.
  • Someone reports a bug and the fix is implemented.
  • Software is updated.
  • An API is reconnected.

If you know which page and which part of that page are directly impacted, smart testing can make light work of confirming that everything is okay.

Just upload the original screenshot of the impacted page and then add a comparison image when the change has been made. (This is where that Screenshot tool really comes in handy.)

LambdaTest Smart Testing
LambdaTest enables users to do side-by-side comparison tests of web pages. (Source: LambdaTest) (Large preview)

Note: There’s obviously nothing wrong with the Smashing Magazine website. But what I did in the example above is use renderings for different versions of the iPhone. Obviously, that’s not how regression tests work, but I wanted to show you how this comparison feature looks when something’s amiss.

Now, as for why this feature is so awesome, here’s how it works:

LambdaTest layered comparison
LambdaTest users can compare two versions of the same web layered on top of one another. (Source: LambdaTest) (Large preview)

This single screenshot allows you to see where the two versions of your page no longer align. So, if the screenshots had been from the same browser view originally, this could be a problem if you hadn’t planned on realigning all of the elements.

You could also use the side-by-side comparison tests to check the same thing:

LambdaTest side-by-side comparison
LambdaTest users can compare two versions of the same web page side-by-side. (Source: LambdaTest) (Large preview)

Again, smart testing is meant to help you quickly locate and report issues during regression testing. Find the method that works best for you, so you can get these issues resolved as quickly as possible from now on.

Automated Testing: Best for Detecting Issues on a Larger Scale

Technically, everything we’ve looked at so far has some form of automation built in, whether it’s processing 20 different browser screenshots simultaneously or letting you instantly see mobile test interfaces for all iOS and Android devices at once.

That said, the LambdaTest platform also comes with a tool called “Automation”. And what this does is enable you to do Selenium testing in the cloud on over 2,000 browsers. A newer feature, “Lambda Tunnel”, can be used to do Selenium testing on your localhost as well. That way, you can see how your code changes appear even before they go live.

There are tons of benefits to combining LambdaTest with Selenium testing:

  • It’s a highly efficient way to conduct large quantities of cross-browser tests, thereby increasing your browser coverage (something that’s impossible to do manually).
  • With parallel cross-browser tests, you’ll reduce the time spent executing automation tests as a whole.
  • Because Selenium testing starts by identifying your preferred coding language, it can more intelligently detect errors that will appear in browsers.

Of course, the biggest benefit of using the LambdaTest Selenium Automation Grid is that LambdaTest will help you evaluate whether or not your tests pass or fail.

LambdaTest Automated Test (Build View)
LambdaTest can help users qualify cross-browser tests as failures when errors are detected. (Source: LambdaTest) (Large preview)

You still have to review the results to confirm that all errors are true failures and vice versa, but it’s going to save you a lot of time and headaches having LambdaTest do the initial work for you.

Wrapping Up

Cross-browser testing isn’t just about making sure websites are mobile responsive. What we’re ultimately looking to do here is take the guesswork out of web design. There may be over a dozen possible browsers and hundreds of browser/device configurations, but automated cross-browser tests can make checking all of these possibilities and locating errors much easier.

Smashing Editorial (ms, ra, yk, il)
What To Do If People Hate Your Brand Mascot

What To Do If People Hate Your Brand Mascot

What To Do If People Hate Your Brand Mascot

Suzanne Scacca

2020-02-17T13:00:00+00:00 2020-02-18T01:09:50+00:00

There are a number of reasons why businesses decide to use mascots to represent their brands:

  • They want there to be a friendly and reliable face to welcome visitors to the site.
  • They know they need something more than an inventory of products to make an emotional connection with shoppers.
  • They want a strong and recognizable personality that can tie all of their marketing channels together.

While it’s clear that mascots can be invaluable for the business-consumer connection, there’s a very thin line between mascots turning customers into loyal advocates and sending prospects running away in fear.

If you’re struggling to get traction on an existing website and fear the mascot might have something to do with it, this post is for you. You should also keep reading if you’re designing a mascot from-scratch and aren’t sure how to create something your audience will fall in love with.

There’s a very thin line between brand mascots turning customers into loyal advocates and sending prospects running away in fear.

Things You Can Do to Create a Brand Mascot People Love

Not everyone is going to get as lucky as TinyPNG, which has had the same brand mascot for years.

This was the mascot that sat at the top of the page in 2014:

TinyPNG website 2014
A snapshot of the TinyPNG website in 2014 with its panda mascot. (Image source: TinyPNG) (Large preview)

Here it is again in 2017, only it’s a bit brighter and larger in size:

TinyPNG website 2017
A snapshot of the TinyPNG website in 2017 with its panda mascot. (Image source: TinyPNG) (Large preview)

The mascot also started appearing with a crown on the bottom right. This callout encouraged users to subscribe to the Pro tool.

To this day, the website continues to use the mascot in this manner (and with nearly the same layout and content):

TinyPNG website 2020
A snapshot of the TinyPNG website in 2020 with its panda mascot. (Image source: TinyPNG) (Large preview)

The panda mascot works for a number of reasons. It looks very happy, for one. Also, it’s got a welcoming presence, like “Hey, I’m just chilling here, eating my bamboo. Feel free to upload your images whenever.” And it’s downright adorable.

But not every seemingly happy, friendly or cute brand mascot works out this well. Mascots are a subjective thing. It’s like they always say: beauty is in the eye of the beholder.

So, if your audience doesn’t interpret the attractiveness, humor or personality of the mascot as the original creators did, it’s going to be a problem for the business as a whole.

Let’s take a look at what your options are if you suspect that your client’s brand mascot isn’t as adored as they hoped it would be.

Option #1: Modernize It

The first thing to think about is whether or not the mascot is worth salvaging. Is there anything good about the mascot or its personality… or should you start over?

Don’t just go based on your gut. Do some market research and throw some user surveys out there. Maybe message old customers of your client or do a poll on Twitter. You need to know why the mascot isn’t hitting the mark.

Once you’ve nailed down what’s wrong, it’s time to redesign it. Let’s look at some websites that have given their mascots facelifts over the years, starting with HostGator:

HostGator website 2012
A snapshot of the HostGator website from 2012 with its alligator mascot logo and imagery. (Image source: HostGator) (Large preview)

This is what the HostGator website looked like in 2012. The alligator mascot had a heavy presence in the header of the website. His head also appears to be peaking out of the main banner.

Fast forward to 2017 and we see a different side of the HostGator mascot:

HostGator website 2017
A snapshot of the HostGator website from 2017 with its mascot slightly revamped. (Image source: HostGator) (Large preview)

For starters, the alligator in the logo is much smaller, so we can now see the entire body. This gives it a more human-like feeling as opposed to the bottomless gator which more closely resembles a puppet.

The mascot in the main banner is designed the same way it’s always been designed (including the facial expression). However, it’s now donning winter gear for a seasonal touch.

Since then, HostGator has given its mascot a major touchup:

HostGator website 2020
A snapshot of the HostGator website in 2020 with a redesigned alligator mascot. (Image source: HostGator) (Large preview)

Do you know what this redesign looks like to me? It looks like the CGI used in The Irishman.

The Irishman CGI touchup Joe Pesci
Vulture magazine shares a side-by-side look at CGI in the movie The Irishman from Netflix. (Image source: HostGator) (Large preview)

I’m not sure if that was the intention behind HostGator’s mascot redesign, but I’m going to assume that there was some user feedback that suggested that a softer and less intimidating mascot would perform better.

Another website that’s given its well-known mascot a touch-up is Chuck E. Cheese.

This was the Chuck E. Cheese website in 2011:

Chuck E. Cheese website 2011
A snapshot of the Chuck E. Cheese website from 2011 with its cartoon mouse mascot (Image source: Chuck E. Cheese) (Large preview)

Not even a decade ago, the Chuck E. Cheese website and its mascot looked like something out of Nickelodeon. Obviously, a design like this would’ve needed an upgrade no matter what considering how much web design has changed.

This is what the website looks like today:

Chuck E. Cheese website 2020
A snapshot of the Chuck E. Cheese website in 2020 without a mascot. (Image source: Chuck E. Cheese) (Large preview)

Gone are the crazy color palette and illustrations. Today, the website is much more subdued and customer-centric.

That said, the mascot pops up from time-to-time. Obviously, though, it’s undergone a much-needed redesign:

Chuck E. Cheese mascot 2020
The Chuck E. Cheese mascot in 2020. (Image source: Chuck E. Cheese) (Large preview)

The new mascot is still a buck-toothed mouse with a welcoming smile and wave. However, it looks more on par with the kinds of animations you’d see coming out of Pixar than old Saturday morning cartoons.

Even if there’s nothing necessarily wrong with the mascot your website is using, it might be worth looking at upgrading it so it better fits with the times as Chuck E. Cheese has done.

Option #2: Change The Tone Of It

Mascots can be really helpful at getting a brand’s message across — over and over again. However, there may be times when the kind of mascot you’ve chosen (or a lack of one) actually stands in the way of the message you’re trying to convey.

Take the old GEICO mascot: the caveman.

GEICO website 2005 - caveman
A snapshot of the GEICO website in 2005 when it featured the caveman mascot. (Image source: GEICO) (Large preview)

I don’t know that there was anything wrong with the caveman advertisements. They were smart and funny and were lauded for taking on the subject of political correctness.

That said, GEICO’s customer data must’ve told them that a change-up was needed. Maybe the messaging was too serious or the humor went over some people’s heads.

So, they scrapped the caveman mascot for an animated Cockney-accented gecko:

GEICO website 2020 - gecko
A snapshot of the GEICO website in 2020 with its gecko mascot. (Image source: GEICO) (Large preview)

Whereas the cavemen were always offended and storming off whenever someone would say “It’s so easy a caveman could do it”, this anthropomorphic mascot is a much more lighthearted figure in the GEICO landscape. The gecko is always there, ready to provide tips on how to get the most with GEICO.

In other words, it might not be enough to change your mascot to an adorable critter. You might also need to switch up your messaging, too.

While I was writing my last article on mobile storytelling, I did some digging into the alcohol industry. One company, in particular, stood out for its use of a human mascot and storyteller: Aviation Gin.

Now, what I hadn’t covered in that write-up was the fact that Aviation Gin has been around for a while. It was founded in the mid-2000s, long before current co-owner and mascot Ryan Reynolds had anything to do with it.

This was the Aviation Gin website in 2007:

Aviation Gin website 2007
A snapshot of the Aviation Gin website from 2007. (Image source: Aviation Gin) (Large preview)

Granted, these are the early days of the web, so we can’t expect much in the way of design. However, as far as mascots go, there are none to be seen. Unless you count the actual bottle of Aviation Gin.

Nearly 10 years later, Aviation Gin was still rocking the product-centric design:

Aviation Gin website 2016
A snapshot of the Aviation Gin website in 2016. (Image source: Aviation Gin) (Large preview)

It was still very simple in design and the bottle of gin remained the sole focus. Aside from some industry awards, Aviation Gin wasn’t the media darling it is now.

In 2018, Ryan Reynolds bought shares in the company and changed the whole tone of the brand:

Aviation Gin website 2020
A snapshot of the Aviation Gin website in 2020 featuring Ryan Reynolds. (Image source: Aviation Gin) (Large preview)

Today, Ryan Reynolds has become the face of Aviation Gin, pushing it at every turn on his social media. It hasn’t changed the direction of the company itself, but by having a human mascot like Reynolds on its side, the message (and likely the audience, too) has changed.

It’s also opened the brand up to bigger opportunities, like Reynolds’ latest announcement about their partnership with the Westminster Kennel Club Dog Show:

So, if you have a website that performs just “okay” with its audience, a change of tone and pace might be needed. And if you don’t have a mascot yet or one that’s not a good fit, creating one that’s well-designed for a modern-day audience might be exactly what you need.

Option #3: Minimize Its Presence On The Website

Let’s say the mascot’s design and the message it brings with it isn’t the problem. What you suspect is that it’s the amount of space given to it that’s the problem.

This is easy enough to confirm with A/B testing. You’ll just need to study your heatmaps as well as your user personas to come up with some hypotheses about where your mascot should or should not be on the site.

Let’s use Cats Who Code as an example. This was the website back in 2009:

Cats Who Code website 2009
A snapshot of the Cats Who Code website in 2009 with cat logo and imagery. (Image source: Cats Who Code) (Large preview)

Back then, cats were quite prevalent on the site, from the laptop-using cat in the header to the cats in the blog images. What’s more, the tagline of the site “Learn as fast as I catch mice!” made it perfectly clear that the kind of “cats” referred to here wasn’t referring to hip or cool cats. It really was referring to the furry pet.

Skip ahead to 2014 and the cat mascot and tagline has received a makeover:

Cats Who Code website 2014
A snapshot of the Cats Who Code website from 2014 with a new mascot. (Image source: Cats Who Code) (Large preview)

For starters, the mascot has gone from a small tabby to a large black-and-white cat. In addition, the website’s tagline now reads “100% animal-friendly web development blog”. Those are both pretty significant changes.

Now, let’s look at the website in the present day:

Cats Who Code website 2020
A snapshot of the Cats Who Code website in 2020. (Image source: Cats Who Code) (Large preview)

The cat mascot no longer exists in its previous iterations. Now, it’s relegated to a small cat-like icon with code brackets where its face used to be. The website’s cat-friendly messaging is gone, too.

Whether it’s because the cat imagery was distracting or people didn’t like it, this website has undergone a drastic change. Everything is now very buttoned-up.

Another brand that cut back on the appearance of its mascot is Green Giant.

This was the website in 2013:

Green Giant website 2013
A snapshot of the Green Giant website and its mascot in 2013. (Image source: Green Giant) (Large preview)

The jolly green giant mascot is front-and-center on the home page. This is in addition to all the small appearances it makes in every product featured on the site.

In 2016, however, the giant’s likeness was removed from the hero banner and moved up to the logo:

Green Giant website 2016
A snapshot of the Green Giant website in 2016 with the mascot in the logo. (Image source: Green Giant) (Large preview)

It looks like the company was experimenting here, trying to see if moving the mascot’s face to the logo would give them more room to allow their products to shine.

In 2020, though, there’s barely any trace of the mascot left:

Green Giant website 2020
A snapshot of the Green Giant website in 2020. (Image source: Green Giant) (Large preview)

The mascot is gone from the logo as well as the hero image… sort of. It’s subtle, but the mascot’s shadow remains.

The website now appears to be more focused towards sustainability and its mission to contribute to a better world. In that sense, it’s completely justified why the mascot and even the blatant pushing of its products would be moved out of the way.

So, if you feel like your mascot might be getting in the way of getting your point across or perhaps the brand has evolved in a way where a cartoonish figure no longer fits, test out other ways to keep your mascot but in a very lowkey way.

Option #4: Lean Into The Creepiness/Weirdness/Ugliness

One other option you have is to lean into it.

Obviously, you shouldn’t go this route if customers find the mascot to be offensive or boring. If it’s just not working and there’s no way to turn the situation around, just scrap the mascot altogether. You’ll be better off focusing on strengthening your content and building trust that way than to push an already delicate situation.

That said, if you feel like people are reacting negatively to the mascot because of how novel or different it is, then you might want to go crazy with it and see what happens. Before I show you an example of a website that does this, I’m going to show you a real-world example of a sports mascot that turned haters into the biggest of fans.

I was living outside of Philadelphia around the time the Flyers hockey team introduced their new mascot Gritty. It didn’t go over well — at first.

This is how they introduced Gritty:

Philadelphia Flyers Gritty mascot
The Philadelphia Flyers introduce their mascot Gritty on Twitter. (Image source: Twitter) (Large preview)

Here are some of the initial responses people had to the creature with the giant beer gut and flaming-orange googly eyes:

@shocks23 speculated about its origins:

Twitter speculation about Gritty mascot
Twitter user @shocks23 suspects the Flyers’ mascot has a seedy past. (Image source: Twitter)

@aclee_clips expressed fear:

Twitter user scared of Gritty
Twitter user @aclee_clips is horrified by the Philadelphia Flyers’ new mascot. (Image source: Twitter)

And, like so many others, @mirtle was shocked and confused:

Twitter user confused about Gritty mascot
Twitter user @mirtle expresses confusion about Philadelphia Flyers’ mascot. (Image source: Twitter)

However, this isn’t a story of a brand mascot that failed.

The city of Philadelphia (along with the rest of the world) eventually fell in love with Gritty after it posed Kim Kardashian-like with a champagne bottle and entered the arena on a wrecking ball Miley Cyrus-style.

Gritty the mascot meme
Flyers mascot Gritty gets cheeky by posing with a champagne glass on his bum. (Image source: Twitter)

Over the past couple of years, Gritty has worked very hard to win the hearts of consumers bringing a fun and lighthearted approach to everything it does both on the ice as well as off. And win the hearts it has.

Take, for instance, an incident that happened earlier this year when Gritty was accused of hitting a child at a game. The accusation was investigated and Gritty was cleared of the charges. Through it all, fans had the mascot’s back.

Twitter users love team mascot Gritty
Twitter users love Gritty even in the face of scandal. (Image source: (Image source: Twitter)

If you can create a mascot with the right kind of personality, message and purpose, your website and brand will be able to experience this kind of die-hard fandom and support.

That said, this is social media we’re talking about. While the Flyers’ have gone all-in on showing off Gritty in the most awkward of situations or while humorously riffing on pop culture, the website itself only has one page where the mascot appears:

Get to Know Gritty fan page
The Get to Know Gritty fan page on the Philadelphia Flyers website. (Image source: Philadelphia Flyers (Large preview)

So, leaning into an awkward/strange/nightmare-inducing mascot might not be right for every site. Here’s one very well-known example where it was the right call:

This is the Mucinex website from 2010:

Mucinex website 2010
A snapshot of the Mucinex website in 2010 featuring its fat, green mucus mascot. (Image source: Mucinex) (Large preview)

If you ask me, this is one of the grossest mascots ever created. It’s literally mucus in human-like form. And yet, it works somehow because it’s done in a humorous manner.

In 2015, Mr. Mucus took on a sweaty and ill-looking appearance:

Mucinex website 2015
A snapshot of the Mucinex website in 2015 with its mucus mascot. (Image source: Mucinex) (Large preview)

This is the only look we get at Mr. Mucus on the website and I’m not sure it worked out very well for the brand. That may be because the mascot resembles Jabba the Hutt instead of a fun-loving mucus ball you want to watch walk down the aisle with Mrs. Mucus.

Nevertheless, the company pushed forward with the mascot, giving it even more airtime. The 2020 version of the website has Mr. Mucus appearing in various states:

Mucinex website 2020 - Mr. Mucus nervous
The Mucinex 2020 website shows off Mr. Mucus in different states. This is the mascot nervous about shipping. (Image source: Mucinex) (Large preview)

This looks similar to the Mr. Mucus we saw in 2015. However, something about the messaging in this banner gives his facial expression and clammy skin a different vibe this time around. It says, “Please don’t order this cold medicine. I don’t want to go away!”

In another banner image, we see Mr. Mucus rocking a dad bod alongside a message about working out:

Mucinex website 2020 - Mr. Mucus dad bod
The Mucinex 2020 website shows off Mr. Mucus in different states. This is the mascot with its dad bod. (Image source: Mucinex) (Large preview)

The mascot is still pretty gross, but there’s no denying how funny this image is. And then you have this banner that’s targeted at cold remedies for kids:

Mucinex website 2020 - Mr. Mucus kid
The Mucinex 2020 website shows off Mr. Mucus in different states. This is the mascot in kid form. (Image source: Mucinex) (Large preview)

I’m not sure if this is supposed to be Mr. Mucus as a kid or the child he had with Mrs. Mucus, but it’s another creative adaptation of the mascot.

According to CBC, Mucinex made a ton of money after launching its Mr. Mucus campaign in 2004, more than doubling its profits. And despite Mr. Mucus being one of the most recognizable mascots, it is also one of the least liked, too.

In this case, being hated was a good thing. Mucinex wanted its customers to be disgusted by Mr. Mucus. The whole purpose of the company is to help people fight off phlegmy throats and stuffed noses.

So, before you throw your hated mascot away, think about where the hate is coming from and if you can make it work to your advantage in another way.

If you can create a mascot with the right kind of personality, message and purpose, your website and brand will be able to experience this kind of die-hard fandom and support.

Wrapping Up

If your website could benefit from a little levity, a mascot would be a fantastic way to draw visitors into the content of your website as well as into the brand’s story. That doesn’t mean that every mascot should draw laughs or be shocking. There are plenty of recognizable and well-loved mascots that have subdued personalities. It’s all about working with the personality of your brand and fitting a mascot to it.

Further Reading on SmashingMag:

Smashing Editorial (ra, il)
Privacy Settings
We use cookies to enhance your experience while using our website. If you are using our Services via a browser you can restrict, block or remove cookies through your web browser settings. We also use content and scripts from third parties that may use tracking technologies. You can selectively provide your consent below to allow such third party embeds. For complete information about the cookies we use, data we collect and how we process them, please check our Privacy Policy
Consent to display content from Youtube
Consent to display content from Vimeo
Google Maps
Consent to display content from Google