emGee Software Solutions Custom Database Applications

Share this

Web Design

Getting Started With The Web MIDI API

Smashing Magazine - Mon, 03/19/2018 - 05:15

As the web continues to evolve and new browser technologies continue to emerge, the line between native and web development becomes more and more blurred. New APIs are unlocking the ability to code entirely new categories of software in the browser.

Until recently, the ability to interact with digital musical instruments has been limited to native, desktop applications. The Web MIDI API is here to change that.

In this article, we’ll cover the basics of MIDI and the Web MIDI API to see how simple it can be to create a web app that responds to musical input using JavaScript.

What Is MIDI?

MIDI has been around for a long time but has only recently made its debut in the browser. MIDI (Musical Instrument Digital Interface) is a technical standard that was first published in 1983 and created the means for digital instruments, synthesizers, computers, and various audio devices to communicate with each other. MIDI messages relay musical and time-based information back and forth between devices.

“You must unlearn what you have learned!” Meet the brand new episode of SmashingConf San Francisco with smart front-end tricks and UX techniques. Featuring Yiying Lu, Aarron Draplin, Smashing Yoda, and many others. Tickets now on sale. April 17-18.

Check the speakers →

A typical MIDI setup might consist of a digital piano keyboard which can send messages relaying information such as pitch, velocity (how loudly or softly a note is played), vibrato, volume, panning, modulation, and more to a sound synthesizer which converts that into audible sound. The keyboard could also send its signals to desktop music scoring software or a digital audio workstation (DAW) which could then convert the signals into written notation, save them as a sound file, and more.

MIDI is a fairly versatile protocol, too. In addition to playing and recording music, it has become a standard protocol in stage and theater applications, as well, where it is often used to relay cue information or control lighting equipment.

MIDI lets digital instruments, synthesizers, and software talk to each other and is frequently used in live shows and theatrical productions. Photo by Puk Khantho on Unsplash. MIDI In The Browser

The WebMIDI API brings all the utility of MIDI to the browser with some pretty simple JavaScript. We only need to learn about a few new methods and objects.


First, there’s the navigator.requestMIDIAccess() method. It does exactly what it sounds like—it will request access to any MIDI devices (inputs or outputs) connected to your computer. You can confirm the browser supports the API by checking for the existence of this method.

if (navigator.requestMIDIAccess) { console.log('This browser supports WebMIDI!'); } else { console.log('WebMIDI is not supported in this browser.'); }

Second, there’s the MIDIAccess object which contains references to all available inputs (such as piano keyboards) and outputs (such as synthesizers). The requestMIDIAccess() method returns a promise, so we need to establish success and failure callbacks. And if the browser is successful in connecting to your MIDI devices, it will return a MIDIAccess object as an argument to the success callback.

navigator.requestMIDIAccess() .then(onMIDISuccess, onMIDIFailure); function onMIDISuccess(midiAccess) { console.log(midiAccess); var inputs = midiAccess.inputs; var outputs = midiAccess.outputs; } function onMIDIFailure() { console.log('Could not access your MIDI devices.'); }

Third, MIDI messages are conveyed back and forth between inputs and outputs with a MIDIMessageEvent object. These messages contain information about the MIDI event such as pitch, velocity (how softly or loudly a note is played), timing, and more. We can start collecting these messages by adding simple callback functions (listeners) to our inputs and outputs.

Going Deeper

Let’s dig in. To send MIDI messages from our MIDI devices to the browser, we’ll start by adding an onmidimessage listener to each input. This callback will be triggered whenever a message is sent by the input device, such as the press of a key on the piano.

We can loop through our inputs and assign the listener like this:

function onMIDISuccess(midiAccess) { for (var input of midiAccess.inputs.values()) input.onmidimessage = getMIDIMessage; } } function getMIDIMessage(midiMessage) { console.log(midiMessage); }

The MIDIMessageEvent object we get back contains a lot of information, but what we’re most interested in is the data array. This array typically contains three values (e.g. [144, 72, 64]). The first value tells us what type of command was sent, the second is the note value, and the third is velocity. The command type could be either “note on,” “note off,” controller (such as pitch bend or piano pedal), or some other kind of system exclusive (“sysex”) event unique to that device/manufacturer.

For the purposes of this article, we’ll just focus on properly identifying “note on” and “note off” messages. Here are the basics:

  • A command value of 144 signifies a “note on” event, and 128 typically signifies a “note off” event.
  • Note values are on a range from 0–127, lowest to highest. For example, the lowest note on an 88-key piano has a value of 21, and the highest note is 108. A “middle C” is 60.
  • Velocity values are also given on a range from 0–127 (softest to loudest). The softest possible “note on” velocity is 1.
  • A velocity of 0 is sometimes used in conjunction with a command value of 144 (which typically represents “note on”) to indicate a “note off” message, so it’s helpful to check if the given velocity is 0 as an alternate way of interpreting a “note off” message.

Given this knowledge, we can expand our getMIDIMessage handler example above by intelligently parsing our MIDI messages coming from our inputs and passing them along to additional handler functions.

function getMIDIMessage(message) { var command = message.data[0]; var note = message.data[1]; var velocity = (message.data.length > 2) ? message.data[2] : 0; // a velocity value might not be included with a noteOff command switch (command) { case 144: // noteOn if (velocity > 0) { noteOn(note, velocity); } else { noteOff(note); } break; case 128: // noteOff noteOff(note); break; // we could easily expand this switch statement to cover other types of commands such as controllers or sysex } } Browser Compatibility And Polyfill

As of the writing of this article, the Web MIDI API is only available natively in Chrome, Opera, and Android WebView.

The Web MIDI API is only available natively in Chrome, Opera, and Android WebView.

For all other browsers that don’t support it natively, Chris Wilson’s WebMIDIAPIShim library is a polyfill for the Web MIDI API, of which Chris is a co-author. Simply including the shim script on your page will enable everything we’ve covered so far.

<script src="WebMIDIAPI.min.js"></script> <script> if (navigator.requestMIDIAccess) { //... returns true </script>

This shim also requires Jazz-Soft.net’s Jazz-Plugin to work, unfortunately, which means it’s an OK option for developers who want the flexibility to work in multiple browsers, but an extra barrier to mainstream adoption. Hopefully, within time, other browsers will adopt the Web MIDI API natively.

Is your pattern library up to date today? Alla Kholmatova has just finished a fully fledged book on Design Systems and how to get them right. With common traps, gotchas and the lessons she learned. Hardcover, eBook. Just sayin'.

Table of Contents → Making Our Job Easier With WebMIDI.js

We’ve only really scratched the surface of what’s possible with the WebMIDI API. Adding support for additional functionality besides basic “note on” and “note off” messages starts to get much more complex.

If you’re looking for a great JavaScript library to radically simplify your code, check out WebMidi.js by Jean-Philippe Côté on Github. This library does a great job of abstracting all the parsing of MIDIAccess and MIDIMessageEvent objects and lets you listen for specific events and add or remove listeners in a much simpler way.

WebMidi.enable(function () { // Viewing available inputs and outputs console.log(WebMidi.inputs); console.log(WebMidi.outputs); // Retrieve an input by name, id or index var input = WebMidi.getInputByName("My Awesome Keyboard"); // OR... // input = WebMidi.getInputById("1809568182"); // input = WebMidi.inputs[0]; // Listen for a 'note on' message on all channels input.addListener('noteon', 'all', function (e) { console.log("Received 'noteon' message (" + e.note.name + e.note.octave + ")."); } ); // Listen to pitch bend message on channel 3 input.addListener('pitchbend', 3, function (e) { console.log("Received 'pitchbend' message.", e); } ); // Listen to control change message on all channels input.addListener('controlchange', "all", function (e) { console.log("Received 'controlchange' message.", e); } ); // Remove all listeners for 'noteoff' on all channels input.removeListener('noteoff'); // Remove all listeners on the input input.removeListener(); }); Real-World Scenario: Building A Breakout Room Controlled By A Piano Keyboard

A few months ago, my wife and I decided to build a “breakout room” experience in our house to entertain our friends and family. We wanted the game to include some kind of special effect to help elevate the experience. Unfortunately, neither of us have mad engineering skills, so building complex locks or special effects with magnets, lasers, or electrical wiring was outside the realm of our expertise. I do, however, know my way around the browser pretty well. And we have a digital piano.

Thus, an idea was born. We decided that the centerpiece of the game would be a series of passcode locks on a computer that players would have to “unlock” by playing certain note sequences on our piano, a la Willy Wonka.

This is a musical lock

Sound cool? Here’s how I did it.


We’ll begin by requesting WebMIDI access, identifying our keyboard, attaching the appropriate event listeners, and creating a few variables and functions to help us step through the various stages of the game.

// Variable which tell us what step of the game we're on. // We'll use this later when we parse noteOn/Off messages var currentStep = 0; // Request MIDI access if (navigator.requestMIDIAccess) { console.log('This browser supports WebMIDI!'); navigator.requestMIDIAccess().then(onMIDISuccess, onMIDIFailure); } else { console.log('WebMIDI is not supported in this browser.'); } // Function to run when requestMIDIAccess is successful function onMIDISuccess(midiAccess) { var inputs = midiAccess.inputs; var outputs = midiAccess.outputs; // Attach MIDI event "listeners" to each input for (var input of midiAccess.inputs.values()) { input.onmidimessage = getMIDIMessage; } } // Function to run when requestMIDIAccess fails function onMIDIFailure() { console.log('Error: Could not access MIDI devices.'); } // Function to parse the MIDI messages we receive // For this app, we're only concerned with the actual note value, // but we can parse for other information, as well function getMIDIMessage(message) { var command = message.data[0]; var note = message.data[1]; var velocity = (message.data.length > 2) ? message.data[2] : 0; // a velocity value might not be included with a noteOff command switch (command) { case 144: // note on if (velocity > 0) { noteOn(note); } else { noteOff(note); } break; case 128: // note off noteOffCallback(note); break; // we could easily expand this switch statement to cover other types of commands such as controllers or sysex } } // Function to handle noteOn messages (ie. key is pressed) // Think of this like an 'onkeydown' event function noteOn(note) { //... } // Function to handle noteOff messages (ie. key is released) // Think of this like an 'onkeyup' event function noteOff(note) { //... } // This function will trigger certain animations and advance gameplay // when certain criterion are identified by the noteOn/noteOff listeners // For instance, a lock is unlocked, the timer expires, etc. function runSequence(sequence) { //... } Step 1: Press Any Key To Begin

To kick off the game, let’s have the players press any key to begin. This is an easy first step which will clue them into how the game works and also start a countdown timer.

function noteOn(note) { switch(currentStep) { // If the game hasn't started yet. // The first noteOn message we get will run the first sequence case 0: // Run our start up sequence runSequence('gamestart'); // Increment the currentStep so this is only triggered once currentStep++; break; } } function runSequence(sequence) { switch(sequence) { case 'gamestart': // Now we'll start a countdown timer... startTimer(); // code to trigger animations, give a clue for the first lock break; } } Step 2: Play The Correct Note Sequence

For the first lock, the players must play a particular sequence of notes in the right order. I’ve actually seen this done in a real breakout room, only it was with an acoustic upright piano rigged to a lock box. Let’s re-create the effect with MIDI.

For every “note on” message received, we’ll append the numeric note value to an array and then check to see if that array matches a predefined array of note values.

We’ll assume some clues in the breakout room have told the players which notes to play. For this example, it will be the beginning of the tune to “Amazing Grace” in the key of F major. That note sequence would look like this.

This is the correct sequence of notes that we’ll be listening for as the solution to the first lock.

The MIDI note values in array form would be: [60, 65, 69, 65, 69, 67, 65, 62, 60].

var correctNoteSequence = [60, 65, 69, 65, 69, 67, 65, 62, 60]; // Amazing Grace in F var activeNoteSequence = []; function noteOn(note) { switch(currentStep) { // ... (case 0) // The first lock - playing a correct sequence case 1: activeNoteSequence.push(note); // when the array is the same length as the correct sequence, compare the two if (activeNoteSequence.length == correctNoteSequence.length) { var match = true; for (var index = 0; index < activeNoteSequence.length; index++) { if (activeNoteSequence[index] != correctNoteSequence[index]) { match = false; break; } } if (match) { // Run the next sequence and increment the current step runSequence('lock1'); currentStep++; } else { // Clear the array and start over activeNoteSequence = []; } } break; } } function runSequence(sequence) { switch(sequence) { // ... case 'lock1': // code to trigger animations and give clue for the next lock break; } } Step 3: Play The Correct Chord

The next lock requires the players to play a combination of notes at the same time. This is where our “note off” listener comes in. For every “note on” message received, we’ll add that note value to an array; for every “note off” message received, we’ll remove that note value from the array. Therefore, this array will reflect which notes are currently being pressed at any time. Then, it’s a matter of checking that array every time a note value is added to see if it matches a master array with the correct values.

For this clue, we’ll make the correct answer a C7 chord in root position starting on middle C. That looks like this.

These are the four notes that we’ll be listening for as the solution to the second lock.

The correct MIDI note values for this chord are: [60, 64, 67, 70].

var correctChord = [60, 64, 67, 70]; // C7 chord starting on middle C var activeChord = []; function noteOn(note) { switch(currentStep) { // ... (case 0, 1) case 2: // add the note to the active chord array activeChord.push(note); // If the array is the same length as the correct chord, compare if (activeChord.length == correctChord.length) { var match = true; for (var index = 0; index < activeChord.length; index++) { if (correctChord.indexOf(activeChord[index]) < 0) { match = false; break; } } if (match) { runSequence('lock2'); currentStep++; } } break; } function noteOff(note) { switch(currentStep) { case 2: // Remove the note value from the active chord array activeChord.splice(activeChord.indexOf(note), 1); break; } } function runSequence(sequence) { switch(sequence) { // ... case 'lock2': // code to trigger animations, stop clock, end game stopTimer(); break; } }

Now all that’s left to do is to add some additional UI elements and animations and we have ourselves a working game!

Here’s a video of the entire gameplay sequence from start to finish. This is running in Google Chrome. Also shown is a virtual MIDI keyboard to help visualize which notes are currently being played. For a normal breakout room scenario, this can run in full-screen mode and with no other inputs in the room (such as a mouse or computer keyboard) to prevent users from closing the window.

WebMIDI Breakout Game Demo (watch in Youtube)

If you don’t have a physical MIDI device laying around and you still want to try it out, there are a number of virtual MIDI keyboard apps out there that will let you use your computer keyboard as a musical input, such as VMPK. Also, if you’d like to further dissect everything that’s going on here, check out the complete prototype on CodePen.

See the Pen WebMIDI Breakout Room Demo by Peter Anglea (@peteranglea) on CodePen.


MIDI.org says that “Web MIDI has the potential to be one of the most disruptive music [technologies] in a long time, maybe as disruptive as MIDI was originally back in 1983.” That’s a tall order and some seriously high praise.

I hope this article and sample app has gotten you excited about the potential that this API has to spur the development of new and exciting kinds of browser-based music applications. In the coming years, hopefully, we’ll start to see more online music notation software, digital audio workstations, audio visualizers, instrument tutorials, and more.

If you want to read more about Web MIDI and its capabilities, I recommend the following:

And for further inspiration, here are some other examples of the Web MIDI API in action:

(rb, ra, hj, il)
Categories: Web Design

Deploy PHP Web Applications Using Laravel Forge

Tuts+ Code - Web Development - Mon, 03/19/2018 - 05:00

Developers love to automate things—for every process between development and production, they are keen to have a script that makes their workflow easier. This is also the case with deployment.

The process of pushing the final build and deploying the app should be as easy as pressing a Deploy now button, but that is not what happens most of the time. We end up investing our time and resources in configuring the server, setting up the environment, moving files that we thought were not relevant for production builds, and so on. 

Some of us prefer to send files to the server manually using FTP or have the code pushed into a GitHub repo, whereas others prefer a deployment tool to make the process easier. One such tool that makes PHP deployment a breeze is Laravel Forge. 

Don't let the Laravel brand name mislead you. Apart from Laravel, you can use the service to host WordPress, Symphony, Statamic, or any other web project as long as it's PHP. Personally, I like Laravel Forge for its simplicity and ease of getting used to. 

In this tutorial, I am going to take you through the steps to hook Laravel Forge with AWS and explore what it has to offer.


Laravel Forge lets you spin up cloud servers and handle deployment processes using Git and some of the popular server providers available. The process is explained below:

First, you will need to connect AWS or any other cloud provider to your Forge account. Next, link your source control such as GitHub to Forge. You will now be able to create servers. Install your source control repository on the server. Finally, press the deploy button. Easy enough, right?

Servers provisioned with Laravel Forge come shipped with the following stack:

  • Ubuntu 16.06 
  • Nginx
  • PHP 7.2/7.1/7.0/5.6
  • MySQL/MariaDB/Postgres
  • Redis
  • Memcached

Once the server has been created, you can further configure things. 

When you sign up, you can choose between the different plans that they offer. I opted for the $12/month basic plan; however, you will get a free trial with access to everything on the list for five days. 

Once you've logged in, you will see something like this below. 

You can choose between Digital Ocean, AWS, Linode, and Vultr for the service provider. Alternatively, you can use Forge with a custom VPC too. As for the source control, Forge supports GitHub, GitLab, and Bitbucket. In this tutorial, I am going to discuss the basics of configuring AWS to work with Forge and GitHub for source control. Once you are done, you will be able to create and provision any number of servers.

If you're using another service provider on the list, you can skip this step and catch up with us later, after we've configured AWS and Laravel Forge.

Setting Up Laravel Forge and AWS

To set up Forge and AWS, here are the steps that you need to follow.

1. Log in to Laravel Forge

Log in to Laravel Forge and choose AWS as the service provider. You'll be asked for an Access Key ID (key) and a Secret Access Key (secret). You will need to create a specific IAM user with a policy that provides sufficient access to Laravel Forge. IAM is Amazon's way of mapping permissions on each user so that you can revoke access if anything goes wrong.

2. Create a New IAM User

Sign in to AWS Console and create a new IAM user.

Give the user a meaningful name and check the box that says Programmatic Access.

3. Choose the Right Policy

Set the right permission for the laravel-forge IAM user. Create a new user group because user groups are ideal for managing permissions. Now the natural question is, "What policies should the forge user have access to?" Although you could provide it with AdministratorAccess, you shouldn't. 

If you need Forge to create and provision servers on your behalf, you will need to add two policies:

  1. AmazonEC2FullAccess
  2. AmazonVPCFullAccess
4. Save the Credentials and Confirm

Confirm the IAM account and, on the next page, you'll find the Access Key and the Secret Code. 

Head over to the Laravel Forge page and paste them there. That's it.

5. Link Your GitHub Account to Forge

Connect your GitHub/Bitbucket account to Forge if you haven't done that already. Forge will add a public key to your account when you create a server. If you need to add a new service provider and/or update the source control, you have those options inside your profile.

Creating a New Server

Go to Create Server page to add a new server. 

Choose t2.micro with 1GB RAM if you're on AWS free tier. As for the other settings, I am going to go with the defaults. This includes MySQL for the database and PHP version 7.2.  You can customize the database name later on. To keep things simple, I've decided not to use a load balancer. If you're wondering about the post-production recipe, I have covered that towards the end of this tutorial.

It might take up to five minutes for the server to be created. You will be given the credentials for the sudo access. Store them in a secure place so that you can use them in the future. To see that things are working as expected, go to the server's IP address and you should see the output of phpinfo() on your screen.

Server Management Interface

The interface that you see after creating a server is the server management dashboard. 

You can do a whole lot of things here, such as:

  • site management
  • adding SSH keys
  • database configuration
  • updating PHP settings
  • scheduling a task
  • starting a daemon
  • managing network and configure firewall
  • monitoring application using Blackfire or Papertail
  • configuring meta settings

That's a lot of features bundled in there. I've covered the important ones in this tutorial. Let's start with the site management. As per the Forge docs:

Sites represent each "domain" on your server. The "default" site is included with each freshly provisioned server; however, you should delete it and create a new site with a valid domain name when you are ready to launch your production site. 

As you can see, Forge has already set up a default site for us. You can create any number of sites and route them to your subdomains. For the purpose of this tutorial, I will stick to the default site. The web directory is set to /public by default. This is how it should be configured for Laravel and most other web applications. 

If you click on a specific site, you will see the site management interface. You can manage, deploy, and configure individual sites from here. 

Site Management Interface

Here is what the interface initially looks like. 

You can either install from a Git repository or install WordPress. For the purpose of this tutorial, I've created a sample Contact us application that you can fork into your account. You can specify the name of the project and the branch. Once you're done, you should have the controls for deploying your application. 

I will give you a quick tour of the options available.

Deploy Now and Quick Deploy

To deploy, you can manually deploy using the Deploy now button. Alternatively, you can enable the Quick Deploy option, which automatically deploys the project when you push code into the master branch of the chosen GitHub repo. 

Deployment Script

The default deploy script pulls code from the repository, installs dependencies, starts the server, and runs migrations every time the app is deployed. Here's the actual deployment script.

cd /home/forge/redmonark.com git pull origin laravelapi composer install --no-interaction --prefer-dist --optimize-autoloader echo "" | sudo -S service php7.2-fpm reload if [ -f artisan ] then php artisan migrate --force fi

If you need to tweak it and add something extra, you can.

Deployment Trigger URL

You can use this to integrate your app into a third-party service or create a custom deployment script. When the URL receives a request, the deployment script is triggered. 

Update the Repo and the Branch

If you need to update the branch or install a newer version of the same project on a different repository, you can use these options. If you are updating the branch, you might have to update the branch name in the deployment script too.


Forge automatically generates an environment file for the application. Some of the details such as database credentials are automatically added to the environment. However, if the app uses an API, you can place the API key safely in the environment. Even if you're running a generic PHP web app, you can access the ENV variables using the getenv() method.

Queue Worker

Starting a queue worker in Forge is the same as running the queue:work Artisan command. Forge manages queue workers using a process monitor called Supervisor so that the process keeps on running permanently. You can create multiple queues based on queue priority or any other classification that you find useful.


Securing SSL for a website was anything but easy and free in the past. Forge lets you install an existing certificate or you can obtain a free certificate from LetsEncrypt. It's fast and easy. If you need SSL for wildcard subdomains, you can add the free Cloudflare certificates to Forge.

Back to the Server Management interface, we have SSH keys.

Adding SSH Keys

Although most of the configurable options are available on the dashboard, if you need to connect to the server, you should do that using SSH. SSH is the more secure way of logging into a VPS and provides more protection than passwords. 

To access the server via SSH, you will need to generate a key pair if you haven't already. The public key will be made accessible to the server, and the private key will reside in your host. You can then use the setup to connect to the server instance. 

Note: The SSH key added from the server management dashboard will be specific to that server. If you need to automatically add keys to all the servers from here on, you can add them from your Profile settings.

To generate a key pair, run the following command.

ssh-keygen -t rsa

You will be asked a couple of questions such as the file where you would like to store the key and the passphrase for additional security. Next, add the SSH key to the ssh-agent.

ssh-add ~/.ssh/id_rsa

Copy the public key and add it to Forge's list of SSH keys.

cat ~/.ssh/id_rsa.pub # Copy the output of this commandConfiguring PHP and MySQL

You can use the interface to configure PHP and MySQL. For the database, the available options include:

  • Create new databases.
  • Add new users.
  • Update users' access to a database.
  • Update Forge's knowledge about the password.

Make sure that you fill in the updated data in your .env file. 

You can configure the following PHP settings:

  • Upgrade to the latest version of PHP.
  • Change the upload file size.
  • Optimize OPCache for production so that the compiled PHP code will be stored in memory.
Other Important Settings

Here I've listed some of the other settings available.

Scheduling a Task

You can use Forge's scheduler to schedule recurring tasks or run cron jobs. If you need to send out email periodically, clean up something, or run a script, you can use the task scheduler. A task is created by default that runs composer self-update on a nightly basis. You can try scheduling a new one with a frequency of your choice.

Starting a Daemon

A daemon is a computer program that runs in a background process. Laravel Forge lets you start a daemon and uses Supervisor to ensure that the daemon stays running. If the daemon crashes for some reason, Supervisor will restart the script automatically. 

Monitoring the Application

Laravel Forge has built-in support for tools that monitor your application for performance measures by gathering data about the resources such as memory, CPU time, and I/O operations. The tools available are Blackfire.io and Papertrail. To start profiling your application, you just need to retrieve the right credentials from the third-party website and that's it.

Configuring the Server Network and Firewall

If you need to update the firewall settings, you don't have to go to the AWS console to make that happen. You can create new firewall rules from the dashboard. If you have other servers provisioned using the same provider and region, you can set up a server network so that they can communicate painlessly. 


Laravel Forge is an incredible tool that makes deployment a piece of cake. It has tons of features and an easy-to-use UI that lets you create and provision servers and deploy applications without any hassle. Once you've configured the service provider, chances are high that you won't need to access the AWS console for managing the server again. 

In this tutorial, I've covered the basics for configuring AWS with Laravel Forge and the steps for provisioning a server and deploying an application. I've also discussed almost all the features available in the Forge interface.

For those of you who are either just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study in Envato Market.

Do you have any experience to share with deploying PHP applications using Laravel Forge or any other popular deployment tool? Let us know in the comments. 

Categories: Web Design

Monthly Web Development Update 3/2018: Service Workers, Building A CDN, And Cheating At Design

Smashing Magazine - Fri, 03/16/2018 - 06:29

Service Worker is probably one of the most misrepresented technologies we currently have. When I hear people talking about it, the topic almost always revolves around serving an app when a user is offline. However, Service Worker can do so much more than that, and every week I come across new articles that show how powerful the technology really is.

This month, for example, we can learn how to use Service Worker for cross-tab messaging and to load off requests into the background with the Background Sync API. I think the toolset we now have in our browsers already allows us to build great experiences regardless of the network state. Now it’s up to us to make the experiences so great that users truly love them. And that’s probably the hardest part.

News Sketch 49 has arrived, and with it comes the new Prototyping in Sketch feature which lets you see the entire flow in action. (Image credit)

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features → General
  • Ed Ellson examined Chrome’s Background Sync API and the retry strategy it uses to perform a request. By allowing synchronization in the background after a first attempt has failed, the API helps us improve the browsing experience for users who go offline or are on unstable connections.
UI/UX Use color and weight to create visual hierarchy instead of size is only one of the seven practical tips for cheating at design that Adam Wathan and Steve Schoger share. (Image credit) Security
  • With GraphQL you can query exactly what you want whenever you want. This is amazing for working with an API but also has complex security implications. Instead of asking for legitimate, useful data, a malicious actor could submit an expensive, nested query to overload your server, database, network, or all of these. To prevent this from happening, Max Stoiber shows us how we can secure the GraphQL API in our projects.
  • WebKit is introducing the Storage Access API. The new API targets one of the major issues with Safari’s Intelligent Tracking Protection (ITP): Identifying users who are logged in to a first-party service but view content of it embedded on a third party (YouTube videos on a blog, for example). The Storage Access API allows third-party embeds to request access to their first-party cookies when the user interacts with them. A good solution to protect user privacy by default and allow exceptions on request.
Web Performance
  • Janos Pasztor built his own Content Delivery Network because he thinks it can be a better solution than using existing third parties. The code for the CDN of his personal website is now available on Github. A nice web performance article that looks at common solutions from a different angle.
  • A year after Facebook’s announcement to broadly use Cache-Control: Immutable, Paul Calvano examined how widespread its usage is on the web — apart from the few big players. Interesting research and it’s still sad to see that this useful performance tool is used so little. At Colloq, we use it quite a lot, which saves us a lot of traffic and load on our servers and enables us to serve a lot of pages nearly instantly to recurring users.
Global stats for the custom CDN that Janos Pasztor built. (Image credit) HTML & SVG JavaScript CSS Accessibility The Accessibility Checklist helps build accessibility into your process no matter your role or stage in a project. (Image credit) Work & Life
  • This week I read an article by Alex Duloz, and his words still stick with me: “When we develop a new application, when we post content on the Internet, whatever we do that people will have access to, we should consider just for a minute if our contribution adds up to the level of dumbness kids/teenagers are exposed to. If it does, we should refrain from going live.” The truth is, most of us, including me, don’t consider this before posting on the Internet. We create funny things, share funny pictures and try to get fame with silly posts. But in reality, we shape society with this. Let’s try to provide more useful resources and make the consumption of this more enjoyable so young people can profit from our knowledge and not only view things we think are funny. “We should always consider how teenagers will use what we release.”
  • The MIT OpenCourseWare released a lot of free audio and video lectures. This is amazing news and makes great content available to broader masses.
  • Jake Knapp says great work requires idealism and cynicism and has strong arguments to back up this theory. An article worth reading.
  • There’s an important article on how unhappiness has grown in America’s population since around the year 2000. It reveals that while income inequality might play a role, the more important aspect is that young people who use a lot of digital media are unhappier than those who use it only up to an hour a day. Interestingly, people who don’t use digital media at all, are unhappy, too, so the outcome of this could be that we should try to use digital media only moderately — at least in our private lives. I bet it’ll make a big difference.
  • Following the theory of Michael Bradley, projects don’t necessarily need a roadmap for success. Instead, he suggests to create a moral compass that points out why the project exists and what its purpose is.
Going Beyond…

We hope you enjoyed this Web Development Update. The next one is scheduled for April 13th. Stay tuned.

Categories: Web Design

Getting Started With the Mojs Animation Library: The Burst Module

Tuts+ Code - Web Development - Fri, 03/16/2018 - 05:00

We started this series by learning how to animate HTML elements using mojs. In the second tutorial, we moved on to animation of built-in SVG shapes using the Shape module. The third tutorial covered more ways of animating SVG shapes using the ShapeSwirl and stagger modules.

Now, we will learn how to animate different SVG shapes in a burst formation using the Burst module. This tutorial will depend on concepts we covered in the previous three tutorials. If you have not already read them, I would suggest that you go through them first.

Creating Basic Burst Animations

The first thing that we need to do before we can create any burst animations is instantiate a Burst object. After that, we can just specify the values of different properties to control how the animation plays out. The names of a lot of properties in the Burst module are the same as the properties in the Shape module. However, these properties perform very different tasks in this case.

The left and right properties determine the initial position of the burst instead of particles inside it. Similarly, the x and y properties determine the shift of the whole burst instead of individual particles.

The radius of the circle formed by all the burst particles is controlled by the radius property. This is very different from the radius property of individual shapes, which determines the size of those shapes. In the case of a burst, the radius determines how much further apart the individual shapes in it are going to be.

The number of shapes or particles in a single burst can be specified using the count property. By default, there will be five particles in each burst that you create. All these particles are evenly spaced over the circumference of the burst. For example, if there are four particles, they will be placed at 90 degrees to each other. If there are three particles, they will be placed at 120 degrees.

If you don't want the burst particles to cover the whole 360 degrees, you can specify the portion that should be covered using the degree property. Any value above 0 is valid for this property. The specified number of degrees will be evenly distributed between all the particles. If the degree value is over 360, the shapes might overlap.

The angle specified using the angle property determines the angle of the whole burst. In this case, individual particles are not rotated around their own center but around the center of the burst. This is similar to how the earth revolves around the sun, which is different from the rotation of the earth on its own axis.

The scale property scales the value of all physical properties of the burst and in turn individual shapes. Just like other burst properties, all shapes in it would be scaled at once. Setting the burst scale to 3 will increase the radius of the whole burst as well as the size of individual shapes by 3.

In the following code snippet, we are creating five different bursts using the properties we just discussed.

var burstA = new mojs.Burst({ count: 20 }); var burstB = new mojs.Burst({ angle: { 0: 360 }, scale: { 1: 2 }, radius: 10 }); var burstC = new mojs.Burst({ angle: { 0: 360 }, scale: { 1: 2 }, radius: { 10: 100 } }); var burstD = new mojs.Burst({ degree: 180, radiusX: 10, angle: -90, scale: { 1: 2 }, radius: { 10: 100 } }); var burstE = new mojs.Burst({ count: 20, degree: 3600 });

You can see that burstA and burstE only differ in the number of degrees that they have to cover. Since the particles in burstA have to cover 360 degrees (the default value), they are placed 360/20 = 18 degrees apart. On the other hand, the particles in burstE are placed 3600/20 = 180 degrees apart. Starting from zero, the first particle is placed at 0 degrees, and the next is placed at 180 degrees. 

The third particle is then placed at 360 degrees, which is basically equal to 0 degrees. The fourth particle is then placed at 540 degrees, but that is basically equal to 180 degrees. In other words, all the odd numbered particles are placed at 0 degrees, and all the even number particles are placed at 180 degrees. In the end, you only see two particles because all others overlap with the first two.

It is important to remember that you cannot directly control the duration, delay or easing function of the burst animations. The module determines all these values automatically based on the values of different children being animated.

Manipulating Individual Burst Particles

So far in this tutorial, all the particles in a burst had the same animation applied to them. Their angle, scale, radius, and position all changed by the same value. Moreover, we were not able to control the duration and delay of either the individual particles or the burst as a whole. The mojs Burst module does not have a set of properties which can directly change all these values. However, we can specify the animation value for individual particles, which in turn affects the burst animation.

All the particles in a burst animation are considered to be children of the original Burst object. Therefore, mojs allows us to control the animation of individual burst particles using a children property, which accepts an object as its value. You can use all the ShapeSwirl properties except x and y inside the children object. This makes sense because the individual particles in a burst animation have to appear at certain positions, and allowing us to randomly change the position of individual particles will change the configuration.

Any children property values that you don't specify will be set to the default provided by the ShapeSwirl module. In the following example, we are animating 20 different lines of our burst animation. This time, the angle property has been set on individual particles instead of the Burst object so that only the lines rotate around their center instead of the whole object. As we learned in the previous tutorial, all the ShapeSwirl objects scale down from 1 to 0 by default. That's why the lengths of the lines change from 40 to 0 in the animation.

var burstA = new mojs.Burst({ count: 20, children: { shape: 'line', stroke: 'black', radius: 20, angle: { 0: 180 } } });

As I mentioned earlier, we can animate all the ShapeSwirl properties inside the burst animations. Each child in the animation can have its own set of properties. If only one value is provided, it will be applied on all the child particles. If the values are provided as an array, they will be applied sequentially, one particle at a time.

Here is the JavaScript code to create five different burst animations using all the concepts we have learned so far.

var burstA = new mojs.Burst({ count: 20, angle: { 0: 180 }, radius: { 0: 100 }, children: { shape: "polygon", stroke: "black", radius: 20, angle: { 0: 360 }, duration: 4000 } }); var burstB = new mojs.Burst({ count: 20, angle: { 0: 180 }, radius: { 0: 100 }, children: { shape: "polygon", fill: ["yellow", "cyan", "orange"], stroke: "black", radius: 20, scale: { 1: 2 }, duration: 2000 }, isShowEnd: false }); var burstC = new mojs.Burst({ count: 20, angle: { 0: -180 }, radius: { 0: 100 }, children: { shape: "circle", fill: ["red", "black", "blue"], radius: { 10: "stagger(5, 1)" } } }); var burstD = new mojs.Burst({ count: 6, radius: { 0: 100 }, children: { shape: "circle", fill: ["red", "yellow", "blue"], scale: { 1: "rand(1, 10)" } }, isShowEnd: false }); var burstE = new mojs.Burst({ count: 6, radius: { 0: 100 }, children: { shape: "circle", fill: ["red", "yellow", "blue"], stroke: "black", scale: { 1: "rand(1, 10)" } } }).then({ angle: { 0: 360 }, radius: { 100: 0 }, scale: { 1: 0 } });

In the first burst animation, the angle applied directly on the Burst object rotates the whole group around the center of the burst object. However, the angle applied inside the children property rotates all the triangles around their own centers. We also slowed down the burst animation by changing the animation duration for all the children to 4000ms.

In the second burst animation, the color of all the triangles is taken from the array passed to the fill property. We have specified only three fill colors, but the total number of triangles is 20. In such cases, mojs keeps cycling through the array elements and fills the triangles with the same three colors again and again.

In the fourth animation, we use rand strings, which we learned about in the previous tutorial, to randomly choose a scale value for all the child particles. We also set the value of isShowEnd property to false in order to hide the particles at the end of the animation.

In the fifth animation, we use the then() method from the Shape module tutorial to play another animation sequence after the first one finishes.

Final Thoughts

The aim of this series was to get you acquainted with the basics of the mojs animation library. Each tutorial focused on a single module and how you can use the properties in that module to create basic animations. 

This last tutorial used the concepts from the previous tutorials to create slightly more complicated animations. Mojs is a very powerful animation library, and the final results you get depend on how creative you can get with all the properties, so keep experimenting.

If there is anything that you would like me to clarify in this tutorial, please let me know in the comments.

Categories: Web Design

Ethical Design: The Practical Getting-Started Guide

Smashing Magazine - Fri, 03/16/2018 - 03:00

By now, most people working in tech know and feel the deep concerns related to surveillance capitalism fostered and upheld by the tech giants. We understand that the root of the problem lies within the business model of capitalising and monetising user data. Stories of how people are being exploited surface on a daily basis, like the recent story about how Instagram withholds like notifications to certain users, with the purpose of increasing the rate of which they open the app. In the same story, The Globe and Mail describe how former high level employees of Facebook are growing a conscience and tell horrifying stories about how features are meticulously being built to exploit human behavior and make us addicts of social media.

As designers and developers we have an obligation to build experiences that are better than that. This article explains how unethical design happens, and how to do ethical design through a set of best practices. It also helps you understand how you can plant the seed to change the meaning within the company you work for and in the design community, even if you are not part of the management layer. Change starts with a movement!

Ethical Design

Let’s start with the core terminology: According to Merriam Webster, ethics is “the discipline dealing with what is good and bad and with moral duty and obligation.” For the purpose of this article, ethics will be defined as a system of moral principles that defines what is perceived as good and evil. Ethical design is, therefore, design made with the intent to do good, and unethical design is its black hat counterpart.

Is your pattern library up to date today? Alla Kholmatova has just finished a fully fledged book on Design Systems and how to get them right. With common traps, gotchas and the lessons she learned. Hardcover, eBook. Just sayin'.

Table of Contents →

Ind.ie is a social enterprise striving for justice in the digital age. It is founded by Aral Balkan and Laura Kalbag who defined an “Ethical Hierarchy of Needs” that describe the core of ethical design very well.

The 'Ethical Hierarchy of Needs' (licensed under CC BY 4.0) (Source: ind.ie)

As with any pyramid-shaped structure, the layers in the Ethical Hierarchy of Needs rest on the layer below it. If any layer is broken, the layers resting on top of it will collapse. If a design does not support human rights, it is unethical. If it supports human rights but does not respect human effort by being functional, convenient and reliable (and usable!), then it is unethical. If it respects human effort but does not respect human experience by making a better life for the people using it, then it is still unethical.

From a practical viewpoint, this means that products and services which exploit user data, use dark patterns and generally are only out to make money, disregarding its human purpose, are unethical. Let’s look at how unethical design manifests itself in business models and design decisions.

Unethical Design: The Black Hat Of The Business 
 Surveillance Capitalism

Data-driven design can be used to do good. But more often than not it is used with monetary intent also known as surveillance capitalism.

As Aral Balkan, ethical designer and founder of ind.ie puts it:

“When a company like Facebook improves the experience of its products, it’s like the massages we give to Kobe beef: they’re not for the benefit of the cow but to make the cow a better product. In this analogy, you are the cow.”

Surveillance capitalism is unethical by nature because at its core, it takes advantage of rich data to profile people and understand their behavior with the sole purpose of making money. The most chilling thought of all is how data is being used not just to predict and manipulate current behavior, but how it is used to profile our future selves through machine learning, ultimately giving companies the power to impact our future decisions and behavioral patterns.

As Cracked Labs, independent research institute and creative laboratory, states in their report about Data Against People:

“Systems that make decisions about people based on their data produce substantial adverse effects that can massively limit their choices, opportunities, and life-chances”.

This happens on a daily basis to everyone who use Facebook, where the individualized feed is carefully filtered to show the posts most likely to trigger engagement and activity. Pricing is also becoming increasingly individualized because companies are able to use rich data to assess the long-term value of customers, also known as data-driven persuasion.

Data trade and data tracking is big business. According to the report “Corporate Surveillance in Everyday Life”, Oracle provides access to 5 billion (yes, billion!) unique user ID’s (this is confirmed on Oracle’s website). The word “scared” does not cover the emotional state which we should all be in over that fact.

An overview of the amount of profiles held by online platforms, credit reporting agencies and consumer data brokers as of June 2017. (Source: Corporate Surveillance in Everyday Life, CC BY-SA 4.0, Cracked Labs)

One can only imagine how companies will be able to utilize data to profile which of us are more likely to develop mental health or physical issues, thus putting us in the “no thanks” pile of applications for our future jobs. With this in mind, I fear for the future of my children.

To some the above sounds like something out of a science fiction movie, but it is not far-fetched at all. Unethical companies are exposed daily, from the VPN app who claimed to protect the data of their 24 million users, but sold it to Facebook to the software called Alphonso which, according to an article in The New York Times, is used in more than 250 game apps (some of which are designed for children) to monitor what tv ads people watch, even if the app is not in active use. The list of companies who harvest and use data with deeply unethical purposes goes on and on and on.

Black Hat Design

Nevertheless, data tracking is not the only way that unethical design plays out. Dark patterns fall under unethical design too, as they are black hat design patterns specifically designed to trick us into doing something we don’t necessarily want to do. It may not be considered unethical when a company makes use of the dark pattern called Roach Motel to make it nearly impossible to delete your account (looking at you, Skype). But looking at the motivation of the business side, it is not hard to see the unethical nature of the design, naming the Chinese shoe company who tricked people to swipe by adding a fake strand of hair on their Instagram ad as just one example.

Harry Brignull, one of the originators and driving forces behind Dark Patterns, states that dark patterns work because they take advantage of the human brain’s weaknesses and the way we are hard-wired. That counts as unethical in my book, and we have a moral obligation to the people who design these products to do better.

Businesses who nurture consumerism and manipulate people into buying more stuff are unethical by design. It is common practice in e-commerce, and it takes advantage of a phenomenon called “loss aversion”. Hotels.com is particularly aggressive, sending several notifications within seconds about how many people have booked and are looking at the same room as you.

Hotels.com loves letting us know just how many others are looking at a room to 'motivate' us into booking fast. The General Data Protection Regulation

The effectuation of the General Data Protection Regulation (GDPR) in late May 2018 will be an efficient tool in the fight against companies that are unethical by design.

GDPR is an extensive regulation that amongst the highlights include:

  • The requirement of any organization that collects data to do so in a secure manner by design;
  • Heavy fines for data breaches;
  • Data must only be collected after explicit consent, and the language used to explain why the data is collected must be plain and simple. In addition, consent must be withdrawable at any time and must be as easy to do as it was giving it (which, by the way, includes Sign up → Delete profile);
  • “The right to be forgotten,” meaning that people have the right to have their data deleted;
  • The right for people to get access to their personal data in any organization, alongside information about how this data is processed;
  • Data portability, meaning that people have the right to get hold of their data in one company and transfer it to another company;
  • Heavy fines for non-compliance of GDPR.

All in all, May 25, 2018, is a pretty good day for the people, and a sign of a much different future for all the unethically designed organizations out there.

But let’s not kid ourselves and think that change will happen overnight or across all organizations in a heartbeat. A deeper change is needed in order to make that happen over time.

Change Happens Through Change Of Meaning

GDPR is not likely to solve all of our problems. Believing that would be naive. That’s why it will continue to be up to the people within company walls to make a difference. The good news is that making a change is possible even if you’re not part of the management team who decides on the business model.

This type of change towards a more ethical design approach is not claimed to happen overnight. Rather, it is possible to make changes incrementally and foster long-term, organizational change through what Don Norman and Roberto Verganti call Meaning-driven Innovation (read more in their article about “Incremental and Radical Innovation”).

Meaning-driven innovation is a result of people starting to articulate new thoughts that create new dynamics, which ultimately lead to radically new meanings.

Don Norman and Roberto Verganti say that radical innovation only happens when one of the following things occur:

  1. A new enabling technology is available in a reliable, economical form (it took 20 years for touch interfaces to exit the labs and enter the phone and tablet market);
  2. When the meaning of something changes in society — also referred to as meaning-driven innovation.

I think that the increasing awareness, focus, and concern about our privacy in respect to data-driven businesses will in a not so distinct future spark radical innovation and change in society. Ironically, the companies who founded surveillance capitalism have also sparked a change in how we perceive our right to privacy, and we are already starting to see companies and organizations innovate and foster privacy driven solutions.

The meaning of companies who track and surveil us is already changing. We used to not think very hard about, and maybe even find it convenient when ads served on Facebook were based on our browsing history. But with the escalation of surveillance capitalism, I will argue that we are going through a meaning change as an increasing mass of people are finding it not only uncomfortable but directly unacceptable to be spied on in the name of a business.

DuckDuckGo, a search engine that doesn’t track, had an average of 16 million search queries per day in 2017, a sign that privacy is an increasing concern among people when using the web. Also, we are seeing apps devoted to privacy reaching markets, such as Signal, a secure phone and messenger app designed to protect privacy. Furthermore, it is highly likely that GDPR will spark further meaning change related to privacy.

Transition To A Human-Centered Design Approach

Human-Centered Design (HCD) is a philosophy developed by Don Norman (among others). According to the User Experience Professionals Association (UXPA), HCD is defined by “the active involvement of users and a clear understanding of user and task requirements”.

Don Norman and Roberto Verganti conclude in their substantial study that HCD is only suitable for incremental innovation — step by step improvements — because new ideas are not discovered while constantly looking at the existing state of things as it is done through user research.

While this sounds reasonable, I believe that HCD can prove to be the offset to meaning-driven innovation, ultimately leading to a broad meaning change about what people will accept and won’t accept from unethical organizations. The reason why I believe this, is that HCD fosters a deeper sense of empathy than any other experience design method.

Human-Centered Design is a framework as well as a mindset. At its core, working “human-centered” means involving the people you serve early and continuously in the process, i.e. using research to establish the needs of these people, understanding what problems they have, and how your product can help solve these problems.

It falls within the natural sphere of experience designers to work human-centered, but what do you do if your job is in design and development, and you are constantly occupied by sprint reviews and daily tasks?

While working with a remote development team, I learned that the developers didn’t have any contact with the people who used the product. This often led to heated discussions where statements like “I think…”, “From a technical perspective…”, and “I feel…” were the main arguments.

The biggest problem with basing decisions on what you think and feel, or what is easiest from a technical perspective, is that it doesn’t involve the people you are serving. The people who your product or service is put in the world to solve problems for. That’s where HCD comes in.

UX designers and researchers typically conduct research, document the insights and bring them forward in a refined state to the design- and product team in the shape of personas, user needs descriptions, user flows, journeys, and so on. And that’s all well and good. The problem is, however, that the distance between the organisation and people you serve remains large, because no one except the UX designers talked to them or have seen them use the product. So they keep going back to “I feel…”, “I think…” and “From a technical perspective…”

To help establish empathy towards the people you serve, there are a couple of very impactful things designers and developers — and the rest of the organization — can do (and can ask for from the UX team).

  1. Involve all team members in watching videos from user testing sessions.
    Actually going through the pains and delights of the people who use your products (or prototypes, depending on what you’re testing) is worth every second. It cannot be stressed enough how important it is to watch other people interact with and comment on the stuff you’re building (and no, your team doesn't count as “people” here!).

    If this is not part of the routine in your company, ask for it to be included. Certainly, the vast majority of UX designers who would not be thrilled to organize and facilitate such sessions. You are guaranteed to go through pain, agony, frustration, happiness and get multiple eye openers, and it will all serve as the stepping stone towards growing a human-centered mindset.
  2. Ask for actual, living portraits of the people you serve.
    This includes photos and video from contextual studies (link), stories from their daily life and stories about them. Getting a deeper sense of the people on the other side of the product you develop creates instant empathy and makes it a lot harder to design things that knowingly are bad for them.
  3. Insist on continuous testing.
    It cannot be emphasized enough how crucial testing is in HCD. This includes early proof of concept tests, prototype tests, and usability tests. A side bonus of early and continuous involvement from the people who are meant to use the product is that it saves money in the long run. The earlier you realize a bad call or error, the cheaper it is to fix.

    A lot has been said about the nuclear alarm that was triggered by mistake in Hawaii on January 13. However, it’s pretty safe to say that early and continuous testing would have helped prevent it.
    A poorly designed screen has been named the cause of a false ballistic missile alert in Hawaii. (Source: Honolulu Civil Beat)
  4. Always ask “why?”
    To start a change of meaning in an organization or community, the first important step is to start asking “why.” Ask why something is being done unethically; ask why you are told to make a black hat feature; question the current state of things.

    Ask on what grounds design decisions are being made. If it’s because of what the CEO or someone else thinks, and it has no root in insights from the people you are serving, ask for that validation. Meaning change grows through small steps.
Ethical Design Best Practices

Alongside establishing a human-centered design tradition in the organization, it is also important to make use of the best practices of ethical design. People who do so are part of taking the lead and showing the rest of the organization how things can be done in a more ethical way, all of which will add to the incremental meaning change. Just as dark patterns fall under unethical design, we have White Hat design patterns that can be utilized to ensure ethical design, some of which you can learn about in the following.

Use Data To Improve The Human Experience

Despite numerous companies using data for unethical purposes, such as increasing consumption and traffic, data can, in fact, be used to actually improve the human experience.

This is the case on the ind.ie forum where setting up an account is suggested as a way to customize your experience by remembering what you’ve read.

ind.ie's forum highlights the benefits of setting up an account — one that won’t harvest your data and use it unethically.

In a current project in which I am involved in making an app for students to more easily access their Learning Management System, we are sorting the student’s individual courses by “last visited”; we know through research that the students most often revisit a small number of pages that relate to the courses they are currently enrolled in. This customization is not designed to change behavior or nudge them into using parts of the app they didn’t intend to. Instead, it is designed to make their experience faster and more efficient.

In this early wireframe from a current project, it it shown how we used knowledge about current usage of the product to increase efficiency in the app by sorting the student’s courses by 'last visited'.

Another positive example is the American pharmacy Walgreens, who sends out reminders when it’s time to refill on things like vitamins. This is an extremely helpful feature that solves a problem a lot of us have.

Data can help inform research initiatives to understand how you’re not tackling the problems people have when interacting with your product.

Skyscanner, a travel search engine, noticed through their data that their newly launched design didn’t go down well for the people who used their service to fly out of Amsterdam. That data helped inform a research initiative that ultimately lead to a customized solution for people flying to and from Amsterdam that broke down the barriers the new design had initially built (here’s the background story).

Advertising Without Tracking

Advertising is not necessarily unethical. Advertising based on granular data is. It is careless (if not stupid) to rely on a single platform for the majority of a brand’s marketing efforts, especially considering that said platform owns and controls the data the brand uses as the foundation for its ad targeting.

Facebook, Instagram, and Google care just about as little about their advertisers as they do about the people who they see as “users,” i.e. they can make any change they want to, disregarding any consequences it might have for people or businesses using their platform. For example, there was a time when they started blocking fake accounts en masse, which hurt numerous companies whose social media admins had set up fake accounts to administer business pages because they (understandably) didn’t want to use their private accounts for this purpose. This is standard procedure from Facebook who only allows one profile per person (likely because allowing several would contaminate their data tracking).

The platform is always the weakest link in a marketing strategy because it is a third party beyond the control of companies. Thinking back to the 90’s when I worked in marketing at a regional newspaper, granular data tracking was not an option. When a store had placed an ad in the paper about an event, they would simply monitor how many people showed up, and compare that to their expectations to determine the success rate.

While “the good old days” were certainly not good in all aspects, the thought of not basing advertising on granular user data tracking is an appealing thought. John Gruber’s blog, Daring Fireball is an example of a site that doesn’t allow ad tracking. Instead, John Gruber encourages advertisers to add a custom link to their ads enabling them to monitor the click rate on their end.

As John Gruber rightfully states:

“If you pay (say) Facebook for an ad, why in the world would you, the advertiser, trust Facebook’s numbers for how the ad performed?”


Another great example worth highlighting is Goodwings, a hotel booking site that donates half of their commission to charity. They can do so because of a close collaboration with a large number of NGO’s which means they spend very little on traditional marketing.

Goodwings is a hotel search engine that donates half of their commission to charity.

And if you think Google Analytics is your only option for collecting meaningful data, think again: Matamo is an open source tool that is installed directly on your own server. It guarantees that data is not shared with advertising agencies such as Google.

Always, Always Prioritize Usability

Surveillance capitalism and data tracking are heavily talked about problems related to ethical design these days. But we must not forget the importance of complying with the best practices of usability. Without it, design is unethical, as a lack of usability almost always entails the use of dark patterns. A good place to go to read more about core usability is Nielsen Norman Group.

Back in the early days, Jakob Nielsen defined 5 core components of usability:

  • Learnability,
  • Efficiency,
  • Memorability
  • Errors, and
  • Satisfaction.

To ensure a usable product, it’s crucial that these five components are front and center in the design and development process. 
 While it may not be the most interesting 404 page around, Apple’s version focuses on error prevention by offering us a forward path when we hit a lost page.

Don’t Ask For More Than You Need

As with many other aspects in life, asking for more than you need results in exploitation. It’s common for e-commerce sites to ask for tons of information when people sign up for an account or buy a product. But if someone is buying a digital product (such as a book), there really is no need to ask for anything other than their email address.

Signal is a great example. Private at its core, it doesn’t ask for anything more than the information that is absolutely necessary for people to start using the app right away.

Signal only asks for the phone number of the device during signup. Be Transparent

Norwegian.com has perhaps one of the best airfare booking systems in the world. Not only is it convenient to use but they also offer full transparency in relation to their optional service fees, something that is often hidden away. Anyone who lives outside of an Amazon storage country knows how hard it is to find the actual delivery price of their location.

Norwegian.com offers full transparency on all additional charges. Conclusion

The movement towards a more ethical future has begun. Change doesn’t happen radically short term unless it’s built into the core of the business model. But that doesn’t mean we cannot change the current state for the better. We can do so through incremental change; one step at a time. By working human-centered, by asking why, and by using best practices for ethical design. That’s our obligation as the ones who build products so deeply ingrained in people’s lives. What we do changes and shapes lives for better or for worse. I choose better.

Learn More

There are a lot of valuable resources available for anyone interested in ethical design. Here are a few to get you started:

  • IDEO’s Human-Centered Design Kit is extremely helpful to understand HCD and offers a wide range of methods on how to work human-centered.
  • Simply Secure is an organization that supports and educates practitioners in ethical design processes. They offer a thorough knowledge base for people interested in building trustworthy technology
  • White Hat UX — The Next Generation in User Experience is a book that offers lots of practical advice on how to design experiences that are transparent, honest and ethical. Written by Trine Falbe, Martin Frederiksen, and Kim Andersen.
  • Cracked Labs is an independent research institute and a creative laboratory based in Vienna, Austria. It investigates the socio-cultural impacts of information technology and develops social innovations in the field of digital culture. They offer in-depth reports about most things related to privacy.
(ah, ra, il)
Categories: Web Design

Best Free Scroll To Top JavaScript Plugins & Snippets

Out of all the free scripts on the web there’s nothing simpler than a scroll-to-top snippet. This adds a small arrow near the bottom of the page which, when...

The post Best Free Scroll To Top JavaScript Plugins & Snippets appeared first on Onextrapixel.

Categories: Web Design

How BBC Interactive Content Works Across AMP, Apps, And The Web

Smashing Magazine - Thu, 03/15/2018 - 05:20

In the Visual Journalism team at the BBC, we produce exciting visual, engaging and interactive content, ranging from calculators to visualizations new storytelling formats.

Each application is a unique challenge to produce in its own right, but even more so when you consider that we have to deploy most projects in many different languages. Our content has to work not only on the BBC News and Sports websites but on their equivalent apps on iOS and Android, as well as on third-party sites which consume BBC content.

Now consider that there is an increasing array of new platforms such as AMP, Facebook Instant Articles, and Apple News. Each platform has its own limitations and proprietary publishing mechanism. Creating interactive content that works across all of these environments is a real challenge. I’m going to describe how we’ve approached the problem at the BBC.

Example: Canonical vs. AMP

This is all a bit theoretical until you see it in action, so let’s delve straight into an example.

Here is a BBC article containing Visual Journalism content:

Our Visual Journalism content begins with the Donald Trump illustration, and is inside an iframe

This is the canonical version of the article, i.e., the default version, which you’ll get if you navigate to the article from the homepage.

Nope, we can't do any magic tricks, but we have articles, books and webinars featuring techniques we all can use to improve our work. Smashing Members get a seasoned selection of magic front-end tricks — e.g. live designing sessions and perf audits, too. Just sayin'! ;-)

Explore Smashing Wizardry →

Now let’s look at the AMP version of the article:

This looks like the same content as the normal article, but is pulling in a different iframe designed specifically for AMP

While the canonical and AMP versions look the same, they are actually two different endpoints with different behavior:

  • The canonical version scrolls you to your chosen country when you submit the form.
  • The AMP version doesn’t scroll you, as you cannot scroll the parent page from within an AMP iframe.
  • The AMP version shows a cropped iframe with a ‘Show More’ button, depending on viewport size and scroll position. This is a feature of AMP.

As well as the canonical and AMP versions of this article, this project was also shipped to the News App, which is yet another platform with its own intricacies and limitations. So how do we do support all of these platforms?

Tooling Is Key

We don’t build our content from scratch. We have a Yeoman-based scaffold which uses Node to generate a boilerplate project with a single command.

New projects come with Webpack, SASS, deployment and a componentization structure out of the box. Internationalization is also baked into our projects, using a Handlebars templating system. Tom Maslen writes about this in detail in his post, 13 tips for making responsive web design multi-lingual.

Out of the box, this works pretty well for compiling for one platform but we need to support multiple platforms. Let’s delve into some code.

Embed vs. Standalone

In Visual Journalism, we sometimes output our content inside an iframe so that it can be a self-contained “embed” in an article, unaffected by the global scripting and styling. An example of this is the Donald Trump interactive embedded in the canonical example earlier in this article.

On the other hand, sometimes we output our content as raw HTML. We only do this when we have control over the whole page or if we require really responsive scroll interaction. Let’s call these our “embed” and “standalone” outputs respectively.

Let’s imagine how we might build the “Will a robot take your job?” interactive in both the “embed” and “standalone” formats.

Contrived example showing an 'embed' on the left, versus the content as a 'standalone' page on the right

Both versions of the content would share the vast majority of their code, but there would be some crucial differences in the implementation of the JavaScript between the two versions.

For example, look at the ‘Find out my automation risk’ button. When the user hits the submit button, they should be automatically scrolled to their results.

The “standalone” version of the code might look like this:

button.on('click', (e) => { window.scrollTo(0, resultsContainer.offsetTop); });

But if you were building this as “embed” output, you know that your content is inside an iframe, so would need to code it differently:

// inside the iframe button.on('click', () => { window.parent.postMessage({ name: 'scroll', offset: resultsContainer.offsetTop }, '*'); }); // inside the host page window.addEventListener('message', (event) => { if (event.data.name === 'scroll') { window.scrollTo(0, iframe.offsetTop + event.data.offset); } });

Also, what if our application needs to go full screen? This is easy enough if you’re in a “standalone” page:

document.body.className += ' fullscreen'; .fullscreen { position: fixed; top: 0; left: 0; right: 0; bottom: 0; } We successfully use full-screen functionality to make the most of our map module on mobile

If we tried to do this from inside an “embed,” this same code would have the content scaling to the width and height of the iframe, rather than the viewport:

It can be difficult going full screen from within an iframe

…so in addition to applying the full-screen styling inside the iframe, we have to send a message to the host page to apply styling to the iframe itself:

// iframe window.parent.postMessage({ name: 'window:toggleFullScreen' }, '*'); // host page window.addEventListener('message', function () { if (event.data.name === 'window:toggleFullScreen') { document.getElementById(iframeUid).className += ' fullscreen'; } });

This can translate into a lot of spaghetti code when you start supporting multiple platforms:

button.on('click', (e) => { if (inStandalonePage()) { window.scrollTo(0, resultsContainer.offsetTop); } else { window.parent.postMessage({ name: 'scroll', offset: resultsContainer.offsetTop }, '*'); } });

Imagine doing an equivalent of this for every meaningful DOM interaction in your project. Once you’ve finished shuddering, make yourself a relaxing cup of tea, and read on.

Abstraction Is Key

Rather than forcing our developers to handle these conditionals inside their code, we built an abstraction layer between their content and the environment. We call this layer the ‘wrapper.’

Instead of querying the DOM or native browser events directly, we can now proxy our request through the wrapper module.

import wrapper from 'wrapper'; button.on('click', () => { wrapper.scrollTo(resultsContainer.offsetTop); });

Each platform has its own wrapper implementation conforming to a common interface of wrapper methods. The wrapper wraps itself around our content and handles the complexity for us.

Simple 'scrollTo' implementation by the standalone wrapper

The standalone wrapper’s implementation of the scrollTo function is very simple, passing our argument directly to window.scrollTo under the hood.

Now let’s look at a separate wrapper implementing the same functionality for the iframe:

Advanced 'scrollTo' implementation by the embed wrapper

The “embed” wrapper takes the same argument as in the “standalone” example but manipulates the value so that the iframe offset is taken into account. Without this addition, we would have scrolled our user somewhere completely unintended.

The Wrapper Pattern

Using wrappers results in code that is cleaner, more readable and consistent between projects. It also allows for micro-optimisations over time, as we make incremental improvements to the wrappers to make their methods more performant and accessible. Your project can, therefore, benefit from the experience of many developers.

So, what does a wrapper look like?

Wrapper Structure

Each wrapper essentially comprises three things: a Handlebars template, wrapper JS file, and a SASS file denoting wrapper-specific styling. Additionally, there are build tasks which hook into events exposed by the underlying scaffolding so that each wrapper is responsible for its own pre-compilation and cleanup.

This is a simplified view of the embed wrapper:

embed-wrapper/ templates/ wrapper.hbs js/ wrapper.js scss/ wrapper.scss

Our underlying scaffolding exposes your main project template as a Handlebars partial, which is consumed by the wrapper. For example, templates/wrapper.hbs might contain:

<div class="bbc-news-vj-wrapper--embed"> {{>your-application}} </div>

scss/wrapper.scss contains wrapper-specific styling that your application code shouldn’t need to define itself. The embed wrapper, for example, replicates a lot of BBC News styling inside the iframe.

Finally, js/wrapper.js contains the iframed implementation of the wrapper API, detailed below. It is shipped separately to the project, rather than compiled in with the application code — we flag wrapper as a global in our Webpack build process. This means that though we deliver our application to multiple platforms, we only compile the code once.

Wrapper API

The wrapper API abstracts a number of key browser interactions. Here are the most important ones:


Scrolls to the given position in the active window. The wrapper will normalise the provided integer before triggering the scroll so that the host page is scrolled to the correct position.

getScrollPosition: int

Returns the user’s current (normalized) scroll position. In the case of the iframe, this means that the scroll position passed to your application is actually negative until the iframe is at the top of the viewport. This is super useful and lets us do things such as animate a component only when it comes into view.


Provides a hook into the scroll event. In the standalone wrapper, this is essentially hooking into the native scroll event. In the embed wrapper, there will be a slight delay in receiving the scroll event since it is passed via postMessage.

viewport: {height: int, width: int}

A method to retrieve the viewport height and width (since this is implemented very differently when queried from within an iframe).


In standalone mode, we hide the BBC menu and footer from view and set a position: fixed on our content. In the News App, we do nothing at all — the content is already full screen. The complicated one is the iframe, which relies on applying styles both inside and outside the iframe, coordinated via postMessage.


Tell the wrapper your content has loaded. This is crucial for our content to work in the News App, which will not attempt to display our content to the user until we explicitly tell the app our content is ready. It also removes the loading spinner on the web versions of our content.

List Of Wrappers

In the future, we envisage creating additional wrappers for large platforms such as Facebook Instant Articles and Apple News. We have created six wrappers to date:

Standalone Wrapper

The version of our content that should go in standalone pages. Comes bundled with BBC branding.

Embed Wrapper

The iframed version of our content, which is safe to sit inside articles or to syndicate to non-BBC sites, since we retain control over the content.

AMP Wrapper

This is the endpoint which is pulled in as an amp-iframe into AMP pages.

News App Wrapper

Our content must make calls to a proprietary bbcvisualjournalism:// protocol.

Core Wrapper

Contains only the HTML — none of our project’s CSS or JavaScript.

JSON Wrapper

A JSON representation of our content, for sharing across BBC products.

Wiring Wrappers Up To The Platforms

For our content to appear on the BBC site, we provide journalists with a namespaced path:

/include/[department]/[unique ID], e.g. /include/visual-journalism/123-quiz

The journalist puts this “include path” into the CMS, which saves the article structure into the database. All products and services sit downstream of this publishing mechanism. Each platform is responsible for choosing the flavor of content it wants and requesting that content from a proxy server.

Let’s take that Donald Trump interactive from earlier. Here, the include path in the CMS is:


The canonical article page knows it wants the “embed” version of the content, so it appends /embed to the include path:


…before requesting it from the proxy server:


The AMP page, on the other hand, sees the include path and appends /amp:


The AMP renderer does a little magic to render some AMP HTML which references our content, pulling in the /amp version as an iframe:

<amp-iframe src="https://news.files.bbci.co.uk/include/newsspec/15996-trump-tracker/english/index/amp" width="640" height="360"> <!-- some other AMP elements here --> </amp-iframe>

Every supported platform has its own version of the content:

/include/newsspec/15996-trump-tracker/english/index/amp /include/newsspec/15996-trump-tracker/english/index/core /include/newsspec/15996-trump-tracker/english/index/envelope ...and so on

This solution can scale to incorporate more platform types as they arise.

Abstraction Is Hard

Building a “write once, deploy anywhere” architecture sounds quite idealistic, and it is. For the wrapper architecture to work, we have to be very strict on working within the abstraction. This means we have to fight the temptation to “do this hacky thing to make it work in [insert platform name here].” We want our content to be completely unaware of the environment it is shipped in — but this is easier said than done.

Features Of The Platform Are Hard To Configure Abstractly

Before our abstraction approach, we had complete control over every aspect of our output, including, for example, the markup of our iframe. If we needed to tweak anything on a per-project basis, such as add a title attribute to the iframe for accessibility reasons, we could just edit the markup.

Now that the wrapper markup exists in isolation from the project, the only way of configuring it would be to expose a hook in the scaffold itself. We can do this relatively easily for cross-platform features, but exposing hooks for specific platforms breaks the abstraction. We don’t really want to expose an ‘iframe title’ configuration option that’s only used by the one wrapper.

We could name the property more generically, e.g. title, and then use this value as the iframe title attribute. However, it starts to become difficult to keep track of what is used where, and we risk abstracting our configuration to the point of no longer understanding it. By and large, we try to keep our config as lean as possible, only setting properties that have global use.

Component Behaviour Can Be Complex

On the web, our sharetools module spits out social network share buttons that are individually clickable and open a pre-populated share message in a new window.

BBC Visual Journalism sharetools present a list of social share options

In the News App, we don’t want to share through the mobile web. If the user has the relevant application installed (e.g. Twitter), we want to share in the app itself. Ideally, we want to present the user with the native iOS/Android share menu, then let them choose their share option before we open the app for them with a pre-populated share message. We can trigger the native share menu from the app by making a call to the proprietary bbcvisualjournalism:// protocol.

Native share menu on Android

However, this screen will be triggered whether you tap ‘Twitter’ or ‘Facebook’ in the ‘Share your results’ section, so the user ends up having to make their choice twice; the first time inside our content, and a second time on the native popup.

This is a strange user journey, so we want to remove the individual share icons from the News app and show a generic share button instead. We are able to do this by explicitly checking which wrapper is in use before we render the component.

Generic share button used in the News App

Building the wrapper abstraction layer works well for projects as a whole, but when your choice of wrapper affects changes at the component level, it’s very difficult to retain a clean abstraction. In this case, we’ve lost a little abstraction, and we have some messy forking logic in our code. Thankfully, these cases are few and far between.

How Do We Handle Missing Features?

Keeping abstraction is all well and good. Our code tells the wrapper what it wants the platform to do, e.g. “go full screen.” But what if the platform we’re shipping to can’t actually go full-screen?

The wrapper will try its best not to break altogether, but ultimately you need a design which gracefully falls back to a working solution whether or not the method succeeds. We have to design defensively.

Let’s say we have a results section containing some bar charts. We often like to keep the bar chart values at zero until the charts are scrolled into view, at which point we trigger the bars animating to their correct width.

Bar chart showing values relevant to my area

But if we have no mechanism to hook into the scroll position — as is the case in our AMP wrapper — then the bars would forever remain at zero, which is a thoroughly misleading experience.

How the bar chart could look if scrolling events aren't forwarded

We are increasingly trying to adopt more of a progressive enhancement approach in our designs. For example, we could provide a button which will be visible for all platforms by default, but which gets hidden if the wrapper supports scrolling. That way, if the scroll fails to trigger the animation, the user can still trigger the animation manually.

We could display a fallback button instead, which triggers the animation on click. Plans For The Future

We hope to develop new wrappers for platforms such as Apple News and Facebook Instant Articles, as well as to offer all new platforms a ‘core’ version of our content out of the box.

We also hope to get better at progressive enhancement; succeeding in this field means developing defensively. You can never assume all platforms now and in the future will support a given interaction, but a well-designed project should be able to get its core message across without falling at the first technical hurdle.

Working within the confines of the wrapper is a bit of a paradigm shift, and feels like a bit of a halfway house in terms of the long-term solution. But until the industry matures onto a cross-platform standard, publishers will be forced to roll out their own solutions, or use tooling such as Distro for platform-to-platform conversion, or else ignore entire sections of their audience altogether.

It’s early days for us, but so far we’ve had great success in using the wrapper pattern to build our content once and deliver it to the myriad of platforms our audiences are now using.

(rb, ra, il)
Categories: Web Design

How To Make A WordPress Plugin Extensible

Smashing Magazine - Wed, 03/14/2018 - 05:40

Have you ever used a plugin and wished it did something a bit differently? Perhaps you needed something unique that was beyond the scope of the settings page of the plugin.

I have personally encountered this, and I'm betting you have, too. If you're a WordPress plugin developer, most likely some of your users have also encountered this while using your plugin.

Here's a typical scenario: You've finally found that plugin that does everything you need — except for one tiny important thing. There is no setting or option to enable that tiny thing, so you browse the documentation and find that you can't do anything about it. You request the feature in the WordPress plugin's support forum — but no dice. In the end, you uninstall it and continue your search.

Imagine if you were the developer of this plugin. What would you do if a user asked for some particular functionality?

The ideal thing would be to implement it. But if the feature was for a very special use case, then adding it would be impractical. It wouldn't be good to have a plugin setting that only 0.1% of your users would have a use for.

You'd only want to implement features that affect the majority of your users. In reality, 80% of users use 20% of the features (the 80/20 rule). So, make sure that any new feature is highly requested, and that 80% of your users would benefit from it, before implementing it. If you created a setting for every feature that is requested, then your plugin would become complicated and bloated — and nobody wants that.

Your best bet is to make the plugin extensible, code-wise, so that other people can enhance or modify it for their own needs.

In this article, you'll learn about why making your plugin extensible is a good idea. I'll also share a few tips of how I've learned to do this.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features → What Makes A Plugin Extensible?

In a nutshell, an extensible plugin means that it adheres to the "O" part of the SOLID principles of object-oriented programming — namely, the open/closed principle.

If you're unfamiliar with the open/closed principle, it basically means that other people shouldn't have to edit your code in order to modify something.

Applying this principle to a WordPress plugin, it would mean that a plugin is extensible if it has provisions in it that enable other people to modify its behavior. It's just like how WordPress allows people to "hook" into different areas of WordPress, but at the level of the plugin.

A Typical Example Of A Plugin

Let's see how we can create an extensible plugin, starting with a sample plugin that isn't.

Suppose we have a plugin that generates a sidebar widget that displays the titles of the three latest posts. At the heart of the plugin is a function that simply wraps the titles of those three posts in list tags:

function get_some_post_titles() { $args = array( 'posts_per_page' => 3, ); $posts = get_posts( $args ); $output = '
    '; foreach ( $posts as $post ) { $output .= '
  • ' . $post->post_title . '
  • '; } $output .= '
'; return $output; }

While this code works and gets the job done, it isn't quite extensible.

Why? Because the function is set in its own ways, there's no way to change its behavior without modifying the code directly.

What if a user wanted to display more than three posts, or perhaps include links with the posts' titles? There's no way to do that with the code above. The user is stuck with how the plugin works and can nothing to change it.

Including A Hundred Settings Isn't The Answer

There are a number of ways to enhance the plugin above to allow users to customize it.

One such way would be to add a lot of options in the settings, but even that might not satisfy all of the possibilities users would want from the plugin.

What if the user wanted to do any of the following (scenarios we'll revisit later):

  • display WooCommerce products or posts from a particular category;
  • display the items in a carousel provided by another plugin, instead of as a simple list;
  • perform a custom database query, and then use those query's posts in the list.

If we added a hundred settings to our widget, then we would be able to cover the use cases above. But what if one of these scenarios changes, and now the user wants to display only WooCommerce products that are currently in stock? The widget would need even more settings to accommodate this. Pretty soon, we'd have a gazillion settings.

Also, a plugin with a huge list of settings isn't exactly user-friendly. Steer away from this route if possible.

So, how would we go about solving this problem? We'd make the plugin extensible.

Adding Our Own Hooks To Make It Extensible

By studying the plugin's code above, we see a few operations that the main function performs:

  • It gets posts using get_posts.
  • It generates a list of post titles.
  • It returns the generated list.

If other people were to modify this plugin's behavior, their work would mostly likely involve these three operations. To make our plugin extensible, we would have to add hooks around these to open them up for other developers.

In general, these are good areas to add hooks to a plugin:

  • around and within the major processes,
  • when building output HTML,
  • for altering post or database queries,
  • before returning values from a function.
A Typical Example Of An Extensible Plugin

Taking these rules of thumb, we can add the following filters to make our plugin extensible:

  • add myplugin_get_posts_args for modifying the arguments of get_posts,
  • add myplugin_get_posts for overriding the results of get_posts,
  • add myplugin_list_item for customizing the generation of a list entry,
  • add myplugin_get_some_post_titles for overriding the returned generated list.

Here's the code again with all of the hooks added in:

function get_some_post_titles() { $args = array( 'posts_per_page' => 3, ); // Let other people modify the arguments. $posts = get_posts( apply_filters( 'myplugin_get_posts_args', $args ) ); // Let other people modify the post array, which will be used for display. $posts = apply_filters( 'myplugin_get_posts', $posts, $args ); $output = '
    '; foreach ( $posts as $post ) { // Let other people modify the list entry. $output .= '
  • ' . apply_filters( 'myplugin_list_item', $post->post_title, $post ) . '
  • '; } $output .= '
'; // Let other people modify our output list. return apply_filters( 'myplugin_get_some_post_titles', $output, $args ); }

You can also get the code above in the GitHub archive.

I'm adding a lot of hooks here, which might seem impractical because the sample code is quite simple and small, but it illustrates my point: By adding just four hooks, other developers can now customize the plugin's behavior in all sorts of ways.

Namespacing And Context For Hooks

Before proceeding, note two important things about the hooks we've implemented:

  • We're namespacing the hooks with myplugin_.
    This ensures that the hook's name doesn't conflict with some other plugin's hook. This is just good practice, because if another hook with the same name is called, it could lead to unwanted effects.
  • We're also passing a reference to $args in all of the hooks for context.
    I do this so that if others use this filter to change something in the flow of the code, they can use that $args parameter as a reference to get an idea of why the hook was called, so that they can perform their adjustments accordingly.
The Effects Of Our Hooks

Remember the unique scenarios I talked about earlier? Let's revisit those and see how our hooks have made them possible:

  • If the user wants to display WooCommerce products or posts from a particular category, then either they can use the filter myplugin_get_posts_args to add their own arguments for when the plugin queries posts, or they can use myplugin_get_posts to completely override the posts with their own list.
  • If the user wants to display the items in a carousel provided by another plugin, instead of as a simple list, then they can override the entire output of the function with myplugin_get_some_post_titles, and instead output a carousel from there.
  • If the user wants to perform a custom database query and then use that query's posts in the list, then, similar to the first scenario, they can use myplugin_get_posts to use their own database query and change the post array.

Much better!

A Quick Example Of How To Use Our Filters

Developers can use add_filter to hook into our filters above (or use add_action for actions).

Taking our first scenario above, a developer can just do the following to display WooCommerce products using the myplugin_get_posts_args filter that we created:

add_filter( 'myplugin_get_posts_args', 'show_only_woocommerce_products' ); function show_only_woocommerce_products( $args ) { $args['post_type'] = 'product'; return $args; } We Can Also Use Action Hooks

Aside from using apply_filters, we can also use do_action to make our code extensible. The difference between the two is that the first allows others to change a variable, while the latter allows others to execute additional functionality in various parts of our code.

When using actions, we're essentially exposing the plugin's flow to other developers and letting them perform other things in tandem.

It might not be useful in our example (because we are only displaying a shortcode), but it would be helpful in others. For example, given an extensible backup plugin, we could create a plugin that also uploads the backup file to a third-party service such as Dropbox.

"Great! But Why Should I Care About Making My Plugin Extensible?"

Well, if you're still not sold on the idea, here are a few thoughts on why allowing other people to modify your plugin's behavior is a good idea.

It Opens Up the Plugin to More Customization Possibilities

Everyone has different needs. And there's a big chance your plugin won't satisfy all of them, nor can you anticipate them. Opening up your plugin to allow for modifications to key areas of your plugin's behavior can do wonders.

It Allows People to Introduce Modifications Without Touching the Plugin's Code

Other developers won't be forced to change your plugin's files directly. This is a huge benefit because directly modifying a plugin's file is generally bad practice. If the plugin gets updated, then all of your modifications will be wiped.

If we add our own hooks for other people to use, then the plugin's modifications can be put in an external location — say, in another plugin. Done this way, the original plugin won't be touched at all, and it can be freely updated without breaking anything, and all of the modifications in the other plugin would remain intact.


Extensible plugins are really awesome and give us room for a lot of customization possibilities. If you make your plugin extensible, your users and other developers will love you for it.

Take a look at plugins such as WooCommerce, Easy Digital Downloads and ACF. These plugins are extensible, and you can easily tell because numerous other plugins in WordPress' plugins directory add functionality to them. They also provide a wide array of action and filter hooks that modify various aspects of the plugins. The rules of thumb I've enumerated above have come up in my study of them.

Here are a few takeaways to make your plugin extensible:

  • Follow the open/closed principle. Other people shouldn't have to edit your code in order to modify something.
  • To make your plugin extensible, add hooks in these places:
    • around and within major processes,
    • when building the output HTML,
    • for altering post or database queries,
    • before returning values from a function.
  • Namespace your hooks' names with the name of your plugin to prevent naming conflicts.
  • Try passing other variables that are related to the hook, so that other people get some context of what's happening in the hook.
  • Don't forget to document your plugin's hooks, so that other people can learn of them.
Further Reading

Here are some resources if you want to learn more about extending plugins:

(mc, ra, al, yk, il)
Categories: Web Design

JWT Authentication in Django

Tuts+ Code - Web Development - Wed, 03/14/2018 - 05:00

This tutorial will give an introduction to JSON Web Tokens (JWT) and how to implement JWT authentication in Django.

What Is JWT?

JWT is an encoded JSON string that is passed in headers to authenticate requests. It is usually obtained by hashing JSON data with a secret key. This means that the server doesn't need to query the database every time to retrieve the user associated with a given token.

How JSON Web Tokens Work

When a user successfully logs in using their credentials, a JSON Web Token is obtained and saved in local storage. Whenever the user wants to access a protected URL, the token is sent in the header of the request. The server then checks for a valid JWT in the Authorization header, and if found, the user will be allowed access.

A typical content header will look like this:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsI

Below is a diagram showing this process:

The Concept of Authentication and Authorization

Authentication is the process of identifying a logged-in user, while authorization is the process of identifying if a certain user has the right to access a web resource.

API Example

In this tutorial, we are going to build a simple user authentication system in Django using JWT as the authentication mechanism.

  • Django
  • Python

Let's get started.

Create a directory where you will keep your project and also a virtual environment to install the project dependencies.

mkdir myprojects cd myprojects virtual venv

Activate the virtual environment:

source venv/bin/activate

Create a Django project.

django-admin startproject django_auth

Install DRF and django-rest-framework-jwt using pip.

pip install djangorestframework pip install djangorestframework-jwt pip install django

Let's go ahead and add DRF to the list of installed apps in the settings.py file.

Configure the JWT Settings

In order to use JWT, we need to configure django-rest-framework permissions to accept JSON Web Tokens.

In the settings.py file, add the following configurations:

REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ), }

Create a new app called users which will handle user authentication and management.

cd django-auth django-admin.py startapp users

Add the users application to the list of installed apps in the settings.py file.

Setting Up the Database

We are going to use the PostgreSQL database because it's more stable and robust.

Create the auth database and assign a user.

Switch over to the Postgres account on your machine by typing:

sudo su postgres

Access the Postgres prompt and create the database:

psql postgres=# CREATE DATABASE auth;

Create a role:

postgres=# CREATE ROLE django_auth WITH LOGIN PASSWORD 'asdfgh';

Grant database access to the user:

postgres=# GRANT ALL PRIVILEGES ON DATABASE auth TO django_auth;

Install the psycopg2 package, which will allow us to use the database we configured:

pip install psycopg2

Edit the currently configured SQLite database and use the Postgres database.

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'auth', 'USER': 'django_auth', 'PASSWORD': 'asdfgh', 'HOST': 'localhost', 'PORT': '', } } Creating Models

Django comes with a built-in authentication system which is very elaborate, but sometimes we need to make adjustments, and thus we need to create a custom user authentication system. Our user model will be inheriting from the AbstractBaseUser class provided by django.contrib.auth.models.

In users/models.py, we start by creating the User model to store the user details.

# users/models.py from __future__ import unicode_literals from django.db import models from django.utils import timezone from django.contrib.auth.models import ( AbstractBaseUser, PermissionsMixin ) class User(AbstractBaseUser, PermissionsMixin): """ An abstract base class implementing a fully featured User model with admin-compliant permissions. """ email = models.EmailField(max_length=40, unique=True) first_name = models.CharField(max_length=30, blank=True) last_name = models.CharField(max_length=30, blank=True) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) date_joined = models.DateTimeField(default=timezone.now) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['first_name', 'last_name'] def save(self, *args, **kwargs): super(User, self).save(*args, **kwargs) return self

REQUIRED_FIELDS contains all required fields on your user model, except the username field and password, as these fields will always be prompted for.

UserManager is the class that defines the create_user and createsuperuser methods. This class should come before the AbstractBaseUser class we defined above. Let's go ahead and define it.

from django.contrib.auth.models import ( AbstractBaseUser, PermissionsMixin, BaseUserManager ) class UserManager(BaseUserManager): def _create_user(self, email, password, **extra_fields): """ Creates and saves a User with the given email,and password. """ if not email: raise ValueError('The given email must be set') try: with transaction.atomic(): user = self.model(email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user except: raise def create_user(self, email, password=None, **extra_fields): extra_fields.setdefault('is_staff', False) extra_fields.setdefault('is_superuser', False) return self._create_user(email, password, **extra_fields) def create_superuser(self, email, password, **extra_fields): extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) return self._create_user(email, password=password, **extra_fields) Migrations

Migrations provide a way of updating your database schema every time your models change, without losing data.

Create an initial migration for our users model, and sync the database for the first time.

python manage.py make migrations users python manage.py migrateCreating a Superuser

Create a superuser by running the following command:

python manage.py createsuperuserCreating New Users

Let's create an endpoint to enable registration of new users. We will start by serializing the User model fields. Serializers provide a way of changing data to a form that is easier to understand, like JSON or XML. Deserialization does the opposite, which is converting data to a form that can be saved to the database.

Create users/serializers.py and add the following code.

# users/serializers.py from rest_framework import serializers from.models import User class UserSerializer(serializers.ModelSerializer): date_joined = serializers.ReadOnlyField() class Meta(object): model = User fields = ('id', 'email', 'first_name', 'last_name', 'date_joined', 'password') extra_kwargs = {'password': {'write_only': True}} CreateUserAPIView

Next, we want to create a view so the client will have a URL for creating new users.

In users.views.py, add the following:

# users/views.py class CreateUserAPIView(APIView): # Allow any user (authenticated or not) to access this url permission_classes = (AllowAny,) def post(self, request): user = request.data serializer = UserSerializer(data=user) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED)

We set permission_classes to (AllowAny,) to allow any user (authenticated or not) to access this URL.

Configuring URLs

Create a file users/urls.py and add the URL to match the view we created. Also add the following code.

# users/urls.py from django.conf.urls import url, patterns from .views import CreateUserAPIView urlpatterns = [ url(r'^create/$', CreateUserAPIView.as_view()), ]

We also need to import URLs from the users application to the main django_auth/urls.py file. So go ahead and do that. We are using the include function here, so don't forget to import it.

# django_auth/urls.py from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^user/', include('users.urls', namespace='users')), ]

Now that we are done creating the endpoint, let's do a test and see if we are on track. We will use Postman to do the tests. If you are not familiar with Postman, it's a tool which presents a friendly GUI for constructing requests and reading responses.

As you can see above, the endpoint is working as expected.

Authenticating Users

We will make use of the Django-REST Framework JWT Python module we installed at the beginning of this tutorial. It adds JWT authentication support for Django Rest Framework apps.

But first, let's define some configuration parameters for our tokens and how they are generated in the settings.py file.

# settings.py import datetime JWT_AUTH = { 'JWT_VERIFY': True, 'JWT_VERIFY_EXPIRATION': True, 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=3000), 'JWT_AUTH_HEADER_PREFIX': 'Bearer', }
  • JWT_VERIFY: It will raise a jwt.DecodeError if the secret is wrong.
  • JWT_VERIFY_EXPIRATION: Sets the expiration to True, meaning Tokens will expire after a period of time. The default time is five minutes.
  • JWT_AUTH_HEADER_PREFIX: The Authorization header value prefix that is required to be sent together with the token. We have set it as Bearer, and the default is JWT.

In users/views.py, add the following code.

@api_view(['POST']) @permission_classes([AllowAny, ]) def authenticate_user(request): try: email = request.data['email'] password = request.data['password'] user = User.objects.get(email=email, password=password) if user: try: payload = jwt_payload_handler(user) token = jwt.encode(payload, settings.SECRET_KEY) user_details = {} user_details['name'] = "%s %s" % ( user.first_name, user.last_name) user_details['token'] = token user_logged_in.send(sender=user.__class__, request=request, user=user) return Response(user_details, status=status.HTTP_200_OK) except Exception as e: raise e else: res = { 'error': 'can not authenticate with the given credentials or the account has been deactivated'} return Response(res, status=status.HTTP_403_FORBIDDEN) except KeyError: res = {'error': 'please provide a email and a password'} return Response(res)

In the code above, the login view takes username and password as input, and it then creates a token with the user information corresponding to the passed credentials as payload and returns it to the browser. Other user details such as name are also returned to the browser together with the token. This token will be used to authenticate in future requests.

The permission classes are set to allowAny since anyone can access this endpoint.

We also store the last login time of the user with this code.

user_logged_in.send(sender=user.__class__, request=request, user=user)

Every time the user wants to make an API request, they have to send the token in Auth Headers in order to authenticate the request.

Let's test this endpoint with Postman. Open Postman and use the request to authenticate with one of the users you created previously. If the login attempt is successful, the response will look like this:

Retrieving and Updating Users

So far, users can register and authenticate themselves. However, they also need a way to retrieve and update their information. Let's implement this.

In users.views.py, add the following code.

class UserRetrieveUpdateAPIView(RetrieveUpdateAPIView): # Allow only authenticated users to access this url permission_classes = (IsAuthenticated,) serializer_class = UserSerializer def get(self, request, *args, **kwargs): # serializer to handle turning our `User` object into something that # can be JSONified and sent to the client. serializer = self.serializer_class(request.user) return Response(serializer.data, status=status.HTTP_200_OK) def put(self, request, *args, **kwargs): serializer_data = request.data.get('user', {}) serializer = UserSerializer( request.user, data=serializer_data, partial=True ) serializer.is_valid(raise_exception=True) serializer.save() return Response(serializer.data, status=status.HTTP_200_OK)

We first define the permission classes and set to IsAuthenticated since this is a protected URL and only authenticated users can access it. 

We then define a get method to retrieve user details. After retrieving user details, an authenticated user will then update their details as desired.

Update your URLs to define the endpoint as follows.

users/urls.py from .views import CreateUserAPIView, UserRetrieveUpdateAPIView urlpatterns = [ url(r'^update/$', UserRetrieveUpdateAPIView.as_view()), ]

In order for the request to be successful, the headers should contain the JWT token as shown below.

If you attempt to request a resource without the authentication header, you will get the following error.

If a user stays beyond the time specified in JWT_EXPIRATION_DELTA without making a request, the token will expire and they will have to request another token. This is also demonstrated below.


This tutorial has covered what is necessary to successfully build a solid back-end authentication system with JSON Web Tokens.

Categories: Web Design

Moving From Flash To HTML, CSS, And JavaScript

Smashing Magazine - Tue, 03/13/2018 - 05:10

Back in the 2000s, it was commonplace to see websites that were built using Flash. By viewing the source of a website, you’d often see very little HTML and an embedded SWF file. This meant a few things. First, the browser didn’t natively support Flash, so you had to download the Flash plugin. Browsers found it difficult to go into the SWF to read content. Amongst other things, this had a detrimental affect on SEO and accessibility.

In 2007, the iPhone was released. It didn’t support Flash. In 2015, Google moved all its YouTube videos to HTML5. In July 2017, Adobe officially announced it would stop working on Flash by 2020. People used Flash because it could do things that HTML, CSS, and JavaScript couldn’t do at the time. It’s incredible to see how far web standards have come (and what’s coming).

We can do a lot today that was previously only possible with Flash. Not only that, but we can do it in a way that’s far more accessible and performant. I’ll go over some of the groundbreaking things Flash could do and how we can go about doing them today.

Disclaimer: I love Flash, and it will always have a place in my heart, but for me at least, its time has passed. Just in case you’re wondering: there are still so many interfaces and engines running in Flash, especially for games, and this article addresses some of the issues that are very relevant there.

Nope, we can't do any magic tricks, but we have articles, books and webinars featuring techniques we all can use to improve our work. Smashing Members get a seasoned selection of magic front-end tricks — e.g. live designing sessions and perf audits, too. Just sayin'! ;-)

Explore Smashing Wizardry → Video

One of the great things Flash heralded was video, offering basic support as early as 2002. It wasn’t until 2009 that the <video> tag was introduced in Chrome, Safari, and Firefox. Furthermore, Internet Explorer (IE) 8 didn’t support the <video> tag, and it wasn’t until 2011, when IE 9 was released, that it got support.

Flash would use the <object> tag, like so:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,16,0" width="320" height="400"> <param name="movie" value="filename.swf"> <param name="quality" value="high"> <param name="play" value="true"> <param name="LOOP" value="false"> <embed src="video-filename.swf" width="320" height="400" play="true" loop="false" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></embed> </object>

Not the nicest of code, but it did work.

Now, we can simply write <video src="filename.mp4" />, although it is important to be aware of different video formats across browsers, the most popular being MP4, Ogg and WebM. Taking things a step further, it’s possible not only to support the <video> tag, but also offer fallbacks and helpful alternatives:

<video width="320" height="400"> <source src="filename.mp4" type="video/mp4" /> <source src="filename.webm" type="video/webm" /> <source src="filename.ogv" type="video/ogg" /> <!-- Flash fallback --> <object type="application/x-shockwave-flash" data="flash-player.swf?videoUrl=filename.mp4" width="320" height="400"> <param name="movie" value="flash-player.swf?videoUrl=filename.mp4" /> <param name="allowfullscreen" value="true" /> <param name="wmode" value="transparent" /> <param name="flashvars" value="controlbar=over&image=placeholder.jpg&file=flash-player.swf?videoUrl=filename.mp4" /> </object> <!-- Text Fallback --> <p>No video support found. Please download the video below, or upgrade your browser: https://browsehappy.com/</p> </video> <ul> <li><a href="linktomovie.mp4">MP4 format</a></li> <li><a href="linktomovie.ogv">Ogg format</a></li> <li><a href="linktomovie.webm">WebM format</a></li> </ul> Video Background

Because YouTube makes use of the <video> tag and has an API, it’s possible to create a full-screen background video. Take the following YouTube video link code, for example:


Using the different parameters it’s possible to change the way the video behaves.

controls=0 Hides the controls. showinfo=0 Hides extra information. rel=0 Hides related content. autoplay=1 Auto plays the video when the site is loaded. loop=1 Loops the video. mute=1 Mutes the sound.

For a full list, check the IFrame Player API.

Using CSS, we can set the video to be fixed in position and to fill the screen.

.video { background: #000; position: fixed; width: 100%; height: 100%; top: 0; right: 0; bottom: 0; left: 0; z-index: -1; pointer-events: none; }

And with the use of media queries, we can set the video to be centered and can help keep the correct aspect ratio.

@media (min-aspect-ratio: 16/9) { .video { height: 300%; top: -100%; } } @media (max-aspect-ratio: 16/9) { .video { width: 300%; left: -100%; } }

Here’s the example put together, with Mr. Smashing Magazine himself presenting a talk:

See the Pen Video Background Demo Using YouTube by Simon Owen (@s10wen) on CodePen.

Interaction And Gaming

Another thing Flash excelled at was interaction and gaming. The popular website Miniclip was founded in 2001 and hosted a wide range of Flash games. In 2008, it was valued at over £900 million and is still going today.


JUST A REFLEKTOR is an interactive music video that rivals and even surpasses the capabilities of Flash. With the use of various web technologies, it’s now possible to interact with the video using a mobile device, as well as at one point using your webcam so that you actually appeared in the music video yourself!

The website Just A Reflektor makes great use of modern web technologies to create an interactive music video. Cube Slam

There’s some fantastic web-based Chrome experiments online today, such as Cube Slam. Cube Slam is a game that makes use of WebRTC (an open web technology), letting you video chat and play a game within the browser. Although Flash was heavily used for video chat, it came with a number of drawbacks compared to WebRTC: It relied on the Flash plugin, it required a media server, and it had various security implications and poor performance.

Cube Slam is a web based Chrome Experiment that allows video chat whilst playing a game. HTML5 Game Engines

There are a number of HTML5 and JavaScript game engines. This next example makes use of canvas and WebGL. WebGL (Web Graphics Library) is an API built in JavaScript that allows interactive 2D and 3D graphics within the <canvas> tag.

As mentioned in Good Boy Digital’s own post regarding the project (the creators of the example):

"Star Wars Arcade really pushes the boundaries of what’s possible with HTML5 and WebGL technologies. This allows for the creation of a single build that works seamlessly on both desktop and mobile browsers without having to download an app; the advantage of this being able to offer an ‘app like’ experience on all devices so anyone can enjoy it, instantly. No passwords, no App Stores, just hit the URL and play!"

goodboy digital, Star Wars Arcade Case Study

I especially love this bit: “Just hit the URL and play!” One of my earliest “Wow” memories of the web was having my own website in 1999 and being able to type that URL into any computer connected to the web and view it. It seemed absolutely incredible to me that this was actually possible (and continues to amaze me to this day!).

Browser Support

One of the advantages of building something—especially a game, due to the extra complexity—in Flash that is still relevant today is browser support. Browser support is generally pretty good these days, and Can I Use can help us to quickly find out about the state of browser support for a particular specification. However, there are still discrepancies that could cause issues. So, if you’re OK with only supporting browsers that are installed with the Flash plugin you’re working with, then you’re likely not to encounter any cross-browser issues.


Flash was originally designed as an animation tool. As such, it had various limitations with typography.

Flash had a pixel-grid system. If typography was laid on the grid at X:100.3 :100.7 and, thus, out of alignment to the pixel grid, it would look blurred.

As a result, I found that pixel fonts were useful because they sat on the grid and remained crisp. Another limitation here would be if you used an 8-pixel font but set it to 10 pixels, it would go out of alignment with the grid and, again, be blurred.

Thankfully, today in HTML and CSS, we have a host of tools to help us. We can set fonts as an absolute unit in px (pixels) or, more common these days, use ems and rems to aid with responsive web design (I’ll be covering more on this later).

Another issue with Flash and typography was fonts. If a font wasn’t available on the device, a fallback font would be provided. To circumvent this in Flash, you could embed the font in the .swf file. By doing this, though, you added to the file size and, thus, the time that the SWF would take to download and appear.

That being said, what was possible with Flash was Scalable Inman Flash Replacement (sIFR). sIFR allowed HTML text to be replaced with Flash. Before this, in order to use custom fonts, we used images. However, using images didn’t allow for selectable text, and it meant you had to create images manually. Moving on from sIFR, developers came up with Cufón. Cufón avoided the use of Flash by using an SVG and VML version of a font. It was faster than sIFR and didn’t require the Flash plugin; but, again, with this technique, it wasn’t possible to select text.

Today, we have the CSS @font-face rule and a host of standard web fonts available:

In Chrome and Firefox (and, hopefully soon, Safari), we have font-display in CSS. If you’re using a custom font, by default the browser will wait to get the custom font. If it can’t get the custom font, it will use a backup font (the speed varies among browsers, but it is usually 3 seconds). This is known as a flash of invisible text (or FOIT). To improve this scenario, we can use the following:

@font-face { font-display: swap; }

By using swap, we’ll see the text immediately using the backup font. When the custom font is loaded, the browser will swap the backup for it. This way, the user gets to read the content as soon as it’s available.


One of the things that Flash did very well was tweening. Tweening is used to animate elements. In Flash, you could create an element in a keyframe, duplicate that keyframe along the timeline, and then add a tween.

With HTML and CSS, we can apply the same animation using @keyframes, transform and animation.

<div class="box"></div> .box { width: 100px; height: 100px; background-color: #333; } @keyframes move { from { transform: translateX(0); } to { transform: translateX(200px); } } div { animation-duration: 3s; animation-name: move; animation-iteration-count: infinite; animation-direction: alternate; }

See the Pen CSS Animation Example by Simon Owen (@s10wen) on CodePen.

With Chrome Developer Tools, we can inspect and adjust the animation by going to Chrome Dev Tools → Cmd + Shift + P → Animation.

An example showing Chrome Developer Tool’s 'Performance' tab.

It’s also possible to debug potential performance issues that may arise when dealing with animation. In Chrome Developer Tools, there’s a “Performance” tab. By clicking this, then the “Record” circle icon, we can see a range of useful information. This technique greatly helped me when I built Mind’s Annual Report 2012-13, particularly the section of the website that has a map with animated circles showing the locations of Mind shops. Initially, the map section was loaded at the start, which caused repaint issues. Using the “Performance” tab, I was able to identify and update this, so the map only started animating when it was in view.

Vector Graphics

The web has benefitted and still does benefit enormously from careful consideration of file size. Back in the early 2000s, the web was mostly viewed on desktop computers, with slow dial-up modems. A simple image could take seconds or even minutes to load. To help with this, Flash made heavy use of vector graphics. Using vector graphics, where appropriate, instead of JPEG or GIF images, significantly reduced file size and thus load more quickly over the web.

Over the past few years, and particularly thanks to Sara Soueidan, scalable vector graphics (SVGs) have become more and more widespread on the web. SVG is an XML-based markup that enables us to create vector graphics for the web. It works extremely well with animation and I’ve had the pleasure of building some websites that make use of this: the Mind report website (previously mentioned) and How Clean Is England? which Sara mentioned on Twitter! Thanks Sara!

Mind’s Annual Report website made use of SVGs and animation to create a fun way to display their statistics for the year. The How Clean Is England? website was heavily based on illustration. SVGs and CSS animations helped to make the illustrations look crisp and keep file sizes to a minimum. Responsive Web Design

One of the main pitfalls of building a website in Flash today is the lack of media queries. Today, mobile and tablet usage has surpassed that of desktop. In order to create the best experience, we must create a website that is accessible on all of these devices. On many devices, Flash will simply not load at all, and even if it did, it would most likely breach the viewport’s width or would scale and be unusable.

Using media queries, we can create a layout that responds to the content. Here’s an example:

<div class="someContent"> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Est excepturi enim id ratione blanditiis voluptate dolore necessitatibus culpa maxime eius assumenda eveniet dolores odit sunt repellat, rerum amet delectus vel.</p> </div> .someContent { color: green; } @media screen and (min-width: 400px) { .someContent { color: yellow; } } @media screen and (min-width: 600px) { .someContent { color: red; } }

See the Pen Simple Media Query Example by Simon Owen (@s10wen) on CodePen.

ActionScript vs. JavaScript

ActionScript is used in Flash and, thus, has the same pitfall of SWF files mentioned earlier, in that it requires the Flash plugin. JavaScript, on the other hand, is readily available in all modern browsers.

Let’s look at an example of setting a variable in both and their differences:

var x:Number = 42; var x = 42;

With ActionScript, we declare that the variable is a number. If the variable is assigned anything else, it will get an error. JavaScript is loosely typed, which means we could assign the variable as something else, such as a string:

var x = '42';

In JavaScript, if we wanted to check that it is a number, we could use typeof(x);, and this would output “number”. Another option would be to create a function and use isNaN to detect whether it is “not a number”:

function isNumber(value) { if (isNaN(value)) { return value + ' is not a number.'; } return value + ' is a number.'; } console.log(isNumber(42)); // "42 is a number." console.log(isNumber('forty two')); // "forty two is not a number." Collaboration

With HTML, CSS, and JavaScript (and many other coding languages), Git and GitHub make collaboration extremely easy. For example, if I wanted to edit the HTML of Smashing Magazine’s “Author Template,” via GitHub, I could click the “Fork” button. This would create a version of the files (also known as the repository) under my own name. I could then make any amendments I like and submit a pull request. This would give the owner at Smashing Magazine the ability to review my pull request and accept or reject it. Once accepted, the code would go in the main repository.

There are a number of great reasons for working in this way: You always have a backup of your work; you can revert to previous versions of your work, and collaboration becomes very easy. Someone could be working on one section of the website, or on the CSS or JavaScript, and when each team member has finished, you could review the changes and pull them in as required.

If we tried the same with Flash, it would be a lot more difficult having to save and send an .fla file each time. If multiple people were to work on the same .fla, things could get very confusing. With HTML, CSS and JavaScript, it’s’ possible to do a “diff” on the code, which allows us to compare and review the code. We can even select certain code chunks, bring them in, or comment on them for further review and work.


Flash was one of the reasons I started building websites. It pioneered in a lot of areas, and this led to people creating amazing things with it. Over the years, it’s pushed the web forward a great deal. Adobe’s official announcement of dropping support of Flash, though, does raise concerns. It would be a massive shame if millions of websites using Flash were lost. There’s a petition to open source Flash and Shockwave. I do hope we don’t lose it forever. We’ve had some great — and weird — times. I’ll leave you with this classic example of the “weird” to which I refer:

Here are the lyrics, if you’d like to sing along.

(ra, hj, al, il)
Categories: Web Design

Building A Static Site With Components Using Nunjucks

Smashing Magazine - Tue, 03/13/2018 - 03:00

It’s quite popular these days, and dare I say a damn fine idea, to build sites with components. Rather than building out entire pages one by one, we build a system of components (think: a search form, an article card, a menu, a footer) and then piece together the site with those components.

JavaScript frameworks like React and Vue emphasize this idea heavily. But even if you don’t use any client-side JavaScript at all to build a site, it doesn’t mean you have to give up on the idea of building with components! By using an HTML preprocessor, we can build a static site and still get all the benefits of abstracting our site and its content into re-usable components.

Static sites are all the rage these days, and rightfully so, as they are fast, secure, and inexpensive to host. Even Smashing Magazine is a static site, believe it or not!

Let’s take a walk through a site I built recently using this technique. I used CodePen Projects to build it, which offers Nunjucks as a preprocessor, which was perfectly up for the job.

A Four-Page Site With A Consistent Header, Navigation, And Footer

This is a microsite. It doesn’t need a full-blown CMS to handle hundreds of pages. It doesn’t need JavaScript to handle interactivity. But it does need a handful of pages that all share the same layout.

Consistent header and footer across all pages

HTML alone doesn’t have a good solution for this. What we need are imports. Languages like PHP make this simple with things like <?php include "header.php"; ?>, but static file hosts don’t run PHP (on purpose) and HTML alone is no help. Fortunately, we can preprocess includes with Nunjucks.

Importing components is possible in languages like PHP

It makes perfect sense here to create a layout, including chunks of HTML representing the header, navigation, and footer. Nunjucks templating has the concept of blocks, which allow us to slot in content into that spot when we use the layout.

<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>The Power of Serverless</title> <link rel="stylesheet" href="/styles/style.processed.css"> </head> <body> {% include "./template-parts/_header.njk" %} {% include "./template-parts/_nav.njk" %} {% block content %} {% endblock %} {% include "./template-parts/_footer.njk" %} </body>

Notice the files that are included are named like _file.njk. That’s not entirely necessary. It could be header.html or icons.svg, but they are named like this because 1) files that start with underscores are a bit of-of a standard way of saying they are a partial. In CodePen Projects, it means they won’t try to be compiled alone. 2) By naming it .njk, we could use more Nunjucks stuff in there if we want to.

None of these bits have anything special in them at all. They are just little bits of HTML intended to be used on each of our four pages.

<footer> <p>Just a no-surprises footer, people. Nothing to see here.<p> </footer>

Done this way, we can make one change and have the change reflected on all four pages.

Using The Layout For The Four Pages

Now each of our four pages can be a file. Let’s just start with index.njk though, which in CodePen Projects, will automatically be processed and create an index.html file every time you save.

Starting off with an index.njk file

Here’s what we could put in index.njk to use the layout and drop some content in that block:

{% extends "_layout.njk" %} {% block content %} <h1>Hello, World!</h1> {% endblock %}

That will buy us a fully functional home page! Nice! Each of the four pages can do the same exact thing, but putting different content in the block, and we have ourselves a little four-page site that is easy to manage.

The index.njk file gets compiled into index.html

For the record, I’m not sure I’d call these little chunks we re-using components. We’re just being efficient and breaking up a layout into chunks. I think of a component more like a re-usable chunk that accepts data and outputs a unique version of itself with that data. We’ll get to that.

Making Active Navigation

Now that we’ve repeated an identical chunk of HTML on four pages, is it possible to apply unique CSS to individual navigation items to identify the current page? We could with JavaScript and looking at window.location and such, but we can do this without JavaScript. The trick is putting a class on the <body> unique to each page and using that in the CSS.

In our _layout.njk we have the body output a class name as a variable:

<body class="{{ body_class }}">

Then before we call that layout on an indivdiual page, we set that variable:

{% set body_class = "home" %} {% extends "_layout.njk" %}

Let’s say our navigation was structured like

<nav class="site-nav"> <ul> <li class="nav-home"> <a href="/"> Home </a> ...

Now we can target that link and apply special styling as needed by doing:

body.home .nav-home a, body.services .nav-services a { /* continue matching classes for all pages... */ /* unique active state styling */ } Styling navigation links with an active class.

Oh and those icons? Those are just individual .svg files I put in a folder and included like

{% include "../icons/cloud.svg" %}

And that allows me to style them like:

svg { fill: white; }

Assuming the SVG elements inside have no fill attributes already on them.

Authoring Content In Markdown

The homepage of my microsite has a big chunk of content on it. I could certainly write and maintain that in HTML itself, but sometimes it’s nice to leave that type of thing to Markdown. Markdown feels cleaner to write and perhaps a bit easier to look at when it’s lots of copy.

This is very easy in CodePen Projects. I made a file that ends in .md, which will automatically be processed into HTML, then included that in the index.njk file.

Files in markdown get compiled into HTML on CodePen Projects. {% block content %} <main class="centered-text-column"> {% include "content/about.html" %} </main> {% endblock %} Building Actual Components

Let’s consider components to be repeatable modules that as passed in data to create themselves. In frameworks like Vue, you’d be working with single file components that are isolated bits of templated HTML, scoped CSS, and component-specific JavaScript. That’s super cool, but our microsite doesn’t need anything that fancy.

We need to create some “cards” based on a simple template, so we can build things like this:

Creating repeatable components with templates

Building a repeatable component like that in Nunjucks involves using what they call Macros. Macros are deliciously simple. They are like as if HTML had functions!

{% macro card(title, content) %} <div class="card"> <h2>{{ title }}</h2> <p>{{ content }}</p> </div> {% endmacro %}

Then you call it as needed:

{{ card('My Module', 'Lorem ipsum whatever.') }}

The whole idea here is to separate data and markup. This gives us some pretty clear, and tangible benefits:

  1. If we need to make a change to the HTML, we can change it in the macro and it gets changed everywhere that uses that macro.
  2. The data isn’t tangled up in markup
  3. The data could come from anywhere! We code the data right into calls to the macros as we’ve done above. Or we could reference some JSON data and loop over it. I’m sure you could even imagine a setup in which that JSON data comes from a sort of headless CMS, build process, serverless function, cron job, or whatever.

Now we have these repeatable cards that combine data and markup, just what we need:

HTML is controlled in the macro, while data can come from anywhere Make As Many Components As You Like

You can take this idea and run with it. For example, imagine how Bootstrap is essentially a bunch of CSS that you follow HTML patterns in which to use. You could make each of those patterns a macro and call them as needed, essentially componentizing the framework.

You can nest components if you like, embracing a sort of atomic design philosophy. Nunjucks offers logic as well, meaning you can create conditional components and variations just by passing in different data.

In the simple site I made, I made a different macro for the ideas section of the site because it involved slightly different data and a slightly different card design.

It's possible to create as many components as you want A Quick Case Against Static Sites

I might argue that most sites benefit from a component-based architecture, but only some sites are appropriate for being static. I work on plenty of sites in which having back-end languages is appropriate and useful.

One of my sites, CSS-Tricks, has things like a user login with a somewhat complex permissions system: forums, comments, eCommerce. While none of those things totally halt the idea of working staticly, I’m often glad I have a database and back-end languages to work with. It helps me build what I need and keeps things under one roof.

Go Forth And Embrace The Static Life!

Remember that one of the benefits of building in the way we did in this article is that the end result is just a bunch of static files. Easy to host, fast, and secure. Yet, we didn’t have to give up working in a developer-friendly way. This site will be easy to update and add to in the future.

  • The final project is a microsite called The Power of Serverless for Front-End Developers (https://thepowerofserverless.info/).
  • Static file hosting, if you ask me, is a part of the serverless movement.
  • You can see all the code (and even fork a copy for yourself) right on CodePen. It is built, maintained, and hosted entirely on CodePen using CodePen Projects.
  • CodePen Projects handles all the Nunjucks stuff we talked about here, and also things like Sass processing and image hosting, which I took advantage of for the site. You could replicate the same with, say, a Gulp or Grunt-based build process locally. Here’s a boilerplate project like that you could spin up.
(ms, ra, hj, il)
Categories: Web Design

Tips For Conducting Usability Studies With Participants With Disabilities

Smashing Magazine - Mon, 03/12/2018 - 05:20

Over the last few years, I ran several usability studies with participants with various disabilities. I thought it would help others if I shared some of my experiences.

In this article, I provide lessons learned or tips to consider in planning and executing usability testing with participants with disabilities. The lessons learned are divided into general that can apply to all types of disabilities; and lessons learned for three specific disability categories: visual, motor, and cognitive. These tips will help you regardless where you work: If you work with an established user research team where usability testing is part of your design process or if you work on your own with limited resources but want to improve the quality of the user research by expanding the diversity of participants.

Windows 10 high contrast mode of Google.com. (Large preview) Background

Several of our clients from a state government agency to several fortune 500 companies came to us at the User Experience Center (UXC) for help with their websites. They wanted to make sure users with disabilities could access their site and accomplish their goals.

There are many different kinds of disabilities, however, there is a general agreement to categorize people with disability into four general categories: visual, auditory, motor (also referred to as "physical"), and cognitive. There are different conditions and much variability within each category, e.g., within visual disabilities, color blindness, low vision, and blindness. There is also a distinction as to when a disability is contracted, e.g., a person who was born blind as opposed to one who lost vision later on in life.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features →

Furthermore, as we age or encounter unique situations (such as multi-tasking), we may have a similar experience to people we think of as disabled. Therefore, disabilities should be thought of as a spectrum of abilities that should be accounted for during the design of all user interfaces and experiences.

Typically, in order to ensure that disabled people can use their digital products and services, companies aim for compliance with accessibility guidelines such as the Web Content Accessibility Guidelines (WCAG 2.0). While this is critical, it is also important to have users with disabilities try to accomplish real tasks on the site in usability testing. There may be gaps in the overall user experience...

Think about the typical doors found in buildings. How many times have you tried to open a door one way and realized they actually open the other, for example, push instead of pull. Technically the door is accessible, but it is usable?

Example of doors that are technically accessible, but not usable (handles give impression you should push but must pull to open). (Large preview)

Even if a site follows the accessibility guidelines and is technically accessible, users may not be able to accomplish their goals on the site.

Lesson Learned

In most ways, usability testing with this segment of the population is no different than testing with anyone else. However, there are several areas you need to pay just a bit more attention to so your sessions run smoothly. The lessons or tips are broken down into general ones that can apply to all participants and specific tips for various disability types such as visual, motor, and cognitive.

General Lessons Learned 1. Ensure a baseline level of accessibility before usability testing

Ensure a baseline level of accessibility before usability testing: Planning usability testing, especially recruiting participants can take time both for the project team and the recruited participants.

Two good examples of basic accessibility issues that should be addressed prior to usability testing are:

  • Missing alternative (alt) text.
    Usability testing can be used to see if the alt text used is appropriate and makes sense to participants, but if all the participants are doing is confirming that the alt text is missing then this is not a good use of their time.
  • Appropriate color contrast.
    All page designs should be reviewed beforehand to make sure all foreground and background colors meet WCAG 2.0 AA color contrast ratios.
2. Focus the recruiting strategy

If you work with an external recruiter ask them if they have experience recruiting people with disabilities; some do. If you are recruiting internally (without an external recruiter), you may need to reach out to organizations that have access to people with disabilities. For example, if you need to recruit participants with visually disabilities in the United States, you should contact a local chapter of the National Federation of the Blind (https://nfb.org/state-and-local-organizations) or a local training center such as the Carroll Center for the Blind in Massachusetts (http://carroll.org/). If you use social media to advertise your study, a good approach is to use the hashtag #a11y (stands for accessibility — there are 11 letters between the "a" and "y") in your post.

3. Bring their own equipment/assistive technology

Allow and encourage participants to bring their own equipment such as their own laptop, especially if they use assistive technology. This way, you can truly see how people customize and use assistive technology.

4. Have a backup plan for assistive technology

As stated above in #3. It is best if participants can bring their own equipment. However, it is always wise to plan for the worst, for example, if a participant does not bring their equipment or if there is a technical problem such as you can't connect their equipment to your Wi-Fi network. In the case of visually impaired participants, install assistive technology (AT) such as screen reader software they will be bringing in on a backup PC. For many of the AT software packages, you can get a free trial that should cover you for the usability testing period. This has saved us several times. Even though the configuration was different than what the participants had, we were able to run the session. Participants were quickly able to go into the settings and make some adjustments (e.g., increase the speech rate) and get started with the session.

5. Allow additional time

Provide additional time in-between sessions. Typically we like to reserve 30 minutes between participants. However, when participants plan to bring in their own equipment additional time may be required for setting up and resolving any issues that may arise. When testing with individuals with disabilities, we schedule an hour between sessions, so we have extra time for setting up assistive technology and testing it.

6. Confirm participant needs

Either with the recruiting screener or via email or telephone, confirm what equipment participants will bring in and need to be supplied beforehand. In our lab, we can connect external laptops (that in this case, were outfitted with special accessibility software and settings) to our 1Beyond system via an HDMI cable. In a recent study, all of our participants' laptops had HDMI ports. However, we forgot to check this beforehand. This is an example of a small but important thing to check to prevent show-stopping issues at the time of the test.

7. Consider additional cost

Depending on the disability type transportation to the usability testing location may add additional burden or cost. Consider the cost of transportation in the incentive amount. If feasible, consider providing an extra $25-$40 in your incentive amount so participants can take a taxi/Uber/Lyft, etc. to and from your location. Depending on access to public transportation and taxi/ride-sharing rates in your area the amount may vary. Our participants came to the UXC in different ways — some more reliable and timely than others.

8. Revise directions

Check the directions you provide for accessibility. Make sure they include an accessible path into your building. Test them out beforehand. Do you need to provide additional signage? If so, ensure all signs are clear, concise, and use plain-language directions.

9. Review the emergency evacuation plan

Review the plan in the event of a fire or other emergency. Map out the emergency evacuation plan in advance.

10. Consider logistics

Consider remote usability testing as an option. One of the benefits of bringing individuals with disabilities into the lab for usability testing is observing first-hand participants' use of the product or website in question. However, the logistics of getting to your location may be just too much for participants. If it's possible to test remotely (we typically do this through Zoom or GoToMeeting), it should be considered. This poses the additional challenge of making sure your process for capturing the remote session is compatible with all of the participant's assistive technology, as well as accessible itself. Troubleshooting remotely is never fun and could be more difficult with this segment of the population.

11. Hearing impaired participants

Some participants may have a hearing impairment where the position of the moderator and participant is critical for adequate communication. In the case of hearing-impaired participants, it is important to get their attention before talking to them and also to take turns when engaging in conversation.

To get the most of this research, it is best if the participants are not discovering basic accessibility issues that should have been discovered during an accessibility review and/or testing.

Lessons Learned For Participants With Visual Disabilities

Participants with visual disabilities range from people who are blind and use screen readers such as JAWS, to people that need to the text or the screen to be enlarged using software such as ZoomText or relying on the native screen enlargement in the browser. People that are color-blind also fall into this category.

  • For any documents needed prior to the study such as the consent form, send via email beforehand and ask them review and send back in lieu of a physical signature. If you don't, be prepared to read aloud the consent form and assist in signing the documents for some participants.
  • Make sure directions provide step-wise directions; do not rely only on graphical maps as these may not be accessible.
  • For all documents, make sure color is not used as the sole cue to convey information. Print out all documents on a black and white printer to make sure color is not required to make sense of the information.
  • Get participants mobile phone numbers in advance and meet them at their drop-off point. Be prepared to guide them to the testing location. Review best practice for guiding blind individuals:
  • While Braille documents can be helpful for participants that read Braille, the time and cost involved may not be feasible. Furthermore, all blind people do not read Braille, especially people that have lost sight later in life. It is best to make sure all documents can be read via a screen reader. Unless you are sure if there are no accessibility issues avoid PDF documents and send out simple Word documents or text-based emails.
  • If participants bring guide dogs do not treat them as pets, they are working. Provide space for the dog and do not pet it unless the participant gives you permission.
  • Make sure to explain beforehand any sounds or noise that are or may be present in the room such as unique audio from recording software. This may avoid the participant from becoming startled or confused during the session.
  • Initially when I started to work with blind participants I was worried my choice in language might offend. However, over the years I have learned that most blind participants are fairly relaxed when it comes to speech. Therefore, during moderation do not be afraid to use phrases such as "see" or "look" and similar words when talking to blind participants; for example, "please take a look at the bottom of the page" or "what do you see in the navigation menu?" In my experience, blind participants will not be offended and will understand the figurative meaning rather than the literal meaning.
  • Test out all recording equipment/processes beforehand. Ensure all audio including both human speech in the room and audio/speech from AT such as screen readers will be recorded correctly. During testing of the equipment adjust the locations of the microphones for optimal recording.
Lessons Learned For Participants With Motor Disabilities

Motor disabilities refer to disabilities that affect the use of arms or legs and mobility. These individuals may need to use a wheelchair. Some people may not have full use of their hands or arms and cannot use a standard mouse and keyboard. These people may need to voice recognition software which allows to use voice input or use a special pointing device, for example, one that is controlled by their mouth.

  • In the directions, make sure the route is accessible and routes them via elevators rather than stairs. Also, if participants are driving note the location of accessible parking.
  • Note if doors have accessible door controls. If not you may need to meet the participant and guide them to the testing location.
  • Make a note of the nearest accessible restrooms to the testing location.
  • As with all participants with disabilities, it is best if they can bring in their own laptop with their assistive technology software installed and any other required assistive technology. However, in the case of participants (such as Adriana in Figure 3) that use voice recognition software such as Dragon Naturally Speaking this is critical because they have trained the software to recognize their voice.
  • Make sure the desk or table where the participant will be working can accommodate a wheelchair and the height is adjustable. According to the American with Disabilities Act (ADA), conference tables must be 27 inches high in order to accommodate knee clearance for individuals in wheelchairs..
Adriana Mallozzi conducting a usability test at the User Experience Center. Adriana has a motor disability (cerebral palsy) which affects her entire body. She uses a wheelchair, a sip-and-puff joystick that acts as a mouse, along with Dragon Naturally Speaking. (Large preview) Lessons Learned For Participants With Cognitive Disabilities

Individuals with these disabilities cover a wide range of relatively mild learning disabilities such as Dyslexia to individuals with a more profound cognitive disability such as Down syndrome. In general, people with cognitive disabilities have challenges with one or more mental tasks. Rather than looking at specific clinical definitions it best to consider functional limitations in key areas such as memory, problem-solving, attention, reading or verbal compensation. Consider how best to accommodate participants during usability testing. Many of the tips below should also apply to all participants, however for this group you need to be extra aware.

  • Sometimes participants will be accompanied by a caretaker or an aide. This person may assist with transportation or may need to be present with the participant during the usability test. If the caretaker is present during the usability test, make sure they understand the structure of the usability test and what will be required of the participant. If you know the participant will be accompanied before the study, you review the goals and protocol prior to arrival via email or phone. That is as much as possible the participant should be one conducting the usability testing, and the caretaker should not be involved unless it is completely necessary.
  • In some cases, the caretaker or aide may act like an interpreter. You may need to communicate with this interpreter in order to communicate with the participant. If this is the case, make sure you record the audio coming from both the participant and the interpreter.
  • Provide instructions in multiple modalities, for example, both written and verbal. Be patient and be prepared to repeat the task or ask the same question multiple times.
  • Be prepared to break tasks into smaller sub-tasks to support memory/attention challenges or fatigue that may set in.
  • Ideally, it is best to be consistent with tasks for all participants however for some participants with cognitive disabilities you should be prepared to go off-script or modify tasks on the fly if the current approach is not working.
  • Have the participant's comfort and well-being the number one priority at all times. Don't be afraid to take multiple breaks or end the session early if things are just not working out or the participant is not comfortable.
Amazon.com home page zoomed in at 250%. (Large preview) Additional Insights

The tips above should serve as guidelines. Each participant is unique and may require various accommodations depending on their situation. Furthermore, while some of the tips are categorized for specific disability types, specific individuals may have multiple disabilities and/or benefit from a tip from a different category than their primary disability.

If you or your company have conducted user or customer research, you know the value of gathering feedback about the issues and benefits of products and systems. Testing with individuals with disabilities is no different, as you learn many insights that you would not gain otherwise. However, an additional takeaway for us was the realization that people use assistive technologies in different ways. The following example is specific to people with visual disabilities, but there are similar examples across all groups.

An assumption might be someone that is blind only uses a screen reader such as JAWS and is an expert at it. We found that people with visual impairments actually differ greatly in the level of support needed from assistive technology.

  • Some users need a screen reader for accessing all content.
  • Some users (with more sight/with low vision) only need to enlarge content or invert page colors to increase contrast.
  • Others may need a combination of approaches. One visually impaired participant used both a screen reader along with the zoom function embedded in the web browser. She only used a screen reader for large paragraphs of text, but otherwise simply zoomed in with the web browser and got very close to the screen when navigating around the website.

Furthermore, just like anyone, all users are not experts on the software they use. While some users would consider themselves experts, some only learn enough about the software to accomplish what they need and no more.

Moving Forward

Hopefully you have learned some useful information that will help you include more diversity into your usability testing. However, since there is variability with different disabilities, this may seem overwhelming. I recommend starting small; for example by including one or two participants with disabilities as part of a larger group of 5 to 10 participants. In addition, initially bring in someone that has both experience with usability testing and a lot of experience with their assistive technology so you can focus on getting their feedback rather than how the usability testing process works or their use of their assistive technology.


I would like to thank Jocelyn Bellas, UX Researcher at Bank of America and Rachel Graham, UX Researcher at Amazon. When Rachel and Jocelyn worked at the User Experience Center as Research Associates in 2016, they worked with me on some of the projects referenced in this article and also contributed to a related blog post on this topic.

References (cc, ra, yk, il)
Categories: Web Design

How to Use Design Thinking to Solve Problems

Design thinking is a term for a specific approach to problem solving. Whether you’re a designer, a developer, a business owner, anyone really, I’m sure at one point or...

The post How to Use Design Thinking to Solve Problems appeared first on Onextrapixel.

Categories: Web Design

The Future Of Mobile Web Design: Video Game Design And Storytelling

Smashing Magazine - Fri, 03/09/2018 - 04:00

As technologies change and design techniques evolve, it’s inevitable that we’d experience massive growth in terms of design quality. There are similar parallels we can see within video game design as well. For instance:

This was CERN, the very first website back in 1991. Just some basic HTML and ample white space:

The very first website to appear online back in 1991. (Large preview)

This example from Smashing Magazine is how we design websites and share information online in 2018:

A much more complicated and yet beautiful web design… 27 years after the advent of websites. (Large preview)

Nope, we can't do any magic tricks, but we have articles, books and webinars featuring techniques we all can use to improve our work. Smashing Members get a seasoned selection of magic front-end tricks — e.g. live designing sessions and perf audits, too. Just sayin'! ;-)

Explore Smashing Wizardry →

Now, if you look at the history of video game design, you’ll note a similar track; one in which early games like Pong were incredibly simplistic and devoid of any real story:

But now there are games like Grand Theft Auto that put players in the actual driver’s seat, allowing them to control the pace, direction, and outcomes of their experience:

As technologies improve and design techniques evolve, improvements in digital design are inevitable. What is truly impressive, however, is how we are now able to use design to tell a story. In other words, we no longer need to use long scrolls to set up plots or describe what a company does. This is especially great when designing for the mobile experience, which already sets pretty strict limits on how much we can “tell” versus “show.”

In this article, I want to look at three ways in which video game designers get the storytelling aspect of design right, and how web designers can use these techniques to provide users with an immersive experience and drive them more quickly and effectively to conversion.

Three Video Game Storytelling Techniques We Need More Of In Web Design

Video games have come a long way since they were introduced in the late ‘70s in terms of graphics, user controls and, of course, story development. With video game design evolving around the same time as web design, there are similar features and trends that can be found between the two. The only thing is, I don’t know if many web designers think to look to video games for design tips.

Granted, the overwhelming use of shocking colors and cheesy dialogue won’t work that well when you’re developing a professional website. However, it’s the way in which video game designers tell a story with design elements — and effectively guide players to the end by using those elements — that we need to pay attention to.

As your visitors’ attention spans shorten and demand grows for more engaging experiences, web designers can greatly benefit from using these storytelling techniques on the web and, more importantly, for mobile.

1. Make Your Visitor the Hero

Ever since the early days of video games, the goal was to put the player in the front seat and to let them be the hero of the story.

Take PAC-MAN, for instance:

The player was always the hero (i.e., PAC-MAN), and his or her mission was to work through the situation (i.e., to fight the ghosts) and get to the end.

The same holds true for modern gaming as well, though many games go the route of giving players the impression they have control over their heroic journey. A good example of this are the Telltale games.

Basically, each of their games is crafted around a well-known story. In the example above, the game is based on the events that unfold in the T.V. show Game of Thrones. Throughout the game, players are called upon to step into the world and make active choices about what happens next. Sometimes this is through dialogue (at 6:00), and sometimes it happens through action (at 11:55).

In the end, every player of the game ends up at the same place regardless of which way they turn or what line they utter. This doesn’t make the experience any less enthralling for the player as they are actively engaged throughout, and there is a reward in the end — even if it’s one they share with every other person who has played this game.

That’s exactly what websites should do for their visitors, right? They allow visitors to take full control over the experience so that they want to get to the end. For the web, this translates to conversion. And the best way to do this, as evidenced by video games, is to give visitors the ability to pick and choose how they traverse through the story.

Here are some ways in which you can do this with web design:

Create User Personas

Develop user personas before you do anything else when strategizing and planning for a website. Your personas should have a key “problem” they face. It’s then your job to establish the user’s journey in a way that helps them discover solutions to that problem.

Enable Avatar Setup

For those of you with websites that allow for users to create profiles, this is a great opportunity to enable them to define their own unique identity. Allow them to upload a photo of themselves and to personalize their profile. You can also give them different access settings which directs what kinds of content they see, what types of offers they receive, and so on.

WordPress membership websites like WPMU DEV are a good example of websites that do this. Users can create their own profiles and earn points and special statuses based on how much work they put into the community.

A fun community where web design and development professionals can set up individual profiles. (Large preview) Use Relatable Content

In video game design, there is something known as “ludonarrative dissonance.” Basically, it “is the unpleasant situation where we’re asking players to do something they don’t want to do… or prevent them from doing what they want.”

You’ve likely encountered this sort of resistance as you’ve designed websites in the past.

You review the analytics and discover high bounce rates on certain pages or even right from within the home page. You discover that there’s a visual element or a line of copy that just doesn’t sit right with your audience. That’s because it’s a disruption in what should be an otherwise immersive experience. By using content that resonates with the visitor, that makes them feel like you’re telling their story, they won’t feel disconnected and want to stray from the goal.

Spin a Fantasy

Here’s an interesting fact: people are 22 times more likely to remember data when it’s presented in a narrative form.

Let’s face it; if you’re building a website on behalf of a business or other professional entity, you don’t have some dramatic tale to spin like a video game does. And that’s fine.

Consumers aren’t visiting websites in order to get caught up in hours of epic storytelling. That said, they do still expect to be engaged by what you’re sharing with them.

So, why not depict a fantastic scenario through visual storytelling? The brain digests visual content 60% more quickly than written content, so your web designs and other visuals (like video, animation, and so on) are the keys to doing this.

The Airbnb blog always does a great job of this type of visual storytelling.

The Airbnb blog is a master of visual storytelling. (Large preview)

While every story is probably told through 800 to 1,000 words, it’s also accompanied by highly attractive visuals that tell you something about what you’d experience at this specific destination.

2. Minimize Distractions by Using Symbols

Let’s talk specifically about websites viewed from mobile devices for a second, shall we? As of August 2017, 52.64% of all visits to websites were done via a smartphone. And, starting in 2017, the most popular size for a smartphone was between five and six inches and will only continue to grow in popularity as the years go on.

That’s not a lot of space to fill with content for the majority of site visitors, is it? So, how do you effectively tell a story if you have limited real estate? If we’re to take a page out of the video game design handbook, then we should turn to symbols.

Kontra makes a good point about this:

"[O]ne, often overlooked, strong point of game UX is the preference towards symbolism. The ability to transform meaning into symbols was a huge step towards visual decluttering."

Functional minimalism is already something you’re doing in your own web design efforts, but have you thought about how it can tie into the storytelling aspect as well? When it comes to video games, symbols help clear the way so that players can focus on the story before them. You’ll see this most often in two-dimensional, side-scroller games:

Street Fighter and other fighting games place the health bar at the top:

Sonic the Hedgehog places the life counter at the bottom:

There are even ones like Virtua Racing and other geographic-dependent games that put their navigation off to the side for players to reference:

As you can see, the use of symbols keeps the gamespace clear and easy to follow along with.

Whether you’re designing mostly for desktop or mobile users, your aim is to design a space that encourages users to follow along and not get caught up in distractions. So, while you might think that full-screen, overlay navigation is a creative choice for your website or the ever-present live chat pop-up will get more engagements, you may be doing yourself a great disservice.

By employing the use of easily recognized symbols throughout your site, you can keep the design clean and clear and distraction-free. The story you’re weaving throughout is the most important thing, and you don’t want to stand in the way of visitors being able to get to it.

MSR is a beautiful example of this done well:

A good example of how to minimize navigation and directional cues so visitors can focus on the main content and story. (Large preview)

The website is for their architecture design firm. Rather than write volumes of text about what they’ve done and how they do it, they allow the images to speak for themselves. They’ve then employed a number of symbols to help visitors continue on to other points of interest in their journey.

Here are some ways in which you might use symbols to declutter your site:

  • Hamburger icon (for the navigation)
  • Profile photo icon (for account details)
  • Pencil icon (for an editing interface)
  • Gear icon (for settings)
  • Shopping cart icon (to checkout)
  • Magnifying glass (to expand the search bar)
  • Connector icon (to open social sharing and RSS feed options)
  • Question mark (to expand live chat, search, or help options)
  • And so on.

One thing to note here is that you don’t want to overdo it with icons. As you can see from the video game examples above, the entire interface isn’t strewn with icons. They’re simply there to hold the place of elements players are already familiar with and will refer to often. That’s the way you should handle icons for your own site. Think about how easy your icons will be to decipher as well as which ones are absolutely necessary. Decluttering doesn’t mean hiding every element under an icon; you simply want to tidy up a bit.

If you’re concerned with the potential for confusion over what your icons mean to users, then use labels, alt text, or tooltips to provide further elaboration to those who need it.

3. Be Smart About How You Use Space

One of the nice things about video games is how they use actual walls and roadblocks to prevent players from navigating into territory where they shouldn’t be. One of my favorite games that does this right now is called LittleBigPlanet. While it is similar to side-scrolling adventures like Super Mario, its design expands beyond the basic two dimensions usually experienced in these kinds of games.

As you can see, the player encounters a number of hard surfaces which then prompt him or her to move back and forth between layers, to climb up various elements, and to find a more ideal route towards the end of the game.

First-person shooter games like Halo also use physical elements to keep players confined to the main gamespace and on track to completing the mission and story.

As a web designer, you don’t have the luxury of crafting walls around the user’s journey on your site. That said, you don’t have to design a website and leave it all to chance. There are ways to steer visitors through a direct path to conversion.

Kill Screen did an interesting write-up about the art of spatial storytelling in video games. In it, writer Sharang Biswas explained the idea that “Spaces can be designed. They can be made to promote certain pathways, encourage specific behaviors, even elicit emotional reactions.”

There are a number of ways in which you can do this with design:

Use a Spotlight

In video games, you can use light and darkness to draw attention to important pathways. On websites, it’s not always easy to employ the use of lightness or darkness as too-dark of a design or too-light of text could lead to a bad user experience. What you want to do instead is create a “spotlight” of sorts. You can do this by infusing a key area of your design with a dramatic color or a boldly stylized font.

In a site that’s otherwise pretty light in color usage, Kappow does a nice job using it to highlight two key areas of the site where it’s clear visitors should visit: its case studies.

It’s more than obvious where Kappow wants visitors to focus their attention as they scroll through the home page. (Large preview) Add Clues

If you’ve ever played a horror video game before, you know how critical the element of sound can be for it. Here’s an example of how Until Dawn uses sound (as well as visual footprints) to try to steer the player in the right direction:

In all honesty, I’m not a big fan of music on websites, even if they’re from auto-play videos that I visited the website for in the first place. I’m sure I’m not the only one who feels this way as there aren’t many websites that employ the use of background music or auto-play audio anymore.

That said, while you might not be able to direct visitors down the page with the sound of something playing down below, you can use other elements to lead them. For one, you can use interactive elements like animation to draw their attention to where it needs to go. Let’s take a game like Angry Birds, for example.

See how the little red birds are hopping up and down while they wait their turn? It’s a subtle gesture, but one that is sure to draw first-time players’ attention to the area of the screen in which they should directly interact if they want to move on to the next level. Animation on a website would work just as effectively if you’re trying to lure visitors’ eyes down to a key element like a contact form or a clickable button.

But it doesn’t just have to be animation. Other video game designers simply plant clues around the landscape to steer players through the journey. I’m not suggesting that your site start hiding Easter eggs all over the place. Instead, you may want to think about using subtle arrows or lines that define the space in which visitors should “play” and then move down through.

Employ a Mascot

For some brands, it might make sense to employ the use of an actual mascot to guide visitors through the story. If it’s an already established mascot and it won’t intrude too heavily on the experience, then why not bring it on the journey to ensure that visitors are checking in at all the right spots?

Or you can do like BarkBox and use a series of related mascots to guide visitors through different parts of the site (especially the signup and subscription process).

BarkBox uses a series of illustrated black-and-white mascots to guide visitors through the conversion processes. (Large preview) Summary

As attention spans shorten and visitors just want to get to the good stuff on a website, designers have to get more creative in how they communicate their website’s “story.” Ideally, your web design will do more showing of that story instead of telling, which is how video game design tends to succeed in this matter.

Remember: Storytelling isn’t just relegated to big brands that can weave bright and shiny tales about how consumers’ lives were changed with their products. Nor is it just for video game designers that have hours of gameplay to develop for their audiences. A story simply needs to convey to the end-user how their problem can be fixed by your site’s solution. Through subtle design strategies inspired by video game storytelling techniques, you can effectively share and shape your own story.

(da, ra, yk, il)
Categories: Web Design

Introducing the Webmaster Video Series, now in Hindi

Google Webmaster Central Blog - Thu, 03/08/2018 - 18:06
Google offers a broad range of resources, in multiple languages, to help you better understand your website and improve its performance. The recently released Search Engine Optimization (SEO) Starter Guide, the Help Center, the Webmaster forums (which are available in 16 languages), and the various Webmaster blogs are just a few of them.
A few months ago, we launched the SEO Snippets video series, where the Google team answered some of the webmaster and SEO questions that we regularly see on the Webmaster Central Help Forum. We are now launching a similar series in Hindi, called the SEO Snippets in Hindi.

IFrom deciding what language to create content in (Hindi vs. Hinglish) to duplicate content, we’re answering the most frequently asked questions on the Hindi Webmaster forum and the India Webmaster community on Google+, in Hindi.
Check out the links shared in the videos to get more helpful webmaster information, drop by our help forum and subscribe to our YouTube channel for more tips and insights!

Posted by Syed Malik, Google Search Outreach
Categories: Web Design

An Introductory Guide To Business Insurance For Designers And Developers

Smashing Magazine - Thu, 03/08/2018 - 03:50

At some point in your career, most web designers and developers can relate to issues with scope creep, unexpected project delays, client relationships breaking down, and unpaid invoices. The good news is that there’s an insurance policy to help with these scenarios. In the UK, we call it “professional indemnity insurance.” Elsewhere, it can be called “professional liability” or “errors and omissions insurance.”

Let’s explore what this insurance is and how it’s designed to keep web professionals in business. I’ll also be sharing real stories of businesses who were glad they had insurance.

What Is Professional Indemnity Insurance?

Professional indemnity insurance protects your business from screw-ups and problem clients.

Let’s say a client threatens legal action, claims loss of income or damages due to a service you provided. Even if you’re in the wrong, professional indemnity steps in to ensure the consequences to your business aren’t crippling.

A creative agency working on a project together. (Large preview)

It’s also important to distinguish what professional indemnity insurance isn’t. After all, business insurance is an umbrella term for different types of cover. One of those covers is public liability insurance — or general liability insurance as it’s known in the US.

Public liability insures your business against claims of:

  • physical injury to clients and members of the public
  • accidents on your work premises
  • damage to third-party property.

This is a popular cover for those who have clients visit their office or those who work from client premises. However, in this article, we’re focusing exclusively on professional indemnity.

Getting the process just right ain't an easy task. That's why we've set up 'this-is-how-I-work'-sessions — with smart cookies sharing what works really well for them. A part of the Smashing Membership, of course.

Explore features → How Can Insurance Help Me If I’m A Designer Or Developer?

Business insurance isn’t often talked about in web circles. I think it’s because insurers have focused their products and user experience on traditional industries. A lot of the information out there isn’t relevant to those of us working in digital.

To add to that, people don’t equate working with a computer as being a danger or massive liability. Especially when you have all of your clients sign a contract. This can lull designers and developers into a false sense of security. A common objection I hear from web professionals when talking about insurance is:

I can't cause any damage as a web designer. For anything that does go wrong, I have a clause in my contract that says I'm not liable.

Firstly, I have to debunk the myth of not needing to have insurance because you work with a contract. Contracts don’t alleviate you from liability. They’re useful for laying the foundation of what duties are expected of both parties, but insurance steps into action when those duties come into question.

With every scenario I’m sharing today, they all had the following in common:

  • A contract was signed by both parties.
  • They had years of experience in their profession.
  • They were professionally insured, but never expected to have to use their insurance.

Below are real stories of how professional indemnity insurance helped these designers and developers.

Scope Creep

A developer built a web platform to spec, but the client complained of missing functionality.

The developer agreed to build the perceived missing functionality for a further fee, but the client believed it should have been included in the initial build. Not only did the client refuse to pay the remaining invoice, but they threatened legal action if the developer didn’t cooperate.

Having professional indemnity insurance meant that the developer had a team of legal experts behind him. They helped the developer communicate with his client to avoid the problem escalating.

The developer’s professional indemnity policy also had a mitigation costs clause. This meant the insurer paid the amount owed to him by his client, which was thousands of pounds.

Project Delays

Designers and developers often work to tight deadlines. Missing deadlines can cause problems if the project has an important launch date.

A creative agency was hired to design a website, but the project started to unravel. Key members of the team left part way through the project and the pace of the work being completed slowed down.

While the website was delivered in time for launch, it was missing a lot of major features. The client said it wasn’t fit for purpose.

After wasting money on a marketing campaign for the launch, the client refused to pay the final invoice. They also incurred extra expenses from hiring new contractors to complete the website’s missing features.

The client threatened to involve solicitors if the agency pursued payment.

The unpaid invoice was settled by the insurer under the mitigation costs clause of their professional indemnity policy. The insurer also provided the agency with legal advisors to confirm with the client that the project is considered at an end.

Client Relationships Breaking Down

This is a common catalyst for professional indemnity claims. Even if we spot a few amber flags, we like to believe we can make our client relationships work and projects run smoothly. However scary it is, sometimes you have to burn bridges with a client.

A designer did this when working with a client they felt didn’t respect them. An ever-changing scope, long hours, and poor pay lead to a breakdown in the relationship. What had started off as a promising project was now a strained working relationship and source of stress. The designer decided to walk away from the project.

Unfortunately, that wasn’t the end of things. The client wanted to be reimbursed for the money they had already paid to the designer. They also wanted damages for the loss of income due to a delayed launch and compensation for hiring other contractors to complete the project.

A team of legal experts was arranged by the insurer to deal with the designer’s client. A settlement was agreed out of court, which was also covered by the insurer.

What Does A Professional Indemnity Policy Insure Against?

Professional indemnity insurance is a meaty policy, so it isn’t feasible to cover every scenario here. At its core, it’s designed to put your business back in the same financial position after a loss as it was in before a loss. As you can see from the stories above, a loss can be legal fees, client damages, compensation or even unpaid invoices. However, this has to stem from a client expressing dissatisfaction with your work.

While all professional indemnity policies differ, let’s look at some of the key features you can expect to see.

Defence Costs

If a client makes a claim against you, your professional indemnity policy will pay the defence costs. This isn’t just for situations that have escalated to court. Insurers want to solve problems before they get to that stage, so they’ll provide a team of legal experts to help negotiate terms with your client.

Intellectual Property Infringement

Web and graphic designers are vulnerable to arguments over copyright infringement, whereas developers could get into disputes over who owns the code. This clause covers claims against copyright infringement, trademarks, slogans, and even domain names.

Mitigation Costs

If you read the stories above, you’ll have seen mitigation costs mentioned where unpaid invoices were paid by the insurer. If a client is dissatisfied with your work, refuses to pay any or all your fees and threatens to bring a claim against you, professional indemnity may pay the amount owed to you by your client. This is only if the insurer believes it will avoid a claim for a greater amount.


Negligence covers a broad spectrum, but think of this as a warranty for any mistakes you make that lead to an unhappy client.

Unintentional Breach Of Contract

Breach of contract can take many forms. It could be something as simple as failing to deliver a project on time or not meeting the client’s expectations. Any breach of contract may entitle the client to make a claim against you.

A web developer working on his laptop. (Large preview) Some Practical Tips For Buying Insurance

The first question people ask when it comes to buying insurance is, “How much should I insure my business for?”. The level of cover will typically start at £100,000 and can go well into the millions. It can be a difficult question to answer, but there are factors that can help you arrive at a reasonable figure.

Client Contracts

If your client contract has an insurance clause, it’s usually for £1,000,000 of professional indemnity. This is the base level of cover a client would expect. It’s the most common level of cover I see businesses buy.

Types of Clients

What type of clients are you working with? Is it large corporations with in-house legal teams, or local small businesses? It’s not unwise to assume the larger companies pose a bigger threat, therefore should have a higher level of cover. You may also find that larger companies will have an insurance clause in their contract.

Type Of Work You Do

A developer building a payment platform will potentially face a bigger risk than somebody designing a website to showcase a restaurant’s menu. Does your work involve dealing with sensitive information or higher-cost products? Are businesses depending on your service to generate income for them?

If it feels like I’ve skirted around answering this, it’s because there isn’t a straightforward figure. A lot of insurers will simply tell you to buy what you’ve budgeted for. If in doubt, consider a base level of £1,000,000 and periodically evaluate your clients and type of work you do. Most insurers allow you to make a mid-term adjustment part way through your policy to increase your level of cover.

Other than the cost of insurance, there are a few other factors to be aware of when buying insurance.

Insuring More Than One Activity

The web is a multi-disciplinary industry. You should be looking for a policy that can cover your various activities. A web developer may also provide web hosting. A designer may also offer consulting services. If you fall outside of the typical box, you might find it useful talking to a broker or using a service like With Jack where your policy can be customized instead of using an online comparison site.

Insuring Your Work Worldwide

By default, professional indemnity policies in the UK exclude US jurisdiction. If you’re working with US clients under US contract law, look for an insurer that can lift the jurisdictional limit from your policy, so you’re insured worldwide. Just beware that it will increase your premium.

Your Policy Can Adapt To Your Needs

Insurance can be flexible. Don’t delay buying insurance because you’re thinking of switching from sole trader to Limited company down the line, or because you’re waiting to add a new service to your business. A good insurance company will allow you to adjust your policy, adapting it as your business changes and grows.

How Insurance Can Help You Build A Bulletproof Business

Whenever I see newcomers ask for advice on starting their business in the web industry, I see a lot of suggestions that look like this:

  • “Get an accountant immediately.”
  • “Build a network!”
  • “Have your clients sign a contract.”
  • “Monitor your cashflow!”

This is all great advice, of course, but rarely do I see anybody mentioning getting insured. Insurance should be a crucial part of any professional designer or developer’s toolbox.

Offering your professional services to clients comes with a degree of risk. It’s your responsibility to mitigate that risk. You have to be confident that — if something does go wrong — you can get back to work quickly. There can be issues with mistakes in your work, a relationship going sour or a client claiming they’re unhappy with your service. It doesn’t matter how good you are, these things happen!

This is why I’m sharing these stories — to highlight the importance of being insured. I want to get web professionals not just thinking about insurance, but understanding it. Insurance is something we don’t necessarily want to budget for or consider, yet as professionals, we have to. The stories above show how critical it can be.

So yes, work with a contract. Monitor your cash flow. Have an accountant manage your bookkeeping, but also get insured. There’s little point in building your business only for one problem client or mistake to take it away from you.

(ra, yk, il)
Categories: Web Design

10 Things Men Can Do to Support Women in Tech

Tuts+ Code - Web Development - Wed, 03/07/2018 - 23:52

While there is no shortage of books, seminars, articles, etc. created to help women succeed in male-dominated workplaces, there is precious little information designed to help men modify their attitude and behaviour in order to promote gender equality at work. 

This is a problem because, let’s face it, women will never achieve equity in the workplace or in life if they’re the only gender working towards it. Men need to be part of the solution. It's a solution worth fighting for when you consider that, according to a study by the National Center for Women & Information Technology, gender-balanced companies demonstrate superior team dynamics and productivity, perform better financially, and produce teams that stay on schedule and under budget. A win-win scenario for everyone!

So how can men be part of the solution? How can they be allies to women in male-dominated industries like tech, where female numbers are small and where they’re bound to feel outnumbered and isolated? In honour of International Women’s Day, with its theme of #PressforProgress, I offer you 10 things men can do to support women in the tech workplace.

Image Source Envato Elements Stock Photo1. Understand What Privilege Is and Accept That You Have It

Before men can think of being allies to women in our quest for gender parity, you first have to acknowledge your privileged position in the workplace and in society as a whole. 

Now I know this is a hard one for many people to understand, let alone accept. So let me first define what I mean by privilege in this context. A privilege is “a special right, advantage, or immunity granted or available only to a particular person or group and not to others.” In relation to gender, being born male—particularly white, heterosexual, and Christian in an industrial nation—confers an enormous amount of privilege in comparison to men and women of other ethnicities, sexual orientations, religions, etc. But this doesn’t mean you haven’t worked hard to achieve what you have, it doesn’t invalidate the challenges you’ve personally had to overcome in your life, nor does it make you guilty of anything!

What it does mean is that as a result of a twisted structure of injustice that is no fault of yours, before you even start to work towards your goals, you are already ahead of the other players in the game. It means that people who weren’t born with your unique and totally accidental combination of characteristics have to overcome varying obstacles and sometimes seemingly insurmountable odds just to get to your starting point. It means, in other words, that some people have to work much harder for the same opportunities you’re automatically afforded. 

It also means taking responsibility for figuring out how the configuration of the playing field affects all players. And more than anything, as someone who benefits from privilege, it means having compassion for others with less privilege and taking active steps to help and support them when you can. 

If you don’t quite get what I’m saying, here are two videos that quite effectively demonstrate how privilege works:

If you'd like to discover your degree of privilege, you can try this quiz.

2. Recognise That Gender Inequality Has More Than One Face 

Though most women face some form of gender inequality at work, not all women face it in the same way. That is because the discrimination a woman faces in the workplace may overlap with her other identities: namely race, class, ethnicity, religion, sexual orientation, etc.

If feminism champions women's rights and promotes equity between the sexes, intersectional feminism questions how these other identities mentioned above affect the way women experience discrimination.

A white woman, for example, may be discriminated against for her gender but has the advantage of race on her side. However, a woman of African ancestry or an Asian lesbian may be discriminated against because of their gender, their ethnicity, and/or their sexual orientation.

Supporting women in the tech workplace means understanding that sexism is sometimes intersectional and requires different levels of awareness and action in order to address it effectively.

3. Hire, Pay, Promote

Many of the problems women face in tech begin with hiring practices. If you’re in a position to hire for your company, you may expand your scope for finding suitable female candidates by attending college job fairs at all-female colleges and reaching out to professional organisations that are geared towards women. In addition, to increase the likelihood of reaching a greater diversity of women, you may seek out professional organisations that cater to ethnic minorities. 

Even if you’re not in a position to hire for your company, you may still influence your company's hiring practices by raising awareness of the need to employ a greater diversity of talent. You might do this by researching relevant talent pools yourself and suggesting that your hiring department consider them as viable options.

4. Advocate for Fair Workplace Policies

Getting a diversity of women in the door is a good start for any tech company, but to keep them there, male allies are needed to champion fair workplace policies. 

One of the most important policies supports fair and equitable compensation by establishing transparent salary guidelines based on criteria like education and skill level, performance level, and going market rates. Other policies benefit everyone—like flexible hours, working from home, generous maternity and paternity leave programmes, and on-site child care. They are also the type of practices that can be of special benefit to women, who are often the primary caregivers in the family. 

5. Take Parental Leave

When women of child-bearing age join the workforce, one of the great difficulties they face is how to balance motherhood with their professional aspirations and their company’s expectations. In fact, companies often hesitate to hire women because of the assumption that they will leave after they have a baby. 

In the ideal world we’re working towards, for a two-parent household, parental leave isn’t just a woman’s issue, but an issue shared by the couple.

In addition to advocating for fair workplace policies, if more men spoke up and insisted on taking parental leave to share the obligations of parenthood equitably, this would lessen the stigma of taking time off for both women and men. It would help eradicate the motherhood bias against hiring women, since both women and men would be seen as potentially liable to take time off from work to care for their children. 

6. Offer to Mentor or Sponsor 

Mentors and sponsors are critical for career advancement—and in the tech world, men are 50% more likely than women to have a mentor or sponsor who can help guide their career path and support them in seeking out new opportunities. 

Elizabeth Borges is a senior manager for a 12-month leadership and networking programme called EverwiseWomen. She suggests that men working in tech can make a huge difference by seeking out a high-potential junior woman to mentor or sponsor. 

To become a mentor, she says to:

Set up time with a junior colleague to provide feedback about what’s she doing well and where she could improve. Ask her what work challenges she’s facing and help coach her through them.

To become a sponsor, male allies can:

Identify a woman who is doing amazing work, who could benefit from more visibility with senior leaders. Devise a stretch project that you could assign her or work with her on to help her gain that visibility, and help her expand her own perception of what she can do.7. Be Mindful of Harassment

If there’s anything we’ve learnt from the #MeToo and Time's Up movements that took the globe by storm in 2017, it’s that sexual harassment and assault is rampant in the workplace. Women have had enough and are no longer prepared to suffer in silence. 

If men of good conscience in the tech industry are to be supportive allies to women, it’s not enough to avoid obvious harassment like sexual innuendo, sexist jokes, or commenting on a woman’s appearance. Men must also have the courage to highlight and report situations in which harassment occurs. Silence in the face of gendered harassment or abuse communicates complicity with the perpetrator and isolates and demoralises the victim.  

Male allies have to insist on a policy of zero tolerance for harassment in the workplace and codify this position with procedures and training about the law, as well as suggested strategies for witnesses and victims about how to react.

Image Source Envato Elements Stock Photo8. Give Women Credit for Their Ideas

Another term that gained currency last year is “hepeating”, popularised by astronomer and physics professor Nicole Gugliucci. She tweeted about hepeating after friends of hers coined the term to describe the scenario where women share their idea at work and are met with silence and indifference. Then, immediately after, the very same idea is put forth by a man who claims it as his own, and everyone approves enthusiastically. 

This annoying and frustrating practice struck a chord with so many people that Gugliucci’s tweet received 200,000 likes and 65,000 retweets. 

According to the Washington Post, women have recently come up with a strategy called “amplification” to stop this from happening. Amplification takes place when other women in the room listen to and repeat the key points made by a female colleague during a meeting and give credit to the woman who came up with the idea, forcing others in the room to remember the contribution and who made it.

This is something that male allies to women in tech can absolutely practice themselves, especially considering that it is unlikely that women in tech may have any other female allies in the room. 

9. Don’t Interrupt

Apart from having their ideas stolen by male colleagues, several studies show that when it comes to meetings, women are more likely than other men to be interrupted and talked over by male colleagues. 

There’s not much to say here, other than don’t do it. It's rude, disrespectful, and unbecoming of an ally!

10. Speak Up

One of the greatest challenges women encounter in the face of sexism in the workplace is silence from men of good conscience. Often, men are silent because they don’t know how to respond. But men need to be aware that when they are silent, their silence is interpreted as support for the bad behaviour of others. 

Being an ally to women means noticing all the forms of injustice that women are exposed to  and taking action to hold the perpetrator accountable and to support the victim. 


Women in the tech workplace don’t need male saviours, but they certainly could use supportive allies of conscience and integrity. These allies are willing to hold themselves and their colleagues accountable and create a healthier and more equitable work environment for all—simply because it’s the right thing to do. 

Categories: Web Design

Bloom Review: Just Another Email List Building Plugin, or One Worth Buying?

Since list building is one of the most important things any website owner can do, it makes sense that there are so many free and premium plugins on the...

The post Bloom Review: Just Another Email List Building Plugin, or One Worth Buying? appeared first on Onextrapixel.

Categories: Web Design

Startups: Here’s the Best Places in the World to Start a Business

Who Is Hosting This Feed - Wed, 03/07/2018 - 15:16

You’re ready to launch your startup: you’ve got the unique solution to a problem your highly-targeted niche never knew they had. You’re ready to put down your roots and open up office, and while you can picture every detail of your booming new business in your mind’s eye, one piece remains blank: the background. Think Beyond […]

The post Startups: Here’s the Best Places in the World to Start a Business appeared first on Who Is Hosting This: The Blog.

Categories: Web Design