emGee Software Solutions Custom Database Applications

Share this

Web Design

8 Things That Make Jest the Best React Testing Framework

Tuts+ Code - Web Development - Mon, 04/02/2018 - 05:00
Overview

Jest is an open JavaScript testing library from Facebook. Its slogan is "Delightful JavaScript Testing". While Jest can be used to test any JavaScript library, it shines when it comes to React and React Native.

This is no surprise as both React and Jest come from Facebook, which is a major user of both. In this tutorial I'll show you eight different aspects of Jest that make it such a delight for testing React applications. 

1. Jest Is a Breeze to Set Up

Jest is pretty simple to install on its own. You can just install it in an empty directly using either npm or yarn. I prefer yarn. See 6 Things That Make Yarn the Best JavaScript Package Manager to understand why. It's as simple as:

yarn add --dev jest 

If you prefer npm, then type:

npm install --save-dev jest

Before we can test, let's write some code to test. Here is palindrome.js:

function isPalindrome(s) { const count = s.length - 1 if count < 2 { return true } for (i = 0; i < (count + 1) / 2; ++i) { if (s[i] !== s[count - i]) return false } return true } module.exports = isPalindrome

Here is a jest test in a file called palindrome.test.js:

const isPalindrome = require('./palindrome') test('it detects palindromes', () => { expect(isPalindrome('palindrome')).toBe(false) expect(isPalindrome('')).toBe(true) expect(isPalindrome('a')).toBe(true) expect(isPalindrome('gg')).toBe(true) expect(isPalindrome('pop')).toBe(true) expect(isPalindrome('1212')).toBe(false) })

To run the tests, add this to package.json:

"scripts": { "test": "jest" }

You can now run the tests with yarn test or npm test:

> yarn test yarn run v1.1.0 warning package.json: No license field $ jest PASS ./palindrome.test.js ✓ it detects palindromes (6ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.667s Ran all test suites. ✨ Done in 3.15s.

This is pretty simple. But if you use react-create-app to create your React project, you don't even have to do that. The jest package comes bundled in, and you can just start writing tests immediately.

2. Jest Is Lightning Fast

Jest is fast. Very fast. When your tests are CPU bound, it can shave significant time from your test runs. Airbnb switched from Mocha to Jest, and their total test runtime dropped from more than 12 minutes to only 4.5 minutes on a heavy-duty CI machine with 32 cores. Local tests used to take 45 minutes, which dropped to 14.5 minutes. 

What makes Jest so fast? It's a combination of several factors:

  • Parallelization: this is pretty obvious, and other test frameworks use it too.
  • Run slowest tests first: this ensures all cores are utilized to the max.
  • Caching babel transforms: reduces CPU-intensive babel transforms. 
3. Jest Is a One-Stop Shop

Jest comes with built-in matchers, spies, and its own extensive mocking library. It used to be based on Jasmine, so it inherited all of Jasmine's goodness. But in more recent versions Jest departed from Jasmine, yet kept the same functionality and added its own flavor and improvements.

When comparing it to a bespoke testing solution based on Mocha, it's clear that ease of use is a major concern of Jest design.

4. Jest Has Awesome Mocks

Mocking is an incredibly important part of unit testing. This is especially important if you care about fast tests (and who doesn't?).

Mocking allows you to replace irrelevant dependencies that may be slow and even control time for code that relies on timing. Jest lets you fully control your dependencies and master time.

Simple Mock Functions

Mocking dependencies is a long-time tradition of unit tests. If your code is reading a file, writing to a file, calls some remote service or is accessing a database, it may be slow and it may be complicated to configure and clean up after the test. When running in parallel, it may not even be possible to control properly.

In these cases, it is better to replace the real dependency with a mock function that does nothing but just records the fact it was called, so you can verify the workflow. The jest.fn() mock function lets you provide canned return values (for multiple consecutive calls), and it records how many times it was called and what the parameters were in each call.

Manual Module Mocks

Sometimes you may need to replace a whole module with its data rather than a couple of functions. Jest lets you do that by placing your own module with the same name in a __mocks__ sub-directory.

Whenever your code is using the target module, it will access your mock rather than the real module. You can even selectively choose for some tests to use the original module by calling jest.Unmock('moduleName').

Timer Mocks

Timing is the bane of unit tests. What if you want to test code that times out after a minute? Code that fires every 30 seconds? Special code that runs a reconciliation algorithm at the end of the month?

Those are difficult to test. You can either succumb to the timing requirements of the original code (and then your tests will be very slow), or you can manipulate time, which is much more useful. Jest lets you control the following timer-related functions:

  • setTimeout()
  • setInterval()
  • clearTimeout()
  • clearInterval()
ES6 Class Mocks

Jest fully supports ES6 classes and provides various ways to mock them:

  • Automatic mock: lets you spy on calls to constructor and all methods, but always returns undefined.
  • Manual mock: implement your own mock in the __mocks__ sub-directory.
  • Mock the class factory with a higher-order function.
  • Selective mocking using mockImplementation() or mockImplementationOnce().
5. Jest Supports TypeScript

TypeScript is a popular typed superset of JavaScript that compiles to plain JavaScript. Jest supports TypeScript via the ts-jest package. It describes itself as a TypeScript preprocessor with source map support for Jest and has a very active community.   

6. Jest Has Got You Covered

Jest has built-in coverage reports. Your tests are only as good as their coverage. If you test only 80% of your code, then bugs in the other 20% will be discovered only in production. 

Sometimes, it makes sense from a business perspective to skip testing for some parts of the system. For example, internal tools that your own expert engineers use and change frequently may not need the same level of rigorous testing as your production code. But, at any rate, this should be a conscious decision, and you should be able to see exactly the test coverage of different parts of your system. 

Here is how to generate a coverage report for the simple palindrome example:

> yarn test --coverage yarn run v1.1.0 warning package.json: No license field $ jest "--coverage" PASS ./palindrome.test.js ✓ it detects palindromes (4ms) -------------- |----------|----------|----------|----------| File | % Stmts | % Branch | % Funcs | % Lines | -------------- |----------|----------|----------|----------| All files | 100 | 100 | 100 | 100 | palindrome.js | 100 | 100 | 100 | 100 | -------------- |----------|----------|----------|----------| Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.712s Ran all test suites. ✨ Done in 3.41s. 7. Jest Does Snapshots

Snapshot testing is great. It lets you capture a string that represents your rendered component and store it in a file. Then you can compare it later to ensure that the UI didn't change. While it is ideal for React and React Native apps, you can use snapshots for comparing serialized values of other frameworks. If you actually change your UI then you need to update your snapshot files to reflect it of course.

8. Jest Does Delta Testing With Watch

Jest can run in watch mode, where it runs the tests automatically whenever you change the code. You run it with the --watchAll command-line argument, and it will monitor your application for changes. I ran jest in watch mode and introduced a bug on purpose to palindrome.js, and here is the result:

FAIL ./palindrome.test.js ✕ it detects palindromes (11ms) ● it detects palindromes expect(received).toBe(expected) // Object.is equality Expected value to be: true Received: false 6 | expect(isPalindrome('a')).toBe(true) 7 | expect(isPalindrome('gg')).toBe(true) > 8 | expect(isPalindrome('pop')).toBe(true) 9 | expect(isPalindrome('1212')).toBe(false) 10 | }) 11 | at Object.<anonymous>.test (palindrome.test.js:8:30) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 0.598s, estimated 1s Ran all test suites. Watch Usage: Press w to show more.Conclusion

Jest is a fast testing framework that's easy to set up. It is actively developed and used by Facebook to test all their React applications as well as by many other developers and companies.

It has all you need in one convenient package, supports TypeScript, and IMO is the best option for React and React Native application testing. It is also very to migrate from other testing solutions.

Remember, React has grown in popularity. In fact, we have a number of items in the Envato Market that are available for purchase, review, implementation, and so on. If you’re looking for additional resources around React, don’t hesitate to check them out.

Categories: Web Design

20 Messages Hidden in 20 of the Most Recognizable Logos

There’s a logo on just about everything these days – smartphones, snacks, cars, clothes – you name it. Some of them are simple while others host hidden messages that...

The post 20 Messages Hidden in 20 of the Most Recognizable Logos appeared first on Onextrapixel.

Categories: Web Design

Creating an Image Editor Using CamanJS: Layers, Blend Modes, and Events

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

In the previous tutorial, you learned how to create an image editor using CamanJS which can apply basic filters like contrast, brightness, and noise to an image. CamanJS also has some other built-in filters like Nostalgia, Pinhole, Sunrise, etc., which we applied directly to the image.

In this tutorial, we will cover some more advanced features of the library like Layers, Blend Modes, and Events.

Layers in CamanJS

In the first tutorial, we only worked with a single layer which contained our image. All the filters that we applied only manipulated that main layer. CamanJS allows you to create multiple layers to enable you to edit your images in a more sophisticated manner. You can create nested layers, but they will always be applied on their parent layer like a stack.

Whenever you create a new layer and apply it on the parent layer, the default blend mode used will be normal. You can create a new layer on the canvas using the newLayer() method. When you create a new layer, you can also pass a callback function which will be useful if you intend to manipulate layer.

This function can be used for a lot of tasks like setting the blend mode for the new layer using the setBlendingMode() method. Similarly, you can control the opacity of the new layer using the opacity() method.

Any new layer that you create can be filled with a solid color using the fillColor() method. You can also copy the contents of the parent layer to the new layer using the copyParent() method. All the filters that we learned about in the previous tutorial can also be applied on the new layer that we are creating. For example, you can increase the brightness of the newly created layer by using this.filter.brightness(10).

Instead of copying the parent or filling the layer with a solid color, you also have the option to load any other image in the layer and overlay it on the parent. Just like the main image, you will be able to apply different filters to the overlaid image as well.

In the following code snippet, we have attached a click event handler to three buttons which will fill the new layer with a solid color, the parent layer, and an overlay image respectively.

$('#orange-btn').on('click', function (e) { Caman("#canvas", function () { this.newLayer(function () { this.opacity(50); this.fillColor('#ff9900'); }); this.render(); }); }); $('#parent-btn').on('click', function (e) { Caman("#canvas", function () { this.newLayer(function () { this.opacity(50); this.copyParent(); this.filter.brightness(20); }); this.render(); }); }); $('#overlay-btn').on('click', function (e) { var oImg = new Image(); oImg.src = "trees.png"; Caman("#canvas", function () { this.newLayer(function () { this.opacity(50); this.overlayImage(oImg); this.filter.brightness(20); }); this.render(); }); });Blend Modes in CamanJS

In the previous section, we kept the opacity of any new layer that we added to the canvas below 100. This was done because the new layer would otherwise hide the old layer completely. When you place one layer over another, CamanJS allows you to specify a blend mode which determines the final outcome after the placement. The blend mode is set to normal by default. 

This means that any new layer that you add on the canvas will make the layer below it invisible. The library has ten blend modes in total. These are normal, multiply, screen, overlay, difference, addition, exclusion, softLight, exclusion, and darken.

As I mentioned earlier, the normal blend mode sets the final color to be equal to the color of the new layer. The multiply blend mode determines the final color of a pixel by multiplying the individual channels together and then dividing the result by 255. The difference and addition blend modes work in a similar manner, but they subtract and add the channels. 

The darken blend mode sets the final color of a pixel to be equal to the lowest value of individual color channels. The lighten blend mode sets the final color of a pixel to be equal to the highest value of individual color channels. The exclusion blend mode is somewhat similar to difference, but it sets the contrast to a lower value. In the case of the screen blend mode, the final color is obtained by inverting the colors of each layer, multiplying them, and then again inverting the result. 

The overlay blend mode acts like multiply if the bottom color is darker, and it acts like screen if the bottom color is lighter.

If you want the colors in different layers to interact in a different manner, CamanJS also lets you define your own blend modes. We will cover this in the next tutorial of the series.

Here is the JavaScript code to apply different blend modes on an image:

$('#multiply-btn').on('click', function (e) { hexColor = $("#hex-color").val(); Caman("#canvas", function () { this.revert(false); this.newLayer(function () { this.fillColor(hexColor); this.setBlendingMode('multiply'); }); this.render(); }); }); $('#screen-btn').on('click', function (e) { hexColor = $("#hex-color").val(); Caman("#canvas", function () { this.revert(false); this.newLayer(function () { this.fillColor(hexColor); this.setBlendingMode('screen'); }); this.render(); }); });

In the above code snippet, we get the Hex color value from an input field. This color is then applied on the new layer. You can write the code to apply other blend modes in a similar manner.

Try to specify a color of your choice in the input field, and then apply any of the blend modes by clicking on the respective button. I have applied the blend modes on a solid color in the example, but you can also apply them on an overlaid image from the previous section.

Events in CamanJS

If you uploaded any large image in either the demo of the first tutorial or the second tutorial, you might have noticed that the result of any applied filter or blend mode became evident after a long time. 

Large images have a lot of pixels, and calculating the final value of different channels for each pixel after applying a specific blend mode can be very time-consuming. For example, when applying the multiply blend mode on an image with dimensions 1920*1080, the device will have to perform multiplication and division over 6 million times.

In such cases, you can use events to give users some indication about the progress of a filter or blend mode. CamanJS has five different events which can be used to execute specific callback functions at different stages. These five events are processStart, processComplete, renderFinished, blockStarted, and blockFinished.

The processStart and processComplete events are triggered after a single filter starts or finishes its rendering process. When all the filters that you specified have been applied on an image, the library fires the renderFinished event. 

CamanJS divides large images into blocks before starting to manipulate them. The blockStarted and blockFinished events are fired after individual blocks of the image have been processed by the library.

In our example, we will only be using the processStart and renderFinished events to inform users about the progress of our image editing operation.

Caman.Event.listen("processStart", function (process) { $(".process-message").text('Applying ' + process.name); }); Caman.Event.listen("renderFinished", function () { $(".process-message").text("Done!"); });

With the processStart and processFinish events, you get access to the name of the process currently operating on the image. The blockStarted and blockFinished events, on the other hand, give you access to information like the total number of blocks, the current block being processed, and the number of finished blocks.

Try clicking on any button in the demo below, and you will see the name of the process currently manipulating the image in the area below the canvas.

Final Thoughts

The first tutorial of the series showed you how to create a basic image editor with built-in filters from the CamanJS library. This tutorial showed you how to work with more than one layer and apply different filters and blend modes to each layer individually.

Since the image editing process can take a while for large images, we also learned how to indicate to users that the image editor is actually processing the image and not sitting idle.

In the next and final tutorial of the series, you will learn how to create your own blend modes and filters in CamanJS. If you have any questions related to this tutorial, feel free to let me know in the comments.

Categories: Web Design

New Short Course: Code a Front-End App With GraphQL and React

Tuts+ Code - Web Development - Wed, 03/28/2018 - 05:23
What You'll Be Creating

GraphQL is an emerging technology for creating APIs and sharing data between the server and front-end. In our new short course, Code a Front-End App With GraphQL and React, you'll learn how to connect to a GraphQL endpoint from a React app. 

What You’ll Learn

In this quick, 50-minute course, Markus Mühlberger will show you how to configure the popular Apollo GraphQL client. This will let you seamlessly retrieve and integrate live server data into your app. 

You'll learn how to structure your queries, access real-time data, perform mutations (updates to the server data), and handle errors. Along the way, you'll build a great-looking trip planning map for the Finnish public transportation system!

Watch the Introduction Take the Course

You can take our new course straight away with a subscription to Envato Elements. For a single low monthly fee, you get access not only to this course, but also to our growing library of over 1,000 video courses and industry-leading eBooks on Envato Tuts+. 

Plus you now get unlimited downloads from the huge Envato Elements library of 460,000+ creative assets. Create with unique fonts, photos, graphics and templates, and deliver better projects faster.

Categories: Web Design

Creating an Image Editor Using CamanJS: Applying Basic Filters

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

A while back, I wrote some tutorials which described how to apply different kinds of filters and blend modes to an image using just CSS. This could be very helpful in situations where you want to show the grayscale, blurred, or high-contrast version of the same image. Instead of creating four different images, you could just apply these effects to the original image using a few lines of CSS. 

Using CSS filters and blend modes works nicely in most cases. However, CSS doesn't modify the pixels of the image itself. In other words, the filters and blend modes or any other effects are not permanent. 

If someone downloads an image with CSS filters applied to it, they will get the original image and not the modified version. This can be a major setback if you were planning on creating an image editor for your users.

If you want the image modifications to be permanent and allow the user to download the modified image, you can use HTML5 canvas. The canvas element allows you to do a lot of things, including drawing lines and shapes, writing text, and rendering animations. 

In this tutorial, we will focus on editing images loaded on the canvas. CSS3 already has built-in functionality to allow you to apply effects like contrast, brightness, and blurring directly. When working with HTML5 canvas, we will use a canvas manipulation library called CamanJS to edit the images. 

The library supports basic effects like brightness, contrast, and saturation out of the box. This will save time and allow us to create more sophisticated filters based on these basic ones.

CamanJS Basics

The name of this library is based on the fact that it is used for doing (ca)nvas (man)ipulation in JavaScript(JS). Before you can start using different features of the library, you will have to include it in your project. This can be done either by downloading the library and hosting it yourself or by linking directly to a CDN.

There are two ways to use the library. The first option is to use the data-caman attribute with your image elements. This attribute can accept a combination of different CamanJS filters as its value. For example, if you want to increase the brightness of an image by 20 and the contrast by 10, you can use the following HTML:

<img src="path/to/image.jpg" data-caman="brightness(20) contrast(10)">

Similarly, you can apply other filters like saturation, exposure, noise, sepia, etc. Besides the basic filters, CamanJS also gives you access to some more sophisticated filters out of the box. These filters can be applied to an image in a similar manner. To apply the sunrise filter, you can simply use the following HTML:

<img src="path/to/image.jpg" data-caman="sunrise()">

Your second option for manipulating images is by calling Caman() with the id of the canvas where you have rendered the image and different filters that you want to apply to the rendered image.

Caman('#canvas-id', function () { this.brightness(20); this.contrast(10); this.render(); });

In this series, we will be going the JavaScript way to create our image editor.

Implementing Upload and Download Functionality

You need to provide users with a way to upload the images they want to edit so that you can render them on the canvas for further manipulation. Once the users have made the changes, they should also be able to download the edited images. In this section, we will add these two functions to our image editor.

Let's begin with the HTML needed to add the canvas and upload/download buttons:

<div class="preview-wrapper"> <canvas id="canvas"></canvas> <p class="process-message"></p> </div> <div class="editor-buttons"> <input type="file" id="upload-file" placeholder="Upload a Picture" /> <label for="upload-file">Upload a Picture</label> <button id="download-btn">Download Image</button> <br/> </div>

Here is the code for implementing the basic image upload functionality:

var img = new Image(); var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var fileName = ''; $("#upload-file").on("change", function(){ var file = document.querySelector('#upload-file').files[0]; var reader = new FileReader(); if (file) { fileName = file.name; reader.readAsDataURL(file); } reader.addEventListener("load", function () { img = new Image(); img.src = reader.result; img.onload = function () { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0, img.width, img.height); $("#canvas").removeAttr("data-caman-id"); } }, false); });

We begin by creating some variables to store the name of the image file selected by the user and the context for our canvas. After that, we write the code to get the image file from the file input after its change event is fired. The files selected by a user are stored in a FileList, and we can get the first file from the list using .files[0]. 

Once we have the file, we use a FileReader object to read the contents of the file selected by the user. The onload event for the FileReader is triggered after the selected file has been read successfully. 

Inside the onload event handler for the FileReader object, we create an HTMLImageElement instance using the Image() constructor. The src attribute of the image is then set to the value of the result property of our FileReader. 

Once the image has loaded successfully, we set the width and height of our canvas to be equal to the width and height of the image selected by the user. After that, we draw the image on the canvas and remove the data-caman-id attribute from the canvas. 

The attribute is added automatically by CamanJS when setting up the canvas for editing an image. We need to remove it every time a user selects a new file in order to avoid any mixup between the old image file we were editing and the new file selected by the user.

Besides loading the image file in the canvas, we have also set the value of the fileName variable to be equal to the name of the file selected by the user. This will be useful when we are saving the edited image.

Users will now be able to upload different images in your image editor. Once they have edited the image, they would also like to download them. Let's write some code that will allow users to save the edited image file.

$('#download-btn').on('click', function (e) { var fileExtension = fileName.slice(-4); if (fileExtension == '.jpg' || fileExtension == '.png') { var actualName = fileName.substring(0, fileName.length - 4); } download(canvas, actualName + '-edited.jpg'); }); function download(canvas, filename) { var e; var lnk = document.createElement('a'); lnk.download = filename; lnk.href = canvas.toDataURL("image/jpeg", 0.8); if (document.createEvent) { e = document.createEvent("MouseEvents"); e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); lnk.dispatchEvent(e); } else if (lnk.fireEvent) { lnk.fireEvent("onclick"); } }

We use the jQuery .on() method to execute a piece of code every time the click event is fired for the download button. This code removes the file extension from the name of the image file selected by the user and replaces it with the suffix -edited.jpg. This name is then passed to the download function along with a reference to the canvas where we rendered and edited the image. 

The download function creates a link and sets its download attribute to filename. The href attribute contains the data URI for the edited image. After setting the value of these two attributes, we programmatically fire the click event for our newly created link. This click starts the download of the edited image.

Applying Built-in Filters

As I mentioned in the beginning of the tutorial, CamanJS comes with basic built-in filters. So you can directly apply brightness, contrast, sepia, saturation, exposure, noise, sharpen, vibrance, and hue. Some filters like brightness and contrast can have a negative as well as a positive value. 

You can make the values as high or as low as you want, but a sensible choice would be to keep them between -100 and 100. For example, the image becomes white when you set the brightness to 100. So any value above 100 will be useless. Similarly, the image will become completely gray if you set the value of the contrast to -100.

Other filters like sepia, noise, sharpen, and blur will only accept a positive value. Keep in mind that the hue filter covers the full 360-degree circle, with values ranging from 0 to 100. The image will look exactly the same when you set the hue to 0 or 100.

Here is the HTML to add buttons for our image editor:

<div class="filter-buttons"> <div class="filter-group"> <button id="brightness-dec">-</button> <span class="filter-name">Brightness</span> <button id="brightness-inc">+</button> </div> <!-- More Such Buttons --> <div class="filter-group"> <button id="gamma-dec" class="disabled">-</button> <span class="filter-name">Gamma</span> <button id="gamma-inc">+</button> </div> </div> <div class="editor-buttons"> <input type="file" id="upload-file" placeholder="Upload a Picture" /> <label for="upload-file">Upload a Picture</label> <button id="download-btn">Download Image</button> <br/> <button id="vintage-btn">Vintage</button> <!-- More Such Buttons --> <button id="lomo-btn">Lomo</button> </div>

All the filters like brightness and contrast have been given increase and decrease buttons. However, the decrease button has been disabled for some filters like noise because they can't have a meaningful negative value.

We will apply the respective filters based on the button clicked with the help of the following JavaScript.

/* Similar Code for All Other Buttons */ $('#brightness-inc').on('click', function (e) { Caman('#canvas', img, function () { this.brightness(10).render(); }); }); $('#brightness-dec').on('click', function (e) { Caman('#canvas', img, function () { this.brightness(-10).render(); }); }); /* Similar Code for All Inbuilt Filters */ $('#nostalgia-btn').on('click', function (e) { Caman('#canvas', img, function () { this.nostalgia().render(); }); }); $('#majestic-btn').on('click', function (e) { Caman('#canvas', img, function () { this.herMajesty().render(); }); });

For the increase and decrease buttons, the strength of the filter is based on how its effect scales. For example, the brightness and contrast are increased by 10, but the value of gamma is only increased by 0.1 after each click.

The following CodePen demo shows the CamanJS image editor we created in action.

Some filters might take some time before you see their final outcome. In such cases, users might think that the filter is not working. We will be using events to keep readers updated about the progress of a filter. All this will be discussed in the next tutorial.

Final Thoughts

The first tutorial was meant to teach you how to create an image editor with basic image upload and download functionality which users can use to edit images. We used basic filters like noise, contrast, and brightness as well as some more complicated effects like Vintage and Nostalgia, which are built into the library.

In the next tutorial, you will learn about more CamanJS features like layers, blend modes, and events. And in the meantime, don't forget to review what we have available in the Envato Market for purchase, study, use, and review.

Categories: Web Design

Design Tips For Extra Large Website Footers

So you want a beautiful footer that’s usable and easy on the eyes? No problem! There’s a lot you can do for effective footers and with so much variety...

The post Design Tips For Extra Large Website Footers appeared first on Onextrapixel.

Categories: Web Design

Rolling out mobile-first indexing

Google Webmaster Central Blog - Mon, 03/26/2018 - 07:57

Today we’re announcing that after a year and a half of careful experimentation and testing, we’ve started migrating sites that follow the best practices for mobile-first indexing.

To recap, our crawling, indexing, and ranking systems have typically used the desktop version of a page's content, which may cause issues for mobile searchers when that version is vastly different from the mobile version. Mobile-first indexing means that we'll use the mobile version of the page for indexing and ranking, to better help our – primarily mobile – users find what they're looking for.

We continue to have one single index that we use for serving search results. We do not have a “mobile-first index” that’s separate from our main index. Historically, the desktop version was indexed, but increasingly, we will be using the mobile versions of content.

We are notifying sites that are migrating to mobile-first indexing via Search Console. Site owners will see significantly increased crawl rate from the Smartphone Googlebot. Additionally, Google will show the mobile version of pages in Search results and Google cached pages.

To understand more about how we determine the mobile content from a site, see our developer documentation. It covers how sites using responsive web design or dynamic serving are generally set for mobile-first indexing. For sites that have AMP and non-AMP pages, Google will prefer to index the mobile version of the non-AMP page.

Sites that are not in this initial wave don’t need to panic. Mobile-first indexing is about how we gather content, not about how content is ranked. Content gathered by mobile-first indexing has no ranking advantage over mobile content that’s not yet gathered this way or desktop content. Moreover, if you only have desktop content, you will continue to be represented in our index.

Having said that, we continue to encourage webmasters to make their content mobile-friendly. We do evaluate all content in our index -- whether it is desktop or mobile -- to determine how mobile-friendly it is. Since 2015, this measure can help mobile-friendly content perform better for those who are searching on mobile. Related, we recently announced that beginning in July 2018, content that is slow-loading may perform less well for both desktop and mobile searchers.

To recap:

  • Mobile-indexing is rolling out more broadly. Being indexed this way has no ranking advantage and operates independently from our mobile-friendly assessment.
  • Having mobile-friendly content is still helpful for those looking at ways to perform better in mobile search results.
  • Having fast-loading content is still helpful for those looking at ways to perform better for mobile and desktop users.
  • As always, ranking uses many factors. We may show content to users that’s not mobile-friendly or that is slow loading if our many other signals determine it is the most relevant content to show.

We’ll continue to monitor and evaluate this change carefully. If you have any questions, please drop by our Webmaster forums or our public events.

Posted by Fan Zhang, Software Engineer
Categories: Web Design

Ubersuggest is the Keyword Suggestion and Optimization You Need in Your Marketing Arsenal

Webitect - Mon, 03/26/2018 - 07:21

An increasing number of site owners are looking to expand their SEO strategy. With Google receiving over 63,000 searchers at any given second, every audience imaginable is using organic search to find answers to their questions. If you’re running a business, expanding your SEO strategy or like to be kept in-the-loop on new software, we’ve got news for you. SEO veteran Neil Patel has acquired a tool to help you do just that… And it’s on track to become a SEO staple, if Neil’s history has anything to go by. Neil Patel started in the world of SEO when he

The post Ubersuggest is the Keyword Suggestion and Optimization You Need in Your Marketing Arsenal appeared first on Clayton Johnson SEO.

Categories: Web Design

Creating an Image Editor Using CamanJS: Creating Custom Filters and Blend Modes

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

In the first tutorial of our CamanJS image editor series, we only used built-in filters to edit our images. This limited us to some basic effects like brightness, contrast, and 18 other more complicated filters with names like Vintage, Sunrise, etc. They were all easy to apply, but we were not in full control of the individual pixels of the image we wanted to edit.

In the second tutorial, we learned about layers and blend modes, which gave us more control over the images we were editing. For instance, you could add a new layer on the canvas, fill it with a color or image, and then place it over the parent layer with a blend mode applied to it. However, we were still not creating our own filters, and the blend modes we could apply were limited to the ones already provided by CamanJS.

The aim of this tutorial will be to teach you how to create your own blend modes and filters. We will also address some bugs present in the library and how you can patch them when using CamanJS in your own projects. 

Creating New Blend Modes

By default, CamanJS offers ten blend modes. These are normal, multiply, screen, overlay, difference, addition, exclusion, softLight, lighten, and darken. The library also allows you to register your own blend modes. This way, you can control how the corresponding pixels of the current layer and parent layer mix together in order to produce the final result.

You can create a new blend mode using Caman.Blender.register("blend_mode", callback);. Here, blend_mode is the name that you want to use in order to identify the blend mode you are creating. The callback function accepts two parameters which contain the RGB values for different pixels on the current layer and corresponding pixels on the parent layer. The function returns an object with final values for the rgb channels.

Here is an example of a custom blend mode which sets the value of individual channels of a pixel to 255 if the value of that channel for the corresponding pixel in the parent layer is over 128. If the value is below 128, the final channel value is the result of subtracting the current layer channel value from the parent channel value. The name of this blend mode is maxrgb.

Caman.Blender.register("maxrgb", function(rgbaLayer, rgbaParent) { return { r: rgbaParent.r > 128 ? 255 : rgbaParent.r - rgbaLayer.r, g: rgbaParent.g > 128 ? 255 : rgbaParent.g - rgbaLayer.g, b: rgbaParent.b > 128 ? 255: rgbaParent.b - rgbaLayer.b }; });

Let's create another blend mode in a similar manner. This time, the final channel values will be set to 0 if the channel value for the corresponding pixel in the parent layer is greater than 128. If the channel value for the parent layer is less than 128, the final result would be the addition of the channel values for the current layer and parent layer of the particular pixel. This blend mode has been named minrgb.

Caman.Blender.register("minrgb", function(rgbaLayer, rgbaParent) { return { r: rgbaParent.r < 128 ? rgbaParent.r + rgbaLayer.r : 0, g: rgbaParent.g < 128 ? rgbaParent.g + rgbaLayer.r : 0, b: rgbaParent.b < 128 ? rgbaParent.r + rgbaLayer.r : 0 }; });

You should try and create your own blend modes for practice.

Creating New Pixel-Based Filters

There are two broad categories of filters in CamanJS. You can either operate on the whole image one pixel at a time or you can modify an image using a convolution kernel. A convolution kernel is a matrix which determines the color of a certain pixel based on the pixels around it. In this section, we will focus on pixel-based filters. Kernel manipulations will be covered in the next section.

Pixel-based filters are given the value of RGB channels for one pixel at a time. The final RGB values for that particular pixel are not affected by the surrounding pixels. You can create your own filters using Caman.Filter.register("filter_name", callback);. Any filter that you create must call the process() method. This method accepts the filter name and a callback function as parameters.

The following code snippet shows you how to create a pixel-based filter which turns images greyscale. This is done by calculating the luminescence of each pixel and then setting the value of individual channels to be equal to the calculated luminescence.

Caman.Filter.register("grayscale", function () { this.process("grayscale", function (rgba) { var lumin = (0.2126 * rgba.r) + (0.7152 * rgba.g) + (0.0722 * rgba.b); rgba.r = lumin; rgba.g = lumin; rgba.b = lumin; }); return this; });

You can create a threshold filter in a similar manner. This time, we will allow the users to pass a threshold value. If the luminosity of a particular pixel is above the user provided limit, that pixel will turn white. If the luminosity of a particular pixel is less than the user provided limit, that pixel will turn black.

Caman.Filter.register("threshold", function (limit) { this.process("threshold", function (rgba) { var lumin = (0.2126 * rgba.r) + (0.7152 * rgba.g) + (0.0722 * rgba.b); rgba.r = lumin > limit ? 255 : 0; rgba.g = lumin > limit ? 255 : 0; rgba.b = lumin > limit ? 255 : 0; }); return this; });

As an exercise, you should try and create your own pixel-based filters which, for example, increase the value for a particular channel on all pixels.

Instead of manipulating the color of the current pixel, CamanJS also allows you to set the color for pixels at absolute and relative locations. Unfortunately, this behavior is a little buggy, so we will have to rewrite some methods. If you look at the source code of the library, you will notice that methods like getPixel() and putPixel() call the methods coordinatesToLocation() and locationToCoordinates() on this. However, these methods are not defined on the prototype but on the class itself.

Another issue with the library is that the putPixelRelative() method uses the variable name nowLoc instead of newLoc in two different places. You can get rid of both these issues by adding the following code inside your script.

Caman.Pixel.prototype.coordinatesToLocation = Caman.Pixel.coordinatesToLocation Caman.Pixel.prototype.locationToCoordinates = Caman.Pixel.locationToCoordinates Caman.Pixel.prototype.putPixelRelative = function (horiz, vert, rgba) { var newLoc; if (this.c == null) { throw "Requires a CamanJS context"; } newLoc = this.loc + (this.c.dimensions.width * 4 * (vert * -1)) + (4 * horiz); if (newLoc > this.c.pixelData.length || newLoc < 0) { return; } this.c.pixelData[newLoc] = rgba.r; this.c.pixelData[newLoc + 1] = rgba.g; this.c.pixelData[newLoc + 2] = rgba.b; this.c.pixelData[newLoc + 3] = rgba.a; return true; };

After correcting the code, you should now be able to create a filter that relies on putPixelRelative() without any issues. Here is one such filter that I created.

Caman.Filter.register("erased", function (adjust) { this.process("erased", function (rgba) { if(Math.random() < 0.25) { rgba.putPixelRelative(2, 2, { r: 255, g: 255, b: 255, a: 255 }); } }); return this; });

This filter randomly sets the value of pixels two rows up and two columns to the right of the current pixel to white. This erases parts of the image. Hence the name of the filter.

Creating New Kernel Manipulation Based Filters

As I mentioned earlier, CamanJS allows you to create custom filters where the color of the current pixel is determined by the pixels surrounding it. Basically, these filters go over each pixel in the image that you are editing. A pixel in the image will be surrounded by eight other pixels. The values of these nine pixels from the image are multiplied by the corresponding entries of the convolution matrix. All these products are then added together to get the final color value for the pixel. You can read about the process in more detail in the GIMP documentation.

Just like pixel-based filters, you can define your own kernel manipulation filters using Caman.Filter.register("filter_name", callback);. The only difference is that you will now call processKernel() inside the callback function.

Here is an example of creating an emboss filter using kernel manipulation.

Caman.Filter.register("emboss", function () { this.processKernel("emboss", [ -2, -1, 0, -1, 1, 1, 0, 1, 2 ]); });

The following CodePen demo will show all the filters that we created in this tutorial in action.

Final Thoughts

In this series, I have covered almost everything that CamanJS has to offer in terms of canvas-based image editing. You should now be able to use all the built-in filters, create new layers, apply blend modes on those layers, and define your own blend modes and filter functions.

You can also go through the guide on the CamanJS website in order to read about anything that I might have missed. I would also recommend that you read the source code of the library in order to learn more about image manipulation. This will also help you uncover any other bugs in the library.

Categories: Web Design

4 Quick On Page Local SEO Factors To Use Right Now

Webitect - Sat, 03/24/2018 - 07:29

On page SEO is quickly shifting towards a much higher importance for local SEO ranking. This is because Google is actively using GPS technology to offer local recommendations for people using mobile devices. It is now more important than ever to get your site ready for local rankings and unfortunately, most website owners have no idea how to do that. The internet is filled with various articles talking about the subject. You can always find quality in articles like Johnn Reviews’ article about useful off-page SEO strategies, but what should you actually add to your sites right now? Here are

The post 4 Quick On Page Local SEO Factors To Use Right Now appeared first on Clayton Johnson SEO.

Categories: Web Design

The Nomadic Designer: Tips And Tricks To Work On The Road

Smashing Magazine - Fri, 03/23/2018 - 05:20

Have you ever wondered what it would be like to travel the world while working as a designer? It might sound like a dream, but all that glitters is not gold, and it might not be the right choice for you. In this article, I’ll share some insights from my four years of travel and work that hopefully will be useful for anyone willing to try a nomadic lifestyle, too.

When I wrote the first draft of this article, I was in London, after a long trip to Asia. Now, I’m making changes to it in Mexico, before going to Argentina to visit my family. Changing countries often has become an important part of my life as a designer; and, curiously, it all happened by accident.

I once heard that, while at the office, you should stand up from your desk, stretch your legs, leave the building and never come back. That’s exactly what I did when I was living in Barcelona in March 2014. At the time, I was working for a big company on a project that I didn’t enjoy, and was participating in meetings with people I didn’t know. Sounds like fun, doesn’t it?

Looking back, I see that quitting a stable job to jump into the void of a traveling life was one of the scariest moments of my life. I was going to start a trip to South America, doing design workshops and lectures that would provide me with income to sustain my journey — but in reality, I had no idea what I was doing. Without knowing it, I was becoming a nomadic designer.

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 → Doing lectures and workshops around the world — and meeting new people because of it — is one of the things I've liked most about moving so much. Location: Barcelona.

When that six-month trip ended and I went back to Barcelona, I was never able to settle again. So, what did I do? Of course, I kept traveling! Four years and 60 countries later, I’m still on it.

And I am not alone. I’d like to quote Vitaly Friedman (founder and long-time editor in chief of Smashing Magazine), who once said:

“There is nothing more liberating and sentimental than the sound of a closing door that you will never open again. As memories are flowing by, you turn your back from that door, you hold your breath for just a second and you walk away. At that point you almost sense the change in the wind flowing by. You let go; and knowing and feeling this change is an incredibly empowering, intoxicating experience.”

If this sounds appealing, and you would like to try it for yourself, I hope my article will help you get started. Please note, however, that I’m not going to give you a “how to” guide, with step-by-step instructions that will work for everyone. Instead, I’ll share some insights from my personal experience.

Whatever People Think It Is, It Is Not That

When I tell someone that I’m constantly traveling, usually the person looks amazed. Most of the time, their first question is, “How can you afford to live like that?” I sometimes joke, saying I’m a millionaire with plenty of free time, but it’s not only because of this that I suspect they get the wrong idea about “working and traveling.” Perhaps, some of them imagine plenty of beaches and a lot of comfort and freedom.

Well, guess what? Working from a beach is not that fun or convenient. Or, as Preston Lee puts it, “Freelancing is not sitting on the beach, sipping margaritas, and reading books by Tim Ferriss.”

I've worked in all kind of places: public libraries, hostels, friends' houses (and, of course, some of them had cats). Can you spot a beach in any of these photos?

But the part about having a lot of freedom is true. I do have a lot of freedom and flexibility — like any other freelancer — with the bonus that I get to know different places, people, cultures and cuisines. The perks of such a lifestyle outweigh the difficulties, but at the same time, not everyone would be willing to handle it.

Today, the “digital nomad” hype is all around, with a lot of people publishing e-books, videos and blog posts selling an ideal lifestyle that’s apparently perfect. Of course, some things are often left out — things like getting tired of packing again and again, being away from family and friends, and starting over often. That’s why people might have a unrealistic idea of what all this is about.

In case you are considering trying something similar, it might help to be aware of some personal characteristics that would be helpful to have.

Comfort With Being Alone

Being a solo traveler allows me to make my own decisions and be wherever I want, whenever I want. I spend a lot of time by myself (luckily, I get along well with myself). Even though it’s fine for me, I know it’s not for everybody. Loneliness is easy to solve, though. Coworking spaces, hostels, couchsurfing hangouts and Meetup are great places when you feel like you need some company and want to meet new friends.

Being Able To Adapt To New Contexts Easily

On a rough average, I move from one place to another every four days. This is very tiring, because every time I switch cities, I have to repeat the same process: book transportation and accommodation, pack my stuff, figure out how to get around, check the weather and find out about the cost of living. Ideally, you won’t be moving that often, but you should be able to grab your things quickly and move to a new place that better meets your expectations.

In my travels, I've taken more flights than I would like to admit. That's a problem when moving so much from one place to another. Location: São Paulo, Brazil.

In some cases, you could plan to stay three or four months in the same spot, but the reality is that you will never know how you’ll feel until you get there. So, my advice is: Go little by little, especially at the beginning.

Flexible But Organized

I think I’ve never been as organized as I’ve been since I started traveling. Apart from the tools that I normally use to generate invoices, track payments and manage projects as a freelance designer, I also have several spreadsheets to organize my flights, accommodation and daily expenses.

The spreadsheet for expenses is divided into different categories and organized by day. I put in there all the money that goes out, so that I know exactly what’s happening, and how close I am to reaching my daily budget. I know there are some apps for this, but so far I haven’t felt comfortable with any of them. The key here is not to cheat (just write down everything) and to be consistent (do it every day) — this will give you good insight into how you are spending your money on the road. Then, it will be easier for you to make decisions based on the data gathered — for example, you could stop buying expensive cocktails so much.

Before Packing: Find A Remote-Friendly Job

If you’ve decided to give it a try, then, as a minimum, plan your start, and don’t leave home without at least one or two months of contracted work. This will keep you busy for the first part of your trip, so you’ll only have to worry about settling in a new place.

When I went to South America at the very beginning of my new life, I contacted several design organizations, schools and agencies that could help me organize design workshops and lectures in different countries. I did this because, a few months before leaving, I, along with a friend (¡hola José!) self-published a book that gained some popularity among designers in Latin America, and I was willing to teach its contents and show how to put them into practice. Doing things like that provided me with at least some idea of dates and an approximate income, while leaving other things to improvisation.

In my case, I’ve always liked being a freelancer, so I give myself a bit more flexibility in managing my schedule. One of the last projects I worked on was for a team in Barcelona and in which the words “remote” and “freelance” were clear in our agreement from the very beginning. This is what allowed me to keep going from country to country, splitting my time between work and getting to know new places and people.

Just so you know how “glamorous” this way of working is, at the beginning of this project I tried to hide my background during video calls or said that I couldn’t turn video on, because I was a bit embarrassed. By the end, though, my teammates didn’t care about that, and so later on, usually the first question of a video call was to ask me for a tour of the place I was staying at, to everyone’s amusement.

Of course, freelancing is not the only way. Working at a remote-friendly company could also be a good option for you. While you’ll lose some of the freedom to move around, if you plan to stay longer in places, then this could be the way to go: Hubspot, Basecamp, Bohemian Coding (of Sketch fame) and Automattic are some examples of companies that successfully work with designers and developers remotely, and there are many more.

A few websites list remote positions for design, so be sure to check them often: We Work Remotely, Remote OK, Working Nomads and Designer News — to name just some of them.

Regardless of whether you are freelancing or working for someone else, I have to say that face to face contact with members of your team is necessary from time to time to time, especially when planning meetings at the beginning of a project, when things are not all that clear. This will partly determine the location you choose, so best to pick a place that allows you to conveniently go where your team is based when needed.

Choosing Your Next Destination

After finding work that allows you to be on the move, the next big thing is to decide where to base yourself. The good thing is that you can work from any place with a decent Internet connection and easy access to coffee (which is essential).

I always say that, to work, I need only an Internet connection and a laptop. So, this place at almost 5,000 meters up is a good place to get stuff done. Location: somewhere near Uyuni, Bolivia.

So far, I’ve been in 60 countries, more or less. Many of them were in Europe, where it is easy to move from one place to another and where you can sometimes cross countries without even noticing. (True story: I once missed a whole country because I fell asleep on the train.)

When choosing where to go next, keep in mind the following.

Reliable Access To Internet

You’ll never know how good the Internet connection is until you get there, but at least you can research which countries have the best and worst. This is important. Even if you’re tempted to spend a few days in the middle of a forest, if there is no access to Internet, it will probably be a no-go.

Time Zones

Choose a place where you’ll be in the same time zone with the rest of your team, or maybe a couple of hours ahead or behind. You’ll thank me when you have to schedule your first online meeting and it’s not 4:00 am.

Work Facilities

I’ve said that I can work from almost anywhere, but I have to make sure that my next destination at least has some good coffee shops, libraries or coworking spaces. You could also work from your hostel, hotel or rented flat, but then you’d have to make sure it’s a proper environment to work in.

Design Ecosystem

It’s always good to be surrounded by like-minded people, so many times before going somewhere, I’ll check whether there’s a designer, a design studio or a meetup where I could visit and get in touch with others. Luckily, some people are always willing to meet new pals, and they’ll give you good insight into how the local design community works. You can exchange and share tools of the trade, and you can make new friends as well.

Sometimes I don't choose my destinations right… at least for getting some work done. Being in the middle of snowy places forced me to take unplanned vacations. Location: Mongolia.

In my case, sending some emails in advance enabled me to meet such talented people as Michael Flarup in Copenhagen and Sacha Greif in Osaka. Just don’t be afraid to ask if you can drop by for a short visit!

Besides that, other factors are at play when you’re deciding where to go: affordability, transportation, safety, weather, etc. Fortunately, Nomad List rounds up the “best” cities,, which you can use as a reference when choosing where to head to next.

Of course, sooner or later, you’ll make some mistake. I’ve learned the hard way that planning where to work is indeed important. I once had to take a few unintended days off when I took the Trans-Siberian train to go from St. Petersburg to Beijing via Mongolia. At some point, the temperatures in the middle of Siberia were so low — the worst day was -50º Celsius — that my phones’ batteries suddenly drained — and being lost in the middle of a snowy small town is anything but fun. (The Russians there thought I was crazy for traveling during winter, and I now know they were right. But if you are like me and go there during wintertime anyway, always keep a paper copy of directions and important information, and bring warm boots and a pocket-sized bottle of vodka.)

Packing And Gear

If you already have a job and know where you are heading to, then you are ready to pack! Someone once said that before starting a trip, you should take half the things you plan to carry and double the money you have budgeted. While the last thing is not always an option, packing light is doable! You’ll thank me when you find your accommodation is uphill.

I started traveling with a 50-liter backpack for my personal things, and a smaller one for work-related items that I carry separately. After some time, I switched the smaller one for a daypack that I can roll up and put into the big one when I don’t need it. Everything (including the laptop) weighs 10 kilograms or so, but I keep assessing what else can I take off in order to have fewer things to carry. Similarly to when working on a design, try to get rid of the unnecessary.

For my work, I chose a MacBook Air because I knew I was going to travel a lot, and I wanted something lightweight and compact. Even though it’s a bit old now, it’s been enough for my requirements so far. I also carry two phones (iPhone and Android, with their corresponding chargers) because I do a lot of UX design for mobile and I often need to test on different devices.

I do have more gadgets and stuff, of course. I carry a remote to control my slides (for conferences and workshops), all kinds of adaptors, and noise-cancelling headphones (very useful for when you travel by train or plane.) But, in general, it is a good idea not to over-buy in advance, and pick up items only when you need them.

Where To Work

I have worked in all kinds of places: buses, trains, coffee shops, airport lounges, libraries, shared rooms in hostels, private rooms in hotels — sometimes anywhere I can set my laptop horizontally… or kind of. I’ve even gotten used to not using a mouse at all, because there is not always a place to put it next to my laptop.

Chances are the room where you stay is also going to be where you will work, so choose carefully. Airbnb is now pretty much widespread, so renting your own room with a desk should be enough — but be sure to mark “laptop friendly” in the search filters.

I try to keep a low budget, so most of the time I stay in a hostel. After a bit of training, I’ve learned to identify places that look better for work — like ones with spacious common areas — just by looking at the pictures. Of course, “party hostels” are not an option if you want to get work done, so if you see a lot of people having fun on the property’s website, that’s a red flag.

I sleep in shared dorms in hostels most of the time, to keep my budget low and meet new people, but there's not much privacy. Location: Sofia, Bulgaria.

One of the main problems is that you never know how good the Internet connection will be. So, if you have difficulty with the Wi-Fi at your hostel, go to a coffee shop, coworking space or even a public library. (Interestingly, public libraries are where I’m most productive, perhaps because of the silence and the fact that I cannot make calls or participate in online meetings.)

Tip: More than once, I’ve visited a coworking space and offered to give a free design lecture to members in exchange of a few days’ worth of using a desk. It’s also nice because afterwards people will know who you are and will approach you openly to share ideas! Feel free to try it yourself.

Finally, a couple of websites could be useful when you’re looking for a place to work — namely, Workfrom and Places to Work.

Things To Keep In Mind When Living On The Road

A few things are important for any traveling designer but are too complex to address completely in one article, so I’ll just briefly mention a few of them, in the hope that it will still be useful.

Please keep in mind that everybody’s situation is different. There’s no one-size-fits-all answer, so you might have to adapt the following to your case.

Taxes

What is convenient for you will depend on your case, and it’s difficult to advise on what’s best, so be aware of the legislation of your home country and of the country where you plan to work. I’ve also been exploring the possibilities that Estonia is offering with its e-citizenship. I’m already an Estonian e-resident, but I haven’t done anything practical with this as of yet.

Managing Your Finances

Besides keeping spreadsheets for expenses, one thing that I discovered (perhaps too late) is that it is normally far more convenient to create an account in an app such as Monzo or Revolut (and there are plenty of others, like N26), so that, when making withdrawals, you pay fewer fees and get better exchange rates. This is especially useful in places where credit or debit cards are not normal; this way, you can also avoid the excessive fees that traditional banks often charge.

Also, check the exchange rate of your home currency before arriving at your next destination. In some cases, I’ve arrived in a new country and bought a very expensive coffee because I didn’t do my homework beforehand. One app I use to avoid situations like this is Currency, an elegant and simple currency converter.

Visas

The situation will depend on where you’re from and where you’re going, so check well in advance regarding the requirements for the passport you are holding.

Something useful I learned when applying for a visa that requires a tentative itinerary is to book hostels and planes that you can later on cancel for free, and print out and bring those booking confirmations.

Health And Insurance

Plenty of companies offer health insurance for travel, so I cannot recommend any one of them. The only thing I can advise is not to leave home without it. An accident in a foreign country, besides being annoying, could also be very expensive. So, prepare in advance.

You never know where you'll be when there's a problem at work, so try to find ways to stay connected on the go. Location: somewhere near Jericoacoara, Brazil. Getting Connected

What I normally do is buy a prepaid SIM card in each country I stay, with a data plan that will be enough for my stay there. I do a bit of research beforehand to see which carrier has the most widespread coverage, and I check if there’s any information in English on their website to make recharges when necessary.

A SIM card is more necessary in some countries than in others. For example, in Russia, most open Wi-Fi networks require you to fill in a phone number, to which a validation code will be sent, before you are able to use the network. Japan, on the other hand, is full of convenience stores with free internet (such as 7-Eleven), so a SIM card is not so necessary. Meanwhile, Europe now has a more convenient way to handling roaming, called “Roam like at home”, and getting a new SIM card in every country is not so necessary anymore.

In any case, before buying a SIM card, make sure it will work across the country, especially if the country is large with many different regions. Another important thing to check beforehand: Will your current phone number work in the new country? Luckily, there’s a website where you can check that information.

Preparing To Be Offline

Moving from one place to another involves a lot of time spent on the road, and in some cases you won’t have the chance to find Wi-Fi or good data network coverage. At these times, Spotify and Netflix are my best friends, because both allow me to download music and TV shows, respectively, so I can use them without an Internet connection. This was especially useful when I had to take several connecting trains to cross Siberia, spending in some cases around 30 hours straight in a railroad car before my next stop.

I still had an Internet connection in these mountains in Bulgaria! However, being offline from time to time and enjoying the natural surroundings is really advisable. Location: Seven Rila Lakes region, Bulgaria.

For the same reason, I always download a map of my next destination, using Google Maps (Maps.me has the same functionality).

If you want more information of this kind, check out another article I wrote, with more travel hacks and tips from my years of traveling.

Final Thoughts

Before I board my next train, let me tell you that becoming a nomadic freelance designer is by far one of my best decisions of my life so far. I have the flexibility that any freelancer has, but I also meet new people and see new places all the time. And it’s not as expensive as you might think. If you control your budget, traveling could be cheaper than living in a big city. So, I can afford to work four to five hours every day, and I use the rest of the time to get to know the place I’m visiting, to work on personal projects and to write articles for Smashing Magazine.

Traveling also makes it a bit hard to separate pleasure from work, because everything seems more enjoyable when you’re moving around. I’ve had to remind myself sometimes that I’m not on a vacation and to focus on getting things done. After a while, though, I’ve found a good balance. Now, I allow myself some moments to just move around, travel and enjoy the ride, doing nothing. It’s not all about work, after all!

Taking a train in Siberia. It's not all about work. You also have to let yourself go and enjoy your ride. Location: somewhere in Russia.

Living like this is sometimes challenging and tiring, but I find it much richer than being in an office Monday to Friday, 9:00 to 5:00. And with all of the current technology, it’s easy for any designer to embrace this lifestyle. The most difficult part is finding a job to sustain your travel, but once you’ve found it, the next part is just to let it flow.

The nomadic lifestyle is not right for everyone, but the only way to know for sure is to try. Neale Donald Walsch once said that life starts where your comfort zone ends, and I completely agree. If you can afford to take the risk, go for it and enjoy a part of life that might not last long but will give you a life-changing experience, teach you new things and change the way you see the world forever.

If, for some reason, it doesn’t work, you can always go back to your previous life, right? Whether you are ready to give it a try or still have some questions about it, feel free to let me know. I’ll do my best to help you out. See you on the road!

Further Reading (mb, ra, al, yk, il)
Categories: Web Design

Modern Web Scraping With BeautifulSoup and Selenium

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

HTML is almost intuitive. CSS is a great advancement that cleanly separates the structure of a page from its look and feel. JavaScript adds some pizazz. That's the theory. The real world is a little different.

In this tutorial, you'll learn how the content you see in the browser actually gets rendered and how to go about scraping it when necessary. In particular, you'll learn how to count Disqus comments. Our tools will be Python and awesome packages like requests, BeautifulSoup, and Selenium.

When Should You Use Web Scraping?

Web scraping is the practice of automatically fetching the content of web pages designed for interaction with human users, parsing them, and extracting some information (possibly navigating links to other pages). It is sometimes necessary if there is no other way to extract the necessary information. Ideally, the application provides a dedicated API for accessing its data programmatically. There are several reasons web scraping should be your last resort:

  • It is fragile (the web pages you're scraping might change frequently).
  • It might be forbidden (some web apps have policies against scraping).
  • It might be slow and expansive (if you need to fetch and wade through a lot of noise).
Understanding Real-World Web Pages

Let's understand what we are up against, by looking at the output of some common web application code. In the article Introduction to Vagrant, there are some Disqus comments at the bottom of the page:

In order to scrape these comments, we need to find them on the page first.

View Page Source

Every browser since the dawn of time (the 1990s) has supported the ability to view the HTML of the current page. Here is a snippet from the view source of Introduction to Vagrant that starts with a huge chunk of minified and uglified JavaScript unrelated to the article itself. Here is a small portion of it:

Here is some actual HTML from the page:

This looks pretty messy, but what is surprising is that you will not find the Disqus comments in the source of the page.

The Mighty Inline Frame

It turns out that the page is a mashup, and the Disqus comments are embedded as an iframe (inline frame) element. You can find it out by right-clicking on the comments area, and you'll see that there is frame information and source there:

That makes sense. Embedding third-party content as an iframe is one of the primary reasons to use iframes. Let's find the <iframe> tag then in the main page source. Foiled again! There is no <iframe> tag in the main page source.  

JavaScript-Generated Markup

The reason for this omission is that view page source shows you the content that was fetched from the server. But the final DOM (document object model) that gets rendered by the browser may be very different. JavaScript kicks in and can manipulate the DOM at will. The iframe can't be found, because it wasn't there when the page was retrieved from the server. 

Static Scraping vs. Dynamic Scraping

Static scraping ignores JavaScript. It fetches web pages from the server without the help of a browser. You get exactly what you see in "view page source", and then you slice and dice it. If the content you're looking for is available, you need to go no further. However, if the content is something like the Disqus comments iframe, you need dynamic scraping. 

Dynamic scraping uses an actual browser (or a headless browser) and lets JavaScript do its thing. Then, it queries the DOM to extract the content it's looking for. Sometimes you need to automate the browser by simulating a user to get the content you need.

Static Scraping With Requests and BeautifulSoup

Let's see how static scraping works using two awesome Python packages: requests for fetching web pages and BeautifulSoup for parsing HTML pages.

Installing Requests and BeautifulSoup

Install pipenv first, and then: pipenv install requests beautifulsoup4 

This will create a virtual environment for you too. If you're using the code from gitlab, you can just pipenv install.

Fetching Pages

Fetching a page with requests is a one liner: r = requests.get(url)

The response object has a lot of attributes. The most important ones are ok and content. If the request fails then r.ok will be False and r.content will contain the error. The content is a stream of bytes. It is usually better to decode it to utf-8 when dealing with text:

>>> r = requests.get('http://www.c2.com/no-such-page') >>> r.ok False >>> print(r.content.decode('utf-8')) <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL /ggg was not found on this server.</p> <hr> <address> Apache/2.0.52 (CentOS) Server at www.c2.com Port 80 </address> </body></html>

If everything is OK then r.content will contain the requested web page (same as view page source).

Finding Elements With BeautifulSoup

The get_page() function below fetches a web page by URL, decodes it to UTF-8, and parses it into a BeautifulSoup object using the HTML parser.

def get_page(url): r = requests.get(url) content = r.content.decode('utf-8') return BeautifulSoup(content, 'html.parser')

Once we have a BeautifulSoup object, we can start extracting information from the page. BeautifulSoup provides many find functions to locate elements inside the page and drill down deep nested elements. 

Tuts+ author pages contain multiple tutorials. Here is my author page. On each page, there are up to 12 tutorials. If you have more than 12 tutorials then you can navigate to the next page. The HTML for each article is enclosed in an <article> tag. The following function finds all the article elements on the page, drills down to their links, and extracts the href attribute to get the URL of the tutorial:

def get_page_articles(page): elements = page.findAll('article') articles = [e.a.attrs['href'] for e in elements] return articles

The following code gets all the articles from my page and prints them (without the common prefix):

page = get_page('https://tutsplus.com/authors/gigi-sayfan') articles = get_page_articles(page) prefix = 'https://code.tutsplus.com/tutorials' for a in articles: print(a[len(prefix):]) Output: building-games-with-python-3-and-pygame-part-5--cms-30085 building-games-with-python-3-and-pygame-part-4--cms-30084 building-games-with-python-3-and-pygame-part-3--cms-30083 building-games-with-python-3-and-pygame-part-2--cms-30082 building-games-with-python-3-and-pygame-part-1--cms-30081 mastering-the-react-lifecycle-methods--cms-29849 testing-data-intensive-code-with-go-part-5--cms-29852 testing-data-intensive-code-with-go-part-4--cms-29851 testing-data-intensive-code-with-go-part-3--cms-29850 testing-data-intensive-code-with-go-part-2--cms-29848 testing-data-intensive-code-with-go-part-1--cms-29847 make-your-go-programs-lightning-fast-with-profiling--cms-29809Dynamic Scraping With Selenium

Static scraping was good enough to get the list of articles, but as we saw earlier, the Disqus comments are embedded as an iframe element by JavaScript. In order to harvest the comments, we will need to automate the browser and interact with the DOM interactively. One of the best tools for the job is Selenium.

Selenium is primarily geared towards automated testing of web applications, but it is great as a general-purpose browser automation tool.

Installing Selenium

Type this command to install Selenium: pipenv install selenium

Choose Your Web Driver

Selenium needs a web driver (the browser it automates). For web scraping, it usually doesn't matter which driver you choose. I prefer the Chrome driver. Follow the instructions in this Selenium guide.

Chrome vs. PhantomJS

In some cases you may prefer to use a headless browser, which means no UI is displayed. Theoretically, PhantomJS is just another web driver. But, in practice, people reported incompatibility issues where Selenium works properly with Chrome or Firefox and sometimes fails with PhantomJS. I prefer to remove this variable from the equation and use an actual browser web driver.

Counting Disqus Comments

Let's do some dynamic scraping and use Selenium to count Disqus comments on Tuts+ tutorials. Here are the necessary imports.

from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.expected_conditions import ( presence_of_element_located) from selenium.webdriver.support.wait import WebDriverWait

The get_comment_count() function accepts a Selenium driver and URL. It uses the get() method of the driver to fetch the URL. This is similar to requests.get(), but the difference is that the driver object manages a live representation of the DOM.

Then, it gets the title of the tutorial and locates the Disqus iframe using its parent id disqus_thread and then the iframe itself:

def get_comment_count(driver, url): driver.get(url) class_name = 'content-banner__title' name = driver.find_element_by_class_name(class_name).text e = driver.find_element_by_id('disqus_thread') disqus_iframe = e.find_element_by_tag_name('iframe') iframe_url = disqus_iframe.get_attribute('src')

The next step is to fetch the contents of the iframe itself. Note that we wait for the comment-count element to be present because the comments are loaded dynamically and not necessarily available yet.

driver.get(iframe_url) wait = WebDriverWait(driver, 5) commentCountPresent = presence_of_element_located( (By.CLASS_NAME, 'comment-count')) wait.until(commentCountPresent) comment_count_span = driver.find_element_by_class_name( 'comment-count') comment_count = int(comment_count_span.text.split()[0])

The last part is to return the last comment if it wasn't made by me. The idea is to detect comments I haven't responded to yet.

last_comment = {} if comment_count > 0: e = driver.find_elements_by_class_name('author')[-1] last_author = e.find_element_by_tag_name('a') last_author = e.get_attribute('data-username') if last_author != 'the_gigi': e = driver.find_elements_by_class_name('post-meta') meta = e[-1].find_element_by_tag_name('a') last_comment = dict( author=last_author, title=meta.get_attribute('title'), when=meta.text) return name, comment_count, last_commentConclusion

Web scraping is a useful practice when the information you need is accessible through a web application that doesn't provide an appropriate API. It takes some non-trivial work to extract data from modern web applications, but mature and well-designed tools like requests, BeautifulSoup, and Selenium make it worthwhile.

Additionally, don’t hesitate to see what we have available for sale and for study in the Envato Market, and don't hesitate to ask any questions and provide your valuable feedback using the feed below.

Categories: Web Design

Creating A UX Strategy

Smashing Magazine - Fri, 03/23/2018 - 03:25

(This is a sponsored article.) As designers working primarily on screen, we often think of user experience design as being primarily a screen-focused activity. In fact, user experience affects the entirety of what we build and that often includes activities that are undertaken off-screen.

To design truly memorable experiences, we need to widen our frame of reference to include all of the brand touchpoints that our users come into contact with along their customer journey. Doing so has the potential to materially impact upon business outcomes, recognizing the role that design — and user experience — can play at the heart of a wider business strategy.

Whether you’re building a website or an application, at heart you are designing for users and, as such, it’s important to consider these users at the center of a customer-focused ecosystem. Great brands are more than just logos or marques, and websites or applications, they’re about the totality of the user experience, wherever a customer comes into contact with the brand.

This expanded design focus — considering touchpoints both on- and off-screen — becomes particularly important as our role as designers widens out to design the entirety of the experience considering multiple points of contact. It’s not uncommon for the websites and apps we build to be a part of a wider, design-focused ecosystem — and that’s where UX strategy comes in.

Over the last few years, we have seen designers move up the chain of command and, thankfully, we are starting to see designers occupy senior roles within organizations. The emergence of designers as part of the C-Suite in companies is a welcome development and, with it, we are seeing the emergence of CDOs, Chief Design Officers.

As James Pallister put it in "The Secrets of the Chief Design Officer," an article exploring the CDO phenomenon written for the UK’s Design Council:

"As Apple’s valuation shot higher and higher in recent years, a flurry of major corporations — Philips, PepsiCo, Hyundai &mdahs; announced the appointments of Chief Design Officers to their boards.

This was no mere coincidence. Seeking to emulate the stellar success of design-led businesses like Apple, global companies are pouring investment into design."

This investment in, and appreciation of, design has been long overdue and is beginning to impact upon our day-to-day role as designers.

Forward-thinking companies are elevating the role of designers within their hierarchies and, equally importantly, stressing the importance of design thinking as a core, strategic business driver. As a result, we are seeing design driving company-wide business innovation, creating better products and more engaged relationships with customers.

As this trend continues, giving designers a seat at the top table, it’s important to widen our scope and consider UX strategy in a holistic manner. In this article, the eighth in my ongoing series exploring user experience design, I’ll open the aperture a little to consider how design impacts beyond the world of screens as part of a wider strategy.

Considering Customer Journeys

Before users come into contact with a website or an app, they will likely have been in contact with a brand in other ways — often off-screen. When considering design in the widest sense, it’s important to focus on the entirety of the customer journey, designing every point of contact between a user and a brand.

Forrester, the market research company, defines the customer journey as follows:

"The customer journey spans a variety of touchpoints by which the customer moves from awareness to engagement and purchase. Successful brands focus on developing a seamless experience that ensures each touchpoint interconnects and contributes to the overall journey."

This idea — of a seamless and well-designed experience and a journey through a brand — should lie at the heart of a considered UX strategy. To design truly memorable experiences, we need to focus not just on websites or apps, but on all of the touchpoints a user might come into contact with.

Consider the Apple Store and its role acting as a beacon for Apple and all of its products. The Apple Store is, of course, an offline destination, but that doesn't mean that the user experience of the store hasn't been designed down to the last detail. The store is just one part of Apple’s wider engagement strategy, driving awareness of the business.

The Apple Store is an entry point into Apple's ecosystem and, as such, it's important that it's considered in a holistic manner: Every aspect of it is designed.

Jesse James Garrett, the founder of Adaptive Path which is an end-to-end experience design company, considers this all-embracing approach in an excellent article, "Six Design Lessons From the Apple Store," identifying a series of lessons we can learn from and apply to our designs. As Garrett notes:

"Apple wants to sell products, but their first priority is to make you want the products. And that desire has to begin with your experience of the products in the store."

Seen through this lens, it becomes clear that the products we design are often just one aspect of a larger system, every aspect of which needs to be designed. As our industry has matured, we’ve started to draw lessons from other disciplines, including service design, considering every point as part of a broader service journey, helping us to situate our products within a wider context.

If service design is new to you, Nielsen Norman Group (helpful as ever), have an excellent primer on the discipline named "Service Design 101" which is well worth reading to gain an understanding of how a focus on service design can map over to other disciplines.

When designing a website or an app, it’s important to consider the totality of the customer journey and focus on all of the touchpoints a user will come into contact with. Do so, and we can deliver better and more memorable user experiences.

Designing Touchpoints

As our industry has evolved, we’ve begun to see our products less as standalone experiences, but as part of a wider network of experiences comprised of ‘touchpoints’ — all of which need to be designed.

Touchpoints are all the points at which a user comes into contact with a brand. As designers, our role is expanding to encompass a consideration of these touchpoints, as a part of a broader, connected UX strategy.

With the emergence of smartphones, tablets, wearables and connected products our scope has expanded, widening out to consider multiple points at which users come into contact with the brands we are designing.

When considering a UX strategy, it helps to spend some time listing all of the points at which a user will come into contact with the brand. These include:

  • Websites,
  • Apps and mobile experiences,
  • Email,
  • Support services,
  • Social media.

In addition to these digital points of contact, it’s important to consider >non-digital points of contact, too. These off-screen points of contact include everything, from how someone answers the phone to the packaging of physical products.

To aid with this, it helps to develop a ‘touchpoints matrix’ — a visual framework that allows a designer to join the dots of the overall user experience. This matrix helps you to visually map out all of the different devices and contexts in which a user will come into contact with your brand.

The idea of a touchpoints matrix was conceived by Gianluca Brugnoli — a teacher at Politecnico di Milano and designer at Frog Design — as a tool that fuses customer journey mapping with system mapping, which can be used as the basis for considering how different user personas come into contact with and move through a brand.

Roberta Tassi, as part of her excellent website Service Design Tools — "an open collection of communication tools used in design processes that deal with complex systems" — provides an excellent primer on how a touchpoints matrix can be used as part of a holistic design strategy. Tassi provides a helpful overview, and I’d recommend bookmarking and exploring the website — it’s a comprehensive resource.

As she summarises:

"The matrix brings a deeper comprehension of interactions and facilitates further development of the opportunities given by the system — of the possible entry points and paths — shifting the focus of the design activities to connections."

This shift — from stand-alone to connected experiences — is critically important in the development of a ‘joined up’ UX strategy.

When you embark upon developing and mapping a broader UX strategy, a touchpoints matrix helps you to see how the different nodes of a design join up to become part of an integrated and connected experience or an 'ecosystem.'

Building Ecosystems

When we holistically consider our role as designers, we can start to explore the design of the whole experience: from initial contact with a brand offline, through engaging with that brand digitally. Collectively, these amount to designing a brand ecosystem.

Ecosystems aren't just for big brands — like Facebook, Instagram or Twitter — they are increasingly for everything we design. In a world that is ever more connected, what we design doesn’t stand in isolation. As such, we need to consider both context and scope as part of an integrated strategy.

In addition to considering the design of products, we also need to consider the wider ecosystem that these products sit within. For example, when considering the design of applications — whether web-based or native — we also need to consider: the user’s first point of contact and how we drive discovery; the experience while using the application itself; and addressing wider issues (such as offering users support).

All of the aspects of an ecosystem need to be designed so that we deliver great user experiences at every point in the process. This includes:

  • The process of discovery, through social and other channels;
  • The design of a company or application’s website, so that the story that’s told is consistent and engaging;
  • The content of email campaigns to ensure they’re equally considered, especially if there are multiple email campaigns targeted at different audiences;
  • The packaging, when we’re designing physical, connected products; and
  • The support we offer, ensuring that customers are looked after at every point of the journey, especially when issues arise.

This list is just the tip of the proverbial iceberg, but it clearly shows that there are multiple points on a customer’s journey that need to be designed. A considered UX strategy helps us to deliver on all of these aspects of an ecosystem and become increasingly important as the ecosystems we design become richer and more complex.

In Closing

The opportunities ahead are fantastic for designers working in this industry. The landscape we are designing for is evolving rapidly and, if we're to stay ahead of the game, it's important that we turn our attention towards the design of systems in addition to products. This involves an understanding of UX strategy in the broadest sense.

When embarking upon the design of a new website or product, or undertaking a redesign, it’s important to widen the frame of reference. Taking a step back and considering the entirety of the user experience leads to better and more memorable experiences.

By considering the entirety of the customer journey and all the touchpoints along the way we can create more robust, connected experiences. By focusing on the design of holistic experiences, we can delight users, ensuring they’re happy with the entire experience we have crafted.

This article is part of the UX design series sponsored by Adobe. Adobe XD is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype, and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.

(ra, yk, il)
Categories: Web Design

Using Ethics In Web Design

Smashing Magazine - Thu, 03/22/2018 - 08:30

Every design decision is a decision made on behalf of other people, those we often refer to as “end-users.” As the creators of designed experiences used by people all over the world, it is our responsibility to think carefully about how our decisions impact the person on the other end of the conversation. Even small and seemingly insignificant decisions can have enormous implications, and ethics can help ensure the longevity of our designs and help us carve paths to better futures for everyone.

Earlier this month, a friend reached out with a question:

How hard would it be to use the processing power of computers visiting their site to mine for cryptocurrencies?

The first I heard of cryptocurrency mining (cryptojacking for short) through websites was a news story from September 2017 about a script found on the website of a TV network called Showtime. Since then, similar scripts have appeared on everything from government websites to good old-fashioned blogs. Sometimes the scripts are put there by hackers (first documented by Scott Helme), other times by the site developers themselves.

The most recent example is from the folks at Salon who are testing out cryptojacking as an alternative revenue stream from visitors who use ad blockers:

Salon.com FAQ page about ad blockers and cryptojacking. (Source)

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 →

In response, I told my friend “this is an ethical question more than a practical one” and sent a series of questions back:

  1. What world are you building for your visitors? What capabilities are you granting or enabling?
  2. What kind of person do you become by doing this, and is that the kind of person you aspire to be?
  3. Would you want every other person in your position to make the same decision you just made? Are you upholding your duties of care?
  4. Does this improve the lives of everyone affected?

I created these questions as a basis of an ethical framework for design decisions. They enable us to think not just about what, how, and why we do things but also to what end and they remind us to put “ought” before “can” when decisions need to be made.

“Ethics” is the word du jour in tech, and it’s for a good reason. As the connected age emerges into adulthood, we are coming to terms with the consequences of decisions made in garages and coffee shops and dorm rooms years ago; solutions built to keep us engaged are distorting our understanding of reality. Platforms built to connect us are becoming breeding grounds of hatred and division. It turns out that even small choices can have a monumental impact when amplified through a user base of billions.

It’s about time that we, the people who build the web, initiate a conversation about where we are and where we want to go, about how we define and measure goodness and rightness in the digital realm, about responsibility, about decisions and consequences, about building something bigger than our own apps. It is time we talk about the ethics of web design.

In this article, we will cover:

  • The current state of ethics in design and technology;
  • The basic design ethics framework;
  • How to evaluate consequences of our work;
  • What norms and expectations are we establishing with our work;
  • What type of person do we become in the process;
  • What environments are we building for the end-user;
  • The Ethical Principles of Web Design (checklist)
Ethics And Design

Every design decision is a decision made on behalf of our users. As the creators of designed experiences used by people all over the world, it is our responsibility to think carefully about not just how we do something at a technical level or what goals we are trying to achieve for ourselves or our clients or companies, but why we do it and how our decisions impact the person on the other end of the conversation. With every decision, we have the shared opportunity and responsibility to think about the ethics of web design, not just as a high flying ideal about doing no harm or doing the right thing, but as a fundamental part of our everyday process.

Rather than a wet moralistic blanket covering the fires of creativity, I aim to show how ethics can be the hearth that makes our creative fires burn brighter, without burning down the house.

The good news is we are not heading into an unexplored wilderness. The world of ethics is well traveled and the cowpaths are all but paved. For centuries, philosophers have grappled with the same questions we now face in the tech industry: how to make decisions that bring more good than bad into the world, to whom and for what we are responsible, how to measure success not just in more wealth for ourselves but also in the betterment of life for everyone. Using their theories as our foundation, we can establish a framework for the ethics of web design that help us make better decisions for everyone both today and in the future.

Ethics is not about making a list of good and bad acts, it’s about creating a method for evaluating each decision and each act from an ethical perspective.

Ethical Principles In The Tech Community

Ethics can and should be a core component of web design and computer sciences in general. The challenge is that ethics is not a label, it’s a practice. In the tech community, ethical principles tend toward grand statements and nice sounding rules like “don’t be evil” or “do the right thing” without anchoring these rules in the solid foundation of an ethical framework. These rules provide an air of ethical decision making while laying the groundwork for moral relativism.

It’s easy enough to say “do no harm,” but if you don’t also define what you mean by “harm”, to whom this harm can be done, and who judges whether or not harm has been done, these words have little to contribute except to make us feel good. If we say we want to do good but don’t have clearly established definitions of what good is, how we judge whether something is good, and why we want to do good in the first place, we have effectively granted ourselves a license to do anything we want — a textbook example of subjective moral relativism.

On the flipside, if some industry or government body makes a list of good and bad acts and declares it the law of the web design lands without providing an ethical framework to make and test these judgments, the door is opened to authoritarian moralism and the inevitable stifling of creativity.

We Need An Ethical Framework

Ethics can provide a framework for careful consideration of the decisions we make and their outcomes, and give us the tools to make better decisions and think more broadly about the implications of our work and actions. An ethical framework for web design should provide tools to objectively judge the value of individual decisions and actions based on agreed-upon principles. Rather than declare every decision or act of a certain type always good or bad, it should grant us the ability to see every decision in its context and judge it based not only on its intentions or outcomes but also on whether it should be a best practice, what virtues it promotes, and what capabilities it grants and enables for those affected. I propose we use the lessons from four moral philosophies as the piers of a bridge to carry future web designers over the ethical marshlands we find ourselves mired in.

In this context the term “web designer” is a broad umbrella covering anyone who makes decisions about the function, functionality, appearance, and interactivity of a web experience, and “web design” a term covering the craft and work of a web designer. Though we commonly think of a “web designer” as the person literally designing the appearance of what is displayed on a screen, the reality is everyone — from back-end developers through information architects, content strategists, UX and UI designers, even content creators — makes design decisions that impact the experience of the people who use our creations. Databases are designed. So are content models and navigation patterns and taxonomy structures and headlines.

Ethical Framework (The Short Version)

Before we dive in, let me give you the short version: a mnemonic device that will help you see where we’re going in this article and help you remember to check the Ethical Principles of Web Design every time a decision is made. I call it the “Bridge of Ethics”:

The Ethical Bridge with its four piers: Capability Approach, Virtue Ethics, Deontology, and Consequentialism.

The Bridge of Ethics allows a designer to cross ethical marshlands by passing over four piers representing the four moral philosophies covered in this article. Each pier has central questions to be answered:

Capability Approach Virtue Ethics Deontology Consequentialism What world are you building for the end-user? What capabilities are you granting or enabling? What type of person do you become in the process? What norms and expectations are you establishing? Are you upholding your duties of care? What are the consequences of your decision? Do they improve the common good of those affected?

When evaluating a new design decision, start from the left establishing what capabilities you grant or enable in the end-user and then move to the right. When evaluating an existing design or service, start from the right establishing the consequences created by the decision and move to the left.

With that image in your head, let’s get crackin’!

A Practical Example To Lead The Way

To make sense of how the Ethics of Web Design would work in a real setting, I’ve built this article around a practical example which looks at how we can use ethics to tackle one of the hard problems of the web: Making money from publishing content online.

Meet Maiken and Kenneth, cat aficionados and online entrepreneurs. They have an online store where they sell products, some of their own creation, some as resellers. Now they want to set up a website where they share tips and tricks about their passion (cats) and earn a bit of passive income in the process.

Ever since web design and development became accessible to the masses, everyone from bloggers to website- and web service owners have tried to figure out how to turn online content into cold hard cash. The first, and most prominent way of doing this is through online advertising; placing ads throughout the site, either in dedicated areas or intermingled with the content, and charging the advertisers either based on impression (someone sees the ad), interaction (someone clicks the ad), or both.

Maiken and Kenneth see advertising as a possible revenue stream and want to implement advertising in an ethical way. This brings us to the first pier of the Bridge of Ethics:

1. Consequentialism: The Many Before The Few

The predominant ethical theory in most industries is consequentialism, more specifically utilitarianism (more in-depth analysis). In short, an act that benefits the majority is considered good even if a minority suffers as a result because the overall utility of the act is positive. To put an edge on it, in consequentialism the ends justify the means, and in utilitarianism, any act is considered good if the resulting benefits outweigh the costs.

Utilitarianism In The Tech Space

Consequentialist and Utilitarian ethics are woven into every aspect of the tech space. We find them in our decision making processes and procedures any time we base our decisions on their overall utility: “Will the majority of our users benefit from this new feature?” “Can this bug be ignored since it only impacts a small percentage of users?” “Can we make this decision on behalf of our users to reduce the complexity of the interface?”

From a business standpoint, this makes sense: If the majority of users are happy, the business thrives. But this approach also opens the door to implicit or explicit bias and discrimination: If the only thing that matters is maximizing utility, ignoring or causing harm to a minority becomes acceptable. This is further complicated by our inability to accurately predict the consequences of our decisions and look at a situation from a neutral position devoid of our own privilege and bias.

Utilitarianism Puts Marginalized Groups On The Sidelines

A prime example of this is web accessibility. For decades web designers have used utilitarianism as an excuse for not building accessible web solutions. Arguments around complexity, cost, and “design limitations” are in reality judgments of utility: Web designers often conclude that the utility gained by people dependent on accessible solutions is outweighed by the utility of time-, cost-, and design efficiency gained by not considering accessibility.

And accessibility is not the only example. As an example, consequentialist ethics can be used to justify underserving or outright ignoring users of inexpensive technologies with older browsers on slower networks in rural areas and countries we can’t place on a map. Talk to any front-end web developer about Internet Explorer support, and you’ll see this in action.

Different vantage points

When Maiken and Kenneth explore the ethics of placing advertisements on their website, they first need to look at their decision from the perspective of a consequentialist: Do the ads on the website maximize utility for the affected parties?

If we look at the ads in isolation, the answer is a resounding “no.” Very few people want to be exposed to ads, and those ads are often distracting, reduce performance, and “cheapen” the experience of visiting the site. If, on the other hand, we zoom out a bit, it can be argued that ads maximize utility because ads on a page pay for the content and access to it. The site owner pays the cost of content creation and hosting through ad revenues, the consumer pays for access by letting themselves be exposed to ads.

Does that mean Maiken and Kenneth have the consequentialist stamp of approval to put ads on their site? It depends.

Consequentialism’s blind spot

When we use maximizing utility as a measure for the rightness or wrongness of an act, we have to remember consequentialism has a massive blind spot: The future. Considering only immediate consequences, or only consequences within ideal use cases, will invariably lead to unintended and often problematic events further down the road. In their book, Design for Real Life, authors Eric Meyer and Sara Wachter-Boettcher provide multiple examples of this, including Facebook’s “Year In Review” feature surfacing cheerful photos of Meyer’s daughter who passed away earlier that year. Unless we take steps to ensure we think beyond the immediate consequences of our decisions, bad things may well happen just beyond the horizon. This is exactly what happened when we made advertising the primary revenue model for the web.

When ad revenue is calculated from impressions and interactions (clicks), the value being traded is attention, a finite resource granted to the site by its visitors. The more attention the visitor gives a site, the more ad revenue the site owner receives. This creates an environment where the site owner will start building content and interactions with the explicit goal of keeping the attention of their visitors and expose them to ads. In theory, this seems like a good thing. We’d all like to believe better quality content gets more attention. The reality is not as rosy.

How Utilitarianism Influenced Elections

Online ads are primarily served up by two companies: Google and Facebook. These companies share the same interest as the site owners: grabbing the attention of the visitors. To do this, social media sites and video sharing sites and search engines have created “personalized” streams where algorithms figure out what type of content an individual is engaged by and subject them to more of the same content. You can see this for yourself: Go to YouTube and watch a video of something new, like a song by Animals as Leaders, and your recommended stream will suddenly skew toward jazz metal, a musical genre you might not even have known existed just a few minutes ago. Watch more videos, and Google pegs you as “fan of jazz metal” and “likely interested in non-standard guitars.”

To make this personalization as accurate as possible, advertising services use pervasive tracking and surveillance to follow users as they travel from site to site and create models of what type of content they are most likely to spend time looking at. The same services then use their other platforms (search, social media, video/photo sharing) to expose you to more of the same, whether that be jazz metal, cute cats, or partisan politics.

This phenomenon has a name: “Filter bubble.” We were warned of these personalized echo chambers in which web users find vastly different content when making the same searches — skewed to their personal, political, and religious convictions years ago.

In short, advertising as a revenue model for the web led to user tracking, filter bubbles, fake news, and eventually worldwide political upheaval.

With this in mind, does advertising pass the consequentialist test? Does it maximize utility? No. At least not the type of predatory advertising we see today.

That doesn’t mean Maiken and Kenneth can’t have advertising on their site; it just means they have to think carefully about what type of advertising they use. That’s where the first pier of the Bridge of Ethics, the Consequentialist Principles of Web Design, comes in:

Using Consequentialism in Web Design

Consequentialist and Utilitarian ethics reminds us to consider the consequences of our actions and to measure their utility. When using consequentialism, we need to be aware of its shortcomings: It’s easy to imagine short-term consequences, much harder to see long-term consequences. And we can’t grant ourselves license to put the benefits of some users over the disadvantages of others, even when doing so maximizes utility. This is especially important when the benefits of a company or its shareholders are weighed against the disadvantages of marginalized users. Being cognizant of these issues we can draw on the best qualities of this theory:

The Consequentialist Principles Of Web Design:
  1. Prioritize the increased utility for all over maximizing utility for the majority.
  2. Provide sufficient remedies for those disadvantaged as a consequence of a decision.
  3. Expect unexpected outcomes.
  4. Favor iterative enhancements over permanent solutions.

To put these principles into practice, use a consequentialist checklist at the bottom of the article to guide decision-making processes.

When Maiken and Kenneth use these principles to evaluate advertising as a revenue model for their site, they are able to draw several conclusions:

  • Ads disadvantage visitors by adding distraction and increasing load times, To avoid this, they must keep ads to a minimum, and place them in areas of the layout that do not distract the visitor from the content.
  • Ad networks track user behavior not only on their site but on other sites. When someone visits a site, they do not have a reasonable expectation of being tracked by an ad network. For the visitor, utility is harmed by such software, in particular, because it contributes to trapping them in filter bubbles. Therefore, ad networks are not an option for this project.
  • For full transparency, visitors need to know why they are being exposed to advertising on the site and what type of relationship the site owners have to the advertisers. A short blurb explaining why there are ads on the site (i.e. “we use ads to pay for hosting costs and to give you free content”) and clear indicators any time there is a relationship between the site owners and the advertisers are required.
  • Direct marketing such as affiliate links must be marked as such. Any time the site owner financially benefits from a visitor clicking a button, they are incentivized to get the visitor to click that button. This can lead to misleading and coercive designs and content and must be avoided.

Based on this, Maiken and Kenneth realize that while they are able to use ads in an ethical way, eliminating ad networks as an option means doing direct ad sales and managing the ads on their own or hiring someone to do it for them. Either way, it adds time, complexity, and cost to the project, so they put ads on hold as they look for other less labor intensive options.

One new revenue model that pops up is using visitor computers to mine for cryptocurrencies. This brings us to the second pier of the Bridge of Ethics:

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 → 2. Deontology: The Rule Of Moral Duty

Deontological Ethics (also known as ‘Duty’ or ‘Obligation Ethics’) judges the rightness or wrongness of an action based on defined rules. Compared to consequentialism, the moral judgment of an act in deontology is based on the act itself — not its consequence. If an act was performed in obligation to the rules, it is considered a good act even if the consequence is a bad one.

Deontology In Web Design

Deontological ethics are found throughout our society and in our professional spaces. We choose not to harm others or steal their property because we have an obligation to follow rules of law and we believe others have that same obligation. We follow ethical protocols not to harass or assault our co-workers because we have an obligation to respect the freedom and security of person in all people, and we believe others have that same obligation.

A clear example of deontology in web design is web standards: There is no higher reason why we must follow web standards to create a web document, but we do so anyway because we have a duty of care; to the site owner who wants their message communicated to the visitor; to the visitor who wants the document to render properly in their browser; to the browser who wants to parse content it can understand; to the web community members who want to build new web documents without having to create separate solutions for each browser and device.

Challenges of deontology

This example also illustrates the challenge of deontology. It rests on one key assumption: You don’t merely follow the rules because they exist, you follow them because you have a duty to do so and want everyone else to feel and act on that same duty. Which raises some obvious questions:

Who makes the rules? What authority do they have to impose those rules on us? And why do we have a duty to follow them? In web design, there are no clear answers, in large part because unlike other professions web design has no unified professional leadership or authority.

Another major problem is we can’t make rules for everything, and we especially can’t make rules for things that haven’t happened yet or things that are happening for the first time.

Act as you want every other person to act in the same situation Immanuel Kant (Image source: Wikimedia Commons)

Deontological philosopher Immanuel Kant tried to resolve this issue with what’s known as Kant’s Categorical Imperative:

“Act only according to that maxim by which you can also will that it would become a universal law.”

In plain language, this translates to something like “every time you do something, do the thing every person should do in the same situation.” For those familiar with the Golden Rule, “Do to others what you want them to do to you”, this will sound familiar, though it’s not exactly the same.

According to the categorical imperative, an act is only good if it can be a universal law, so even if a company is OK with users posting abusive content on their platform that does not mean allowing such content on all platforms is justified and should, therefore, be a universal law.

Kant invokes universality and obligation to grant each of us license to make moral judgments without having to agree to a predefined set of rules. The categorical imperative tells each individual actor to turn the spotlight on themselves and ask if their act is one they’d want every other person to perform in the same or similar situations, and relies on the obligation to ensure this principle is followed. In other words, it asks us to judge our actions not just on whether we think they are good and want others to do the same, but whether we think everyone should do it.

Deontology’s Blind Spot

Back to our entrepreneurs. Maiken and Kenneth do the consequentialist test on cryptojacking using the processing power of their visitors’ computers and conclude this revenue stream maximizes utility: visitors use a small bit of their power to pay for access to content, and everybody walks away a bit richer, in knowledge or digital coins. Implementing this feature is also relatively easy: Several solutions provide a range of options, from ad-like banners where the visitor can press a button to mine coin on the site owner’s behalf to hidden scripts that run in the background without the visitor’s knowledge.

The question isn’t whether they can do it, but whether every website ought to use this technology. There is also a question whether the couple upholds their duty of care to the visitor by mining coin on their computer. That’s where the second pier of the Bridge of Ethics, the Deontological Principles of Web Design comes in:

Using Deontology In Web Design

Deontology enables us to create rules and systems to enforce those rules but falls short when new situations for which there are no rules occur or edge cases are encountered. Kant’s categorical imperative can be a partial buffer for these circumstances, but applying it is tricky and often results in using the Golden Rule instead which relies too heavily on the individual actor and their personal moral beliefs. Being cognizant of these issues we can draw on the best qualities of this theory:

The Deontological Principles of Web Design
  1. Follow existing rules, best practices, and guidelines.
  2. Use the categorical imperative as a starting point to creating new rules.
  3. When no rule exists, use the full ethical principles of web design to create new ones.
  4. Uphold the duty of care: to the client, to the user, to the information, and to the future.

To put these principles into practice use, a deontological checklist at the bottom of the article to guide decision-making processes. Using these principles, Maiken and Kenneth evaluate the ethics of cryptojacking on visitors’ computers as a revenue stream and draw some immediate conclusions:

  • This approach is transactional, trading access to content for the usage of several limited resources including electricity, internet bandwidth, and processing power. If several sites did this simultaneously, the visitor would end up with higher power and internet bills and see a significant slowdown of the performance of their computer. In other words, if everyone did it, the internet would pretty much stop working. The categorical imperative is clear here: Unless you can turn your act into a universal law, it is not ethical.
  • Even if they ignore the categorical imperative, they still have a duty of care to the visitor. Because this is a transaction, it is the duty of the site owners to clearly notify the visitor of what is happening and allow them to opt into the feature. This limits the usefulness of the feature as few people would say yes to using their processing power if they had a choice. Maiken and Kenneth could remedy this by making access contingent on opting in, effectively creating a cryptojacking paywall similar to what Salon.com is testing, but that would go against the premise of their site which is to share information with everyone. It also brings up issues around paywalls, something we’ll address later.

In their discussion, they also discover one of the key issues with deontology: The theory is appealing because we are surrounded by rules and know how to follow them. But unless these rules are defined, agreed upon, and followed and there are consequences when they are broken, deontology quickly leads us to moral relativism.

Without rules, enforced by an agreed upon authority, everyone can do anything they want. And even with rules and enforcement in place, people will bend or break them to get ahead. In other words, even if they decide cryptojacking is not ethical, some content publishers and others think it’s perfectly acceptable.

So, as the saying goes, if everyone else is doing it, why can’t they? This brings us to the third pier of the Bridge of Ethics:

3. Virtue Ethics: Aspirational Foundations

Virtue Ethics is the oldest of the ethical traditions covered in this article, and likely also the one most foreign to our way of thinking about ethics on a day-to-day basis. Where consequentialism looks at the outcomes of actions and deontology looks at the act itself, virtue ethics looks at the actors themselves; their reasons for performing the act and what they become through the act.

A Virtuous Person Is One Who Acts As Someone Who Holds These Virtues

To understand this, we first need to understand what a virtue is, a topic that supporters of virtue ethics have debated for thousands of years.

Socrates statue at the Louvre (Image source: Wikimedia Commons)

We can turn to ancient philosophy for some guidance here. Socrates argued that virtue is knowledge: the more knowledge you acquire, the more virtuous you become and the more likely you are to make the right decisions in any circumstance. Aristotle proposed a list of 18 moral and intellectual virtues including courage, temperance, truthfulness, modesty, intelligence, logic, good sense, and theoretical and practical wisdom. In the millennia since, philosophers have proposed other virtues and created other systems. In the book, Technology and the Virtues (published in 2016), philosopher Shannon Vallor proposes 12 “technomoral virtues”: Honesty, Self-Control, Humility, Justice, Courage, Empathy, Care, Civility, Flexibility, Perspective, Magnanimity, and Technomoral Wisdom. The overall principle remains the same: A virtuous person is one who acts as someone who holds a defined set of virtues.

The question facing Maiken and Kenneth, about whether other people doing something gives them license or leave to do the same, is one of virtue. To answer it they need to dig deep and consider what type of people they want to be.

Virtue Ethics In Web design

To understand virtue ethics in web design we need to answer the question “what makes a virtuous web designer?” To answer this, we first need to decide what virtues a web designer should aspire to. There is no one true answer here, but I believe there are some virtues most web designers can agree on:

  • Knowledge
    Know the craft and keep your skills current and up to date.
  • Care
    Uphold the duty of care to the client, the end-user, the content, and yourself.
  • Equity
    Be fair, and ensure every end-user can access the same content.
  • Truthfulness
    Be honest with clients, content, end-users, and yourself.
  • Courage
    Take intelligent risks, push norms and boundaries, move the craft forward.
  • Collaboration
    Share knowledge, and help lift the skills of your peers.
  • Openness
    Be transparent, and value the opinions of others and yourself.
  • Access
    Make everything you create accessible to anyone who may encounter it.
  • Resilience
    Push forward and learn new things. Own your mistakes and learn from them.

Let’s for a moment assume these are the virtues of web design. How can Maiken and Kenneth use them to make a decision? How can they act as someone who has these virtues?

Fake It ‘till You Become It

Psychologist Amy Cuddy has a famous talk about how you can “fake it till you become it” which fits well here. If they have a clear idea of how a knowledgeable, caring, truthful, courageous, collaboratory, open, accessibility-focussed, and resilient person would act in that same situation, they’ll be able to do the same thing and move themselves a bit closer to that goal of being virtuous. The reality is a bit more complex because the interpretation of what exactly constitutes knowledge or care or truth or any of the other proposed virtues will vary from person to person.

In this case, Maiken and Kenneth need to consider whether they want to be the kind of people who mine cryptocurrency on a visitor’s computer, and more broadly, whether they think that person has the virtues they aspire to. In their case the answer is ‘no’ and the earlier question, if everyone else is doing it why can’t we, answers itself.

So what would be a virtuous way of generating revenue from their website? One option Maiken and Kenneth choose to explore is selling memberships. This approach seems more egalitarian: people who have the means can pay for exclusive access, and the revenue from memberships can be used to cover the cost of limited access for everyone else. The question is if selling memberships builds the virtues the couple aspire to. That’s where the third pier of the Bridge of Ethics, the Virtuous Principles of Web Design, comes in:

Using Virtue Ethics in Web Design

Virtue ethics is the most introspective of the three moral philosophies we have looked at so far. It grants us the tools to look at ourselves as actors and recognize that with each act we perform, we not only change the outside world but also ourselves. In that way, virtue ethics compliments and resolves some of the issues raised by consequentialism and deontology.

Where consequentialism looks squarely at the external outcomes of an act and deontology looks at your reasons for performing that act, virtue ethics looks at what you become by performing that act and uses your desire to become a more skilled and knowledgeable, more successful, and overall better person as its driving force. We can draw on the best qualities of this theory to lay the third pier of our ethical bridge:

Four virtuous principles of web design:
  1. Define and share the virtues you aspire to hold and how they describe the virtuous web designer you want to be.
  2. Act as this virtuous web designer would act, i.e. act as the web designer you want to be.
  3. With every act, consider what person it turns you into.
  4. Align every act with the virtues you aspire to hold.

To put these principles into practice, use a virtual ethics checklist at the bottom of the article to guide decision-making processes.

Maiken and Kenneth want to become better people and better business people through their actions, and that extends to how they collect revenue from the site they are building. Using the virtuous principles of web design they evaluate the ethics of selling memberships as a revenue model and draw some conclusions:

  • The relevant virtues they aspire to are knowledge, care, equity, truthfulness, courage, collaboration, openness, access, and resilience. Any revenue model should help them move closer to these virtues.
  • Memberships and paid subscriptions are typically used to create paywalls where paying members get access to exclusive content. This goes against the virtues of care, openness, and access because it literally excludes non-members, keeps content closed off from the public, and restricts access to only those who can pay. To promote the virtues the couple aspires to, this means membership cannot impact access to content which takes away much of the incentive to be a member in the first place.

One possible approach Maiken and Kenneth consider is offering memberships that grant members influence rather than access; the ability to suggest new topics or even submit their own content to be published on the site. However, this can easily impact equity as the system grants those with means more influence than those without. So while it is possible to set up a membership model that passes the virtue ethics test, its return will be limited unless visitors choose to become members to support the content rather than get exclusive privileges — which is a hard bargain.

Looking At An Even Bigger Picture

Taking a step back from the question of memberships and looking at the bigger picture painted by the virtuous principles, we start to see a shift from the focus on the actor and the act to those acted upon and how they are impacted; a crucial aspect of the transaction our conversation has not yet addressed.

Consequentialism looks at outcomes divorced from the actor’s intent, deontology looks at the actor’s intent divorced from the outcome, and virtue ethics look at what the actor becomes as a result of their actions. The next question we need to ask is what about the end-user and how they are impacted. This brings us to the fourth and final pier in our ethical bridge:

4. Capability Approach: User-Centered Design

Web design is in almost every case service design: We build solutions for other people that they can use to achieve their goals. That’s why user experience design is such a big part of web design and why human-centered design is at the core of user experience and interaction design.

So, for our ethical framework for web design to be complete, the fourth and final pier must support the end-user to anchor our ethics in the human experience. For this, we turn to a modern theory that crosses the boundary between philosophy and economics called Capability Approach. The Stanford Encyclopedia of Philosophy has a comprehensive primer that includes this short introduction:

“The capability approach is a theoretical framework that entails two core normative claims: first, the claim that the freedom to achieve well-being is of primary moral importance, and second, that freedom to achieve well-being is to be understood in terms of people's capabilities, that is, their real opportunities to do and be what they have reason to value.”

Capability approach is often considered an offshoot of virtue ethics, but I feel it is different enough to be considered its own moral philosophy. What matters is not just what you do or why or how you do it, but also what future you enable the person at the other end of the transaction to build for themselves!

Capability Approach In Web design

Capability Approach gives us a tool to justify our decisions based on the long-term outcomes the end-user experiences as a result. It also provides a foundation for following established best-practices like accessibility and Resilient Web Design: If our goal is to always grant and enable capabilities in the end-user, the minimum requirement becomes the end-user having access and ability to use what we design in whatever way they can. Rather than giving everyone a bicycle, we give everyone the capability of transport by allowing them to choose the best solution. Capability approach can also be found implicitly or explicitly in legislation around the right to data portability, most notably under Europe’s General Data Protection Regulation (GDPR).

Making ethics part of our design process helps us build the world we all want to live in.

More widely, the Capability Approach in web design allows us to take a step back and consider why we do what we do. Every design decision we make carves a path our end-users follow into the future. The Capability Approach makes us think carefully about where that path leads and what happens to the people who interact with our creations when they follow us into that future. So in addition to asking what we are going to build, how we are going to build it, and why we are building it, we have to ask to what end: If we build this, what world do we build for the visitor in the process?

Evaluating Sponsorship Models, A Capability Approach Example

In their quest for an ethical revenue model for the content on their site, Maiken and Kenneth have turned their attention to the tried and true sponsorship model, already well established in print and digital media as well as events. The sponsorship model exchanges funding for presence in some form (usually a large banner, a mention in audio and video clips, or “sponsored content”). In simple terms, sponsorship differs from advertising in that a sponsor pays an agreed upon sum of money up front for exposure to the audience whereas advertising typically pays on a per-impression or per-click basis.

To evaluate the ethical implications of sponsorships as a revenue model, they turn to the capability approach and ask what capabilities are granted or enabled on the positive side or prevented or removed on the negative side by accepting sponsorships.

They consider three sponsorship models:

  1. Philanthropic sponsorship, i.e. “See a list of our sponsors/supporters on this page”
  2. Passive sponsorship, i.e. “this article brought to you by…”
  3. Active sponsorship, i.e. “And now, a word from our sponsor” aka advertorial content

The first one is the obvious preference, but it relies on companies and individuals being willing to give them money without exposure (something that rarely happens). Passive sponsorship is the most common of the three models. Here a company gets visible (or auditory) presence as a funder of the content being presented. This model works, but is only attractive to sponsors if the site has a large following and can claim to be “influential.”

Active sponsorship leaves the sponsor in charge of some content on the site. This is the more attractive option from the sponsor’s perspective and likely also where the most revenue can be collected. However, handing control of content to a sponsor has serious implications.

What Capabilities To Test For? Left: Martha Nussbaum (Image source) Right: Amartya Sen (Image source)

To analyze these three sponsorship models, we first have to define what capabilities to test for. Here capability approach suffers the same challenge faced by deontology and virtue ethics: who decides what capabilities should be in focus and how to test the success of any decision or act in terms of capabilities granted and enabled.

Amartya Sen argues there is no one true list of capabilities because such a list would be too difficult to define. Martha Nussbaum has proposed a list of 10 Central Capabilities that though not complete or unchangeable should form the baseline for judgments. The list includes:

  • Life
  • Senses
  • Imagination and Thought
  • Practical Reason
  • Control over one’s Environment (Political and Material)

Nussbaum suggests that a decision or act must be judged on whether it helps the recipient secure a minimum level of these ten capabilities.

Sen argues that when evaluating well-being, “the most important thing is to consider what people are actually able to be and do.” He illustrates this by asking us to think of a bicycle. While a bicycle is considered a transportation tool for all people, the capability of actually using a bicycle for transportation changes from person to person and context to context. Just because someone has a bicycle does not mean they have the capability of transportation. In other words, to provide the capability of transportation to a person we first have to take into consideration that person’s ability to use different transportation methods. One size rarely fits all.

Using Capability Approach In Web Design

The fourth pier of the Bridge of Ethics, the Capability Approach Principles of Web Design, focuses our attention on the end-user and their experience. The immediate value of the capability approach is its focus on the long-term outcomes of the end-user. Web designers build solutions for people, and every decision a web designer makes has a long-term impact on the people who interact with it. Thinking carefully about what capabilities each of our design decisions grant and enable, and choosing only those decisions that produce and increase the well-being of the end-user is a key component in a well-formed ethical design process. We can draw on the best qualities of this theory to lay the fourth and final pier of our ethical bridge:

The Capability Approach Principles Of Web Design
  1. Define the capabilities you want to build in users, communities, and the world.
  2. Design solutions that grant each user capabilities to (re)claim their agency.
  3. Measure success by the functionings achieved and the increased well-being of every individual end-user.
  4. With every decision, carve a path to the future you wish to live in.

To put capability approach principles into practice, use a checklist at the bottom of the article to guide decision-making processes.

Using the capability approach principles of web design, Maiken and Kenneth evaluate the ethics of various forms of sponsorships as a revenue model and draw some conclusions:

  • Passive sponsorships (“this content/site brought to you by”), can be argued to grant the visitor agency because they have enough information to know the relationship between the site owners and the brands that appear on the site. This assumes there is clear messaging stating “brought to you by” or “sponsored by” or similar.
  • The active sponsorship model (content made by the sponsors) can enable the same capabilities, though to a lesser degree, as long as this content is clearly marked as advertorial and the visitor can clearly differentiate it from other non-sponsored content.
  • Failure to properly disclose sponsorship relationships is actively harmful to the visitor as it removes their agency. This is why regulators are cracking down on in-kind sponsorships and lack of disclosure from social media influencers.
  • So-called “content marketing,” the practice of creating content to build influence and drive customers toward a specific product or brand, can be considered harmful to the visitor as the content is designed to influence and even actively coerce them.

So can Maiken and Kenneth ethically use sponsorships as their revenue model? According to the capability approach, the answer is yes as long as it’s done in a way that clearly discloses all relationships and meets the visitor’s reasonable expectation of being presented with honest and unbiased content from the site owners (in other words, active sponsorships and content marketing content are out).

Using The Ethical Principles Of Web Design In Production

At the start of this article, I introduced the image of a bridge held up by four ethical theories and explained you can travel across it in both directions. Now that we’ve covered all four piers of the bridge we are ready to look at how to use this bridge in our everyday decision making processes.

When evaluating existing solutions, it’s easiest to start on the right side and move your way back, documenting real-life consequences first, then considering what rules and best practices were used, what virtues were promoted, and what capabilities were granted or enabled. This is how we typically make decisions in our industry today, though we rarely make it past consequentialism.

Put The User First

What I propose is a literal pivot; Evaluating every new decision by crossing the bridge from the left to the right. As we saw with Maiken and Kenneth, the capability approach shifted their focus from how they can make money ethically to how their revenue models impact their audience, the visitors. This is important because all our decisions, whether they be about server infrastructure or content management systems or front-end frameworks or content strategy or revenue models or social media sharing and integration need to put the end-user first, every time.

Starting with the capability approach, we first establish what capabilities we want to grant and enable in our visitors and end-users and define the future world we build for them with our solutions. Next, virtue ethics help us consider what type of professionals we become by building those solutions. Deontology reminds us to consider what best practices we establish and what duties of care we must uphold. And finally, consequentialism helps us map out short- and long-term consequences and reminds us to think carefully about how we measure utility and whether we are excluding people with our decisions.

This method puts the end-user and their experience at the center of every decision and keeps them in focus as we evaluate what those decisions do to ourselves, our craft, and the world as a whole.

Every Design Decision Is A Decision Made On Behalf Of The End-User

So, where does this leave our friends Maiken and Kenneth? How will they monetize the content on their site? Based on the evaluations in this example, their most ethical option is a combination of philanthropic and passive sponsorship and a membership model. Opt-in cryptojacking and direct sales advertising are also possibilities, but their return on investment will likely be too low to be meaningful.

Here comes the tricky part: There’s a high likelihood you disagree with some or all of these conclusions. And that’s OK! One of the most interesting parts of ethics is apart from extreme cases, how people evaluate different decisions and acts will differ, often greatly. There is rarely one true answer to any ethical question, but ask a large enough group to evaluate the question and you’ll see a strong trend in one direction.

The question you’re most likely asking yourself now is “Doesn’t that make the whole thing pointless?” The answer is “no”, and here’s why:

The purpose of the Ethical Principles of Web Design is not to create an authoritative list of good and bad decisions for all to follow any more than the principles of UX instruct designers on the one true way to design a specific interaction. These principles are tools for us to use to facilitate careful and considerate thinking about the decisions we make. More often than not, using these principles will bring up questions that would otherwise have never been discussed, and many of them will not result in full or final answers. What they will do is remind you and everyone you interact with that every design decision is a decision made on behalf of the end-user, and every decision changes their world and builds their future in some small way.

Better Futures For Everyone

Even small and seemingly insignificant decisions can have enormous implications, and though ethics often stand in the way of immediate rapid innovation, growth, and quick revenue, they help ensure the longevity of our designs and help us carve paths to better futures for everyone.

Being mindful of what we do is essential. It’s what gives us the power to create. Making ethics part of that process helps us build the world we all want to live in. Using the Ethical Principles of Web Design, you will be better equipped to make design decisions you can stand by today and in the future; decisions that help you build the future you want to live in along side every person you impact with your designs.

The Ethical Principles Of Web Design (Checklist)

This checklist is a practical tool to be used alongside other design techniques like Design Sprints and Journey Maps. Use it, expand on it, and make it your own:

Theory Capability Approach Virtue Ethics Deontology Consequentialism Mnemonic device What world / future are you building for the end-user? What type of person do you become in the process? What norms and expectations are you establishing? What are the consequences of your actions? Principles 1. Define the capabilities you want to build in users, communities, and the world.

2. Design solutions that grant each user capabilities to (re)claim their agency.

3. Measure success by the functionings achieved and the increased well-being of every individual end-user.

4. With every decision, carve a path to the future you wish to live in. 1. Define and share the virtues you aspire to hold and how they describe the virtuous web designer you want to be.

2. Act as this virtuous web designer would act - ie act as the web designer you want to be.

3. With every act, consider what person it makes you become.

4. Align every act with the virtues you aspire to hold. 1. Follow existing rules, best practices, and guidelines.

2. Use the Categorical Imperative as a starting point to creating new rules.

3. When no rule exists, use the full ethical principles of web design to create new ones.

4. Uphold the Duty of Care: to the client, to the user, to the information, and to the future. 1. Prioritize the increased utility for all over maximizing utility for the majority (no person left behind).

2. Provide sufficient remedies for those disadvantaged as a consequence of a decision (every user matters).

3. Expect unexpected outcomes (the future is unknown).

4. Favor iterative enhancements over permanent solutions (never settle/all paths are open). Checklist 1. What capabilities does this decision grant and/or enable in the end-user?

2. Do these capabilities increase the functionings of the end-user, what they are capable, want to be capable, or should be capable to be and/or do?

3. Does this decision lead the end-user on a path to a future where their well-being is improved?

4. Does this decision grant agency to the end-user and leave them in control over their freedom and future? 1. What virtues are relevant in this decision? Knowledge, care, courage, openness, other virtues or a combination of virtues?

2. How will this decision move you closer to holding these virtues? What path are you laying down for yourself by making this decision?

3. Is this decision the same as what the virtuous web designer you want to become would make?

4. When you look back on this decision in the future, will you see it as a good and virtuous decision?

5. Are you able to communicate how this decision will bring you closer to your ideal of being a virtuous web designer to someone else? 1. Are there existing rules to be followed? Do you understand them and are they applicable in this situation?

2. If no rule exists, can you create a new universal rule everyone should follow in the same or similar situation?

3. Are you comfortable with your decision being published on the front page of a major newspaper?

4. Have you sought confirmation from peers or subject matter experts?

5. Are you upholding the Duty of Care to your client?

6. Are you upholding the Duty of Care to the end-user?

7. Are you upholding the Duty of Care to the content?

8. Are you upholding the Duty of Care to yourself? 1. Who benefits from this decision, and why?

2. Who is disadvantaged by this decision, and why?

3. How is utility/disadvantage from this decision measured?

4. Who decides what utility/disadvantage ratio is acceptable?

5. How are disadvantages created by this decision addressed and reduced / remedied?

6. How flexible is this decision? Is there sufficient room for course corrections?

7. Who and what are the outliers we have not considered?

8. Assuming this decision has unintended consequences, what are they and how do we deal with them? Where To Start?

When I talk to people about ethics and the bridge I’ve described in this article, I often get responses such as “I see why it matters, but I don’t think this will fit into my/our process.” This is a fair critique. Decision making based on an ethical framework is not something we are used to doing, in web design or anywhere else in our lives. For the most part, ethics is something subconscious and unspoken; we “just know” or have a “gut feeling” whether something is right or wrong.

Formalizing a method for testing the ethics of a decision is a skill like any other, and it requires practice to become natural. The good news is you can lean on your own built-in ethical barometer (that “gut feeling” about the rightness or wrongness of an act) and use the simplified version of the bridge to get started. To apply the Ethical Principles of Web Design in your practice today, start with the mnemonic devices for each theory:

  1. What world are you building for the end-user? What capabilities are you granting or enabling?
  2. What type of person do you become in the process?
  3. What norms and expectations are you establishing? Are you upholding your duties of care?
  4. What are the consequences of your decision, and do they improve the common good for those affected?

As you’ve learned, these principles are not about creating a dogmatic list of right and wrong, but rather a toolkit to help you explore questions around the ethics of your decisions.

To help you explore each of these questions in more detail, you can use the checklist provided above.

Once asking these questions becomes second nature, dive deeper into the individual theories that make up the piers of the bridge and establish a deeper understanding of what ethics and moral philosophy are, and why it plays a role in all aspects of our lives.

To get you started, I’ve assembled a list of resources below. Some of the links are from the article, some are added as further reading.

In the end, ethics is a practice we all need to work on every day. To borrow a quote from Robert M. Pirsig:

“The place to improve the world is first in one's own heart and head and hands, and then work outward from there.” Resources Capability Approach Virtue Ethics Deontology (Duty Ethics) Consequentialist Ethics Related Philosophy Other Related Materials (md, ra, hj, il)
Categories: Web Design

The Current State Of Email Marketing Programming: What Can And Can’t Be Used

Smashing Magazine - Thu, 03/22/2018 - 02:30

Many people want to create the best email campaigns possible, and this goal can be realized by following best practices for email design and coding and by implementing advanced techniques correctly. This comprehensive guide, for novices and pros alike, delves deep into the nitty gritty of email marketing.

Here’s what you’ll learn:

  • best practices for email design, from creating a theme to designing the footer;
  • how to add images and incorporate rich media (GIFs, cinemagraphs, video) in your emails;
  • how to design responsive emails for a better user experience;
  • email client support for responsive mobile emails;
  • finally, advanced techniques in email design.
Introduction

Emails have transformed from being an ordinary text-based personal communication tool into a future-proof marketing channel. We have moved into a world of visually attractive HTML emails that have the feel of microsites in the inbox.

Getting acquainted with the best practices of email coding is, therefore, imperative if you want to avoid a broken user experience and instead improve user engagement. Moreover, as the digital world becomes more mobile, creating responsive emails is the need of the hour.

In this article, we shall delve deeper into best practices to follow for all email clients, as well as advanced techniques you can include for email clients that support interactive elements.

Let’s start with the basic structure of an email.

“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 → Basic Email Structure

As Leonardo da Vinci said, ”Simplicity is the ultimate sophistication.” Accordingly, keep the design of your email simple.

Check out the email design below by Charity: Water. Simple yet engaging.

View large version

Developers have been coding emails using <table> layouts for a long time now. So, it is recommended that you place your email elements in a grid-based layout, rather than arbitrarily placed. Moreover, any element that might overlap needs to be added to a different layer.

The email shown above by Charity: Water looks like this when exported to a tabular layout:

View large version

Email design is made up of different subelements. Let’s explore them now.

1. Email Theme

The logo is not the only element that reflects your brand’s personality. The overall theme of your email, including the fonts, color scheme and imagery, should be in sync with branding guidelines.

2. Width And Height Of Email Template

Because your subscribers use diverse email clients and devices, your email should be appropriately visible in the preview pane of all email clients. Keep in mind that the email will be displayed according to the display pane of the email service provider or client. Only certain email clients, such as Thunderbird, Apple Mail and native mobile email clients, will display email at full width.

For other email clients, the display boxes have variable sizes. Many service providers, such as MailChimp, go over the basics of HTML email, by recommending, for example, 600 to 800 pixels as a width, so that the full email gets displayed. Remember, that most subscribers never use the horizontal scroll bar in an email.

The height of your email template should usually be long enough to accommodate your copy within two scroll lengths. You can certainly have a longer email template if you have to convey a huge amount of information. However, if your email template gets too long, it might become boring for subscribers, who will be less likely to scroll to the end to check out all of the offers and promotions included.

The height of the preview pane of most email clients (which contains content commonly referred to as “above the fold”) is generally between 300 and 500 pixels. Make the best use of this space, so that the content included above the fold entices the subscriber to scroll down.

Every email developer knows that if an email’s file size exceeds 102 KB, Gmail’s app will clip the email, and they will not be able to track metrics.

Check out the screenshot below to see what an email looks like in Gmail when it is clipped:

View large version

To avoid Gmail’s clip, make sure your email does not have unnecessary code and is not over-formatted. Go for a minimalist email design, without any shortened URLs. Note that images will not be embedded in the email and, so, will not increase the file’s size. That being said, removing unnecessary images will help to reduce the email size.

For marketers who use predesigned templates, the height and width will already be taken care of. If you want to use your own design, consider the ideal width and height of an email template.

3. Body Of Email

Emails usually begin with a hero image at the top, followed by the main copy, a call to action and then the footer.

Because most people read on screens positioned about 2 to 3 feet away, your h1 title should be around 16 pixels; if your title is short, it could even go up to 20 pixels. A good idea would be to render the h1 title as text, along with an attractive hero image.

Your descriptive text should not be smaller than 12 pixels. It should be easily readable across all email clients and devices. Moreover, the alignment of paragraphs and paragraph size also play an important role.

4. Call To Action

The primary objective of email marketing is to persuade customers to take action. To do that, your call to action (CTA) should have engaging, actionable verbs. Use convincing and actionable text, like “Start the free trial,” rather than drab phrases like “Click here.”

An interesting study by ContentVerve, “10 Call-to-Action Case Studies With Takeaways and Examples From Real Button Tests”,” shows that use of the first-person perspective in CTAs increase clicks by 90%, regardless of the product. For example, “Get my free copy” converts better than “Get your free copy.”

Create a sense of urgency in CTAs and get higher click-through rates by adding the word “now.”

View large version

Campaign Monitor, in one of its guides, “10 Tips to Optimize Your Calls to Action,” emphasizes that a CTA button should always contrast strongly with the background color, so that it doesn’t blend in and that it grabs the subscriber’s attention. Based on your target audience, your industry and the message to be conveyed, including CTAs at regular intervals can increase email conversions and the desired subscriber action. Its height should be at least 30 pixels, and it should be easily tappable with a thumb on mobile devices.

Check out the email below from Asana. It places a CTA strategically above the first fold and also follows the CTA best practices discussed above.

Email by Asana strategically places CTA above the first fold. (View large version) 5. Images And Interactive Elements

If you are putting images or rich media in your email, add relevant alternative (alt) text, so that the purpose of the email is preserved even when the visuals are blocked by the email client. This is also greatly helpful with accessibility, because screen readers will be able to read the alternative text and convey your message.

Most email marketers tend to send emails consisting of a single image, which is first of many common HTML mistakes compiled by MailChimp. It recommends a text-to-image ratio of 80 to 20, to make sure that emails do not get trapped in spam filters. According to a recent study by MailChimp, 200 words per image yield a good click-through rate.

Using linked images in your email ensures an optimum file size. Load images from an external server using <img> tags.

The main advantage of this technique is that you can change images even after sending the email. It makes the email light and reduces the time taken to send the email. The disadvantage is that subscribers will have to download the images from the external server, which will incur download costs for those on metered connections, and the images might also get blocked by some email services.

Rich media elements, such as GIFs, cinemagraphs and video, are becoming popular in email these days.

You can add a GIF or cinemagraph in an email simply by uploading the file to the server that stores your images. Then, copy the URL and use the following HTML:

<img src="/wp-content/uploads/thefiletobeinserted.gif">

Test the email to make sure that the GIF works properly.

Embedding video is a very adaptable technique of web development, but unfortunately, it’s not supported in email. Therefore, opt for HTML5 video.

To add a video in email, use the code below:

<video width="400" height="200" controls poster="http://www.art.com/images/blog_images/Imagefiles/2017/html5_video/valentinesday.jpg"><br/><source src="http://www.videofile.com/htmlfiles/movie-14thfeb.mp4" type="video/mp4"><br/><!-- fallback 1 --><br/><a href="http://www.xyz.com" ><br/><img height="200" src=" http://www.art.com/pictures/important/Imagefiles/2017/html5_video/valentinesday.jpg " width="400" /><br/></a><br/></video><br/><br/><br/>

HTML5 primarily supports the MP4, OGG and WebM video formats.

Pro tip: Apple supports the MP4 video format in its email clients and browsers.

Some points to remember:

  • Make sure that the server configuration you use can output the right MIME type, so that the email client identifies the correct video format when retrieving the video.

  • If you are using an Apache web server, add this entry to the .htaccess file: Add Type video/mp4.mp4 m4v.

6. Number Of Email Folds

Your email should have just two folds, as mentioned earlier. The first fold should capture your brand and include the h1 title with a relevant CTA. If your email template exceeds two scrolls, then the third scroll should cross-sell your products. The idea is to change up the content and keep subscribers hooked by providing interesting information.

7. Footer

The footer is the most overlooked part of any email. However, it probably has information that subscribers are looking for, such as the company address, social sharing buttons and contact details. In order for your email to be CAN-SPAM compliant, the footer should have some additional elements.

An “Unsubscribe” link should allow subscribers to opt out of your mailing list easily and will reduce spam complaints.

Your contact details should link back to your company website and should include your postal and email address.

Additionally, you can have ancillary links, such as “Forward to a friend” and “View in Browser.”

As stated in “The Best Practices of Footer Design” by Bee, the fine print of your email should have the following sections:

  • Explanation of why the recipient got this email
    Your subscribers have probably subscribed to numerous mailing lists. Subtly remind recipients of the reason they received the email, to maintain your reputation as an emailer and to minimize spam complaints.
  • Copyright
    Include the copyright mark, along with the current year and your business name.
  • Privacy policy
    Link to your privacy policy, because subscribers should know where that information is stored. This is critical for e-commerce retailers.
  • Terms of use
    If you are sending out a promotional email highlighting discount offers, share the terms of use that govern the deals.
Designing The Footer

Cramming information into the footer sounds tempting, but you should determine the most important information for your business and restrict the footer to the minimum. Stuffing it with too much information could lead readers to dismiss it entirely because they will not be able to figure out which links to click.

Check out the footer below by Cotton on Body. Although it is well organized, it could be overwhelming for the subscriber who is scanning the email.

View large version

Have a look at the footer below by Alice and Olivia. It is simple, and it maintains a visual hierarchy according to the actions they want subscribers to take.

View large version

The footer by HSN below is clean and makes good use of padding and white space. It is not overwhelming, yet it conveys important information that readers might be looking for.

View large version Mobile Responsive Emails

Most subscribers will check email on their phone. Owing to this trend, your emails ought to be responsive. Responsive design includes several elements, such as media queries, fluid grids and fluid images, so that users can view the email as intended, regardless of screen size or device. The basics of responsive email design include the table element, easily stackable sections and full-width CTAs.

If your subscriber list consists of many mobile users, then avoid overlapping layouts. Hide non-primary sections, such as navigation and email advertisements, to cater to mobile subscribers. Mobile-specific email elements such as a navigation menu and image sliders can also be used.

Responsive email design is supported in these email clients:

  • iOS Mail app
  • Windows Phone 7.5
  • Android 4.x Email (OEM) app
  • BlackBerry Z10
  • BlackBerry OS7
  • iPhone Gmail app

The following email clients do not support responsive email:

  • Android Yahoo Mail app
  • iPhone Yahoo Mail app
  • BlackBerry OS 5
  • Windows Phone 7
  • iPhone Mailbox app
  • Windows Phone 8
  • Android Gmail app
  • Windows Mobile 6.1

Responsive design enables you to do the following:

  • change hierarchy,
  • modify navigation,
  • enlarge fonts,
  • change layout,
  • scale images,
  • add padding,
  • change or hide content.
Designing Responsive Email

To make their emails responsive, developers use a media query that is commonly referred to as @media. It is a special set of CSS styles, included in the header, that work as conditional statements or dynamic rules.

The point of media queries is to identify the screen size of the device being used and to execute various rules according to that screen size. The challenge is that media queries do not work in all email clients and might need detailed planning and testing compared to other design techniques.

Have a look at the media query below:

@media only screen and (min-width:479px) and (max-width:701px) { .em_main_table { width: 100% !important; } .em_hide { display: none !important; } }

When this email is accessed on a device whose screen is between 479 and 701 pixels wide, the email’s width will be 100%, according to the width: 100% !important; attribute. The !important function forces this attribute in email clients such as Gmail, where it might be ignored.

The styles in the CSS rule block should specify the container or element type that the styles will dictate. Assign these rules in the HTML if you want them to work.

Here is the CSS:

td[class="body-header"]{ font-size: 18px !important; }

And here is the HTML:

<td align="left" class="body-header">

It is important that the element (td) and the class (body-header) added in the CSS and HTML match each other.

Advanced Techniques

With the advent of advanced email clients, such as Apple Mail, which is based on Webkit, email developers can even play around with keyframe animation, interactive elements such as carousels, and live feeds.

Conditional coding for different email clients (such as for Outlook and for Samsung and Apple devices) has also become possible.

View large version Wrapping Up

If you follow these simple tips, you will surely be able to create awesome email marketing campaigns that convert, whether you are a novice or pro at email programming. In the end, aim to create a good user experience and make subscribers look forward to your emails. Happy emailing!

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

8 Best WordPress Themes for Weddings & Engagements

Are you looking for an easy way to give your wedding guests a central hub where they can easily find everything they need to know about your big day?...

The post 8 Best WordPress Themes for Weddings & Engagements appeared first on Onextrapixel.

Categories: Web Design

Lazy Loading JavaScript Modules With ConditionerJS

Smashing Magazine - Wed, 03/21/2018 - 06:00

Linking JavaScript functionality to the DOM can be a repetitive and tedious task. You add a class to an element, find all the elements on the page, and attach the matching JavaScript functionality to the element. Conditioner is here to not only take this work of your hands but supercharge it as well!

In this article, we’ll look at the JavaScript initialization logic that is often used to link UI components to a webpage. Step-by-step we’ll improve this logic, and finally, we’ll make a 1 Kilobyte jump to replacing it with Conditioner. Then we’ll explore some practical examples and code snippets and see how Conditioner can help make our websites more flexible and user-oriented.

Conditioner And Progressive Enhancement Sitting In A Tree

Before we proceed, I need to get one thing across:

Conditioner is not a framework for building web apps.

Instead, it’s aimed at websites. The distinction between websites and web apps is useful for the continuation of this story. Let me explain how I view the overall difference between the two.

Websites are mostly created from a content viewpoint; they are there to present content to the user. The HTML is written to semantically describe the content. CSS is added to nicely present the content across multiple viewports. The last and third act is to carefully layer JavaScript on top to add that extra zing to the user experience. Think of a date picker, navigation, scroll animations, or carousels (pardon my French).

“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 →

Examples of content-oriented websites are for instance: Wikipedia, Smashing Magazine, your local municipality website, newspapers, and webshops. Web apps are often found in the utility area, think of web-based email clients and online maps. While also presenting content, the focus of web apps is often more on interacting with content than presenting content. There’s a huge grey area between the two, but this contrast will help us decide when Conditioner might be effective and when we should steer clear.

As stated earlier, Conditioner is all about websites, and it’s specifically built to deal with that third act:

Enhancing the presentation layer with JavaScript functionality to offer an improved user experience. The Troublesome Third Act

The third act is about enhancing the user experience with that zingy JavaScript layer.

Judging from experience and what I’ve seen online, JavaScript functionality is often added to websites like this:

  1. A class is added to an HTML element.
  2. The querySelectorAll method is used to get all elements assigned the class.
  3. A for-loop traverses the NodeList returned in step 2.
  4. A JavaScript function is called for each item in the list.

Let’s quickly put this workflow in code by adding autocomplete functionality to an input field. We’ll create a file called autocomplete.js and add it to the page using a <script> tag.

function createAutocomplete(element) { // our autocomplete logic // ... } <input type="text" class="autocomplete"/> <script src="autocomplete.js"></script> <script> var inputs = document.querySelectorAll('.autocomplete'); for (var i = 0; i < inputs.length; i++) { createAutocomplete(inputs[i]); } </script>

Go to demo →

That’s our starting point.

Suppose we’re now told to add another functionality to the page, say a date picker, it’s initialization will most likely follow the same pattern. Now we’ve got two for-loops. Add another functionality, and you’ve got three, and so on and so on. Not the best.

While this works and keeps you off the street, it creates a host of problems. We’ll have to add a loop to our initialization script for each functionality we add. For each loop we add, the initialization script gets linked ever tighter to the document structure of our website. Often the initialization script will be loaded on each page. Meaning all the querySelectorAll calls for all the different functionalities will be run on each and every page whether functionality is defined on the page or not.

For me, this setup never felt quite right. It always started out “okay,” but then it would slowly grow to a long list of repetitive for-loops. Depending on the project it might contain some conditional logic here and there to determine if something loads on a certain viewport or not.

if (window.innerWidth <= 480) { // small viewport for-loops here }

Eventually, my initialization script would always grow out of control and turn into a giant pile of spaghetti code that I would not wish on anyone.

Something needed to be done.

Soul Searching

I am a huge proponent of carefully separating the three web dev layers HTML, CSS, and JavaScript. HTML shouldn’t have a rigid relationship with JavaScript, so no use of inline onclick attributes. The same goes for CSS, so no inline style attributes. Adding classes to HTML elements and then later searching for them in my beloved for-loops followed that philosophy nicely.

That stack of spaghetti loops though, I wanted to get rid them so badly.

I remember stumbling upon an article about using data attributes instead of classes, and how those could be used to link up JavaScript functionality (I’m not sure it was this article, but it seems to be from right timeframe). I didn’t like it, misunderstood it, and my initial thought was that this was just covering up for onclick, this mixed HTML and JavaScript, no way I was going to be lured to the dark side, I don’t want anything to do with it. Close tab.

Some weeks later I would return to this and found that linking JavaScript functionality using data attributes was still in line with having separate layers for HTML and JavaScript. As it turned out, the author of the article handed me a solution to my ever-growing initialization problem.

We’ll quickly update our script to use data attributes instead of classes.

<input type="text" data-module="autocomplete"> <script src="autocomplete.js"></script> <script> var inputs = document.querySelectorAll('[data-module=autocomplete]'); for (var i = 0; i < inputs.length; i++) { createAutocomplete(inputs[i]); } </script>

Go to demo →

Done!

But hang on, this is nearly the same setup; we’ve only replaced .autocomplete with [data-module=autocomplete]. How’s that any better? It’s not, you’re right. If we add an additional functionality to the page, we still have to duplicate our for-loop — blast! Don’t be sad though as this is the stepping stone to our killer for-loop.

Watch what happens when we make a couple of adjustments.

<input type="text" data-module="createAutocomplete"> <script src="autocomplete.js"></script> <script> var elements = document.querySelectorAll('[data-module]'); for (var i = 0; i < elements.length; i++) { var name = elements[i].getAttribute('data-module'); var factory = window[name]; factory(elements[i]); } </script>

Go to demo →

Now we can load any functionality with a single for-loop.

  1. Find all elements on the page with a data-module attribute;
  2. Loop over the node list;
  3. Get the name of the module from the data-module attribute;
  4. Store a reference to the JavaScript function in factory;
  5. Call the factory JavaScript function and pass the element.

Since we’ve now made the name of the module dynamic, we no longer have to add any additional initialization loops to our script. This is all we need to link any JavaScript functionality to an HTML element.

This basic setup has some other advantages as well:

  • The init script no longer needs to know what it loads; it just needs to be very good at this one little trick.
  • There’s now a convention for linking functionality to the DOM; this makes it very easy to tell which parts of the HTML will be enhanced with JavaScript.
  • The init script does not search for modules that are not there, i.e. no wasted DOM searches.
  • The init script is done. No more adjustments are needed. When we add functionality to the page, it will automatically be found and will simply work.

Wonderful!

So What About This Thing Called Conditioner?

We finally have our single loop, our one loop to rule all other loops, our king of loops, our hyper-loop. Ehm. Okay. We’ll just have to conclude that our is a loop of high quality and is so flexible that it can be re-used in each project (there’s not really anything project specific about it). That does not immediately make it library-worthy, it’s still quite a basic loop. However, we’ll find that our loop will require some additional trickery to really cover all our use-cases.

Let’s explore.

With the one loop, we are now loading our functionality automatically.

  1. We assign a data-module attribute to an element.
  2. We add a <script> tag to the page referencing our functionality.
  3. The loop matches the right functionality to each element.
  4. Boom!

Let’s take a look at what we need to add to our loop to make it a bit more flexible and re-usable. Because as it is now, while amazing, we’re going to run into trouble.

  • It would be handy if we moved the global functions to isolated modules. This prevents pollution of the global scope. Makes our modules more portable to other projects. And we’ll no longer have to add our <script> tags manually. Fewer things to add to the page, fewer things to maintain.
  • When using our portable modules across multiple projects (and/or pages) we’ll probably encounter a situation where we need to pass configuration options to a module. Think API keys, labels, animation speeds. That’s a bit difficult at the moment as we can’t access the for-loop.
  • With the ever-growing diversity of devices out there we will eventually encounter a situation where we only want to load a module in a certain context. For instance, a menu that needs to be collapsed on small viewports. We don’t want to add if-statements to our loop. It’s beautiful as it is, we will not add if statements to our for-loop. Never.

That’s where Conditioner can help out. It encompasses all above functionality. On top of that, it exposes a plugin API so we can configure and expand Conditioner to exactly fit our project setup.

Let’s make that 1 Kilobyte jump and replace our initialization loop with Conditioner.

Switching To Conditioner

We can get the Conditioner library from the GitHub repository, npm or from unpkg. For the rest of the article, we’ll assume the Conditioner script file has been added to the page.

The fastest way is to add the unpkg version.

<script src="https://unpkg.com/conditioner-core/conditioner-core.js"></script>

With Conditioner added to the page lets take a moment of silence and say farewell to our killer for-loop.

Conditioners default behavior is exactly the same as our now departed for-loop. It’ll search for elements with the data-module attribute and link them to globally scoped JavaScript functions.

We can start this process by calling the conditioner hydrate method.

<input type="text" data-module="createAutocomplete"/> <script src="autocomplete.js"></script> <script> conditioner.hydrate(document.documentElement); </script>

Go to demo →

Note that we pass the documentElement to the hydrate method. This tells Conditioner to search the subtree of the <html> element for elements with the data-module attribute.

It basically does this:

document.documentElement.querySelectorAll('[data-module]');

Okay, great! We’re set to take it to the next level. Let’s try to replace our globally scoped JavaScript functions with modules. Modules are reusable pieces of JavaScript that expose certain functionality for use in your scripts.

Moving From Global Functions To Modules

In this article, our modules will follow the new ES Module standard, but the examples will also work with modules based on the Universal Module Definition or UMD.

Step one is turning the createAutocomplete function into a module. Let’s create a file called autocomplete.js. We’ll add a single function to this file and make it the default export.

export default function(element) { // autocomplete logic // ... }

It’s the same as our original function, only prepended with export default.

For the other code snippets, we’ll switch from our classic function to arrow functions.

export default element => { // autocomplete logic // ... }

We can now import our autocomplete.js module and use the exported function like this:

import('./autocomplete.js').then(module => { // the autocomplete function is located in module.default });

Note that this only works in browsers that support Dynamic import(). At the time of this writing that would be Chrome 63 and Safari 11.

Okay, so we now know how to create and import modules, our next step is to tell Conditioner to do the same.

We update the data-module attribute to ./autocomplete.js so it matches our module file name and relative path.

Remember: The import() method requires a path relative to the current module. If we don’t prepend the autocomplete.js filename with ./ the browser won’t be able to find the module.

Conditioner is still busy searching for functions on the global scope. Let’s tell it to dynamically load ES Modules instead. We can do this by overriding the moduleImport action.

We also need to tell it where to find the constructor function (module.default) on the imported module. We can point Conditioner in the right direction by overriding the moduleGetConstructor action.

<input type="text" data-module="./autocomplete.js"/> <script> conditioner.addPlugin({ // fetch module with dynamic import moduleImport: (name) => import(name), // get the module constructor moduleGetConstructor: (module) => module.default }); conditioner.hydrate(document.documentElement); </script>

Go to demo →

Done!

Conditioner will now automatically lazy load ./autocomplete.js, and once received, it will call the module.default function and pass the element as a parameter.

Defining our autocomplete as ./autocomplete.js is very verbose. It’s difficult to read, and when adding multiple modules on the page, it quickly becomes tedious to write and error prone.

This can be remedied by overriding the moduleSetName action. Conditioner views the data-module value as an alias and will only use the value returned by moduleSetName as the actual module name. Let’s automatically add the js extension and relative path prefix to make our lives a bit easier.

<input type="text" data-module="autocomplete"/> conditioner.addPlugin({ // converts module aliases to paths moduleSetName: (name) => `./${ name }.js` });

Go to demo →

Now we can set data-module to autocomplete instead of ./autocomplete.js, much better.

That’s it! We’re done! We’ve setup Conditioner to load ES Modules. Adding modules to a page is now as easy as creating a module file and adding a data-module attribute.

The plugin architecture makes Conditioner super flexible. Because of this flexibility, it can be modified for use with a wide range of module loaders and bundlers. There’s bootstrap projects available for Webpack, Browserify and RequireJS.

Please note that Conditioner does not handle module bundling. You’ll have to configure your bundler to find the right balance between serving a bundled file containing all modules or a separate file for each module. I usually cherry pick tiny modules and core UI modules (like navigation) and serve them in a bundled file while conditionally loading all scripts further down the page.

Alright, module loading — check! It’s now time to figure out how to pass configuration options to our modules. We can’t access our loop; also we don’t really want to, so we need to figure out how to pass parameters to the constructor functions of our modules.

Passing Configuration Options To Our Modules

I might have bent the truth a little bit. Conditioner has no out-of-the-box solution for passing options to modules. There I said it. To keep Conditioner as tiny as possible I decided to strip it and make it available through the plugin API. We’ll explore some other options of passing variables to modules and then use the plugin API to set up an automatic solution.

The easiest and at the same time most banal way to create options that our modules can access is to define options on the global window scope.

window.autocompleteSource = './api/query'; export default (element) => { console.log(window.autocompleteSource); // will log './api/query' // autocomplete logic // ... }

Don’t do this.

It’s better to simply add additional data attributes.

<input type="text" data-module="autocomplete" data-source="./api/query"/>

These attributes can then be accessed inside our module by accessing the element dataset which returns a DOMStringMap of all data attributes.

export default (element) => { console.log(element.dataset.source); // will log './api/query' // autocomplete logic // ... }

This could result in a bit of repetition as we’ll be accessing element.dataset in each module. If repetition is not your thing, read on, we’ll fix it right away.

We can automate this by extracting the dataset and injecting it as an options parameter when mounting the module. Let’s override the moduleSetConstructorArguments action.

conditioner.addPlugin({ // the name of the module and the element it's being mounted to moduleSetConstructorArguments: (name, element) => ([ element, element.dataset ]) });

The moduleSetConstructorArguments action returns an array of parameters which will automatically be passed to the module constructor.

export default (element, options) => { console.log(options.source); // will log './api/query' // autocomplete logic // ... }

We’ve only eliminated the dataset call, i.e. seven characters. Not the biggest improvement, but we’ve opened the door to take this a bit further.

Suppose we have multiple autocomplete modules on the page, and each and every single one of them requires the same API key. It would be handy if that API key was supplied automagically instead of having to add it as a data attribute on each element.

We can improve our developer lives by adding a page level configuration object.

const pageOptions = { // the module alias autocomplete: { key: 'abc123' // api key } } conditioner.addPlugin({ // the name of the module and the element it's being mounted to moduleSetConstructorArguments: (name, element) => ([ element, // merge the default page options with the options set on the element it self Object.assign({}, pageOptions[element.dataset.module], element.dataset ) ]) });

Go to demo →

As our pageOptions variable has been defined with const it’ll be block-scoped, which means it won’t pollute the global scope. Nice.

Using Object.assign we merge an empty object with both the pageOptions for this module and the dataset DOMStringMap found on the element. This will result in an options object containing both the source property and the key property. Should one of the autocomplete elements on the page have a data-key attribute, it will override the pageOptions default key for that element.

const ourOptions = Object.assign( {}, { key: 'abc123' }, { source: './api/query' } ); console.log(ourOptions); // output: { key: 'abc123', source: './api/query' }

That’s some top-notch developer convenience right there.

By having added this tiny plugin, we can automatically pass options to our modules. This makes our modules more flexible and therefore re-usable over multiple projects. We can still choose to opt-out and use dataset or globally scope our configuration variables (no, don’t), whatever fits best.

Our next challenge is the conditional loading of modules. It’s actually the reason why Conditioner is named Conditioner. Welcome to the inner circle!

Conditionally Loading Modules Based On User Context

Back in 2005, desktop computers were all the rage, everyone had one, and everyone browsed the web with it. Screen resolutions ranged from big to bigger. And while users could scale down their browser windows, we looked the other way and basked in the glory of our beautiful fixed-width sites.

I’ve rendered an artist impression of the 2005 viewport:

The 2005 viewport in its full glory, 1024 pixels wide, and 768 pixels high. Wonderful.

Today, a little over ten years later, there’s more people browsing the web on mobile than on desktop, resulting in lots of different viewports.

I’ve applied this knowledge to our artist impression below.

More viewports than you can shake a stick at.

Holy smokes! That’s a lot of viewports.

Today, someone might visit your site on a small mobile device connected to a crazy fast WiFi hotspot, while another user might access your site using a desktop computer on a slow tethered connection. Yes, I switched up the connection speeds — reality is unpredictable.

And to think we were worried about users resizing their browser window. Hah!

Note that those million viewports are not set in stone. A user might load a website in portrait orientation and then rotate the device, (or, resize the browser window), all without reloading the page. Our websites should be able to handle this and load or unload functionality accordingly.

Someone on a tiny device should not receive the same JavaScript package as someone on a desktop device. That seems hardly fair; it’ll most likely result in a sub-optimal user experience on both the tiny mobile device and the good ol’ desktop device.

With Conditioner in place, let’s configure it as a gatekeeper and have it load modules based on the current user context. The user context contains information about the environment in which the user is interacting with your functionality. Some examples of environment variables influencing context are viewport size, time of day, location, and battery level. The user can also supply you with context hints, for instance, a preference for reduced motion. How a user behaves on your platform will also tell you something about the context she might be in, is this a recurring visit, how long is the current user session?

The better we’re able to measure these environment variables the better we can enhance our interface to be appropriate for the context the user is in.

We’ll need an attribute to describe our modules context requirements so Conditioner can determine the right moment for the module to load and to unload. We’ll call this attribute data-context. It’s pretty straightforward.

Let’s leave our lovely autocomplete module behind and shift focus to a new module. Our new section-toggle module will be used to hide the main navigation behind a toggle button on small viewports.

Since it should be possible for our section-toggle to be unloaded, the default function returns another function. Conditioner will call this function when it unloads the module.

export default (element) => { // sectionToggle logic // ... return () => { // sectionToggle unload logic // ... } }

We don’t need the toggle behavior on big viewports as those have plenty of space for our menu (it’s a tiny menu). We only want to collapse our menu on viewports more narrow than 30em (this translates to 480px).

Let’s setup the HTML.

<nav> <h1 data-module="sectionToggle" data-context="@media (max-width:30em)"> Navigation </h1> <ul> <li><a href="/home">home</a></li> <li><a href="/about">about</a></li> <li><a href="/contact">contact</a></li> </ul> </nav>

Go to demo →

The data-context attribute will trigger Conditioner to automatically load a context monitor observing the media query (max-width:30em). When the user context matches this media query, it will load the module; when it does not, or no longer does, it will unload the module.

Monitoring happens based on events. This means that after the page has loaded, should the user resize the viewport or rotate the device, the user context is re-evaluated and the module is loaded or unloaded based on the new observations.

You can view monitoring as feature detection. Where feature detection is about an on/off situation, the browser either supports WebGL, or it doesn’t. Context monitoring is a continuous process, the initial state is observed at page load, but monitoring continues after. While the user is navigating the page, the context is monitored, and observations can influence page state in real-time.

This nonstop monitoring is important as it allows us to adapt to context changes immediately (without page reload) and optimizes our JavaScript layer to fit each new user context like a glove.

The media query monitor is the only monitor that is available by default. Adding your own custom monitors is possible using the plugin API. Let’s add a visible monitor which we’ll use to determine if an element is visible to the user (scrolled into view). To do this, we’ll use the brand new IntersectionObserver API.

conditioner.addPlugin({ // the monitor hook expects a configuration object monitor: { // the name of our monitor with the '@' name: 'visible', // the create method will return our monitor API create: (context, element) => ({ // current match state matches: false, // called by conditioner to start listening for changes addListener (change) { new IntersectionObserver(entries => { // update the matches state this.matches = entries.pop().isIntersecting == context; // inform Conditioner of the state change change(); }).observe(element); } }) } });

We now have a visible monitor at our disposal.

Let’s use this monitor to only load images when they are scrolled in to view.

Our base image HTML will be a link to the image. When JavaScript fails to load the links will still work, and the contents of the link will describe the image. This is progressive enhancement at work.

<a href="cat-nom.jpg" data-module="lazyImage" data-context="@visible"> A red cat eating a yellow bird </a>

Go to demo →

The lazyImage module will extract the link text, create an image element, and set the link text to the alt text of the image.

export default (element) => { // store original link text const text = element.textContent; // replace element text with image const image = new Image(); image.src = element.href; image.setAttribute('alt', text); element.replaceChild(image, element.firstChild); return () => { // restore original element state element.innerHTML = text } }

When the anchor is scrolled into view, the link text is replaced with an img tag.

Because we’ve returned an unload function the image will be removed when the element scrolls out of view. This is most likely not what we desire.

We can remedy this behavior by adding the was operator. It will tell Conditioner to retain the first matched state.

<a href="cat-nom.jpg" data-module="lazyImage" data-context="was @visible"> A red cat eating a yellow bird </a>

There are three other operators at our disposal.

The not operator lets us invert a monitor result. Instead of writing @visible false we can write not @visible which makes for a more natural and relaxed reading experience.

Last but not least, we can use the or and and operators to string monitors together and form complex context requirements. Using and combined with or we can do lazy image loading on small viewports and load all images at once on big viewports.

<a href="cat-nom.jpg" data-module="lazyImage" data-context="was @visible and @media (max-width:30em) or @media (min-width:30em)"> A red cat eating a yellow bird </a>

We’ve looked at the @media monitor and have added our custom @visible monitor. There are lots of other contexts to measure and custom monitors to build:

  • Tap into the Geolocation API and monitor the location of the user @location (near: 51.4, 5.4) to maybe load different scripts when a user is near a certain location.
  • Imagine a @time monitor, which would make it possible to enhance a page dynamically based on the time of day @time (after 20:00).
  • Use the Device Light API to determine the light level @lightlevel (max-lumen: 50) at the location of the user. Which, combined with the time, could be used to perfectly tune page colors.

By moving context monitoring outside of our modules, our modules have become even more portable. If we need to add collapsible sections to one of our pages, it’s now easy to re-use our section toggle module, because it’s not aware of the context in which it’s used. It just wants to be in charge of toggling something.

And this is what Conditioner makes possible, it extracts all distractions from the module and allows you to write a module focused on a single task.

Using Conditioner In JavaScript

Conditioner exposes a total of three methods. We’ve already encountered the hydrate and addPlugin methods. Let’s now have a look at the monitor method.

The monitor method lets us manually monitor a context and receive context updates.

const monitor = conditioner.monitor('@media (min-width:30em)'); monitor.onchange = (matches) => { // called when a change to the context was observed }; monitor.start();

This method makes it possible to do context monitoring from JavaScript without requiring the DOM starting point. This makes it easier to combine Conditioner with frameworks like React, Angular or Vue to help with context monitoring.

As a quick example, I’ve built a React <ContextRouter> component that uses Conditioner to monitor user context queries and switch between views. It’s heavily inspired by React Router so might look familiar.

<ContextRouter> <Context query="@media (min-width:30em)" component={ FancyInfoGraphic }/> <Context> // fallback to use on smaller viewports <table/> </Context> </ContextRouter>

I hope someone out there is itching to convert this to Angular. As a cat and React person I just can’t get myself to do it.

Conclusion

Replacing our initialization script with the killer for loop created a single entity in charge of loading modules. From that change, automatically followed a set of requirements. We used Conditioner to fulfill these requirements and then wrote custom plugins to extend Conditioner where it didn’t fit our needs.

Not having access to our single for loop, steered us towards writing more re-usable and flexible modules. By switching to dynamic imports we could then lazy load these modules, and later load them conditionally by combining the lazy loading with context monitoring.

With conditional loading, we can quickly determine when to send which module over the connection, and by building advanced context monitors and queries, we can target more specific contexts for enhancement.

By combining all these tiny changes, we can speed up page load time and more closely match our functionality to each different context. This will result in improved user experience and as a bonus improve our developer experience as well.

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

Prototyping An App’s Design From Photoshop To Adobe XD

Smashing Magazine - Wed, 03/21/2018 - 02:40

(This is a sponsored article.) Designing mobile apps means going through different stages: pre-planning, visual concepts, designing, prototyping, development. After defining your project, you need to test how it will work before you begin to develop it.

This stage is captured by prototyping. Prototyping allows designers to get a feel for the functionality and flow of an app, and to preview screens and interactions. Testing with prototypes provides valuable insights into user behavior and can be used to validate the interaction model. It is possible to represent the interactivity of an app before its development, and this gives developers a global vision of an app’s functioning, user behavior and steps to afford.

Prototyping is the simulation of the final result of an app’s development. Through this step, it’s possible to show a workflow of an app and consider problems and solutions. The two fundamental roles who will work in this phase are the user interface (UI) designer, who creates the look and feel, and the user experience (UX) designer, who creates the interaction structure between elements.

There are many ways to design and create an app’s look. As a loving user of Adobe products, I work most of the time in Illustrator and Photoshop. Illustrator helps me when I create and draw UI elements, which I can simply save and use later with Adobe XD. The process is the same as I’ve done for icons and that I showed you in my previous article “Designing for User Interfaces: Icons as Visual Elements for Screen Design.”

Photoshop comes in handy when I have to work with images in UI. But that’s not all: With the latest Adobe XD release, we can bring Photoshop design files into XD very quickly, and continue prototyping our app.

Today, I’ll offer a tutorial in which we discover how to transfer our app’s design from Photoshop to XD, continuing to work on it and having fun while prototyping. Please note that I’ve used images from Pexels.com in order to provide examples for this article.

We will cover the following steps:

  1. Simple hand sketch,
  2. Designing In Photoshop,
  3. Importing PSD files to XD,
  4. Developing a prototype,
  5. Tips.

For Adobe tools, I will use Photoshop CC, Illustrator CC and XD CC — all in the 2018 versions.

Let’s get started!

1. Simple Hand Sketch

Before we start designing our app, we need a plan for how to go about it. There are some questions we have to answer:

  • What is the app for?
  • What problem does it solve?
  • How easy is it to use?

Let’s assume we want to create an app for recipes. We want something simple: a space for pictures with ingredients and recipes.

I sketched by hand what I have in mind :

Then, I grabbed Photoshop and created my layouts.

2. Designing In Photoshop

Before we create layouts for our app, we can take advantage of a very useful resource by Adobe: free UI design resources. Because we will be designing an iOS app, I downloaded the iOS interface for Photoshop.

Feel free to experiment with the layouts you’ve downloaded.

In Photoshop, I created a new blank document from a preset for the iPhone 6 Plus:

Below is our layout, as I designed it in Photoshop. I tried to reproduce what I drew by hand earlier.

The PSD file contains four artboards. Each has its own layers.

Note: The images used in this prototype are from Pexels.com.

Let’s see how to import this PSD file into Adobe XD.

3. Importing PSD Files To Adobe XD

Let’s run Adobe XD and click on “Open.” Select our PSD file, and click “Open.”

Ta-dah! In a few seconds, you’ll see all of your PSD elements open in XD.

More importantly, all of the elements you just imported will be organized exactly as they were in Photoshop. You can see your artboards on the left:

When you select an artboard, you will see its layers on the left — exactly the way it was in Photoshop before exporting.

Let’s do something in XD to improve our layout.

Go to Artboard 3. In this artboard, I want to add some more images. I just created three spaces in Photoshop to get an idea of what I want. Now, I can add more with some very simple steps.

First, delete the second and third image. From the first rectangle, delete the image, too, by double-clicking on it. You’ll have just one rectangle.

With this rectangle selected, go to “Repeat Grid” on the right and click it. Then, grab the handle and pull it downward. The grid will replicate your rectangle, inserting as many as you want. Create six rectangles, and adjust your artboard’s height by double-clicking on it and pulling its handle downwards.

Now, select all of the images you want to put in rectangles, and drag them all together onto the grid you just created:

Et voilà! All of your pictures are in place.

Now that all of the layouts are ready, let’s play with prototyping!

4. Developing A Prototype

Let’s begin the fun part!

We have to create interactions between our artboards and elements. Click on “Prototype” in the top left, as shown in the image below.

Click on the “Start here” button. When the little blue arrow appears, click and drag it to the second artboard. We are connecting these two artboards and creating interaction by clicking the intro button. Then, you can decide which kind of interaction to use (slide, fading, time, etc.).

See how I’ve set it in the image below:

Scrolling tip: Before viewing our prototype preview, we need to do another important thing. We have to make our artboards scrollable, giving them the same effect as when pushing a screen up and down with a finger on the phone.

Let’s go back a step and click on “Design” in the top left. Check which artboards are higher — in this case, the third and fourth. Select the third artboard from the left, and you’ll see the section “Scrolling” on the right. Set it to “Vertical.”

Then, you’ll see that your “Viewport Height” is set to a number, higher than the original artboard’s size. That’s normal, because we made it higher by adding some elements. But to make our artboard scrollable, we need to set that value to the original artboard’s size — in this case, 2208 pixels, the height of the iPhone 6 Plus, which we set in Photoshop and then imported to XD.

After setting that, you’ll see a dotted line where your artboard ends. That means it is now scrollable.

To see our first interactions in action, click on “Prototype” in the top left, and then click the little arrow in the top right. See them in action below:

Let’s finish up by connecting all of our artboards, as we’ve seen before, and check our final prototype. Don’t forget to connect them “back” to the previous artboard when clicking on the little arrow to go back:

And here is the final demo:

In this tutorial, you have learned:

  • that you can design your app in Photoshop,
  • how you can bring it into Adobe XD,
  • how to create a simple prototype.
Tips
  • Decide on one primary action per screen, and highlight its containing element through visual design (e.g. a big CTA).
  • White space is very important on small screens. It prevents confusion and gives the user more clickable space. And here comes that rule again: One primary action works well with more white space.
  • If you are not on a desktop, avoid all unnecessary elements.
  • Always test your prototypes with regular users. They will help you to understand whether the flow is easy to follow.

This article is part of a UX design series sponsored by Adobe. Adobe XD is made for a fast and fluid UX design process, as it lets you go from idea to prototype faster. Design, prototype, and share — all in one app. You can check out more inspiring projects created with Adobe XD on Behance, and also sign up for the Adobe experience design newsletter to stay updated and informed on the latest trends and insights for UX/UI design.

(ra, al, il)
Categories: Web Design

Copyright Law Basics For UK Software Developers

Smashing Magazine - Tue, 03/20/2018 - 05:25

Software developers all over the world can benefit from an increased understanding of intellectual property (IP) laws and how those laws may affect their work. Software programs are often complex works that include both functional and artistic elements and may be covered by a variety of different types of IP laws. This can be very confusing for those who haven’t been taught about IP and can cause them to miss out on opportunities to protect their own work or to accidentally infringe on the work of another.

The purpose of this article is to provide information about one type of IP law, copyright law, for software developers who live or work in the United Kingdom. Below we will discuss the definition of copyright law, the source of UK copyright law, and how it applies to technological works. I'll also elaborate on what is not covered by copyright law, as well as the UK concepts of fair dealing and moral rights as they are related to copyright law.

Copyright Law Essentials

You can learn more about copyright law in general and about how it applies to software in my previous article. Go to article →

What Is Copyright Law?

Copyright law is a type of intellectual property law that protects creative works, which can include things like plays, movies, drawings, songs, and many other things. Around the world, copyright laws give the authors or creators of literary, dramatic, musical, or artistic works the right to control the ways in which their material may be used. With regard to software, copyright law generally covers the artistic elements of a software program as opposed to the functional elements.

“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 → What Is The Source Of Copyright Law In The UK?

Copyright law originated in the United Kingdom from a concept of common law; the Statute of Anne 1709. It became statutory with the passing of the Copyright Act 1911. The current act is the Copyright, Designs and Patents Act of 1988. Those interested can read the full text here.

The relevant government office for copyright inquiries is the UK Intellectual Property Office. The UK is also a signatory to the Berne Convention, an international agreement concerning copyright law that has been adopted by 172 countries worldwide.

How Does UK Copyright Law Apply Specifically To Technological Works?

Copyright law can apply to all kinds of technological works that are used with computers, tablets, smartphones, or video game systems. This includes apps, computer programs, databases, spreadsheets, screen displays, and even virtual reality environments. Copyright also applies to works that are used or distributed on the internet like websites, blogs, and other online content. In the UK, computer programs are specifically protected as literary works.

Throughout the European Union, the Computer Programs Directive provides guidance regarding the legal protection of computer programs. The Copyright (Computer Programs) Regulations of 1992 extended the rules covering literary works to include computer programs in other European countries as well.

What Is Not Covered By UK Copyright Law?

Copyright law in the UK, as elsewhere, does not protect ideas, procedures, methods of operations, or mathematical concepts (though other types of IP may protect them under certain circumstances). In other words, copyright law is about protecting a particular expression of an idea, not the idea itself, and not functional elements of a work. Additionally, names, titles, short phrases, and colors are not generally considered unique or substantial enough to be covered by copyright law. However, a work that combines some of the elements, such as a logo or design, could possibly be eligible for copyright (and perhaps trademark) protection.

How Long Does Copyright Protection In The UK Last?

Because the UK is a signatory to the Berne Convention which covered this issue, a copyright in the UK will typically be protected for either the life of the author plus 70 years from the death of the author or, for published works, for 70 years from the date of first publication. However, there are many exceptions to this rule, and each work should be treated on a case-by-case basis if there are any doubts.

One notable UK-specific exception has to do with the boy who never grew up, Peter Pan. Author J.M. Barrie gifted all of the rights to his creation to a children’s hospital in London. When the original copyright expired in 1987, an extension was added to the Copyright, Designs and Patents Act of 1988 mentioned above so that the hospital could continue to collect royalties based on uses of the work (though the hospital has no creative control over how the work is used). Ultimately, this is only an unusual — and perhaps endearingly British — exception to the normal copyright term.

Photo by Christian Battaglia on Unsplash. (Large preview) What Is Fair Dealing?

The copyright laws of almost all countries allow exceptions for certain permitted uses of copyrighted works such as news reporting, educational uses, or where the use of the work is de minimus. In the United States, one can assert a "fair use" defense if accused of infringing a copyright if the use was due to one of these permitted activities. In the UK, these permitted activities fall under the legal concept known as "fair dealing." According to the University of Nottingham, eligible activities which can be conducted without infringing a copyrighted work include:

  • Private and research study purposes;
  • Performance, copies or lending for educational purposes;
  • Criticism and news reporting;
  • Incidental inclusion;
  • Copies and lending by librarians;
  • Format shifting or back up of a work you own for personal use;
  • Caricature, parody or pastiche;
  • Acts for the purposes of royal commissions, statutory enquiries, judicial proceedings and parliamentary purposes;
  • Recording of broadcasts for the purposes of listening to or viewing at a more convenient time;
  • Producing a back-up copy for personal use of a computer program.
How Does "Fair Dealing" Affect Technology Copyrights In The UK?

The "fair dealing" exceptions mentioned above may specifically impact copyrights for technology-related works such as software programs or databases. For example, producing a backup copy of a software program for personal use only would not be considered copyright infringement under a fair dealing exception. Though fair dealing explicitly excludes decompilation or copying a software program during decompilation, the European Software Directive allows software licensees to use their copy of the software "to observe study or test the functioning of the program" in order to "determine the ideas and principles which underlie any element of the program."

Therefore, users may freely observe a program as it operates to determine their functions and its underlying ideas, even if the goal is to create a competing program (see the UK case SAS Institute v. World Programming for more information on this concept). However, actual copying, for example in the case of source code copying, is not tolerated since this is explicitly protected by copyright.

For practical reasons, database copyrights would not be infringed if a person with the legal right to use part or all of a database performs steps necessary to use or access the contents of the database. Also, accessing a database for the purposes of private study or non-commercial research does not infringe copyright in a database.

Photo by rawpixel.com on Unsplash. (Large preview) Moral Rights In The UK

Another difference between the UK and other parts of the world with regard to copyright law is the UK’s emphasis on the importance of moral rights. Though this issue may not often arise in technology-related copyright disputes, moral rights are additional rights over and above the economic rights typically protected by copyright law.

In the UK, moral rights are: the right to attribution, or the right to be known or recognized as the author of a work; the right to object to derogatory treatment of a work, which includes any addition, deletion, or adaptation of a work that would distort or “mutilate” the work or injure the honor or reputation of the author; the right to object to false attribution, which basically means that you would not be named as the author of something you didn’t create; and the right to privacy of certain photographs and recordings, such as those commissioned for a private occasion.

One reason moral rights might be important for developers is that the moral right to attribution gives the developer the right to be named as the author of the software program, even though it is not common industry practice to do so. By the same token, if a developer doesn’t get their name associated with projects they didn’t work on, the right to object to false attribution protects them also. Find more information about moral rights here.

It is our hope that this information has been helpful for UK software designers and developers. Though this is only introductory information, and should not be substituted for legal counsel in the event of specific questions or disputes, education about copyright law issues and other IP issues helps to empower software designers and developers to make sure their works are fully protected.

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

Challenge: Create a To-Do List in React

Tuts+ Code - Web Development - Tue, 03/20/2018 - 04:51

Are you ready to test your knowledge of React? In this video from my course on Modern Web Apps With React and Redux, you'll be challenged to build a basic to-do list app in React. Specifically, you’ll need to pass data to a child component where it will be updated and sent back to the parent component.

If you're not sure how to do that, don't worry—you can skip ahead to the solution. I'll take you through the whole process in detail, to show you how it's done!

Challenge: Create a To-Do List in React The Challenge

In this challenge, you're going to create a basic to-do list app in React. 

We have two components already built: a TodoList component and a TodoItem component.

The TodoList component just has a list of to-dos in its state, and each one has a text property and a done property. Then we can render our list of to-do items in the TodoItem component. 

Then in the TodoItem component, we just render a list item with an input box which has the value. If this to-do item is done then the value is not editable—it's read-only. Then we have a button which we can use to "Finish" or "Unfinish" a task. 

Right now, it's rendering just fine over on the right side, but we can't actually change these things in the state of our TodoList component. So if I try to make changes in these input elements, nothing happens. If I click Finish, the text on the button doesn't change as it should. And I can still select text in the input fields and, if I could actually make changes, it would be editable

All of that needs to be wired up correctly. And that's your challenge! Here's the CodePen with all of the source code for you to work with. 

Fork the pen and try to figure out your own solution! Or read on and I'll walk you through it below.

The Solution

Start by forking the original CodePen and giving it a different name, e.g. by adding "MY SOLUTION".

We have a couple of different things we need to do here. First, inside our TodoItem component, we need to be able to make changes to this data. That means we need to have an onClick handler for the button and an onChange handler for the input element.

But then we need a way to pass those changes back up to the parent TodoList component. So that means that TodoList needs to pass a function down to TodoItem, so that it can call that function. 

Creating an updateTodo Function

So we'll start by adding an updateTodo function in TodoList with some dummy text for now, which we'll update later. And now that we've created updateTodo, we can use it within TodoItem. 

So how might this work? Well, let's start with the button. We'll add an onClick handler, and we'll add this.handleClick. 

So now we need to write our handleClick function. The handleClick function is going to make a change to the todo property that was passed down to TodoItem. 

When this is clicked, we want to reverse whatever the value of done is. So if it's false, switch it to true, and if it's true, switch it to false. And then, of course, we want to pass that newly updated todo object back up through the updateTodo function. 

We can get our newTodo by doing Object.assign, so that we don't mutate the data. And we will copy all the properties in our existing to-do, which is actually this.props.todo.

But then we want to make sure that we overwrite the done property, which should be the reverse or the negative of this.props.todo.done. 

So that's our newTodo. And then we can do this.props.updateTodo, and we will pass it our newTodo.

OK, so that's handling the click. Now let's go down and write our updateTodo now, so that we can actually see this in action. Right now, if I click Finish, you can see that our new to-do object is being printed out where done is set to true, but we're not seeing that reflected in the UI yet. That's because right now, we need to save this new todo back into our todos state.

Setting the State

So let's go ahead and write an updateTodo function, and it's going to take that newTodo as its parameter. And inside it, we're going to do this.setState. 

Now, I'm going to set the state in a way that you may not have seen before. We're going to pass a function to set the state instead of passing an object. This is actually considered a good practice in React and may possibly be the only way to set state in the future. The function that you pass to setState will receive the current state as a parameter. So we can receive that state as a parameter to this function, and then we return our new state from this function.

This is actually a more reliable way of creating a new state that is based on the old state. You can almost think of it as a kind of reducer function, within our setState call. 

So we're going to go ahead and return a new object here. And since that's all we're going to do from this function, we can actually just wrap the curly braces in parentheses so that it knows that this is an object and not the function block. 

Let's get our existing state.todos, and we will map over each todo there, and if the todo.id is equal to the newTodo.id, then we know that this is the todo object that we have to replace. So we can replace it with the newTodo, and otherwise we can just return the old todo, because it's not the one that we're looking to replace. 

And then we just need to change our updateTodo function to refer to this.updateTodo.

Now, if you click Finish, you'll see that the button changes to Unfinish, and that's because todo.done is now true instead of false. Also, the "wash floor" text is now a little bit grayed out, and it's no longer editable. If I click Unfinish, it switches back to Finish, and the text box is editable again.

Making the Text Editable

Our next step is to make the text editable by adding an onChange handler.

On the input line, we'll add onChange={this.handleChange}. And then we need to write handleChange. 

We'll start by creating a newTodo and copying all the properties from this.props.todo, and then handleChange will pass our event object. We're going to set the text to be e.target.value. And then underneath that we'll do this.props.updateTodo, and we'll pass it the newTodo. 

So now, if we change the text, it works just fine. We can now say buy eggs instead of milk, and we can say wash the car instead of the floor. So now, we are successfully making changes to an object in a child component and passing those changes back up to the parent component, where they can be stored.

Simplifying the Code

So it now works as we wanted it to, but there's still one more thing I want to do. You'll notice that the handleChange function and the handleClick function have a lot of similar code. I've often had child components like this where we want to update an object in some way and then pass it back to a parent, and you'll find that a common pattern for doing that is using Object.assign in this way.

So what we're going to do to tidy things up is create a new function called sendDelta. In this case, delta is just the term for whatever needs to change between this to-do and the new to-do that we need. So what we can do here is pass our delta, or our object for just the properties that need to change, to sendDelta. 

Then we just copy the code from handleClick and paste it in sendDelta. The delta is basically the last argument that we've passed to Object.assign, so we can go ahead and replace the code highlighted below with delta, and then just send that. 

So now in handleClick and handleChange, we can simply replace most of the code with this.sendDelta, as shown below. As you can see, it's a lot more concise.

So that's the solution! For the full source code, you can refer to the solution CodePen shown below:

Of course, you may have come up with a different solution. If so, that's great. In any case, we've now successfully created a child component that can change its data and then send those changes back up for storing to its parent component.

Watch the Full Course

In the full course, Modern Web Apps With React and Redux, you'll learn how to use React and Redux to build a complete web application. You'll start with the simplest possible architecture and slowly build up the app, feature by feature. By the end, you'll have created a complete flashcards app for learning by spaced repetition, and you'll also have learned a whole lot about React and Redux, as well as sharpening your ES6 (ECMAScript 2015) skills.

You can take this course straight away with a subscription to Envato Elements. For a single low monthly fee, you get access not only to this course, but also to our growing library of over 1,000 video courses and industry-leading eBooks on Envato Tuts+. 

Plus you now get unlimited downloads from the huge Envato Elements library of 460,000+ creative assets. Create with unique fonts, photos, graphics and templates, and deliver better projects faster.

Categories: Web Design

Pages