Designing A Realistic Chronograph Watch In Sketch

If you’re into wristwatches, like me, and are also a fan of the Sketch app (or just want to get better at it), then this is the tutorial for you. In it, you will learn how to create a very realistic and detailed vector illustration of a watch using basic shapes, layer styles and cool Sketch functions such as “Rotate Copies” and “Make Grid.” You’ll learn how to apply multiple shadows and how to use gradients, and you will see how objects can be rotated and duplicated in special ways. No bitmap images will be used, which means you will be able to easily adapt the final image to different sizes and resolutions.

While Sketch is undoubtedly an excellent UI design tool, it can be used as a powerful illustration tool as well. So, in this tutorial, we’ll be walking through the process of creating the iconic Heuer Autavia wrist chronograph, all in vectors.

Taking A Closer Look At Sketch

What really sets Sketch apart from the rest? If you’re a UI designer, you’ll want to take a closer look at its well-rounded set of features that cater to your requirements. Read a related article →

Heuer Autavia

The name “Autavia” comes from a combination of the watch’s target markets (automotive and aviation), and it was unveiled way back in 1962.

An old advertisement (1962) for the Heuer Autavia chronograph. (source)

The watch became iconic almost instantly, thanks to its simple yet elegant design, optimum readability, built-in chronograph mechanism and rotating bezel. And there’s a beautiful “panda style”: a light-colored dial with three black subdials. You can search on Google Image before we begin to check some reference images of this watch.

The File For This Tutorial

To be able to better follow the steps in this tutorial, download the Autavia.sketch editable file (1 MB). This file will help you follow the process more easily; however, I encourage you to replicate the steps in a new file, with a blank canvas. Have fun!

The completed Heuer Autavia, using 100% vectors in Sketch. (View large version)

Set The Artboard

The first step is to create a new document, named Autavia. Set up a new artboard with the same name, 1400 pixels wide and 1600 pixels high, and positioned 0 (X) and 0 (Y).

To make alignment of all elements easier, let’s add some guidelines. First, show the rulers with Ctrl + R. Then, add a vertical guideline at the center of the artboard with a click on the upper ruler, and do the same for the horizontal guide on the left ruler. Pressing Shift when hovering over the ruler will snap to 10-pixel increments, making it easier to set the guides precisely. For correct placement, you could also look at the positions of the guides when you hover over the rulers: 700 pixels for the vertical guide and 800 pixels for the horizontal guide.

(View large version)

The Case

The base of the watch case is a simple circle. Switch to the Oval tool by pressing O on the keyboard, and draw a circle from the intersection of the guides (i.e. the center of the artboard), with a diameter of 950px.

(View large version)

Let’s create the lugs. Select the Vector tool by pressing V on the keyboard, and draw a shape like in the image below.

(View large version)

Press Enter to go into vector point mode, select top-left point, and from the Inspector panel, set Corners to 6. Leave this mode again by pressing Enter. Hold the Alt key, and point to the vertical guide with the mouse to measure the distance from the center.

(View large version)

Duplicate (Cmd + D) this shape, Flip Horizontally, and position it like in the image below. Hold the Alt key and point to the vertical guide with the mouse; leave it there; and use the arrow keys to set the shape to exactly the same distance from the center, like the first one. Now, measure the distance from the horizontal guide. We’ll need to position the bottom lugs the same distance from the center.

(View large version)

Duplicate both of these shapes, Flip Vertically, and move them to the bottom part of the circle, as shown in the image below. Hold Alt, point to the horizontal guide with the mouse, and use the arrow keys to move the shapes until they are the same distance from the center, like the top lugs.

(View large version)

Now, select all shapes, including the circle, and simply merge them into one shape using the Union operation from the top toolbar; give the resulting shape the name case. Duplicate this shape, because we’re going to use it later to add texture, and hide it by clicking on the eye icon next to the layer’s name, in the Layers panel.

(View large version)

It’s time to add some style to our case, to give it a metallic appearance. Turn off the Borders, then click on Fill, choose Linear Gradient, and add a gradient. Color steps can be added by clicking on the gradient line directly on the shape. The gradient properties are, from top to bottom:

  1. #4B4B4B
  2. #5F5F5F
  3. #BEBEBE
  4. #FFFFFF
  5. #B5B5B5
  6. #787878
  7. #E4E4E4
  8. #F0F0F0
  9. #787878
  10. #B5B5B5
  11. #FFFFFF
  12. #C4C4C4
  13. #4B4B4B
  14. #4B4B4B
(View large version)

Using the Vector tool (V), draw four triangles over each lug, from the inner side, to add some depth to the case. For the color, use #545454, and turn off the borders. Use the image below as a reference.

(View large version)

Let’s fit the triangles inside the case. Select the case shape and all four rectangles, and click on Mask in the top toolbar. The result of this masking operation will automatically be placed in a new group in the Layers list. Change the name of this group to case.

(View large version)

Remember the copy of our case shape? Unhide it, and move it into the case group, as the top layer. Click on Fill and choose Noise Fill, set Intensity to 15%, and apply Motion Blur with an Amount of 20px, to create a brushed metal texture.

(View large version)

The Bezel

Let’s move on and create the bezel. The bezel is made of two rings: an outer with toothed edging, and a black inner with digits and minute marks.

Toothed Edged Outer Ring

First, we will create an outer ring with toothed edging. Draw a circle from the center of the artboard, with a diameter of 950px. Turn off the borders.

(View large version)

To create the toothed edging, first create a small triangle, 10px by 8px, using Triangle from Insert → Shape in the menu bar. Click on the Center Align icon in the Inspector panel to align the triangle to the center of the artboard and the circle (since everything is in the center of the artboard), and make sure that its downside overlaps with the circle, and turn of the borders.

(View large version)

We need those triangles around the circle, and it would be a very time-consuming (and complex!) task to manually create and rotate each and every triangle. Luckily for us, Rotate Copies — a magnificent feature that can do both at the same time — has come to the rescue. So, select the triangle, and choose Rotate Copies from Layer → Paths in the menu bar. The following dialog will let you define how many additional copies of the selected element to make. Enter 259; so, in total, we will have 260 triangles around the circle that will be the toothed edge. After you have entered this value and confirmed the dialog, you will be presented with all of the triangles and a circular indicator in the middle.

Note: Performing this step is very CPU- and memory-intensive. If you are working on a modern machine, you probably will not experience any issues; but if your Mac is a bit older, then your mileage may vary. In general, when working with a large number of copies, try to turn off borders to avoid getting stuck and to achieve the result of the operation faster.

(View large version)

Move the indicator down until it is at the intersection of the guides — and voilà! we have 260 triangles around the circle. Please note that if you miss putting the circular indicator (the center of rotation) right at the intersection of the guides, the triangles won’t be placed perfectly around the circle, and you won’t be able to alter their position anymore as soon as you click anywhere else on the canvas; but it will still be possible to change the individual elements after accessing the related Boolean group.

(View large version)
(View large version)

Performance tip: Alternatively, you can perform this step in two passes, which will be a much less CPU-intensive task for your Mac. First, enter 129 for the additional copies; so, in total, you will have 130 triangles around the circle. Move the indicator down until it is at the intersection of the guides. Second, duplicate (Cmd + D) this shape, and then, using Rotate from the top toolbar, rotate it by 4 degrees. Finally, select both shapes and merge them into one using Union from the top toolbar.

Now, go inside this Boolean group and erase all triangles except the central one at the top and the six to the left and right of its sides.

(View large version)

Use Rotate Copies again, but this time we need 11 additional copies. Align the circular indicator to the intersection of the guides.

(View large version)

Select the resulting Boolean group and circle, and perform a Union operation. Name the resulting object outer bezel, and apply the following styles.

First, a Gradient fill:

  1. #C6C6C6
  2. #CFCFCF
  3. #EFEFF2
  4. #E7E7E7
  5. #FFFFFF
  6. #E7E7E7
  7. #D2D3D5
  8. #CBCBCB
  9. #CBCBCB
  10. #BCBCBC
(View large version)

We will now use Inner Shadows and Shadows to make it look slightly raised.

Let’s add a light Inner Shadows effect with the following properties:

  • Color: #FFFFFF
  • Alpha: 50%
  • X: 1; Y: 1; Blur: 2; Spread: 1

Then, add a dark Inner Shadows effect:

  • Color: #000000
  • Alpha: 10%
  • X: -1; Y: -1; Blur: 2; Spread: 1

Finally apply Shadows effect:

  • Color: #000000
  • Alpha: 50%
  • X: 0; Y: 0; Blur: 4; Spread: 1

This is what the outer bezel looks now with all of the styles applied.

(View large version)

To make this a ring, we need to make the hole in the middle. Draw a circle in the middle of the artboard, with a diameter of 780px, select “outer bezel” and this circle, and simply apply a Subtract operation from the top toolbar. Name the resulting shape outer ring.

(View large version)

Black Inner Ring

For the inner ring, first draw a circle from the center, with a diameter of 930px. Add an Outside border with a Thickness of 1 and the Color set to #313131.

Next, change Fill to Angular Gradient, and adjust the gradient with the following parameters:

  1. #303030
  2. #343434
  3. #282828
  4. #484848
  5. #292929
  6. #333333
  7. #282828
  8. #343434
(View large version)

To add subtle 3D look, add Inner Shadows, with the Color set to #FFFFFF at 30% alpha. Set Blur to 4, Spread to 2 and both the X and Y positions to 0. Then apply Shadows, to make it look raised a bit. Set Color to #000000 at 50% alpha, Blur and Spread to 1 and the X and Y positions set to 0. Name this shape inner bezel.

(View large version)

We have two scales on our inner ring: the minute and hour scales. Let’s deal with the minute scale first. The minute scale consists of minute marks and numerals at five-minute intervals. We will use circles for the minute marks. So, draw a circle with a diameter of 16px, set Color to #FDFDFE, and turn off the borders. Move it away 48px from the outer edge of the inner ring. Hold the Alt key, point to the circle with the mouse, leave it there, and use the arrow keys to reposition the shape until the spacing is correct. Center it to the artboard and inner ring using Center Align from the Inspector panel.

(View large version)

We actually need 59 more of these marks, so go to Layer → Paths, select Rotate Copies, enter 59 in the dialog box, click OK, and align the circular indicator to the intersection of the guides. Rename this resulting shape to minute marks, and delete every fifth mark, starting from the top-middle one.

(View large version)

Let’s add minute numerals at those five-minute positions. Unfortunately, we can’t use “Rotate Copies” to distribute text layers, so we will need to position them manually. For the numerals, we will use the slightly rounded Rubik font family from Google. Add the “60” at the top, with a font size of 49, a Medium weight, Center alignment, and a #FDFDFE fill. Move it 20px away from the outer edge of the inner ring, and center it to the inner ring horizontally. Now, duplicate this number by pressing Cmd + D on the keyboard, and select Rotate from the top toolbar. Because we need to rotate the numbers around the center of our artboard, click and drag the crosshair marker to the intersection of the guides, and rotate it 30 degrees. Continue duplicating and rotating each number one after another, without letting the selection go. That way, the anchor will stay in the middle and you won’t have to move it every time.

(View large version)

Finally, edit the numbers one by one, and change the digits to the corresponding minute marks.

(View large version)

Next, add the hour scale above the minute scale. First, duplicate the number “60,” change the font size to 26 and the number to 12, and move it up using the arrow keys so that it’s 1px away from the outer edge of the inner ring. Now, using the method explained above, add the remaining hour numerals.

(View large version)

Let’s finish the inner ring markings by adding a triangle at the 12-hour position. First, delete the “60” and “12” numbers from both scales, select the Triangle tool from Insert → Shape, and draw a 60px by 65px triangle. Move it 5px away from the outer edge of the inner ring, and center it to the inner ring horizontally. For the color, use the same color that we used for the marks and digits — #FDFDFE — and turn off the borders.

(View large version)

We also need to create the hole in the middle, just like we did for the outer ring, to make it look like the real ring. So, draw a circle in the middle of the artboard with the diameter of 780px, select inner bezel and this circle, and perform a Subtract operation from the top toolbar. Name the resulting shape inner ring.

(View large version)

Select all of the bezel layers, and place them inside the group rotating bezel.

The Dial

It’s time to work on the dial. First, we will create the outer ring of the dial.

Switch to the Oval tool (O), and create a circle in the middle of the artboard, with a diameter of 768px. Set Fill to #CCCCCC, and add an Outside border, with a Thickness of 4px and the Color set to #D9D9D9. Also, apply Inner Shadows, with the Color set to #000000 at 50% alpha and the Blur set to 10. Name this shape outer dial.

(View large version)

For the base of the dial, create a circle in the middle of the artboard, with a diameter of 706px, a Fill set to #FAFBF9 and an Outside border with a Thickness of 4px and a Color of #D9D9D9. Add Inner Shadows, with the Color set to #000000 with 50% alpha and a 6Blur. Give this shape a name of inner dial.

(View large version)

One-Fifth of a Second Scale

To break the ground, we’ll add the scale for the one-fifth of a second, which means that 300 thin markings should line the outer rim of the dial. Create a rectangle with a width of 2px and a height of 18px, with the Fill set to #050B05 and the borders turned off. (Turning off borders will help avoid the Mac’s spinning beach ball of death.)

Center the rectangle to the inner dial horizontally, and move it 19px away from the the outer edge of inner dial. Once again, we’ll use “Rotate Copies” to create the scale. Go to Layer → Paths, select Rotate Copies, enter 299 in the dialog, click OK, and align the circular indicator to the intersection of the guides. Rename this resulting shape to one-fifth of a second scale.

(View large version)

60-Second Markings

Next, we’ll add 60-second markings. These markings are the same as the “one-fifth of a second” markings but longer. So, create exactly the same rectangle as in the previous step, but make it 36px high, and position it the same way (19px from the outer edge and aligned horizontally to inner dial). Open the Rotate Copies, enter 59 in the dialog box, click OK, and align the circular indicator to the intersection of the guides.

(View large version)

We don’t need the marks at the hours’ positions, so we will have to delete every fifth mark, starting from the one in the 12:00 position. You can also use a rotating bezel as a guide for which mark to delete.

(View large version)

Rename this resulting shape to 60 seconds markings.

Five-Minute Markings

Let’s add the minute markings. Create a rectangle with a width of 4px and a height of 18px, with the Fill set to #050B05 and borders turned off. Center it to the inner dial horizontally, and move it 19px away from the outer edge of inner dial. Because we need 12 hour marks in total, go to Rotate Copies, enter 11 in the dialog box, click OK, and align the circular indicator to the intersection of the guides. Give this shape a name of 5-minute markings.

(View large version)

15-Minute Markings

For the 15-minute markings, we will use circles. Draw a circle with a diameter of 16px, align it horizontally with the inner dial, and move it 20px away from the top. Set its Fill to #E5BF8E, and add Shadows with the Color set to #000000 at 50% alpha, the Blur set to 2 and the Spread set to 1.

(View large version)

Use Rotate Copies to add circles at the quarter-hour positions. At the end, delete the one at the 12:00 position. Rename this shape to 15 minute markings.

(View large version)

Hour Markings

In this step, we will create hour markings. Select the Rectangle tool (R), and create a rectangle with a width of 30px and a height of 70px, with the Fill set to #E7E7E7. Add an Outside border, with a Thickness of 3px and the Color set to #FFFFFF. Position it at 12:00, and move it 43px away from the the outer edge of inner dial. Apply Inner Shadows, with the Color set to #000000 with 30% alpha and a Blur of 5, and Shadows with the exact same color, a Blur of 2 and a Spread of 1, to make it look slightly raised from the inner dial. This will be the base of the hour mark.

(View large version)

We need to add two smaller rectangles at the top and bottom to finish the hour mark. The easiest way to do this is to duplicate (Cmd + D) the rectangle, turn off borders and shadows, change the height to 16px and the Fill to #E5BF8E, and alter the Inner Shadows so that the Color is now set to #FFFFFF with 60% alpha, the Y to 1 and the Blur is 2.

(View large version)

To add a rectangle to the bottom, duplicate the rectangle that we just created, Flip Vertically, change the Fill to #393F3B, and align it to the bottom of our base, by selecting both of these rectangles, right-clicking, and selecting Align Bottom. Finally, select all three rectangles and group them into an hour mark group using Cmd + G.

(View large version)

Duplicate the hour mark group and turn the duplicate into a symbol by right-clicking and selecting Create Symbol. Name this symbol hour-mark. Now we need to distribute hour-mark symbols around the dial. Select the hour-mark symbol, choose Rotate from the top toolbar, drag the crosshair marker to the center of the artboard (the intersection of the guides), and rotate it to the position of 1:00 (30 degrees). Continue duplicating and rotating the symbol (in 30-degree increments), without letting the selection go. Finally, delete the hour-mark symbols at the positions of 3:00, 6:00 and 9:00, since we won’t need them.

(View large version)

The hour mark at 12:00 needs to be a bit different, and it should consist of two narrower hour marks. This is why we kept the original hour mark group! We will simply modify the existing hour mark, by selecting all three shapes inside the hour mark group and changing the width to 20px from the Inspector Panel on the right. Next, duplicate this group, move it 9px to the right using the arrow keys; then, select both groups, and place them in a new group named 12-hour mark; align them horizontally with the inner dial. Lastly, select all hour marks and put them in the hours group.

(View large version)

Please note that the same can be done with symbols as well, because they can be resized while keeping the internal spacing intact.

Subdials

Subdials give information not provided by the main watch dial, and they are common features of chronograph watches. Chronographs use subdials to keep track of seconds and of elapsed minutes and hours. In this step, we will create three subdials: an active seconds subdial, a 30-minute counter and a 12-hour counter.

Active Second Subdial

This subdial shows continuously running seconds. Let’s start by drawing a circle from the center of the artboard (i.e. the intersection of the guides), with a diameter of 204px. Add a Center border with a Thickness of 1 and the Color set to #424242. Apply Inner Shadows with the Color set to #00000 at 60% alpha and the Blur set to 20, to make it look like it’s inserted in the main dial. Name this shape subdial base.

(View large version)

Let’s add the markings. First, we will add tiny markings. Create a white rectangle with a width of 4px and a height of 25px and the borders turned off. Align it horizontally to the subdial base, and position it 5px away from the top of the subdial base. Use Rotate Copies to create a 12-marking scale. This subdial has tiny markings at five-second interval, so we need to delete every second marking, starting from the top one (at the 60-second position).

(View large version)

Next, we need to add a bit bolder markings at the 60, 20 and 40 positions. Create a rectangle like the previous one, but make it a bit wider: 6px in width and 25px in height, and at the same position. Open Rotate Copies and create a three-marking scale.

(View large version)

Let’s add the remaining three markings at the 10, 30 and 50 positions. Create a rectangle like the previous one, but make it a bit longer, 6px in width and 35px in height, and position it 5px away from the bottom of the subdial base. Open Rotate Copies and create a three-marking scale.

(View large version)

Now, we need to add numbers to the subdial. Add the 60 at the top; for the font, use Rubik again, with a font size of 26, a Regular weight, Center alignment and a #FFFFFF fill. Move it 30px away from the outer edge of subdial base, and center it horizontally.

(View large version)

Duplicate this number. Select Rotate from the top toolbar, drag the crosshair marker to the intersection of the guides, rotate it 120 degrees, and change the number to 20. But we don’t want the number to be rotated this way; it should stay normal, like the 60. To do that, set the Transform to 0 in the Inspector Panel on the right. Now, use the arrow key to move the number away from the marking, to the left by 6px (press the left arrow key six times).

(View large version)

Using the same method, add the number 40 at the 40-seconds position, but this time move the number 6px to the right.

(View large version)

Let’s add a hand to finish the subdial. First, draw a white circle from the middle of the artboard, with a dimeter of 30px and borders turned off. Then, draw a white 6px by 68px rectangle, and Align Horizontally with the circle we’ve just created, making sure they overlap. Select both shapes and perform a Union operation to create one object. Add Shadows with the Color set to #000000 with 70% alpha, the Blur set to 8 and a Spread of 2, to raise the hand from the subdial.

(View large version)

Create a small circle on top, with a diameter of `12px`. Set the **Fill** to `#A3A3A3`, turn off borders, and add black **Shadows** with `50%` alpha and a **Blur** of `2`. Now duplicate this circle, turn off **Shadows**, change the **Fill** to `#353535`, and scale it down to `50%`. These two circles will represent a small screw to keep the hand in place. Group all shapes for the hand, and name this group `hand`.

(View large version)

Select all of the shapes that we used to create the subdial, and group them into the `subdial` group. We will use this group as a base to create all three subdials.Now, duplicate the group and rename it to `active second subdial`, and then move it to the 9:00 position. Using the left arrow key, move the subdial to the left until it’s `55px` away from the left edge of `inner dial`. Add the vertical guide at the center (`504px`) of `active second subdial`. This will help us to adjust the position of the hand. Use a simple math operation to determine where the vertical center is: The subdial’s diameter is `204`, so the radius is `102px` — just add `102px` to the current X position in the Inspector Panel on the right.

(View large version)

**30-Minute Counter**This subdial is used to record events longer than one minute (and lasting up to 30 minutes) and it’s placed on the right side of the dial, at the 3:00 position.We’ll be using the `subdial` group as the base for this one, so duplicate the `subdial` group, rename it to “30 minute counter” and alter it a bit. Delete the tiny markings scale. Create a new one, in the same way we did above, but with `30` markings. Go into this new scale and delete markings that are in the same positions with the bold markings, and then change the numbers to `30`, `10` and `20`. Move this subdial to the right until it’s `55px` away from the right edge of `inner dial`, and then add the vertical guide at the center (`896px`). Use the image below as a reference.

(View large version)

**12-Hour Counter**This subdial is used to record events longer than 30 minutes (up to 12 hours), and it’s placed at the bottom side of the dial, at the 6:00 position.We will use the remaining `subdial` group to create the 12-hour counter. This counter has smaller markings at half-hour intervals, which means that we have 24 of these around the circle, and longer markings at the hour positions, which means that there are 12 of these around the circle.Once again, **Rotate Copies** will help us creating those markings. For the half-hour markings, use a rectangle with the size of `4px` by `15px`, and for the hour marks, use a longer and bit bolder rectangle, `6px` by `25px`. Remember to delete those half-hour markings that are in the same position as the hour markings, since there’s no need to have both. Also, add a small “Swiss T” title `12px` away from the hand, using a white **Rubik Medium** font with the size set to `10px`, **Center** alignment and a spacing **Line** of `10`.When done, change the group name to `12 hour counter`, move it into position at 6:00, `55px` away from the bottom edge of `inner dial`, and add a horizontal guide at the center (`996px`). Use the image below as a reference.

(View large version)

Our subdials are in place, and we can set the time for each subdial if we want. Simply select the `hand` group, select **Rotate** from the top toolbar, drag the crosshair to the intersection of the guides, and perform the rotation.

(View large version)

#### Finishing the DialIt’s time to put some branding on the dial. Jump over to Wikimedia Commons and download the [Tag Heuer](https://commons.wikimedia.org/wiki/File:TAG_HEUER_logo.svg) logo in SVG format. This is the current version of the logo; we will need to modify it a bit because we are recreating a watch from pre-Tag era.Open the logo in Sketch, and delete everything except the red rectangle that holds the word Heuer. First, change the color of the letters to `#2E2E2E`. Then, select the rectangle, turn off **Fill** and add **Borders**, set the **Position** to **Outside** and the **Color** to `#2E2E2E`. Change the name of the group to `Heuer logo`.

(View large version)

Bring the modified logo into our design. Switch to the **Scale** tool in the top toolbar, and in the dialog box enter `50px` in the height field, to adjust the size of the logo. The scale function will automatically calculate the correct width for any given height. Align the logo horizontally with `inner dial`, and place it `200px` away from the top. Once again, select the rectangle that holds the lettering, and set the border **Thickness** to `3`.

(View large version)

Let’s add the watch’s name above the logo. Download the Walkway Expand font family (it’s free), install only the “Walkway Extend Black” font, and type the word “Autavia.” Place it 3px above the logo, and align it horizontally with the logo. Set the Size to 24px, the spacing Character to 2, the Line to 24 and the Color to #2E2E2E (the same one that we used for the logo).

(View large version)

Next, convert the text block into vector shapes, by right-clicking and selecting Convert to Outlines. Then, modify the “A” a bit to make it look similar to the original “A” in vintage Heuer watches. Select the resulting vector shape, press Enter to go into vector point mode, zoom in close enough (I zoomed in to 800%) and select top-left point of the letter “A,” and move it 1px to the left. Then, select the top-right point, and move it to the right by 1px. After that, select the small triangle inside the letter, add one point anywhere on the side line, and drag it up until it’s on the same level as the middle point (a horizontal red line will appear). Adjust the position by dragging them a bit left and right inwards, and then readjust the positions of the other points to make an even width on the slanting lines. Use the image below as a reference.

(View large version)

Do the same thing for the remaining “A” letters.

(View large version)

To finish the dial, we need to do one more thing: add the one-fifth of a second scale to outer dial. This is where the proper naming of shapes and groups helps. In the Layers panel on the left, find one-fifth of a second scale and copy it. Find the outer dial shape and paste it over. We need to scale it up, because it’s smaller than outer dial. Select the Scale feature, and scale it up to 114%. Now it should be inside outer dial, right where we want it to be!

(View large version)

Apply a Gaussian Blur with an Amount of 2px, and lower the Opacity to 40%. Just to be sure that the scale doesn’t exceed the outer dial, select both shapes and perform a Mask operation from the top toolbar. Sketch will place the result automatically into a group. Give this resulting group the name outer dial finished.

Performance tip: Gaussian blur is a CPU- and memory-intensive process. I noticed that Sketch’s performance is better if Show Pixels is turned on. This setting can be enabled by going to View → Canvas → Show Pixels or by using the Ctrl + P shortcut. Given how complex the illustration is, periodically saving and restarting Sketch seems to help a bit, too.

(View large version)

The Watch Hands

It’s time to create the watch hands. We need to create the hour hand, the minute hand and the large second hand (which is part of the stopwatch).

The Hour Hand

Let’s start with the hour hand because it’s physically closest to the dial. Similar to how the subdial hands were made, this hand will also be made of a circle and rectangle. Zoom in a bit and create a circle in the middle of inner dial, with a diameter of 58px. Then, add a rectangle, also in the middle of inner dial, with dimensions of 30px by 246px. The rectangle should be 150px away from the top of inner dial.

(View large version)

Make sure the rectangle is still selected. Enter shape editing mode by double-clicking the rectangle or hitting Enter. Now, hold Command and click on the top segment to add a point in the exact middle. Push this point up by 20px.

(View large version)

Select both shapes (the rectangle and circle), and merge them with Union from the top toolbar. Add a Fill of #585858, and add Borders with a Color of #E4E4E4, a Position of Outside and a Thickness of 2

(View large version)

Let’s give the hand a three-dimensional appearance. First, add a Linear Gradient fill on top of the existing fill; use #4A4A4A with 100% alpha for the first color stop and white with 0% for the last stop. Bring the gradient to a horizontal position with the left-pointing arrow in the color dialog. Now, add another point with a double-click on the gradient axis in the color dialog, and move it to the exact middle by pressing 5 on the keyboard. Give it 100% alpha, and make sure its color is #4A4A4A. Add another one to the right, and also move it to the center and then 1px to the right using right arrow key. Change the color of this stop to #898989 with 20% alpha.

(View large version)

Next, apply white Inner Shadows with 50% alpha and a Blur of 2. Then apply black Shadows with 70% alpha, a Blur of 6 and a Spread of 1.

(View large version)

To finish the hour hand, we need to fill it with a luminescent color, so that it is possible to check the time in the dark. To do this, draw a rectangle with a size of 16px by 100px, and position it 22px away from the top of the hour hand. For the Fill, use #FFE4C0. Enter shape editing mode, select the two bottom points, and set the Radius to 3px. Add a Center border with a Thickness of 2, and set the Color to #626262. Add Inner Shadows to make it look like it’s inside the hand. For the Color, use #000000 with 30% alpha, a Blur of 3 and a Spread of 3.

(View large version)

Select all of the hour-hand shapes, and place them in the hour hand group using Cmd + G.

The Minute Hand

The minute hand is basically the same as the hour hand but longer and with a smaller circle. Duplicate the hour hand, hide the original layer, and name the new one minute hand. Go into the group, select the circle from the merged shape, go to Layer → Transform → Scale (or Cmd + K), and enter 80% (to scale it down by 20%).

(View large version)

Make sure that the merged shape is selected, enter shape editing mode, select the top three points (hold Shift while clicking on the points to select them all), and push them up by 90px. Holding Shift and the up arrow key will move the selection in 10-pixel increments.

(View large version)

Click on the gradient fill and bring the gradient to the opposite side, using the right-pointing arrow twice in the color dialog. Also, edit the Shadows: Lower the alpha to 50%, set the Blur to 5 and the Spread to 1.

(View large version)

Finally, select the luminescent rectangle on top, enter shape editing mode, select two top points, and push them up by 90px as well. The minute hand is now complete.

(View large version)

Large Second Hand

This hand moves only when the stopwatch mode is on, and it measures the elapsed time in seconds.

This hand is also made of a circle and rectangle, and we will create it using the same method. Hide the minute hand group, and draw a circle with a diameter of 30px in the middle of inner dial. Add on top a tiny rectangle with a size of 8px by 408px, and move the bottom two vector points in by 2px each to form a trapezoid; set it in the middle and 26px away from the top of inner dial. Use the same Fill of #404040 for the circle and rectangle, with borders turned off.

(View large version)

Add a point in the exact middle of the top and bottom segments, and push the top one 6px up and the bottom one 6px down.

(View large version)

Merge both shapes into a large seconds hand group using Union. Apply white Inner Shadows with 40% alpha and a Blur of 2, and black Shadows with 50% alpha, a Blur of 4 and a Spread of 1.

(View large version)

Finally, add a screw on top to hold the watch hands in place. Create a circle with a diameter of 14px in the middle of the artboard, with a Fill of #5F5F5F and borders turned off. Add a black Shadows effect with 50% alpha, the Blur set to 2 and a Spread of 1.

(View large version)

Add one more circle on top, this time with a diameter of 6px and the Fill set to #4C4C4C. Add an Outside border with a Thickness of 1 and a Color of #888888, and apply a black Inner Shadows effect with 50% alpha and a Blur of 3. Select both circles and group them into a screw group.

(View large version)

Now we can set the time to 10:08:24. Select large seconds hand, click on Rotate in the top toolbar, drag the crosshair marker to the intersection of the guides, and rotate it by 144 degrees to set it at 24 seconds.

(View large version)

Bring back minute hand into the scene by unhiding it, and then rotate it by 48 degrees, just like we did with large seconds hand, to read 8 minutes.

(View large version)

Finally, unhide hour hand, and set it to a little after 10:00 (-56 degrees — rotating counter-clockwise is much easier than going around the full circumference).

(View large version)

The Crown

Time to create the watch crown. Start with a rectangle of 78px by 162px. Align it vertically to the artboard, turn off borders, and apply Linear Gradient with the following parameters, from top to bottom:

  1. #989898
  2. #A5A5A5
  3. #E8E8E8
  4. #8C8C8C
  5. #787878
(View large version)

Enter shape editing mode, select the two vector points on the right side of the rectangle, and set the Radius to 10px.

(View large version)

Hold Cmd and click on the right segment to add a point in the middle. Push this point right by 20px and double-click on it to turn it to a Mirrored vector point.

(View large version)

Select the Vector tool (V) and draw a line like in the image below. Set the border Color to #F0F0F0 and the Thickness to 3. Add a black Shadows effect with 20% alpha, and set Y and Blur to 2.

(View large version)

We will use this line to create toothed edges around the crown. Go to Arrange → Make Grid, and in the dialog box set Rows to 13, Margin to 1px and Columns to 1, and click on Make Grid. “Make Grid” will distribute the selected layers with predefined spacing between them.

(View large version)

We have filled the top half of the crown. The easiest way to fill the bottom half is to select all paths created with “Make Grid,” group them, Duplicate (Cmd + D), Flip Vertically, and move it to the bottom half of the crown. Then, select both groups and the crown shape, and perform a Mask operation so that none of the created elements go outside of the crown shape. Name the resulting group crown.

(View large version)

Drag the crown to the left, and send it behind the case in the Layers panel.

(View large version)

The Pushers

Chronograph buttons (or “pushers”) start, stop and reset the chronograph function without interfering with the watch. Let’s add those buttons to the side of the case. Each pusher is made of two rectangles, one on top of the other. Draw a first rectangle of 28px by 74px, turn off borders, and apply a Linear Gradient for the Fill:

  1. #8D8D8D
  2. #D3D3D3
  3. #8A8A8A
(View large version)

Apply black Inner Shadows with 30% alpha, and set Y to -13 and Blur to 10.

(View large version)

Draw second rectangle on top, 20px away from the left segment, with a size of 86px by 106px, and Align Vertically with the one below. Set Radius to 14px, make sure borders are turned off, and use Linear Gradient for the fill:

  1. #8C8C8C
  2. #CACACA
  3. #FFFFFF
  4. #BABABA
  5. #707070
(View large version)

Select both rectangles and group them in the pusher group, and Align Vertically to artboard. Duplicate this group, because we need two pushers, one above and one below crown.

(View large version)

Send them below case in the Layers panel, and rotate the first by -30 degrees and the second by 30 degrees, with the crosshair marker set at the intersection of the guides.

(View large version)

The Strap

We’re almost there. For the final touches, we will create the straps.

Add a rectangle of 476px by 376px between the top lugs, and align it vertically with the artboard. Select the top two vector points, and set the Radius to 60px. Then, move the bottom two vector points by 10px each to form a trapezoid.

(View large version)

Uncheck Borders, click on the Fill button, switch to Linear Gradient, and create a gradient using the following settings:

  1. #636363
  2. #3B3B3B
  3. #2B2B2B
  4. #000000
  5. #1F1F1F
  6. #000000
(View large version)

Add a horizontal Linear Gradient to imitate the leather embossing effect that real stitches make. The settings are:

  1. #0C0C0C with 40% alpha
  2. #0E0E0E with 10% alpha
  3. #2E2E2E with 80% alpha
  4. #181818 with 10% alpha
  5. #181818 with 10% alpha
  6. #2E2E2E with 80% alpha
  7. #0E0E0E with 10% alpha
  8. #0C0C0C with 40% alpha
(View large version)

Add Noise Fill on top, with Soft Light blending and an Opacity of 20%, to add a subtle texture. Finally, add white Inner Shadows with 10% alpha, and set Y to 15 and Blur to 10.

(View large version)

Finish the strap by adding contrast stitching that is common on the straps. Create a Rounded Rectangle (U) of 10px by 30px, with a Radius of 5. Set the border Color to #3B3B3B, with an Inside position and a Thickness of 1. Change the Fill to #E6E6E6.

(View large version)

Add texture by using Noise Fill on top, with Overlay blending and an Opacity of 70%. Then, apply Shadows with the color set to #000000 with 50% alpha and the Blur and Spread set to 2.

(View large version)

Use Make Grid to add stitches vertically. In the dialog box, set Rows to 7, Margin to 2px and Columns to 1.

(View large version)

Select all of the stitches, duplicate and move them to the right side of the strap.

(View large version)

Select all of the shapes that are part of the strap (the stitches and strap shape), and group them into the strap top group. Move this group just above case in the Layers panel. To create a bottom strap, duplicate the strap top group, Flip Vertically, move it between the bottom lugs, and change the name to bottom strap. Select and put all watch elements into one group, autavia. Our watch is now officially finished!

(View large version)

Finally, let’s add a background. Create a rectangle of the same size as the artboard, set the Fill to #0D0F0E, and push it below the autavia group.

(View large version)

Conclusion

Now you know how to recreate one of my favorite watches. Chronographs are magnificent pieces of engineering and state-of-the-art technology, and while the tutorial probably wasn’t easy, the result is quite good in my opinion — not unlike the process of building a real watch!

The next step, of course, is to design your own favorite illustration. Select a watch (or another object you like), and be sure to get as many photos from different angles, so that you can replicate all of the important details. As you can see, there are certain tools and features in Sketch that you can master to create similar objects; use them to speed up and simplify the whole process.

Each wristwatch has different features, but in this case we’ve covered most of them, and I’m pretty sure that you can now reverse-engineer any other watch.

Next, imagine exporting these elements to SVG format and animating them. Imagine recreating not only how they look, but also how they work!

Finally, if you have any questions, please leave a comment or ping me on Twitter. I will gladly help you.

Smashing Editorial(mb, al, il)

Minimalistic Design With Large Impact: Functional Minimalism For Web Design

(This is a sponsored post). As web design focuses more and more on good user experience, designers need to create the most usable and attractive websites possible. Carefully applied minimalist principles can help designers make attractive and effective websites with fewer elements, simplifying and improving users’ interactions.

In this article, I will discuss some examples of minimalism in web design, things to consider when designing minimalist interfaces, and explain why sometimes “less is more”. If you’d like to get more creative with your own designs, you can download and test Adobe XD, and get started right away.

Selecting An Effective Color Scheme

When designing a new app, it’s often difficult to decide on a color scheme that works well, as there are an infinite number of possible color combinations out there. Read a related article →

A Short History Of Minimalist Design

Some web designers mistakenly think of minimalism as a primarily aesthetic choice. To avoid the pitfall of focusing only on aesthetics, let’s be clear about the roots of minimalist design.

While it might be a newer trend in web design, the underlying ideas have been around for much longer. When discussing minimalist design, a person might naturally think of traditional Japanese culture. Japanese culture values balance and simplicity. Japanese architecture, interior design, art, and graphic design have long employed minimalist aspects.

Fine Wind, Clear Morning” by Katsushika Hokusai (1830). The emphasis is on simple colors, creating a sense of calm. (View large version)

As a Western movement, minimalism began early in the 20th century. Influenced by the introduction of modern materials, such as glass and steel, many architects began to employ minimalist designs in their buildings. Ludwig Mies Van der Rohe, the German-American architect, was one of the pioneers of the minimalist movement. He is credited with first applying the phrase “less is more” to architectural design.

Barcelona Pavilion, designed by Ludwig Mies van der Rohe, 1929 (View large version)

The less-is-more attitude quickly moved from architecture to other arts and industries: interior and industrial design, painting, and music. As a direction of visual design, minimalism became popular in the 1960s, when artists moved toward geometric abstraction in painting and sculpture. The artistic movement found its impression in the artwork associated with the Bauhaus school. One well-known minimalist artist who influenced the movement was Donald Judd, whose artwork is full of simple shapes and color combinations.

In diverse spheres of visual arts, a key principle of minimalism was leaving only the essential part of a feature, in order to focus the recipient’s attention as well as to enhance the overall elegance. As Donald Judd said, “A shape, a volume, a color, a surface is something itself. It shouldn’t be concealed as part of a fairly different whole. The shapes and materials shouldn’t be altered by their context.”

In his work, Judd sought autonomy and clarity for the constructed object and the space created by it. (Image credit: Judd Foundation) (View large version)

What Is Minimalist Web Design?

Today, minimalism has reemerged as a powerful technique in modern web design. It became popular as a reaction to a trend of increasing complexity in web design. (Visual complexity has been shown to affect a user’s perception of a website: The more elements a design has, the more complex it will look to the user.) Applied correctly, minimalism can help us focus our designs in order to simplify user tasks. A study conducted by EyeQuant suggests that clean design results in lower bounce rate. Minimalism has brought additional benefits to websites, in faster-loading times and better compatibility between screen sizes.

Perhaps one of the most well-known examples of minimalism in web design is Google Search. Google has prioritized simplicity in its interfaces ever since its beta offering in the 1990s. The home page is designed entirely around its central search function. Anything unnecessary to the function, other than branding, was avoided.

Even though Google now offers a huge variety of products, its home page has changed very little over 15 years. (View large version)

Its simplicity might lead one to believe that minimalism is uncomplicated, but under the surface lies far more than just “less is more.” Let’s define characteristics of minimalism.

Only the Essentials

A minimalist strategy in web design is one that seeks to simplify interfaces by removing elements and content that do not support user tasks. To create a truly minimalist interface, a designer has to prioritize elements rigorously, showing only those elements of the highest importance and stripping away everything that would distract users from what’s important (such as superfluous decorative elements). Every item in a design, whether an image or copy, should have a purpose; it shouldn’t be included unless it’s necessary to make the message clear. As Joshua Becker mentions in the book The More of Less, “You don’t need more space. You need less stuff.”

At the same time, be sure that you aren’t making your users’ primary tasks more difficult by removing or hiding content that they need. The idea is to make the message more clear, not more hidden. Thus, design around the content, and leave just enough visible elements (such as primary navigation) so that users don’t get confused.

Negative Space

It should be no surprise that the most common element in minimalism is no element at all. Negative (or white) space is the most important feature of minimalism and gives it much of its power. Negative space is just the empty space between visual elements. More empty space means more emphasis on existing elements. In Japanese culture, it’s known as the ma principle: treating the space between objects as a means to emphasize the value of those objects.

While negative space is often called white space, it doesn’t have to be white. Some websites use full-color backgrounds to energize a blank canvas.

The primary design element that most people associate with minimalism is negative space. (Image credit: Bouguessa) (View large version)

Visual Characteristics

In a minimalist design, every detail has significance. What you choose to leave in is vital:

  • Flat texture

    Minimalist interfaces often use flat textures, icons and graphic elements. Flat interfaces don’t make use of any of the obvious highlights, shadows, gradients or other textures that would make UI elements look glossy or 3D.
A minimal visual hierarchy accentuated by touches of flat UI elements is quite common on modern websites. (Image credit: F-Secure) (View large version)
  • Vivid photography and illustration

    Images are the most prominent form of artwork in minimalist design; they enable an entire world of emotional connection and set an atmosphere. But a photo or illustration has to follow the principles of minimalism. A wrong image (such as a busy photograph full of distracting elements) would negate the benefits of the surrounding minimalist interface and ruin the integrity of the layout.
All of the characteristics of minimalism should be present in images. (Image credit: Ada Blackjack) (View large version)
  • Limited color scheme

    Color has great potential in web design because it’s able to set both informative and emotional connections between the product and the user. Color can add visual interest or direct attention without needing any additional design elements or actual graphics. Designers aiming for minimalism tend to squeeze the maximum from just a few selected colors, and it’s not that rare to use just a single color (a monochrome color scheme).
With less visual information, a color palette will be more noticeable and will heighten the impact on the user. (Image credit: Mixd) (View large version)
  • Dramatic typography

    In addition to color, typography is a core visual element. Bold typography brings immediate focus to the words and content, while helping to craft a much larger intriguing visual.
Use typography to convey meaning and create visual interest. (Image credit: The Outpost) (View large version)
  • Contrast

    Because the goal of minimalist design is ease of use and efficiency, high-contrast copy or graphic elements might be a good choice. High contrast can direct the user’s attention to important elements and make text more readable.
Many minimalist designs use only one bold color as an accent, highlighting the most important elements of the page. (Image credit: We Ain’t Plastic) (View large version)

Best Practices

Because a minimalist design demands the same level of clarity and functionality as a “normal” design, but with fewer elements, it can be a challenge for designers to create.

Have a Single Focal Point Per Screen

The minimalist philosophy centers on the idea of designing around the content: Content is king, and the visual layout salutes the king. The aim is to make the message clearer not just by stripping away distractions, but also by keeping focus on what’s important. Because minimalism involves stripping away elements that are unnecessary, a strong focal area is important.

Follow the rule of “one concept per page,” and design each page or screen to focus on only one concept, centered on a single visual. (Image credit: Bureau Tonic) (View large version)

Set Great Expectations With the Top Area of the Screen

What is visible on the page without requiring any action is what will encourage users to explore the website. To make sure that people do that, you need to provide content that keeps them interested. Thus, place high-level content with ample negative space at the top of the screen, and then increase the content density as the scroll deepens.

Apple’s home page above the fold (View large version)

Write Crisp Copy

In their book The Elements of Style, Strunk and White advise, “Omit needless words.” This is true for minimalism. Edit your copy to include only the bare minimum needed to adequately explain your message.

Get rid of all unnecessary words, and communicate as succinctly as you can. (Image credit: BFF) (View large version)

Simplify (But Don’t Hide) the Navigation

While simplicity and minimalism aren’t the same, minimalism should be simple. One thing that simplifies the user’s experience is being able to accomplish tasks easily and without distraction. The biggest contributing factor to this kind of simplicity is intuitive navigation. But navigation in a minimalist interface presents a significant challenge: In an attempt to remove all unnecessary elements and streamline the content, designers often hide some or all of the navigation. A menu icon that expands to a full list of items remains a popular design choice, especially in minimal web design and mobile UIs. This often results in lower discoverability of navigation items. Take this website’s hidden navigation:

Quite often, simple-looking, minimal UIs carry hidden complexity. In this case, the primary navigation options are hidden by default. (Image credit: Brian Hoff) (View large version)

Compare that to this website’s permanently visible navigation:

In most cases, permanently visible navigation works better for users. (Image credit: Nerds) (View large version)

Remember that easy navigation is always one of the top goals of web design. If you design minimalist websites, ensure that visitors can find what they need easily.

Incorporate Functional Animation

Like any other element, animation should follow the principles of minimalism: subtle and only what is essential. Good UI animation has a purpose: It is meaningful and functional. For example, you could use animation to save screen space (revealing hidden details on hover). The animation in the example below adds a level of discoverability, making an otherwise mundane task feel a bit more fun.

Animation makes interaction with a website more dynamic. (Image credit: UI Movement)

Use Minimalism for Landing Pages and Portfolios

While the minimalist philosophy behind content-driven design applies to every website, a minimalist aesthetic might not always be appropriate. Minimalism is well suited to portfolio websites and landing pages, like in examples below, which have fairly simple goals and relatively little content.

The portfolio of Marie Laurent is a typical example of what many designers would call a minimalist website. (View large version)
(Image credit: Ramotion) (View large version)

At the same time, applying minimalism effectively to a more complex website can be much more difficult. A lack of elements can be harmful to a content-rich website (low information density forces the user to scroll more for content). A better option might be to create a minimalist landing page that leads to more detailed pages.

Conclusion

Minimalist websites simplify interfaces by removing unnecessary elements and paring down content that does not support user tasks. What makes such websites inspiring is the combination of usability and great aesthetics: An easily navigable, beautiful website is a powerful vehicle of communication.

Resources And Tools

  • Adobe Color CC

    These minimalist color palettes deviate from the standard black on white.
  • Color Contrast Checker,” WebAIM

    Enter your background and foreground colors to calculate the ratio of contrast, to create the most accessible color combination.

This article is part of the UX design series sponsored by Adobe. Adobe XD tool 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.

Smashing Editorial(ms, yk, vf, al, il)

Non-Disclosure Agreements For Developers: What To Know Before You Sign

Most days, your goal as a developer is to design, develop and program awesome software. However, part of the job is also finding new clients, and you don’t want to be caught off guard by unexpected legal documents that come up while you’re establishing new clients.

The most common legal document you will be asked to sign when working on a website or app is a non-disclosure agreement (NDA). If you’re not sure whether to sign an NDA as a developer, this article will guide you to make an educated decision.

Staying On The Safe Side

Free sample documents and commentary are never a substitute to legal advice, but they can be quite useful to help you get an idea what needs to be included. There are a wide range of starting points for less experienced creative professionals available. Read a related article →

What Is An NDA?

An NDA is a type of contract in which one party, typically called the receiving party, agrees to keep confidential certain information it learns from the other party, typically called the disclosing party. NDAs can also be mutual, whereby each party agrees to keep certain types of shared information confidential. Frequently, an NDA will specify that the project, such as the development of a new app, should not be discussed except with those who have also signed the NDA.

An NDA is very useful for clarifying the expectations of the parties at the outset of the relationship. It also enables the disclosing party to feel comfortable sharing confidential information that is crucial for the project to proceed.

NDAs can also protect trade secrets. A trade secret could be anything from a business method to a customer list. It could even be a special formula that has economic value because it is kept secret from the general public and cannot easily be figured out by third parties based on publicly available information.

Theft of trade secrets is a major concern in both the United States and Europe. In the US, most states have already adopted the Uniform Trade Secrets Act, which defines trade secrets as well as remedies under state law for the theft of such trade secrets. In 2016, the US went one step further with the Defend Trade Secrets Act, which also protects trade secrets under federal law. In Europe, a 2013 study found that more than 20% of companies in the European Union, including many technology companies, have suffered such theft. In 2016, the European Commission proposed new rules to improve fairness and consistency across the EU with regard to access for legal actions for trade secret theft. These rules were approved by the European Council in May 2016. Therefore, in both the US and Europe, there is currently a big push to protect trade secrets and to punish violators more forcefully.

Trying to code, but you're stressed out over paperwork.
(Image: Émile Perron) (View large version)

Why Are You Being Asked To Sign An NDA?

If you are a developer, trade secrets such as algorithms, prototypes, designs, drawings and business intelligence might be of critical importance to your client’s business. Your client might even have an invention that it plans to patent.

Today, both the US and Europe use a first-to-file patent system, making it more important than ever to keep inventive information confidential until a patent application is safely on file with the US Patent and Trademark Office or the European Patent Office. Given the value of these types of intellectual property, your client will naturally want to protect them with an NDA.

Unfortunately, the histories of some of today’s most popular apps and websites are littered with examples of people who were damaged because they didn’t have a good NDA in place. Twitter cofounder Noah Glass came up with the name of the ubiquitous platform and did a lot of the early work on it, but he failed to secure NDAs at the outset of the company to protect his work and ideas. He was later forced out. Web app developer Theodore Schroeder claims that investor Ben Cohen stole his ideas about the concept of “boards” and infinite scrolling and shared them with Pinterest CEO Ben Silbermann. However, Schroeder could not prove his case, and it was dismissed. In both of these cases, a well-drafted NDA could have helped to protect these developers.

How Do You Make Sure The NDA Is Fair?

When you are given an NDA, your responsibility is to read it over and make sure it is also fair to you.

When reviewing the clauses, here are five important issues to keep in mind.

Timing

When are you being asked to sign the document, and who is asking you to sign it? Usually, it isn’t reasonable for a potential client to ask you to sign an NDA before your first conversation about the project. You don’t want to agree to something when you have no idea what the project is about or whether you might already have a conflict. However, if you have had a high-level conversation and have a good idea of the project by the time you’ve agreed to work together, then it would be appropriate for them to ask you to sign an NDA.

What Does the NDA Say About the Source of the Confidential Information?

For example, most NDAs would prohibit the receiving party from using the confidential information to develop a separate project or from using it in another party’s work. As a developer, you want the NDA to specifically say that you are prohibited from using the confidential information in such a manner if it was learned from the disclosing party. If you learn the confidential information in another way, such as through an accidental public disclosure or from a different client, you would want the NDA to be flexible enough to permit you to use it in other projects.

Confidential Information Vs. Trade Secrets

Does the NDA distinguish between treatment of confidential information and treatment of trade secrets? A well-drafted NDA will clearly identify how each type of information should be treated. For example, there may be some people in the project with whom you shouldn’t discuss trade secrets. In addition, the NDA should have a limit on the term protecting information that is merely confidential, whereas a savvy client will know that trade secrets need to be protected indefinitely.

Effective Length of Confidentiality

The NDA should clearly specify the term during which the confidential information must be maintained secret. In the fast-paced world of technology, you don’t want to be tied to an inordinately long term, because today’s new app could be tomorrow’s old news. However, as discussed above, trade secrets should always be kept confidential, because disclosure of a trade secret would destroy its value.

Consequences of Breach

In the event that one or both parties breach the agreement, the NDA needs to be clear on the consequences. A breach could lead to legal liability, monetary damage, loss of professional reputation, even a stop-work injunction from a court — not to mention the headache of being caught up in a lawsuit. Both sides should fully understand what they are asking, what is being asked of them, and what the consequences are if one or both parties do not abide by the terms of the NDA.

Red Flags

Now that you understand what an NDA is and some important things to look out for, you will want to make sure that the NDA you are signing conforms to industry standards (and if it doesn’t, ask why not). To provide a little more context, here are six red flags that could indicate you shouldn’t sign.

An Overly Broad Definition of Confidential Information

If alarm bells go off when you read the definition of confidential information, bring it up right away. An overly broad clause could impact your other work. It might be helpful to list items that are explicitly not confidential, including but not limited to publicly available information, information known prior to receiving it from the disclosing party, and information provided from a third party on a non-confidential basis. You also want something to protect you in the event of compelled disclosure, such as a subpoena or government investigation.

Excessive Term of Confidentiality

As discussed, a well-drafted agreement will differentiate between the terms of confidentiality for trade secrets and for confidential information. If it does not, or if the terms otherwise seem excessive, this is a definite red flag, especially in the fast-moving tech industry.

Every Clause Is One-Sided, or No Willingness Is Shown to Negotiate Clauses

It’s not unusual for an NDA to be slanted toward the party that is asking you to sign, especially if they are using an NDA prepared by their lawyers. However, if every clause in the document obviously favors them and they show an unwillingness to negotiate any clauses in the document, this should give you pause. A difficult client who demonstrates trust issues right from the beginning of the business relationship and shows an inability to compromise might be more trouble than they are worth.

Noncompete Clauses That Go Beyond the Scope of the Project

Read non-compete clauses very carefully. Discuss any clause that appears to go beyond the scope of the project and that could impact your work with other clients. Keep in mind that enforcement of non-compete clauses varies based on state law in the US, with some states (such as California) almost refusing to enforce them. In Europe, a company generally must show a reasonable business interest in having a non-compete clause.

Unfair Damages Clause

A good damages clause should clearly address the consequences of a breach of confidentiality. A fairly drafted clause often lists different consequences, depending on whether the breach of the agreement was intentional, negligent or without fault of the breaching party.

NDA Should Not Obligate You to Work on the Project

An NDA is not the same thing as a contract or project agreement. Nothing in the NDA should require you to work on the project. Ideally, you wouldn’t be asked to sign the NDA unless you’ve already agreed to work on the project. If the client does ask you to sign an NDA before you have agreed to work together, make sure the NDA does not obligate you to do the project once it is signed.

What To Do If You Spot A Red Flag

Sometimes a simple discussion with the client about the NDA will help. NDAs are legal documents written by lawyers, and clients themselves very often do not understand the implications of what they are asking developers to sign. Mention to the client that you have carefully reviewed the NDA and have some concerns about it and that some of the clauses seem unnecessary or excessive. Ask if the relevant clauses can be edited or removed, and gauge their response. Remember that you can also consult your own lawyer if you don’t understand something or have additional questions.

Another helpful thing you can do is to compare the NDA with a standard, publicly available NDA in order to show why one clause or another makes you uncomfortable. (Legal Templates offers a legal document builder that bills you after a 14-day trial.) You can also check out other articles that discuss important clauses for more details on any of the clauses discussed above. Comparing your NDA to these can help you better understand it and catch any unusual clauses early on. Finally, if you are truly uncomfortable with the NDA but still want to work with the client, you could ask the client simply to add a confidentiality clause to the contract that describes your working relationship instead.

When Should You Ask The Other Party To Sign An NDA?

If you are in a work-for-hire relationship as a developer, then an NDA is usually not necessary. However, if you feel that your own confidential business information needs to be protected, then a mutual NDA might be a great idea.

What types of information might need to be protected? Some examples include passwords, account numbers and login names; salary information; business methods; future business plans; and customer data. If you think you might be acting as more of a business partner than just a developer and your business ideas might be used in the eventual app or product, this is another time to consider a mutual NDA (and you’ll also want to make sure the contract that clarifies your working relationship satisfies your needs as well).

It’s normal to feel a little intimidated when reviewing a legal document. However, NDAs are a part of life for developers. If you want to work for top clients, you will be asked to sign them. A client who has an idea for the next hot app would be smart to protect it. Keep these tips in mind, and don’t hesitate to ask questions. And remember, when done correctly, an NDA can protect you and the code you write, too.

Smashing Editorial(da, vf, yk, al, il)

Pumpkins, Spooky Fellows And Fall Inspiration For Your Desktop (October 2017 Edition)

Bright, colorful leaves, rainy days, Halloween. That’s October — at least if you’re living in the Northern hemisphere. To provide you with some fresh inspiration even when the weather is gray, artists and designers from across the globe once again challenged their creative skills to design beautiful, one-of-a-kind (and this time around also spooky) wallpapers for you to indulge in.

This monthly wallpapers mission has been going on for nine years already, and we are very thankful to everyone who has and still is contributing to it each month anew. The wallpapers in this collection all come in versions with and without a calendar for October 2017 and can be downloaded for free. Happy October!

Please note that:

  • All images can be clicked on and lead to the preview of the wallpaper,
  • You can feature your work in our magazine by taking part in our Desktop Wallpaper Calendars series. We are regularly looking for creative designers and artists to be featured on Smashing Magazine. Are you one of them?

Spooky Icons And Halloween Inspiration

Spooky Pumpkins

Whether or not you celebrate Halloween, there is something magical about that special spooky day. It allows our imagination to unfold and lets us be whatever we want to be — for that one very special day (and night). Spice up your designs with some freebies and spooky designs. Get creative →

Hello, Autumn, I’m Glad to See You Again

Designed by Lívi from Hungary.

Hello, Autumn, I’m Glad to See You Again

Trick Or Treat

“Have you ever wondered if all the little creatures of the animal kingdom celebrate Halloween as humans do? My answer is definitely YES! They do! They use acorns as baskets to collect all the treats, pastry brushes as brooms for the spookiest witches and hats made from the tips set of your pastry bag. So, if you happen to miss something from your kitchen or from your tool box, it may be one of them, trying to get ready for All Hallows’ Eve.” — Designed by Carla Dipasquale from Italy.

Trick Or Treat

Hocus Pocus

“It’s time to bring that monster outside. October is the only month where people easily believe that you are a monster. We wish that you all will celebrate this Halloween with our calendar. So, ready for the Trick or Treat?” — Designed by Color Mean Creative Studio from Dubai.

Hocus Pocus

Haunted House

“Love all the halloween costumes and decorations!” — Designed by Tazi from Australia.

Haunted House

Happy Halloween

“It’s the time of the year when people light bonfires and wear costumes to ward off roaming ghosts. It is October and it’s Halloween time!” — Designed by BootstrapDash from India.

Happy Halloween

A Very Pug-o-ween

“The best part of October is undoubtedly Halloween. And the best part of Halloween is dog owners who never pass up an o-paw-tunity to dress up their pups as something a-dog-able. Why design pugs specifically in costumes? Because no matter how you look at it, pugs are cute in whatever costume you put them in for trick or treating. There’s something about their wrinkly snorting snoots that makes us giggle, and we hope our backgrounds make you smile all month. Happy Pug-o-ween from the punsters at Trillion!” — Designed by Trillion from Summit, NJ.

A Very Pug-o-ween

Halloween

“I love the spirit of Halloween and the energy that comes with it.” — Designed by Swati Rastogi from India.

Halloween

Autumn Gate

“The days are colder, but the colors are warmer, and with every step we go further, new earthly architecture reveals itself, making the best of winters’ dawn.” — Designed by Ana Masnikosa from Belgrade, Serbia.

Autumn Gate

Happy Fall!

“Fall is my favorite season!” — Designed by Thuy Truong from the United States.

Happy Fall!

Tea And Cookies

“As it gets colder outside, all I want to do is stay inside with a big pot of tea, eat cookies and read or watch a movie, wrapped in a blanket. Is it just me?” — Designed by Miruna Sfia from Romania.

Tea And Cookies

Hello Pumpkin

“Pumpkins, you can see them everywhere you look this month and not only for Halloween but also as autumn decorations.” — Designed by Melissa Bogemans from Belgium.

Hello Pumpkin

Happy Birthday R.L. Stine!

“8th October is the birthday of one of my favourite horror authors, R.L. Stine. Growing up, I have always loved reading the Goosebumps books, my favourite was ‘Night of the Living Dummy’.” — Designed by Safia Begum from the United Kingdom.

Happy Birthday R.L. Stine!

Boo!

“Sometimes it can get a little scary in Washington D.C., other times it can get adorably so.” — Designed by The Hannon Group from Washington D.C.

Boo!

Pumpkin Season

Designed by Ilaria Bagnasco from Italy.

Pumpkin Season

Deadline Hurry-Burry

“We all have the potential to create fine things, perhaps wondrous things. However, it’s only the last-minute hurry-burry that makes us realize the gravity of what we are midst. It untangles all the hiccups and urges us to spring up to a different world of fashioning incredible things!” — Designed by Sweans from London.

Deadline Hurry-Burry

Hanlu

“The term ‘Hanlu’ literally translates as ‘Cold Dew.’ The cold dew brings brisk mornings and evenings. Eventually the briskness will turn cold, as winter is coming soon. And chrysanthemum is the iconic flower of Cold Dew.” — Designed by Hong,ZI-Qing from Taiwan.

Hanlu

Rainy Romance

Designed by UrbanUI from India.

Rainy Romance

Be The Change For The Good

“We are witnessing violence and hatred around the world in the name of nationality, religion, creed, caste, etc. These are what Mahatma Gandhi had stood against. Let us pledge to become the reason of change to bring about a change in the world around us, following what Gandhji left behind.” — Designed by Acodez IT Solutions from Mumbai, India.

Be The Change For The Good

Festival Of Lights

“In India, one of the most celebrated festival is Diwali or the Festival of Lights. It’s a five-day celebration that includes delicious food, fireworks, colored sand (Rangoli), lovely earthen lamps (Diya) and lanterns. Diwali is celebrated beyond cultures and religions, embracing all. Its signifies the victory of good over evil and light over darkness. Happy Diwali to everyone!” — Designed by Hemangi Rane from Gainesville, FL.

Festival Of Lights

Oktoberfest

“Say cheers to October!” — Designed by Mozilor Technologies from India.

Oktoberfest

Dreams Of Flying

Designed by Template Watch from India.

Dreams Of Flying* [preview](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/oct-17-dreams-of-flying-preview.png “Dreams Of Flying – Preview”)* with calendar: [360×640](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-360×640.png “Dreams Of Flying – 360×640”), [1024×768](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1024×768.png “Dreams Of Flying – 1024×768”), [1280×720](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1280×720.png “Dreams Of Flying – 1280×720”), [1280×800](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1280×800.png “Dreams Of Flying – 1280×800”), [1280×960](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1280×960.png “Dreams Of Flying – 1280×960”), [1280×1024](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1280×1024.png “Dreams Of Flying – 1280×1024”), [1366×768](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1366×768.png “Dreams Of Flying – 1366×768”), [1400×1050](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1400×1050.png “Dreams Of Flying – 1400×1050”), [1440×900](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1440×900.png “Dreams Of Flying – 1440×900”), [1600×900](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1600×900.png “Dreams Of Flying – 1600×900”), [1680×1200](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1680×1200.png “Dreams Of Flying – 1680×1200”), [1920×1080](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/cal/oct-17-dreams-of-flying-cal-1920×1080.png “Dreams Of Flying – 1920×1080”)* without calendar: [360×640](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-360×640.png “Dreams Of Flying – 360×640”), [1024×768](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1024×768.png “Dreams Of Flying – 1024×768”), [1280×720](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1280×720.png “Dreams Of Flying – 1280×720”), [1280×800](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1280×800.png “Dreams Of Flying – 1280×800”), [1280×960](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1280×960.png “Dreams Of Flying – 1280×960”), [1280×1024](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1280×1024.png “Dreams Of Flying – 1280×1024”), [1366×768](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1366×768.png “Dreams Of Flying – 1366×768”), [1400×1050](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1400×1050.png “Dreams Of Flying – 1400×1050”), [1440×900](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1440×900.png “Dreams Of Flying – 1440×900”), [1600×900](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1600×900.png “Dreams Of Flying – 1600×900”), [1680×1200](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1680×1200.png “Dreams Of Flying – 1680×1200”), [1920×1080](http://files.smashingmagazine.com/wallpapers/oct-17/dreams-of-flying/nocal/oct-17-dreams-of-flying-nocal-1920×1080.png “Dreams Of Flying – 1920×1080”)### Happy Diwali“May the festival of lights be the harbinger of joy and prosperity. Happy Diwali!” — Designed by [Star Bootstrap Admin Dashboard](https://github.com/BootstrapDash/StarAdmin-Free-Bootstrap-Admin-Template) from India.

Happy Diwali

Endless Opportunities

Designed by Metrovista from Orlando, FL.

Endless Opportunities

No Such Thing As Ghosts

“It’s Halloween on the 31st, and that’s what inspired my ghostly design this month!” — Designed by James Mitchell from the United Kingdom.

No Such Thing As Ghosts

Everything Changes

“Time will pass and seasons will come and go!” — Designed by PlusCharts Javascript Charts from India.

Everything Changes

Join In Next Month!

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

A big thank you to all designers for their participation. Join in next month!

What’s Your Favorite?

What’s your favorite theme or wallpaper for this month? Please let us know in the comment section below.

CSS Grid Gotchas And Stumbling Blocks

With grid all of our sizing happens on the container. Once we have created our grid tracks, we can then tell individual items how many tracks to span, but we have an actual grid. We can completely lose row wrappers as grid already has rows. This also means that we can have items span rows too, in exactly the same way as we span columns. Something that has been very difficult to do before now.

Example 5: A 12-column layout using Grid.

Should Grid Be Used For Main Layout And Flexbox For Components?

This myth keeps popping up as people start to learn grid layout. Perhaps it comes from the use of grid systems such as those found in Bootstrap or Foundation where we are concerned with placing items on an overall grid. That is certainly one way to use grid layout. I would however move to thinking about the differences I mentioned in the last section. Ask yourself, is this layout one or two dimensional?

If you can take your component and draw a grid over it, with rows and columns. It is two-dimensional — use grid layout for that.

A grid has strict rows and columns. Changing the size of an item in a cell in a row or column will change the size of the entire track.

If instead, you want individual items to expand within a row, without respecting what happens in the row above. That’s a flex layout.

In this flex layout we want items to arrange themselves by row, and not try to line up as columns.

It doesn’t matter if the item you are trying to lay out is a full page, or a tiny component. What matters is how you want the items inside that layout to distribute space and relate to each other.

Can Grid Track Sizing Be Dictated By Content?

We’ve now seen how, when using Grid Layout, we set up the grid and grid sizing on the container. However it is possible for items inside the grid to dictate track sizing. The key thing to remember here is that a change of size in one cell will change the size all along that track. If you don’t want that to happen, you probably want a single dimensional flex layout.

The simplest way in which we see items changing the sizing of their track is when we use auto, which is the default for tracks created in the implicit grid. An auto sized track will expand to contain all of the content placed into it. In the example below I have a two-column layout, adding more content to the right hand column causes the whole row to expand. The second row is also auto sized, again expanding to contain the content.

Example 6: A two-column layout with content.

We can allow tracks to size within two parameters, for example creating tracks that are at least a minimum size but will still grow to accommodate larger items. We do this with the minmax() function. The first value passed into minmax() being a minimum size for the track, and the maximum the maximum size. Therefore you can form rows that are 200 pixels tall but by setting the maximum as auto ensure that you don’t end up with overflows when there is larger content.

Example 7: minmax() allows fixed height until too much content is entered.

We also have some interesting new sizing keywords, that I’ll be having a proper look at in a future article. These work with grid specifically to allow content to change track sizing, and can be found detailed in the CSS Intrinsic and Extrinsic Sizing module. The keyword min-content for example, when used for grid track sizing will create a track that displays as small as possible when all soft-wrapping opportunities are taken.

In my example below this means the word opportunities. becomes the widest thing and the track shrinks down to fit that.

Example 8: min-content.

The opposite happens if you use max-content — you get a track that stretches as large as possible without wrapping. This may lead to overflow situations, in my example I have set the grid to overflow: scroll so the max-content track is causing a scrollbar.

Example 9: max-content.

Once again, the key thing to remember is that this is going to happen right across the track. You need to ensure that items in other cells of that track will also absorb that extra space neatly.

Understanding how to size tracks, and how content will change track sizing is probably one of the things that newcomers to grid layout find most confusing. It’s ok to find this takes a little while to understand — we’ve not had anything that behaves like this before. Play with examples, it is the best way to start to understand how things work.

Can I Do A Masonry Layout With Grid?

There is a misconception that grid layout is the same as a Masonry or Pinterest layout. This is generally based on seeing how auto-placement works in grid layout, which at first look seems a bit like Masonry. In this next example I have a layout using auto-placement with grid-auto-flow set to dense. This causes grid to pick items up, take them out of source order and try to backfill gaps in the grid.

Example 10: Using dense packing.

However this isn’t really Masonry as we still have a strict grid of rows and columns, and potentially items are taken out of source order. A real Masonry layout would keep things in source order working across the row. Items are pushed up to fill partial spaces left. It’s more like doing flex layout but in both dimensions at once.

a Masonry-style Layout currently needs JavaScript, such as this example using macy.js — macyjs.com. (Large preview)

You can get the look of Masonry with a grid layout by positioning all of your items but the ability to do an auto-placed Masonry layout isn’t there yet. It is something we are thinking about however for future levels of the specification.

How Do I Add Backgrounds And Borders To Grid Areas?

While on the subject of things that grid doesn’t do yet, a common request is to style the backgrounds and borders of the grid areas themselves. Can you add borders and visually display the grid? At the current time this isn’t possible, you need to insert an element and style that, this could be an HTML element but could also be some generated content.

In this next example I have added some generated content to the grid, positioned it using line-based placement and then added a background and border to that area.

Example 11: Generated content can be styled to add a background or border to an area.

Another thing I sometimes do to get round the lack of backgrounds and borders, is use a single pixel grid gutter — as in this next example.

Example 12: Using a 1px gutter in a contrasting colour to fake cell borders.

To be able to have proper styling of areas of the grid we would need to introduce the concept of grid area pseudo-elements, a special sort of generated content. There is an issue raised regarding this on the CSS WG GitHub site, so you can follow discussion and add your own thoughts.

Spanning To The End Of The Grid

Grid Layout has a concept of the implicit and explicit grid. The Explicit grid is the grid that we define when we use grid-template-rows and grid-template-columns and pass in a track listing. This track listing defines the extent of the explicit grid. The implicit grid is created when we place an item outside of the explicit grid, or when we have more items placed via auto-placement than we have created tracks for.

Tracks created in the implicit grid will be auto sized unless you set a track sizing using grid-auto-rows or grid-auto-columns.

In many cases the implicit and explicit grids behave in the same way, and for many layouts you will find you define columns and then allow the rows be created as an implicit grid. There is a difference however that trips people up, and this is found when you start using negative line numbers to refer to the end line of the grid.

Line -1 is the end of the explicit grid

Grid respects writing mode. In a left to right language, column line 1 is on the left and you can us line -1 to target the right-hand column line. In a right to left language, column line 1 is on the right and -1 will target the left-hand line.

Example 12: Using line numbers on the grid I left to right and right to left directions.

Where people get caught out is that it is only the explicit grid that can count backwards. If you have added rows in the implicit grid and then try to target the end line with -1, you will find that you get the last explicit grid line and not the actual end of your grid.

Example 12: Line -1 represents the end of the explicit grid.

I’m Having Trouble With My Percentages!

At the beginning of this article I described how grid is very different to the layout methods that came before it. Due to the limitations of float and flex-based grids, we have needed to become good at calculating percentages in order to do layout and so the first thing that most people do is try and use the same method in their grid layouts. However, before doing so don’t forget our new friend the fr unit. This unit is designed for grid, and works because of the way that grid sets up sizing on the parent element.

The fr unit allows us to distribute a share of available space. It does so by looking at what space is available in the grid container, taking away any space needed for gutters, fixed width items, or content that is defining track sizing and then sharing out the rest according to the proportions we have specified for the tracks. This means that the scenario we have with a floated or flex layout for example, where we have to have flexible gutter tracks so that all of our percentages add up, isn’t the case with grid layout.

Example 14: Using the fr unit, the space needed for fixed sized gutters and tracks is removed before space is distributed..

In most cases the fr unit is a better choice than percentages. A reason you might choose to use percentage would be where you need a grid layout to match up with other elements using some other layout method and relying on percentage sizing. However if that isn’t the case, see if the fr unit will serve your needs before starting down the route of doing all the maths yourself!

Can I Nest Grids?

A grid item can also become a grid container, in the same way that a flex item can become a flex container. These nested grids however have no relationship to the parent grid, so you can’t use them to line up internal elements with other nested grids.

Example 15: Grids inside grids.

Example 15: Grids inside grids

In a future level of grid layout we may well have a method of creating nested grids that do maintain relationship to the parent grid. This would mean that items other than direct children of the grid could participate in an overall grid layout.

Can I Polyfill Grid Layout?

I’m often asked if there is a way to polyfill grid layout, with people wanting to know if there is a drop in and forget it way to support older browsers.

My advice would be that this isn’t something you want to do. It is likely to create a very slow and janky experience for those browsers already struggling to render modern websites. If you need older browsers to look identical to modern ones then maybe you should reconsider using grid on this project. However in most cases it is possible to use older methods to create a simpler fallback tailored to non-supporting devices without needing to create two completely different sets of CSS. This really needs an article to cover it in detail, so look out for that on Smashing Magazine soon!

Debugging Grid Layouts

As you start to work with grid you will quickly want to be able to see your grid and how the items on it are laid out. I would suggest that you download a copy of Firefox Nightly and use the Grid Inspector in the Firefox DevTools. If you select a grid you can then click the small grid icon — which I like to think of as a waffle — to display the grid.

Using the Firefox Grid Inspector. (Large preview)

Firefox have created an excellent tool here, and while Chrome have begun to implement something into Chrome DevTools, right now the Firefox tool is the best in class and it makes working with grid so much easier.

This Is Still New To All Of Us

I know the CSS Grid specification very well, but I’ve only been able to use it in production since March, just like everyone else. As we all move from creating little examples and really start to push the edges of the specification in production work, we will start to find new ways to use grid and of course new problems to solve! I would love to see your own write-ups and demos of the way you are using Grid and other layout methods. I’m also going to be digging into layout issues here at Smashing Magazine over the next few months, so do let us know what you are finding out, and what you would like to know more about.

Smashing Editorial(yk, vf, il)

An Overview Of The Most Common UX Design Deliverables

(This is a sponsored post). What do UX designers do on a daily basis? A lot of things! UX professionals need to communicate design ideas and research findings to a range of audiences. They use deliverables (tangible records of work that has occurred) for that purpose.

The list below contains the most common deliverables produced by UX designers as they craft great experiences for users. For better readability, I’ve combined the deliverables according to UX activities:

  1. Project Assessment
  2. Competitor Assessment
  3. User Research
  4. Information Architecture
  5. Interaction Design

If you’d like to create and design your own prototypes a bit more differently, you can download and test Adobe XD, and get started right away.

Obtaining The Best Mobile User Experience Possible

Always remember that design isn’t just for designers — it’s for users. It’s important to treat your work as a continually evolving project, and use data from analytics and user feedback to constantly improve the experience. Read a related article →

Project Assessment

Project assessment is an evaluation process which helps UX designers understand a current state of the product.

Analytics Audit

An analytics audit is a way to reveal which parts of a website or app are causing headaches for users and are reducing conversions. During an analytics audit, an auditor will use a variety of methods, tools and metrics — traffic sources, traffic flows, conversions (and abandonments) hot spots, etc. — to analyze where a product is going wrong (or right). Ultimately, an analytics audit should enable UX designers to know how to boost conversions by making it easier for users to achieve their goals on the website or app.

Numbers provided by an analytics tool on how the user interacts with a product — clicks, user session time, search queries, conversion, etc. — will help UX designers to uncover the unexpected, surfacing behaviors that aren’t explicit in user tests. (Image: Ramotion) (View large version)

Tip: Get into the habit of A/B testing your design changes. Knowing that all of your changes will be A/B tested will give you a tremendous amount of freedom to try new (and potentially risky) things. If they work, you’ll find out almost immediately. Also, you won’t need to worry that some change you’ve made will ruin everything.

Content Audit

Content audit is the process of evaluating information assets on some part or all of an app or website. It could be said that a content audit is a content inventory and evaluation of each page’s content (either qualitative by a person or quantitative using analytics) and/or an assignment of content owners. It involves gathering all of the content on your website or in your app and assessing its relative strengths and weaknesses in order to prioritize your future marketing activities. By auditing, you’ll understand the content much better. You might find things you didn’t know existed, spot duplicated or outdated content, or identify all kinds of relationships in the content. The results of a content audit can be used for a global task (creating a content strategy) or a local task (optimizing a certain page).

(Watch video)

Usability Test Report

Usability testing is a way to see how easy a product is to use by testing it with real users. A usability test report summarizes usability findings in a clear, concise and descriptive way, helping the project team to identify issues and work towards a solution.

An example of usability testing report. (Image: tiffanyho) (View large version)

Tip: Rank your findings. Every issue that’s discovered through usability testing is not equally important. A usability report could have 5 or 100 findings, depending on the scale of the study, and sometimes it might be overwhelming for a team to go through all of them. That’s why findings should be ranked in terms of severity (low, medium or high). This will help the team identify critical issues exposed by the usability study.

Competitor Assessment

Competitor assessment is an assessment of the strengths and weaknesses of current and potential competitors. Assessing the strengths and weaknesses of your rivals is a critical part of your own UX strategy.

Competitive Analysis Report

An analysis of competitor’s products will map out their existing features in a comparable way. This competitive analysis report helps UX designers to understand industry standards and identify opportunities to innovate in a given area.

A competitive analysis allows designers to assess a competitor’s strengths and weaknesses in a selected marketplace and implement effective strategies to improve a product’s competitive advantage. (Image: yellowpencil) (View large version)

Tip: A useful starting point for identifying strengths and areas for improvement might be user experience heuristics. While competitive analysis isn’t intended to replicate heuristics evaluation, heuristics can be a good starting point because they offer a good structure for presenting information. Heuristics include efficient navigation, clarity of text and labels, consistency, readability, scannability, etc.

Value Proposition

A value proposition is a statement that maps out the key aspects of a product: what it is, who it is for and how it will be used. A value proposition helps the team form consensus around what the product will be.

A value proposition helps UX designers to keep focus on the important things. (Image: UX Mag (View large version)
(Watch video)

Tip: Make sure your value proposition is directly associated with key business objectives. By doing this, it will be much easier to have discussions about time and budget for UX activities.

User Research

User research focuses on understanding user behaviors, needs and motivations through observation techniques, task analysis and other feedback methodologies.

Personas

A persona is a fictional character who uses the product in a similar way to a potential user type. Personas make it easier for designers to empathize with users throughout the design process. Personas are a controversial tool in the UX armory: Some UX designers love them, others hate them. Thus, it’s important to understand not just benefits but also downsides of personas before using them in your UX design process.

A persona is a fictional character who highlights the behaviors, needs and motivations of your target users. (Image: xtensio) (View large version)

Tip: The most effective personas are created from in-depth user interviews and observation data of real users. Collect as much information and knowledge about users as possible by interviewing and/or observing a sufficient number of people who represent your target audience.

User Story

A user story is a simple description of a feature told from the perspective of a user of the product. Basically, it’s a very high-level definition of a requirement (at a conceptual level), containing just enough information that the developers can produce a reasonable estimate of the effort required to implement it.

(Image: realtimeboard) (View large version)

Tip: Use user stories to prevent feature creep. Feature creep is a term that comes up regularly during product design. It refers to the tendency to want to keep adding more features and expanding the scope of a project. Try to refuse to add any feature without a user story that explains why that particular feature matters.

Use Cases

A use case is a written description of how users will perform tasks in the app or website. It outlines, from a user’s point of view, an app or website’s behavior as it responds to a request. Each use case is represented as a sequence of simple steps, beginning with a user’s goal and ending when that goal is fulfilled.

A use case is a list of actions or steps in an event, typically defining the interactions between a user and a system, to achieve a goal. (Image: Slideshare) (View large version)

Tip: Use cases aren’t reserved for the UX phase; they can used for the QA phase as well. Thus, when reviewing the usability of a given product, it’s critical that the QA specialist have the use cases on hand. This will give the QA specialists a set of criteria that will have to have been addressed by the design.

Experience Map

An experience map is a diagram that explores the multiple steps taken by users as they engage with a product. It enables designers to frame the user’s motivations and needs at each step of the journey, designing solutions that are appropriate for each.

A simple experience map reflects one possible path during one scenario. (Image: effectiveui) (View large version)
How to create a customer journey map (Watch video)

Tip: The process of creating a customer journey map has to begin with getting to know users. While you can turn to many sources for data about your users, one of the most obvious is website or mobile app analytics. Analytics provide valuable insight into what users are doing on your website or in your app, and this data will help you build compelling cases.

Storyboards (Current)

Storyboards are illustrations that represent shots and that ultimately represent a story. In UX, this story is the series of actions that users would take while using the product. Storyboards help designers to honor the real experiences of the people for whom they are designing.

Smiles and expressions of sadness on human faces have a strong emotional impact. This makes it possible to bring a story to life in the hearts and minds of your audience. (Image: Chelsea Hostetter) (View large version)

Tip: When thinking about storyboarding, most people focus on their ability (or inability) to draw. The good news is that you don’t need to be good at drawing before you start drawing storyboards. What is far more important is the actual story you want to tell. Clearly conveying information is key.

Storyboard frame from Martin Scorsese’s film Goodfellas. (View large version)

Survey

A survey is a quick and inexpensive way to measuring the level of user satisfaction and to collect feedback about the product. While a survey is a great way to collect information from a large number of users, it’s obvious limitation is a lack of qualitative insights — for example, why customers use the product in a certain way.

(Watch video)

Tip: Keep the survey short. The temptation when creating a survey is to add more questions. The problem is that it can become painfully long, and people will simply skip questions. If you want to collect more valuable information, you should use a better approach. Keep the survey succinct and run another in a month or two.

Information Architecture

Information architecting is the practice of deciding how to arrange the parts of something to be understandable. For digital products, information architecture results in the creation of navigation, site maps, taxonomies and wireframes.

(Image: Murray Thompson, UX Booth) (View large version)

Site Map

A site map is a diagram of a website’s pages, organized hierarchically. It makes it easy to visualize the basic structure and navigation of the website.

Site map example (Image: Behance) (View large version)

Tip: If you want to create site map quickly and easily, use the card-sorting method.

Taxonomy

A taxonomy results from an exploration of multiple ways to categorize content and data: articles in a news website, product categories in an e-commerce app, etc. A taxonomy helps designers to define the content structure that supports the user’s and the business’ goals.

(Image: Christian Ricci) (View large version)

Tip: A taxonomy is a living document, and it needs to be retested and updated regularly.

Wireframe

A wireframe is a visual guide that represents a page’s structure, as well as its hierarchy and key elements. Wireframes are useful when UX designers need to discuss ideas with team members and stakeholders, and to assist the work of visual designers and developers.

Wireframes can be presented in the form of sketches:

Sketching is a quick way to visualize an idea (such as a new interface design). (Image: Nicholas Swanson) (View large version)

Wireframes can also be presented as digital illustrations:

Example of wireframes for a mobile app. Download Wires, two free wireframe UX kits for mobile and web, built for Adobe XD. (View large version)
(Watch video)

Tip: Keep wireframes simple, and annotate. The aim of a wireframe is to show the structure of a page’s design — details come later. If you plan to present a wireframe to the team, try to include annotations. Annotations help to create context and quickly deliver key ideas.

Interaction Design

Interaction design (often abbreviated as IxD) is the practice of designing interactive digital products. It’s a process by which designers create engaging user interfaces with logical and thought-out behaviors and actions.

Storyboards (Planned)

Basically, this is the same storyboard that we saw in the section on user research, with just one difference: These storyboards are used to sell design solutions. Designers use them to show the benefits of a proposed solution and to convince stakeholders with it.

(Image: digiflip) (View large version)

Tip: Design a clear outcome. Make sure your storyboard leaves the audience with no doubt about the outcome of the story. If you’re describing an unfavorable situation, end with the full weight of the problem; if you’re presenting a solution, end with the benefits of that solution for your character.

User Flow Diagram

A user flow diagram is a visual representation of the user’s actions to complete tasks within the product. A visualized user flow makes it easier to identify which steps should be improved or redesigned.

User flow helps build a common understanding of each page of your app or website. (Image: Behance) (View large version)

Tip: For many projects in the active design phase, creating user flows might be time-consuming, because drawings will become instantly outdated as screens change. Ryan from Basecamp proposes a simplified version of user flows. This format is really fast to sketch, and it communicates the essentials of what needs to happen.

Prototype

A lot of people use the terms “wireframe” and “prototype” interchangeably, but there’s a significant difference between the two design deliverables: They look different, they communicate different things, and they serve different purposes. While wireframes are similar to architectural blueprints (for example, a building plan), a prototype is a mid- to high-fidelity representation of the final product. The goal of a prototype is to test products (or product ideas) before investing a lot of time and money in the final product.

A prototype gives a taste on how the user will interact with the product. It can be analog:

Low-fidelity analog prototype (Video: UX Playground) (View large version)

Or it can be digital:

High-fidelity interactive prototype created in Adobe XD and mirrored on an iPhone (View large version)

The most important thing is that the prototype should allow the user to experience content and test the main interactions with the interface in a way similar to how they would with the final product.

Tip: Test prototypes on real devices as much as possible. While an emulator on your desktop might work in some cases, nothing replaces experiencing designs on a real device.

Conclusion

Most likely you are surprised by the number of deliverables mentioned in this article. Rest assured, each project is different and a UX designer wouldn’t need to produce all of them for each project. Also, remember that there is no one-size-fits-all deliverable that will be equally effective for all projects. Each deliverable becomes an effective communication tool in the right context and with the right audience.

This article is part of the UX design series sponsored by Adobe. Adobe XD tool 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 visit the Adobe XD blog to stay updated and informed.

Smashing Editorial(ms, vf, yk, al, il)

60 Travel Icons To Awaken Your Wanderlust (Freebie)

Summer might be over, but the memories of the places you’ve visited and the people you’ve met remain. No matter if you explored an exotic country, packed your car for a road trip or took out the hiking boots to discover the nature around you — traveling is a great opportunity to discover new places, gain a fresh view on things, and make lasting experiences.

To keep the essence of summer alive a bit longer, the creative minds at AgenteStudio dedicated an entire icon set to traveling. It includes 60 icons with everything from transportation and equipment to nature, activities and other motifs that are bound to awaken your wanderlust. The icons come in two versions — one monochromatic line art and one with color accents. EPS, AI, SVG and PNG formats are available, so it’s easy to customize the icons to your liking.

Travel icons cover shot
Pack your suitcase and let the travel adventure begin! Where will it lead you? (Full preview)

Please note that this icon set is released under a Creative Commons Attribution 4.0 International license. This means that you may modify the size, color, and shape of the icons. Attribution is required, so if you would like to use the icons, please do remember to credit the designers and to link to this article if you want to spread the word in blog posts or anywhere else.

Looking For More Free Icons?

Touristic Icons

Whether it’s the London Bridge, the Sydney Opera House, or the Taj Mahal, monuments such as these can be used to create logos to adorn websites, travel guides, and even video motion graphics. We’ve got a freebie in vector format ready to be used in any type of medium right away! Download the freebie →

A Closer Look At The Travel Icon Set

Closeup Travel Icons
Red and blue color accents give the icons a fresh, airtravel-inspired look. (Full preview)
Closeup Travel Icons
Only your imagination is the limit. Why not use the anchor to illustrate “security”, for example, or the lighthouse for staying in touch? (Full preview)

Full Preview Of The Icon Set

Full preview Travel Icons
(Larger view)

Insights From The Designers

“Summer is one of our favorite seasons. It is the best time to travel, gain new experience, and discover wonderful things. We decided to share our passion for this season with you by creating one more icon set. Our first set was devoted to the most beautiful cities of the world, and this set contains the coolest travel symbols (in our opinion).”

Download The Icon Set For Free

A big thank you to the folks at AgenteStudio for designing this wonderful icon set — we sincerely appreciate your time and efforts! Keep up the fantastic work!

Exploring Animation And Interaction Techniques With WebGL (A Case Study)

Two years ago, I decided to start a series of short WebGL experiments on Codepen. Earlier this year, I finally found the time to compile them all together on a single website named “Moments of Happiness”. Since its incarnation, I’ve found ways to explore and learn different animation and interaction techniques, which I’ve implemented in these interactive toys.

As you’ll see, the gameplay is very different in each one, but all of the experiments share one principle: The behavior of each character responds programmatically to user input. No precalculated animation — every movement is defined at runtime. Breathing life into these characters with only a few lines of code was the main challenge.

Defining Animations And Explaining Their Purpose

When an animation doesn’t fit a functional purpose, it usually feels awkward or annoying. Well, there are nine logical purposes that can help you validate functional animation. Read a related article →

A Process Of Constraints

Mainly built using three.js and GreenSock libraries, these experiments were completely hand-coded, with no resort to any 3D or animation software.

The process consisted of shaping the characters programmatically, one cube at a time. Most of my effort was spent refining the proportions, the positions and the overall rendering by tweaking the values in the code, and then, finally, moving each part according to user input (moving the mouse, clicking, dragging, etc.).

The advantage of this process isn’t obvious. But it enables me to use only a text editor to create the whole experiment, thereby avoiding all of the struggle of exporting assets and adjusting the properties of the characters using many tools. Taking advantage of the live preview offered by Codepen made the whole process very flexible.

That being said, the process came with its own set of constraints to keep things manageable: The characters had to be built with as few parts as possible; each part consisted of a very low number of vertices; and the animations had to target a limited number of behaviors.

Note:To be clear, this process works for me, but if you are comfortable with a 3D app, you’d better use it to make your models. It’s all about finding the right balance between your own skills to be as effective as possible. In my case, I’m much more efficient when I keep all of my processes in a single tool.

Moments of Happiness
Moments of Happiness is a series of WebGL experiments that will make you happy.

Turning Constraints Into Opportunities

The minimalism required by this process was, in the end, a great opportunity to find the most accurate movement to depict each behavior (comfort, joy, disappointment, etc.).

Every cube and every movement was subject to questioning: Do I really need this one? Does it make the experience better, or is it just the whim of a wannabe character designer?

I ended up with very simple toys, all living in muted and minimalist environments.

Sneeze the dragon
The characters are mainly built with cubes — even the fire and smoke were, too!

Animating things programmatically was probably the biggest challenge. How do you build natural and organic movement without any animation software or visual timeline? How do make this animation respond to user input while keeping it natural?

Step 1: Observation

Before starting any of these experiments, I spent some time observing, remembering and conjuring the feelings I wanted to convey.

By the time I made Chill the Lion, petting my dog had become a great source of inspiration; I observed how he closed his eyes for pleasure and exposed his neck to ask for a scratch. Finding the right algorithm to programmatically translate this was a mix of empathy and basic math skills.

Chill the lion
Oh, that feeling!

For the “paranoid birds” (below), I remember imitating an uncomfortable-looking guy who had a fleeting look, trying to make the behaviour look convincing by figuring out how much time separated his eye and head movement.

Paranoid vs Shy Birds
Capturing this awkward movement is just a matter of life experience.

But sometimes, you can’t just rely on your own experience; visual inspiration is sometimes necessary to catch a particular trait. Fortunately, there is Giphy, where you can find subtle expressions of any kind. I also spent a lot of time on YouTube and Vimeo looking for the right movements.

Let’s see an example.

Observing a Running Cycle

One of the trickiest animations I had to make in Moments of Happiness was the rabbit fleeing from the wolf.

The frantic running of the valiant rabbit
There are as many ways to run as there are reasons to flee.

To achieve this, it was first important to understand how a running cycle works. I looked at some of the most exciting slow-motion GIFs available on Giphy, and I came across this one:

Dogs running
(Image: Giphy)

What is interesting to note in this GIF is that a running cycle is not just about moving legs. It is about the whole body, including the smallest parts of it, moving in perfect synchronization. Look at the ears, the mouth and even the tongue participating to enhance the feeling of speed and gravity.

The truth is that there are as many possible running cycles as there are animals and reasons to run. It wouldn’t be a bad idea to have other more accurate references to look at if you want to dig into running cycles. Two useful resources are the “Run Cycle” collection on Pinterest and the awesome “Quadruped Locomotion Tutorial” video.

If you look at these studies, the mechanics behind each running cycle become clearer. Your brain will start to catch on to the relationship between each part of the body, and the sequence and rhythm in the race will reveal a cyclic, repeated and reproducible form.

Now, we need a technical solution to achieve this.

Observing Automatas

Being fascinated by automatas, those mechanical toys that come alive in complex movement as you rotate a single handle, I wanted to try a similar technique and explore a code-based solution that fits my process better than a timeline and keyframes.

The idea is that a looping movement, simple or complex, depends entirely on the progress of one main cycle.

Automata
An automaton, a complex animation driven by one rotation of the handle, from Brinquedos Autômatos.

In a running cycle, this entails that each leg, ear, eye, body and head movement is driven by the same main cycle. In some cases, the rotation generated is converted into a horizontal movement and, in other cases, into a vertical one.

When it comes to converting a circular movement into a linear one, trigonometry seems to be the best option.

Step 2: Sharpen Your Weapons, Learn Trigonometry

Don’t run away! The kind of trigonometry needed here is very basic. Most of the formulas will look like this:

x = cos(angle)*distance;y = sin(angle)*distance;

This is basically used to convert the polar coordinates of a point (angle, distance) to Cartesian coordinates (x, y).

By varying the angle, we can make the point rotate around the center.

Trigonometry principles
Converting polar coordinates into Cartesian coordinates

Thanks to trigonometry, we can do much more sophisticated movement, just by playing around with the different values of the formulas. The beauty of this technique is the smoothness you get in the movement.

Here are some examples:

Examples of animations made with trigonometry principles
Examples of animations made thanks to trigonometry principles

Now, You Practice

To understand trigonometry, you’ll have to get your hands dirty. Theory without experience is mere intellectual play.

In order to implement some of the formulas above, we’ll need to set up a basic environment. This can be done using canvas, SVG or any library with a graphics API, such as three.js, PixiJS or BabylonJS.

Let’s walk through a very basic three.js setup.

First, download the latest version of three.js, and import the library in the html head:

<script type="text/javascript" src="js/three.js"></script>

Then, add a container, which will hold the whole experiment:

<div></div>

Make this container cover the screen by adding a CSS style:

#world { position: absolute; width: 100%; height: 100%; overflow: hidden; background: #ffffff;}

The JavaScript part is a bit longer, but not that complicated:

// Initialize variables.var scene, camera, renderer, WIDTH, HEIGHT;var PI = Math.PI;var angle = 0;var radius = 10;var cube;var cos = Math.cos;var sin = Math.sin;function init(event) { // Get the container that will hold the animation. var container = document.getElementById('world'); // Get window size. HEIGHT = window.innerHeight; WIDTH = window.innerWidth; // Create a three.js scene; set up the camera and the renderer. scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera( 50, WIDTH / HEIGHT, 1, 2000 ); camera.position.z = 100; renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setSize(WIDTH, HEIGHT); renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1); container.appendChild(renderer.domElement); // Create the cube. var geom = new THREE.CubeGeometry(16,8,8, 1); var material = new THREE.MeshStandardMaterial({ color: 0x401A07 }); cube = new THREE.Mesh(geom, material); // Add the cube to the scene. scene.add(cube); // Create and add a light source. var globalLight = new THREE.AmbientLight(0xffffff, 1); scene.add(globalLight); // Listen to the window resize. window.addEventListener('resize', handleWindowResize, false); // Start a loop that will render the animation in each frame. loop();}function handleWindowResize() { // If the window is resized, we have to update the camera aspect ratio. HEIGHT = window.innerHeight; WIDTH = window.innerWidth; renderer.setSize(WIDTH, HEIGHT); camera.aspect = WIDTH / HEIGHT; camera.updateProjectionMatrix();}function loop(){ // Call the update function in each frame to update the cube position. update(); // Render the scene in each frame. renderer.render(scene, camera); // Call the loop function in next frame. requestAnimationFrame(loop);}// Initialize the demo when the page is loaded.window.addEventListener('load', init, false);

Here, we have basically created a scene, a camera, a light and a cube. Then, we started a loop to update the position of the cube at each frame.

Now, we need to add the update() function, where we can insert some trigonometry formulas to play around with:

function update(){ // The angle is incremented by 0.1 every frame. Try higher values for faster animation. angle += .1; // Try modifying the angle and/or radius for a different movement. cube.position.x = cos(angle) * radius; cube.position.y = sin(angle) * radius; // You might want to use the same principle on the rotation property of an object. Uncomment the next line to see what happens. //cube.rotation.z = cos(angle) * PI/4; //Or vary the scale. Note that 1 is added as an offset to avoid a negative scale value. //cube.scale.y = 1 + cos(angle) * .5; /* Your turn! You might want to: - comment or uncomment the lines above to try new combinations, - replace cos by sin and vice versa, - replace radius with an other cyclic function. For example : cube.position.x = cos(angle) * (sin(angle) *radius); ... */}

If you feel lost, you can find this setup ready to use on Codepen. Play around with the sine and cosine functions to make the cube move in different ways and to better understand how to take advantage of trigonometry for your animations.

Or you can just move on to the next demo and use it as a starting point to make your own walking or running cycle.

How to Make a Walking or Running Cycle Using Trigonometry

Now, as we learned how to make a cube move with code, by using the same principles, we’re going to make a simple walking cycle, step by step.

We are mostly using the same setup as before, the main difference being that we need more cubes to make the different body parts.

With three.js, it is possible to embed groups of objects inside other groups. For example, we can create a body group that holds the legs, arms and head.

Let’s see how our main character is made:

Hero = function() { // This will be incremented later at each frame and will be used as the rotation angle of the cycle. this.runningCycle = 0; // Create a mesh that will hold the body. this.mesh = new THREE.Group(); this.body = new THREE.Group(); this.mesh.add(this.body); // Create the different parts and add them to the body. var torsoGeom = new THREE.CubeGeometry(8,8,8, 1);// this.torso = new THREE.Mesh(torsoGeom, blueMat); this.torso.position.y = 8; this.torso.castShadow = true; this.body.add(this.torso); var handGeom = new THREE.CubeGeometry(3,3,3, 1); this.handR = new THREE.Mesh(handGeom, brownMat); this.handR.position.z=7; this.handR.position.y=8; this.body.add(this.handR); this.handL = this.handR.clone(); this.handL.position.z = - this.handR.position.z; this.body.add(this.handL); var headGeom = new THREE.CubeGeometry(16,16,16, 1);// this.head = new THREE.Mesh(headGeom, blueMat); this.head.position.y = 21; this.head.castShadow = true; this.body.add(this.head); var legGeom = new THREE.CubeGeometry(8,3,5, 1); this.legR = new THREE.Mesh(legGeom, brownMat); this.legR.position.x = 0; this.legR.position.z = 7; this.legR.position.y = 0; this.legR.castShadow = true; this.body.add(this.legR); this.legL = this.legR.clone(); this.legL.position.z = - this.legR.position.z; this.legL.castShadow = true; this.body.add(this.legL); // Ensure that every part of the body casts and receives shadows. this.body.traverse(function(object) { if (object instanceof THREE.Mesh) { object.castShadow = true; object.receiveShadow = true; } });}

Now we need to add this character to the scene:

function createHero() { hero = new Hero(); scene.add(hero.mesh);}

This is how a simple character could be made with three.js. If you want to learn more about making characters using three.js, read my detailed tutorial on Codrops.

After building this body, we are going to progressively make all of these parts move one by one, until we reach a simple walking cycle.

The whole logic is located in a run function of the Hero object:

Hero.prototype.run = function(){ // Increment the angle. this.runningCycle += .03; var t = this.runningCycle; // Ensure that the angle we will use is between 0 and 2 Pi. t = t % (2*PI); // Amplitude is used as the main radius of the legs movement. var amp = 4; // Update the position and rotation of every part of the body. this.legR.position.x = Math.cos(t) * amp; this.legR.position.y = Math.max (0, - Math.sin(t) * amp); this.legL.position.x = Math.cos(t + PI) * amp; this.legL.position.y = Math.max (0, - Math.sin(t + PI) * amp); if (t<PI){ this.legR.rotation.z = Math.cos(t * 2 + PI/2) * PI/4; this.legL.rotation.z = 0; } else{ this.legR.rotation.z = 0; this.legL.rotation.z = Math.cos(t * 2 + PI/2) * PI/4; } this.torso.position.y = 8 - Math.cos( t * 2 ) * amp * .2; this.torso.rotation.y = -Math.cos( t + PI ) * amp * .05; this.head.position.y = 21 - Math.cos( t * 2 ) * amp * .3; this.head.rotation.x = Math.cos( t ) * amp * .02; this.head.rotation.y = Math.cos( t ) * amp * .01; this.handR.position.x = -Math.cos( t ) * amp; this.handR.rotation.z = -Math.cos( t ) * PI/8; this.handL.position.x = -Math.cos( t + PI) * amp; this.handL.rotation.z = -Math.cos( t + PI) * PI/8;}

These lines of code are the most interesting part, but you can find the full code of the walking cycle on Codepen.

To make it easier to follow, I’ve made the following demo, which breaks down the movement and which highlights the part of the body being moved and the formula used at each step.

See the Pen Walking cycle breakdown by Karim Maaloul (@Yakudoo) on CodePen.

Once you are comfortable with sines and cosines, distances and frequencies, it becomes pretty easy to make different cycles, such as running, swimming, flying, even moonwalking.

Your Turn!

I won’t let you go without playing with the bunny.

The Codepen below lets you apply a different angle offset and a different amplitude to each part of the body. You can also modify the speed of the cycle for a more frantic result.

Can you figure out a different running cycle for this guy? Have fun!

See the Pen Run bunny run by Karim Maaloul (@Yakudoo) on CodePen.

Conclusion

One might think that code-based animation leads to unnatural movement. On the contrary, I believe it offers a great opportunity to tweak movement in a very flexible way, which makes it easier to achieve a convincing behavior for your character.

Moments of Happiness is a collection of different experiments, and each had its own challenges. In this article, I’ve detailed the solution used to make a running cycle. On my Codepen page, all of these experiments are available, with the code at your disposal. Feel free to play around and make your own interactive toys.

Smashing Editorial(vf, al, il)

User Authentication For Web And iOS Apps With AWS Cognito (Part 2)

In today’s digital landscape, developers constantly need to be adding new tools to remain competitive and at the top of their craft. If you regularly create new web or mobile applications, then Amazon Cognito is a powerful tool that can cut 90% of the time it usually takes to set up a custom user-management solution. If that is intriguing to you, then let’s continue the journey to learn more about what Amazon Cognito has to offer.

In Our Last Episode

In the previous article, I introduced the concept of user management and how complicated it is in our current digital landscape. In addition, I introduced Amazon Cognito (henceforth referred to as Cognito), a service provided through Amazon Web Services, as a way to deal with this complexity. To illustrate this, I created an iOS application that uses Cognito to provide a login for users using a custom user pool.

Cognito custom user pool diagram (View large version)

Now that we have the basics of an application in place, I want to implement several aspects of user management within the sample application. These aspects include user signup, email verification, password resetting and multi-factor authentication. After that, I want to talk through some of the additional value that Cognito provides through its security model and how you could use it to secure the back end of your application.

To get up and running for this article, you’ll need to leverage the user pool that was created in the previous article. If you haven’t done that work, you can be up and running in about 30 minutes and ready to move forward with what I am covering today.

Rethinking Common Password Habits

The more services we use, the more passwords we’re forced to remember. Is there a way to improve this? Well, just like everything else, we need to do what’s right for our users. Read a related article →

Sample Code

If you are following along with the sample code, you will need to have set up a user pool, configured it properly, and added the settings to a plist file before the application will work. This is a fairly simple (but lengthy) process that was covered thoroughly in the previous article. Most every section of this article will include a link to the Git tag that is used at that point of the code. I hope this will make it easier to follow along.

Letting Users Sign Up

The first step in a user’s journey in your application is the signup process. Cognito provides the capability to allow for users to sign up or to allow only administrators to sign up users. In the previous article, we configured the user pool to allow users to sign up.

One key element to remember in regards to signup is that this is where your attribute settings and password policy are enforced. If you set attributes as required in the user pool, you will have to submit all of those values in order for your signup call to be successful. In our case, we need to gather the user’s first name, last name, email address and desired password.

In this new view controller, SignupViewController, we have an action that gets called when the user clicks the “Complete Registration” button. We need to respond to a few things if they occur:

  • If there is an error, we need to present the error to the end user and allow them to resubmit the form.
  • If we are successful with the signup, we need to check whether the user requires verification of their email address. According to how we set up the user pool, this is a requirement. In most all cases, the user will be required to go to the next step and verify their email address.

The following code represents this process in action:

@IBAction func signupPressed(_ sender: AnyObject) { // Get a reference to the user pool let userPool = AppDelegate.defaultUserPool() // Collect all of the attributes that should be included in the signup call let emailAttribute = AWSCognitoIdentityUserAttributeType(name: "email", value: email.text!) let firstNameAttribute = AWSCognitoIdentityUserAttributeType(name: "given_name", value: firstName.text!) let lastNameAttribute = AWSCognitoIdentityUserAttributeType(name: "family_name", value: lastName.text!) // Actually make the signup call passing in those attributes userPool.signUp(UUID().uuidString, password: password.text!, userAttributes: [emailAttribute, firstNameAttribute, lastNameAttribute], validationData: nil) .continueWith { (response) -> Any? in if response.error != nil { // Error in the signup process let alert = UIAlertController(title: "Error", message: response.error?.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler:nil)) self.present(alert, animated: true, completion: nil) } else { self.user = response.result!.user // Does user need verification? if (response.result?.userConfirmed != AWSCognitoIdentityUserStatus.Confirmed.rawValue) { // User needs confirmation, so we need to proceed to the verify view controller DispatchQueue.main.async { self.performSegue(withIdentifier: "VerifySegue", sender: self) } } else { // User signed up but does not need verification DispatchQueue.main.async { self.presentingViewController?.dismiss(animated: true, completion: nil) } } } return nil }}

Verifying Email Addresses

Email verification is configured in the creation of the user pool, which we covered in the previous article. As you can see in the following image, we chose to require email validation for users. By verifying email addresses, we can leverage the addresses for other use cases, such as resetting passwords.

Step 4 of user pool creation: configuring verifications for the user pool. (View large version)

Workflow

The entire signup process will also include verification if the user pool was configured that way. The “happy path” representation of this flow would be as follows:

  1. The user is presented with the login screen when launching the application.
  2. The user presses the “Sign up for an account” option on the login screen.
  3. The user is presented with the signup form.
  4. The user fills out the signup form correctly with their information.
  5. The user is presented with the email verification form.
  6. The user enters the code from their email.
  7. The user is sent back to the login form, where they can now log in with their new account.

This flow can be seen in the following view controllers, which are a part of the sample application:

Signup and verification flow (View large version)

There is one important note about verification to consider. If you decide to require both email address and phone number for verification, Cognito will choose to insert the phone number verification into the signup process. You will then have to detect whether the email address is verified and include the logic required to verify it. However, in most cases, if you verify one of the attributes and use it for password resetting, then there isn’t as much of a need to verify the other. If you plan to use multi-factor authentication, I would recommend requiring phone-number verification only.

Coding the Email Verification

Two key actions need to be supported in the view controller that is handling the verification process: submitting the verification code, and requesting that the code be sent again. Luckily, these two actions are fairly easy to implement, and the code can be seen below:

func resetConfirmation(message:String? = "") { self.verificationField.text = "" let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Retry", style: .default, handler: nil)) self.present(alert, animated: true, completion:nil)}@IBAction func verifyPressed(_ sender: AnyObject) { // Confirm / verify the user based on the text in the verify field self.user?.confirmSignUp(verificationField.text!) .continueWith(block: { (response) -> Any? in if response.error != nil { // In this case, there was some error or the user didn't enter the right code. // We will just rely on the description that Cognito passes back to us. self.resetConfirmation(message: response.error!.localizedDescription) } else { DispatchQueue.main.async { // Return to Login View Controller - this should be handled a bit differently, but added in this manner for simplicity self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) } } return nil })}@IBAction func resendConfirmationCodePressed(_ sender: AnyObject) { self.user?.resendConfirmationCode() .continueWith(block: { (response) -> Any? in let alert = UIAlertController(title: "Resent", message: "The confirmation code has been resent.", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) self.present(alert, animated: true, completion:nil) return nil })}

As discussed in the signup and verification flow section, if the user is successful in verifying their address, they will be sent back to the login screen. After this login, the user will be able to get into the protected view within the application, which will display their attributes.

Signup and verification were relatively painless. If you want to see the code at this point of the article, check out the signup-verify tag of the code on GitHub.

Forgot Password

Another key use case in user management is helping users to reset their password securely. Cognito provides this functionality through either email or text message, depending on how the user pool has been configured.

It is important to note that verification is required for resetting a user’s password. If you don’t specify either the phone number or email address to be verified, then the user will have to reach out to you to reset their password. In short, every user pool should have, at minimum, one verified attribute.

Workflow

Just as with signup and verification, the forgot-password workflow is a multi-step process. To achieve the goal of resetting the user’s password, we need to follow these steps (which only include the happy path):

  1. We need to get the user’s email address to get a reference to the user.
  2. We need to request that a verification code be sent to the user. If the user pool has a verified phone number, it will be sent as an SMS. If there isn’t a verified phone number, it will be sent as an email.
  3. We need to inform the user where to look for the code in a secure manner. Cognito returns a masked version of the phone number or email address, to give the user a heads up of where to look.
  4. We allow the user to fill out a form, including both the verification code and a new password.
  5. We submit the password and verification code to Cognito.
  6. We let the user know that their password reset was successful, and they can now log into the application.
  7. We send them back to the login screen.

This flow can be seen in the following view controllers, which are a part of the sample application:

Forgot-password workflow (View large version)

Coding the Forgot-Password Workflow

The first step in coding this workflow is to request that the user be sent a verification code. To do this, LoginViewController will pass the email address to ForgotPasswordViewController before the segue is performed. Once the new view appears, the email address will be used to get a reference to the user and request a verification code.

override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if !emailAddress.isEmpty { // Get a reference to the user pool let pool = AppDelegate.defaultUserPool() // Get a reference to the user using the email address user = pool.getUser(emailAddress) // Initiate the forgot password process, which will send a verification code to the user user?.forgotPassword() .continueWith(block: { (response) -> Any? in if response.error != nil { // Cannot request password reset due to error (for example, the attempt limit is exceeded) let alert = UIAlertController(title: "Cannot Reset Password", message: (response.error! as NSError).userInfo["message"] as? String, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in self.clearFields() self.presentingViewController?.dismiss(animated: true, completion: nil) })) self.present(alert, animated: true, completion: nil) return nil } // Password reset was requested and message sent. Let the user know where to look for code. let result = response.result let isEmail = (result?.codeDeliveryDetails?.deliveryMedium == AWSCognitoIdentityProviderDeliveryMediumType.email) let destination:String = result!.codeDeliveryDetails!.destination! let medium = isEmail ? "an email" : "a text message" let alert = UIAlertController(title: "Verification Sent", message: "You should receive (medium) with a verification code at (destination). Enter that code here along with a new password.", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) return nil }) }}

One point to note on this is that Cognito returns information that enables you to tell the user where to find the code. In the code above, we are detecting whether the code will be sent to an email address or phone number, as well as the masked version of the destination. This can be seen in the sample application in the image below.

Forgot-password prompt

After requesting the code, we need to allow the user to enter the new code and updated password. This code from ForgotPasswordViewController is triggered when the user clicks on the “Reset Password” button.

@IBAction func resetPasswordPressed(_ sender: AnyObject) { // Kick off the 'reset password' process by passing the verification code and password user?.confirmForgotPassword(self.verificationCode.text!, password: self.newPassword.text!) .continueWith { (response) -> Any? in if response.error != nil { // The password could not be reset - let the user know let alert = UIAlertController(title: "Cannot Reset Password", message: (response.error! as NSError).userInfo["message"] as? String, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Resend Code", style: .default, handler: { (action) in self.user?.forgotPassword() .continueWith(block: { (result) -> Any? in print("Code Sent") return nil }) })) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) in DispatchQueue.main.async { self.presentingViewController?.dismiss(animated: true, completion: nil) } })) self.present(alert, animated: true, completion: nil) } else { // Password reset. Send the user back to the login and let them know they can log in with new password. DispatchQueue.main.async { let presentingController = self.presentingViewController self.presentingViewController?.dismiss(animated: true, completion: { let alert = UIAlertController(title: "Password Reset", message: "Password reset. Please log into the account with your email and new password.", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) presentingController?.present(alert, animated: true, completion: nil) self.clearFields() } ) } } return nil }}

Once this process is complete, the user is returned to the login screen and informed that the password reset was successful. At this point, the user can log into the application using their new password.

If you want to see the code at this point of the article, check out the forgot-password tag of the code on GitHub.

Multi-Factor Authentication

Multi-factor authentication (MFA) is becoming a standard for anything requiring heightened security. Right now, if I want to log into my email, my bank, my mortgage account or even GitHub, I have to enter a code that I get via text message. Because of this extra layer of security, we prevent anyone from logging into an account if they have both my username and password. Instead of just using a single factor (the password) with the username, they have to use multiple factors (password and the code via SMS).

The great thing is that Cognito supports this out of the box through SMS. The Cognito team has stated that it is also working to add support for email MFA; however, at the time of writing, this isn’t an option. To make this work, we’ll need to change some configuration settings in AWS and create a new user pool.

New User Pool

To properly demonstrate the capabilities of multi-factor authentication using SMS, I will be creating a new custom user pool with only a few modifications compared to our previous user pool. Note that some features (such as required attributes) cannot be modified once a user pool has been created. Because of this, you’ll want to have a solid strategy around your user pool before starting to use it.

The modifications that I made compared to the previous user pool are detailed below:

  • Phone number has been added as a required attribute.
  • Users can sign in using their email address or phone number (we will still choose the email address here).
  • Multi-factor authentication has been set as optional.
  • Email verification has been disabled, and phone number verification has been enabled.

Using SMS Instead of Email

If you are going to send anything more than a few SMS messages per month, you’ll need to request a higher Simple Notification Service (SNS) limit for SMS messages. This is mostly painless, but it is a requirement if you are going to ship an app. The following excerpt from Cognito’s documentation will point you in the right direction. While the team responds to requests fairly quickly, it isn’t instant. I would recommend submitting the request at least a few weeks before a push to production. According to “Specifying User Pool MFA Setting and Email and Phone Verification Settings” in the Amazon Cognito Documentation:

The default spend limit per account (if not specified) is 1.00 USD per month. If you want to raise the limit, submit an SNS Limit Increase case in the AWS Support Center. For New limit value, enter your desired monthly spend limit. In the Use Case Description field, explain that you are requesting an SMS monthly spend limit increase.

Workflow

Because we aren’t forcing multi-factor authentication for the user pool (although you certainly could), we will have a multi-step process to enable and then execute multi-factor authentication. These steps are detailed below (these are the happy path steps):

  1. When the user signs up for an account, they will be asked to verify their phone number (instead of their email address).
  2. After logging into the application, the user will be able to enable multi-factor authentication in their profile.
  3. After enabling multi-factor authentication, the user will be presented with the authentication challenge upon their next login.
  4. Upon entering the multi-factor authentication code correctly, the user will be able to use the application as expected.

Coding Multi-Factor Authentication

The Cognito SDK triggers the display of the multi-factor authentication view controller. You have to define how you want to handle that trigger. In the sample application, this happens in AppDelegate. Because our AppDelegate implements AWSCognitoIdentityInteractiveAuthenticationDelegate, we have the option to define how we want this to be handled. The code below shows the implementation in the sample application:

func startMultiFactorAuthentication() -> AWSCognitoIdentityMultiFactorAuthentication { if (self.multiFactorAuthenticationController == nil) { self.multiFactorAuthenticationController = self.storyboard?.instantiateViewController(withIdentifier: "MultiFactorAuthenticationController") as? MultiFactorAuthenticationController } DispatchQueue.main.async { if(self.multiFactorAuthenticationController!.isViewLoaded || self.multiFactorAuthenticationController!.view.window == nil) { self.navigationController?.present(self.multiFactorAuthenticationController!, animated: true, completion: nil) } } return self.multiFactorAuthenticationController!}

In the case above, we instantiate the view controller from the storyboard, and then we present it. Finally, this view controller is presented.

Within MultiFactorAuthenticationController, we handle the process much like we did in LoginViewController. The view controller itself implements a protocol that is specific to this use case: AWSCognitoIdentityMultiFactorAuthentication. By implementing this protocol, you get an instance in the getCode method, which you must use to pass in the code for verification. The result of this verification will trigger the didCompleteMultifactorAuthenticationStepWithError method.

class MultiFactorAuthenticationController: UIViewController { @IBOutlet weak var authenticationCode: UITextField! @IBOutlet weak var submitCodeButton: UIButton! var mfaCompletionSource:AWSTaskCompletionSource? @IBAction func submitCodePressed(_ sender: AnyObject) { self.mfaCompletionSource?.set(result: NSString(string: authenticationCode.text!)) }}extension MultiFactorAuthenticationController: AWSCognitoIdentityMultiFactorAuthentication { func getCode(_ authenticationInput: AWSCognitoIdentityMultifactorAuthenticationInput, mfaCodeCompletionSource: AWSTaskCompletionSource) { self.mfaCompletionSource = mfaCodeCompletionSource } func didCompleteMultifactorAuthenticationStepWithError(_ error: Error?) { DispatchQueue.main.async { self.authenticationCode.text = "" } if error != nil { let alertController = UIAlertController(title: "Cannot Verify Code", message: (error! as NSError).userInfo["message"] as? String, preferredStyle: .alert) let resendAction = UIAlertAction(title: "Try Again", style: .default, handler:nil) alertController.addAction(resendAction) let logoutAction = UIAlertAction(title: "Logout", style: .cancel, handler: { (action) in AppDelegate.defaultUserPool().currentUser()?.signOut() self.dismiss(animated: true, completion: { self.authenticationCode.text = nil }) }) alertController.addAction(logoutAction) self.present(alertController, animated: true, completion: nil) } else { self.dismiss(animated: true, completion: nil) } }}

One additional piece needs to be noted. Because we didn’t force every user to use multi-factor authentication, we have to give the user the option to enable it. To do this, we’ll need to update the user’s settings. The code below (from AppViewController) demonstrates how to both enable and disable multi-factor authentication by using UISwitch as input:

let settings = AWSCognitoIdentityUserSettings()if mfaSwitch.isOn { // Enable MFA let mfaOptions = AWSCognitoIdentityUserMFAOption() mfaOptions.attributeName = "phone_number" mfaOptions.deliveryMedium = .sms settings.mfaOptions = [mfaOptions]} else { // Disable MFA settings.mfaOptions = []}user?.setUserSettings(settings).continueOnSuccessWith(block: { (response) -> Any? in if response.error != nil { let alert = UIAlertController(title: "Error", message: (response.error! as NSError).userInfo["message"] as? String, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) self.present(alert, animated: true, completion:nil) self.resetAttributeValues() } else { self.fetchUserAttributes() } return nil})

To see the code at this point of the article, check out the mfa tag of the code on GitHub.

Taking It Further: API Security

One of the benefits of using Cognito for user management is how it integrates with other AWS services. One great example of this is how it integrates with API Gateway. If you want to have a set of APIs that only logged-in users can access, you can use the user group authorizer for API Gateway. This allows you to pass the token you receive when logging into your API calls, and API Gateway will handle the authorization for you.

This can be particularly powerful if you want to set up a serverless back end (via Lambda) that is exposed through API Gateway. This means you could pretty quickly set up a secured set of API endpoints to power your web or mobile application. If you are interested in exploring this more, feel free to check the following article from the API Gateway documentation: “Use Amazon Cognito User Pools with API Gateway.”

Unfortunately, setting up a back end with Lambda is beyond the scope of this article. However, Amazon has provided a resource on getting started with Lambda: “Build an API to Expose a Lambda Function.”

Conclusion

Within a couple of articles, we have managed to progress from an insecure application to an application that supports all of the common user management use cases. What’s even better is that this user management capability is a service supported by AWS, and until you get over 10,000 active users, it is mostly free to use. I believe that whether you are a web, iOS or Android developer, this toolset will prove to be a valuable one. I’m sure you’ve got an idea of what you can build to test this out. Feel free to use the sample code to help you in that process.

Happy coding!

Links and Resources

Smashing Editorial(da, yk, al, il)

Playing With Color: Vibrant Options For Apps And Websites

(This is a sponsored post). Color is one of the most powerful tools in a designer’s toolkit. Color can draw attention, set a mood, and influence the user’s emotion, perception and actions. When it comes to the web and mobile app design, this is definitely a time of vibrant colors. Designers use vibrant colors to focus people’s attention on important elements and to make their designs memorable.

In this article, I’ll summarize a few popular techniques of using vibrant colors in web and mobile design. Also, if you’d like to get started designing and prototyping your own web and mobile experiences, download Adobe XD.

Make Or Break A User’s Experience

All kinds of visual communication in your designs leave at least some kind of cumulative impression on users. Nevertheless, you still need to be careful not to exaggerate. Read a related article →

Monotone

One of the most popular ways to use vibrant colors is with a monotone color palette. A monotone palette has a single color with a mixture of tints and tones. Such color palettes are visually stimulating. Paired with attention-grabbing typography, a monotone color scheme is able to create a really memorable experience.

Sydney Stockhom uses bold color to create a memorable look in a very simple way.
(Image: Pillow) (View large version)

Tip: Monotone is great for mobile apps. Using a single color with black and white accents is a great way to create visual interest on a small screen.

The color, iconography and simple typeface in the Streaks app creates a striking combination that is easy to read and engage with.

Duotone

As the name suggests, a duotone is made up of two colors. It could be two shades of the same color or two contrasting colors. This technique, once a print staple, has found new life online. Thanks to Spotify, duotones are growing in popularity every day.

Two-color photos have almost become a visual symbol of Spotify. (View large version)

Create Emotions

Duotones enable you to inject any image with the emotional attributes of any color. Different colors evoke different emotions:

  • Soft and modest combinations of colors create a serious atmosphere. In Holm Marcher & Co, shown below, every detail contributes to the businesslike atmosphere, and the background image is no exception.
    The soft duotone effect sets a businesslike atmosphere. (Image: Holm Marcher & Co)

  • A combination of bright colors creates a sense of happiness. The main visual for New Deal Design is striking, thanks to the bold color choice. It creates a friendly atmosphere and sets a positive mood.
One intense image is worth a thousand words. (View large version)

Improve Readability

A duotone can give text plenty of contrast. The color variation in an image is adjusted so that text can be shown in a single color almost anywhere on the image.

(Image: Method) (View large version)
(View large version)

Translates Well on Mobile

Last but not least, while the duotone effect lends itself to large desktop images, it can work on mobile screens as well.

(Image: Ognjen Divljak)

Tip: If you want to use a duotone for a hero image, select a simple high-quality photo with a single, clear subject. A busy photograph with a lot of detail might be harder to interpret.

Gradient

Gradients have made their way back into modern user interfaces, this time as high-contrast complementary colors. Modern gradients can include multiple colors, can radiate from the center, and can come from a corner or fall horizontally.

They serve the following functions in user interfaces.

Create a Modern Look

Gradients have made a comeback and breathed new life into flat design. Paired with flat color palette, they can evoke a feeling of modernism.

By using one of the bright, saturated colors associated with material design, you can evoke a feeling of modernism. (View large version) (Image credit: Ramotion)

Improve Content Comprehension

Gradients can improve visual communication. The transition from orange to pink in Symodd’s example below gives depth and contrast to the interface, and it creates some eye-catching visual effects. The shift from light to dark follows the natural scanning patterns of the human eye, moving from the top left of the page to the bottom right.

Symodd’s home page features a full gradient background from orange to pink. It’s a subtle gradient; the two hues aren’t very different from each other, making this easy on the eyes. (View large version)

Create a Pseudo 3D Effect

While the flat aesthetic is sleek and easy to look at, one potential shortcoming is that it lacks an element of realism. To compensate, designers often use gradients to give depth to their backgrounds. This will likely continue to grow as designers try to incorporate more realism and 3D elements into web design.

(Image: Swiss Army Man) (View large version)

Try a Gradient Accent

While gradients are often used as backgrounds for pages, they can work in smaller places as well. Consider using a gradient as an accent in navigation, for a secondary image or for specific types of content. Smaller areas of gradient give you more freedom to play with this technique. For example, you could create visually interesting pairs of multicolor, as Bloomberg does:

Bloomberg uses a gradient for the “Latest News” ticker. (View large version)

Overlay

A color overlay is probably the most self-explanatory effect. And it is one of the most useful and commonly used effects in popular design. If you want to incorporate it in your design, all you need to do is cover an image or video with a semi-transparent colored box.

Trendy Look

By using one of the bright, saturated colors associated with material design, you can evoke a feeling of modernism.

A color overlay enhances the impact of a photograph and enables the designer to modify tone and interpretation. (Image: Hype)

Strongest Clickability Signifier

Consider using an image overlay for interactive card-style elements, for video content and for call-to-action buttons.

Apply hover animations to cards. (Image: Column Five)

Focus User Attention

Overlay effects can focus users on certain design elements. However, when using a single color as an overlay, think about the degree of saturation and transparency of the color:

  • Heavy color combinations (i.e. less transparency and more saturation) put more focus on the color itself.
Studio Up uses less transparency and more saturation for its color overlay. (View large version)
  • Light combinations put more focus on the image.
The color overlay used by Outlines puts more focus on the image. (Image: Outlines) (View large version)

Conclusion

Few design elements are more fun to play with than color. Color effects can be dramatic, impressive and even serene. You the designer really get to experiment when using color effects. Whether you are a fan of bright, bold hues or prefer a more minimalist black and white, the one thing to remember is that there are no wrong colors. What matters most is how you use them.

This article is part of the UX design series sponsored by Adobe. Adobe Experience Design CC (Beta) tool 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 visit the Adobe XD blog to stay updated and informed.

Smashing Editorial(ms, vf, yk, al, il)

Building Inclusive Toggle Buttons

Editor’s Note: This article originally appeared on Inclusive Components. If you’d like to know more about similar inclusive component articles, follow @inclusicomps on Twitter or subscribe to the RSS feed. By supporting inclusive-components.design on Patreon, you can help to make it the most comprehensive database of robust interface components available.

Some things are either on or off and, when those things aren’t on (or off), they are invariably off (or on). The concept is so rudimentary that I’ve only complicated it by trying to explain it, yet on/off switches (or toggle buttons) are not all alike. Although their purpose is simple, their applications and forms vary greatly.

In this inaugural post, I’ll be exploring what it takes to make toggle buttons inclusive. As with any component, there’s no one way to go about this, especially when such controls are examined under different contexts. However, there’s certainly plenty to forget to do or to otherwise screw up, so let’s try to avoid any of that.

Improving Interface Design

Did you know that with just a few simple tricks, you can help make a user’s interaction more pleasant? We’ve got your back, with an inspiring list of dialog and modal windows, signup and login screens, navigation and menus, and even more sliders and toggles. Read a related article →

Changing State

If a web application did not change according to the instructions of its user, the resulting experience would be altogether unsatisfactory. Nevertheless, the luxury of being able to make web documents augment themselves instantaneously, without recourse to a page refresh, has not always been present.

Unfortunately, somewhere along the way we decided that accessible web pages were only those where very little happened — static documents, designed purely to be read. Accordingly, we made little effort to make the richer, stateful experiences of web applications inclusive.

A popular misconception has been that screen readers don’t understand JavaScript. Not only is this entirely untrue — all major screen readers react to changes in the DOM as they occur — but basic state changes, communicated both visually and to assistive technology software, do not necessarily depend on JavaScript to take place anyway.

Checkboxes And Radio Buttons

Form elements are the primitives of interactive web pages and, where we’re not employing them directly, we should be paying close attention to how they behave. Their handling of state changes have established usability conventions we would be foolish to ignore.

Arguably, an out-of-the-box input of the checkbox type is a perfectly serviceable on/off switch all its own. Where labelled correctly, it has all the fundamental ingredients of an accessible control: it’s screen reader and keyboard accessible between platforms and devices, and it communicates its change of state (checked to unchecked or vice versa) without needing to rebuild the entire document.

In the following example, a checkbox serves as the toggle for an email notifications setting.

<input type="checkbox" name="notify" value="on"> <label for="notify">Notify by email</label> 
The notify my email control with checkbox checked

Screen reader software is fairly uniform in its interpretation of this control. On focusing the control (moving to it using the Tab key) something similar to, “Notify by email, checkbox, unchecked” will be announced. That’s the label, role, and state information all present.

On checking the checkbox, most screen reader software will announce the changed state, “checked” (sometimes repeating the label and role information too), immediately. Without JavaScript, we’ve handled state and screen reader software is able to feed back to the user.

Screen readers are not just for the blind

Some operate screen readers to assist their understanding of an interface. Others may be visually dyslexic or have low literacy. There are even those who have little physical or cognitive trouble understanding an interface who simply prefer to have it read out to them sometimes.

Supporting screen reader software is supporting screen reader software, not blind people. Screen readers are a tool a lot of different people like to use.

In this case, the on/off part of the switch is not communicated by the label but the state. Instead, the label is for identifying the thing that we are turning off or on. Should research show that users benefit from a more explicit on/off metaphor, a radio button group can be employed.

<fieldset> <legend>Notify by email</legend> <input type="radio" name="notify" value="on" checked> <label for="notify-on">on</label> <input type="radio" name="notify" value="off"> <label for="notify-off">off</label></fieldset> 
Fieldset with notify by email group label (legend) and radio buttons labeled on and off. The on one is selected.

Group labels are a powerful tool. As their name suggests, they can provide a single label to related (grouped) items. In this case, the <fieldset> group element works together with the <legend> element to provide the group label “Notify by email” to the pair of radio buttons. These buttons are made a pair by sharing a name attribute value, which makes it possible to toggle between them using your arrow keys. HTML semantics don’t just add information but also affect behavior.

In the Windows screen readers JAWS and NVDA, when the user focuses the first control, the group label is prepended to that control’s individual label and the grouped radio buttons are enumerated. In NVDA, the term “grouping” is appended to make things more explicit. In the above example, focusing the first (checked by default) radio button elicits, “Notify by email, grouping, on radio button, checked, one of two”.

Now, even though the checked state (announced as “selected” in some screen readers) is still being toggled, what we’re really allowing the user to do it switch between “on” and “off”. Those are the two possible lexical states, if you will, for the composite control.

Styling form elements

Form elements are notoriously hard to style, but there are well-supported CSS techniques for styling radio and checkbox controls, as I wrote in Replacing Radio Buttons Without Replacing Radio Buttons. For tips on how to style select elements and file inputs, consult WTF Forms? by Mark Otto.

This doesn’t quite feel right

Both the checkbox and radio button implementations are tenable as on/off controls. They are, after all, accessible by mouse, touch, keyboard, and assistive technology software across different devices, browsers, and operating systems.

But accessibility is only a part of inclusive design. These controls also have to make sense to users; they have to play an unambiguous role within the interface.

The trouble with using form elements is their longstanding association with the collection of data. That is, checkboxes and radio buttons are established as controls for designating values. When a user checks a checkbox, they may just be switching a state, but they may suspect they are also choosing a value for submission.

Whether you’re a sighted user looking at a checkbox, a screen reader user listening to its identity being announced, or both, its etymology is problematic. We expect toggle buttons to be buttons, but checkboxes and radio buttons are really inputs.

A True Toggle Button

Sometimes we use <button> elements to submit forms. To be fully compliant and reliable these buttons should take the type value of submit.

<button type="submit">Send</button> 

But these are only one variety of button, covering one use case. In truth, <button> elements can be used for all sorts of things, and not just in association with forms. They’re just buttons. We remind ourselves of this by giving them the type value of button.

<button type="button">Send</button> 

The generic button is your go-to element for changing anything within the interface (using JavaScript and without reloading the page) except one’s location within and between documents, which is the purview of links.

Next to links, buttons should be the interactive element you use most prolifically in web applications. They come prepackaged with the “button” role and are keyboard and screen reader accessible by default. Unlike some form elements, they are also trivial to style.

So how do we make a <button> a toggle button? It’s a case of using WAI-ARIA as a progressive enhancement. WAI-ARIA offers states that are not available in basic HTML, such as the pressed state. Imagine a power switch for a computer. When it’s pressed — or pushed in — that denotes the computer is in its “on” state. When it’s unpressed — poking out — the computer must be off.

<button type="button" aria-pressed="true"> Notify by email</button> 

WAI-ARIA state attributes like aria-pressed behave like booleans but, unlike standard HTML state attributes like checked they must have an explicit value of true or false. Just adding aria-pressed is not reliable. Also, the absence of the attribute would mean the unpressed state would not be communicated (a button without the attribute is just a generic button).

You can use this control inside a form, or outside, depending on your needs. But if you do use it inside a form, the type="button" part is important. If it’s not there, some browsers will default to an implicit type="submit" and try to submit the form. You don’t have to use event.preventDefault() on type="button" controls to suppress form submission.

Switching the state from true (on) to false (off) can be done via a simple click handler. Since we are using a <button>, this event type can be triggered with a mouse click, a press of either the Space or Enter keys, or by tapping the button through a touch screen. Being responsive to each of these actions is something built into <button> elements as standard. If you consult the HTMLButtonElement interface, you’ll see that other properties, such as disabled, are also supported out-of-the-box. Where <button> elements are not used, these behaviors have to be emulated with bespoke scripting.

const toggle = document.querySelector('[aria-pressed]');toggle.addEventListener('click', (e) => { let pressed = e.target.getAttribute('aria-pressed') === 'true'; e.target.setAttribute('aria-pressed', String(!pressed));});

A clearer state

An interesting thing happens when a button with the aria-pressed state is encountered by some screen readers: it is identified as a “toggle button” or, in some cases, “push button”. The presence of the state attribute changes the button’s identity.

When focusing the example button with aria-pressed="true" using NVDA, the screen reader announces,“Notify by email, toggle button, pressed”. The “pressed” state is more apt than “checked”, plus we eschew the form data input connotations. When the button is clicked, immediate feedback is offered in the form of “not pressed”.

Styling

The HTML we construct is an important part of the design work we do and the things we create for the web. I’m a strong believer in doing HTML First Prototyping™, making sure there’s a solid foundation for the styled and branded product.

In the case of our toggle button, this foundation includes the semantics and behavior to make the button interoperable with various input (e.g. voice activation software) and output (e.g. screen reader) devices. That’s possible using HTML, but CSS is needed to make the control understandable visually.

Form should follow function, which is simple to achieve in CSS: everything in our HTML that makes our simple toggle button function can also be used to give it form.

  • <button>button element selector
  • aria-pressed="true"[aria-pressed="true"] attribute selector.

In a consistent and, therefore, easy to understand interface, buttons should share a certain look. Buttons should all look like buttons. So, our basic toggle button styles should probably inherit from the button element block:

/* For example... */button { color: white; background-color: #000; border-radius: 0.5rem; padding: 1em 2em;}

There are a number of ways we could visually denote “pressed”. Interpreted literally, we might make the button look pressed in using some inset box-shadow. Let’s employ an attribute selector for this:

[aria-pressed="true"] { box-shadow: inset 0 0 0 0.15rem #000, inset 0.25em 0.25em 0 #fff;}

To complete the pressed/unpressed metaphor, we can use some positioning and box-shadow to make the unpressed button “poke out”. This block should appear above the [aria-prressed="true"] block in the cascade.

[aria-pressed] { position: relative; top: -0.25rem; left: -0.25rem; box-shadow: 0.125em 0.125em 0 #fff, 0.25em 0.25em #000;}
Left button, sticking out, is labeled aria-pressed equals false. Right button, visually depressed, is labelled aria-pressed equals true.

(Note: This styling method is offered just as one idea. You may find that something more explicit, like the use of “on”/“off” labels in an example to follow, is better understood by more users.)

Don’t rely on color alone

“On” is often denoted by a green color, and “off” by red. This is a well-established convention and there’s no harm in incorporating it. However, be careful not to only use color to describe the button’s two states. If you did, some color blind users would not be able to differentiate them.

The aria-pressed false button has a red background color and the aria-pressed true button has a green background color
These versions of the control would fail WCAG 2.0 1.4.1 Use Of Color (Level A)

Focus styles

It’s important buttons, along with all interactive components, have focus styles. Otherwise people navigating by keyboard cannot see which element is in their control and ready to be operated.

The best focus styles do not affect layout (the interface shouldn’t jiggle around distractingly when moving between elements). Typically, one would use outline, but outline only ever draws a box in most browsers. To fit a focus style around the curved corners of our button, a box-shadow is better. Since we are using box-shadow already, we have to be a bit careful: note the two comma-separated box-shadow styles in the pressed-and-also-focused state.

/* Remove the default outline and add the outset shadow */ [aria-pressed]:focus { outline: none; box-shadow: 0 0 0 0.25rem yellow;}/* Make sure both the inset and outset shadow are present */ [aria-pressed="true"]:focus { box-shadow: 0 0 0 0.25rem yellow, inset 0 0 0 0.15rem #000, inset 0.25em 0.25em 0 #fff; }

Changing Labels

The previous toggle button design has a self-contained, unique label and differentiates between its two states using a change in attribution which elicits a style. What if we wanted to create a button that changes its label from “on” to “off” or “play” to “pause”?

It’s perfectly easy to do this in JavaScript, but there are a couple of things we need to be careful about.

  1. If the label changes, what happens with the state?
  2. If the label is just “on” or “off” (“play” or “pause”; “active” or “inactive”) how do we know what the button actually controls?

In the previous toggle button example, the label described what would be on or off. Where the “what” part is not consistent, confusion quickly ensues: once “off”/unpressed has become “on”/pressed, I have to unpress the “on” button to turn the “off” button back on. What?

As a rule of thumb, you should never change pressed state and label together. If the label changes, the button has already changed state in a sense, just not via explicit WAI-ARIA state management.

In the following example, just the label changes.

const button = document.querySelector('button');button.addEventListener('click', (e) => { let text = e.target.textContent === 'Play' ? 'Pause' : 'Play'; e.target.textContent = text;});

The problem with this method is that the label change is not announced as it happens. That is, when you click the play button, feedback equivalent to “pressed” is absent. Instead, you have to unfocus and refocus the button manually to hear that it has changed. Not an issue for sighted users, but less ergonomic for blind screen reader users.

Play/pause buttons usually switch between a play symbol (a triangle on its side) and a pause symbol (two vertical lines). We could do this while keeping a consistent non-visual label and changing state.

<!-- Paused state --> <button type="button" aria-pressed="false" aria-label="play"> &#x25b6;</button><-- Playing state --> <button type="button" aria-pressed="true" aria-label="play"> &#x23f8;</button> 

Because aria-label overrides the unicode symbol text node, the paused button is announced as something similar to, “Play button, not pressed” and the playing button as ,“Play button, pressed”.

This works pretty well, except for where voice recognition and activation is concerned. In voice recognition software, you typically need to identify buttons by vocalizing their labels. And if a user sees a pause symbol, their first inclination is to say “pause”, not “play”. For this reason, switching the label rather than the state is more robust here.

Three implementation examples. The first just changes label from play to pause and is okay. The second keeps the play label and changes state, which is incorrect because the pause button cannot be identified with voice recognition. The third changes label and state so the button becomes a pause button which is pressed, which is incorrect. Only use one of the first two implementations.
Never change label and state at the same time. In this example, that would result in a paused button in the pressed state. Since the video or audio would be playing at this point, the lexical “pause” state cannot be also be considered “pressed” on “on”.

Auxiliary labeling

In some circumstances, we may want to provide on/off switches which actually read “on/off”. The trick with these is making sure there is a clear association between each toggle switch and a respective, auxiliary label.

Imagine the email notification setting is grouped alongside other similar settings in a list. Each list item contains a description of the setting followed by an on/off switch. The on/off switch uses the terms “on” and “off” as part of its design. Some <span> elements are provided for styling.

<h2>Notifications</h2> <ul> <li> Notify by email <button> <span>on</span> <span>off</span> </button> </li> <li> Notify by SMS <button> <span>on</span> <span>off</span> </button> </li> <li> Notify by fax <button> <span>on</span> <span>off</span> </button> </li> <li> Notify by smoke signal <button> <span>on</span> <span>off</span> </button> </li></ul> 
A list of notifications settings with associated buttons reading with either on or off highlighted, depending on the state

The virtue of lists is that, both visually and non-visually, they group items together, showing they are related. Not only does this help comprehension, but lists also provide navigational shortcuts in some screen readers. For example, JAWS provides the L (list) and I (list item) quick keys for moving between and through lists.

Each ‘label’ and button is associated by belonging to a common list item. However, not providing an explicit, unique label is dangerous territory — especially where voice recognition is concerned. Using aria-labelledby, we can associate each button with the list’s text:

<h2>Notifications</h2> <ul> <li> <span>Notify by email</span> <button aria-labelledby="notify-email"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by SMS</span> <button aria-labelledby="notify-sms"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by fax</span> <button aria-labelledby="notify-fax"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by smoke signal</span> <button aria-labelledby="notify-smoke"> <span>on</span> <span>off</span> </button> </li></ul> 

Each aria-labelledby value matches the appropriate span id, forming the association and giving the button its unique label. It works much like a <label> element’s for attribute identifying a field’s id.

The switch role

Importantly, the ARIA label overrides each button’s textual content, meaning we can once again employ aria-pressed to communicate state. However, since these buttons are explicitly “on/off” switches, we can instead use the WAI-ARIA switch role, which communicates state via aria-checked.

<h2>Notifications</h2> <ul> <li> <span>Notify by email</span> <button role="switch" aria-checked="true" aria-labelledby="notify-email"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by SMS</span> <button role="switch" aria-checked="true" aria-labelledby="notify-sms"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by fax</span> <button role="switch" aria-checked="false" aria-labelledby="notify-fax"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by smoke signal</span> <button role="switch" aria-checked="false" aria-labelledby="notify-smoke"> <span>on</span> <span>off</span> </button> </li></ul> 

How you would style the active state is quite up to you, but I’d personally save on writing class attributes to the <span>s with JavaScript. Instead, I’d write some CSS using pseudo classes to target the relevant span dependent on the state.

[role="switch"][aria-checked="true"] :first-child, [role="switch"][aria-checked="false"] :last-child { background: #000; color: #fff;}

An interesting thing happens when a button with the aria-pressed state is encountered by some screen readers: it is identified as a “toggle button” or, in some cases, “push button”. The presence of the state attribute changes the button’s identity.

When focusing the example button with aria-pressed="true" using NVDA, the screen reader announces,“Notify by email, toggle button, pressed”. The “pressed” state is more apt than “checked”, plus we eschew the form data input connotations. When the button is clicked, immediate feedback is offered in the form of “not pressed”.

Styling

The HTML we construct is an important part of the design work we do and the things we create for the web. I’m a strong believer in doing HTML First Prototyping™, making sure there’s a solid foundation for the styled and branded product.

In the case of our toggle button, this foundation includes the semantics and behavior to make the button interoperable with various input (e.g. voice activation software) and output (e.g. screen reader) devices. That’s possible using HTML, but CSS is needed to make the control understandable visually.

Form should follow function, which is simple to achieve in CSS: everything in our HTML that makes our simple toggle button function can also be used to give it form.

  • <button>button element selector
  • aria-pressed="true"[aria-pressed="true"] attribute selector.

In a consistent and, therefore, easy to understand interface, buttons should share a certain look. Buttons should all look like buttons. So, our basic toggle button styles should probably inherit from the button element block:

/* For example... */button { color: white; background-color: #000; border-radius: 0.5rem; padding: 1em 2em;}

There are a number of ways we could visually denote “pressed”. Interpreted literally, we might make the button look pressed in using some inset box-shadow. Let’s employ an attribute selector for this:

[aria-pressed="true"] { box-shadow: inset 0 0 0 0.15rem #000, inset 0.25em 0.25em 0 #fff;}

To complete the pressed/unpressed metaphor, we can use some positioning and box-shadow to make the unpressed button “poke out”. This block should appear above the [aria-prressed="true"] block in the cascade.

[aria-pressed] { position: relative; top: -0.25rem; left: -0.25rem; box-shadow: 0.125em 0.125em 0 #fff, 0.25em 0.25em #000;}
Left button, sticking out, is labeled aria-pressed equals false. Right button, visually depressed, is labelled aria-pressed equals true.

(Note: This styling method is offered just as one idea. You may find that something more explicit, like the use of “on”/“off” labels in an example to follow, is better understood by more users.)

Don’t rely on color alone

“On” is often denoted by a green color, and “off” by red. This is a well-established convention and there’s no harm in incorporating it. However, be careful not to only use color to describe the button’s two states. If you did, some color blind users would not be able to differentiate them.

The aria-pressed false button has a red background color and the aria-pressed true button has a green background color
These versions of the control would fail WCAG 2.0 1.4.1 Use Of Color (Level A)

Focus styles

It’s important buttons, along with all interactive components, have focus styles. Otherwise people navigating by keyboard cannot see which element is in their control and ready to be operated.

The best focus styles do not affect layout (the interface shouldn’t jiggle around distractingly when moving between elements). Typically, one would use outline, but outline only ever draws a box in most browsers. To fit a focus style around the curved corners of our button, a box-shadow is better. Since we are using box-shadow already, we have to be a bit careful: note the two comma-separated box-shadow styles in the pressed-and-also-focused state.

/* Remove the default outline and add the outset shadow */ [aria-pressed]:focus { outline: none; box-shadow: 0 0 0 0.25rem yellow;}/* Make sure both the inset and outset shadow are present */ [aria-pressed="true"]:focus { box-shadow: 0 0 0 0.25rem yellow, inset 0 0 0 0.15rem #000, inset 0.25em 0.25em 0 #fff; }

Changing Labels

The previous toggle button design has a self-contained, unique label and differentiates between its two states using a change in attribution which elicits a style. What if we wanted to create a button that changes its label from “on” to “off” or “play” to “pause”?

It’s perfectly easy to do this in JavaScript, but there are a couple of things we need to be careful about.

  1. If the label changes, what happens with the state?
  2. If the label is just “on” or “off” (“play” or “pause”; “active” or “inactive”) how do we know what the button actually controls?

In the previous toggle button example, the label described what would be on or off. Where the “what” part is not consistent, confusion quickly ensues: once “off”/unpressed has become “on”/pressed, I have to unpress the “on” button to turn the “off” button back on. What?

As a rule of thumb, you should never change pressed state and label together. If the label changes, the button has already changed state in a sense, just not via explicit WAI-ARIA state management.

In the following example, just the label changes.

const button = document.querySelector('button');button.addEventListener('click', (e) => { let text = e.target.textContent === 'Play' ? 'Pause' : 'Play'; e.target.textContent = text;});

The problem with this method is that the label change is not announced as it happens. That is, when you click the play button, feedback equivalent to “pressed” is absent. Instead, you have to unfocus and refocus the button manually to hear that it has changed. Not an issue for sighted users, but less ergonomic for blind screen reader users.

Play/pause buttons usually switch between a play symbol (a triangle on its side) and a pause symbol (two vertical lines). We could do this while keeping a consistent non-visual label and changing state.

<!-- Paused state --> <button type="button" aria-pressed="false" aria-label="play"> &#x25b6;</button><-- Playing state --> <button type="button" aria-pressed="true" aria-label="play"> &#x23f8;</button> 

Because aria-label overrides the unicode symbol text node, the paused button is announced as something similar to, “Play button, not pressed” and the playing button as ,“Play button, pressed”.

This works pretty well, except for where voice recognition and activation is concerned. In voice recognition software, you typically need to identify buttons by vocalizing their labels. And if a user sees a pause symbol, their first inclination is to say “pause”, not “play”. For this reason, switching the label rather than the state is more robust here.

Three implementation examples. The first just changes label from play to pause and is okay. The second keeps the play label and changes state, which is incorrect because the pause button cannot be identified with voice recognition. The third changes label and state so the button becomes a pause button which is pressed, which is incorrect. Only use one of the first two implementations.
Never change label and state at the same time. In this example, that would result in a paused button in the pressed state. Since the video or audio would be playing at this point, the lexical “pause” state cannot be also be considered “pressed” on “on”.

Auxiliary labeling

In some circumstances, we may want to provide on/off switches which actually read “on/off”. The trick with these is making sure there is a clear association between each toggle switch and a respective, auxiliary label.

Imagine the email notification setting is grouped alongside other similar settings in a list. Each list item contains a description of the setting followed by an on/off switch. The on/off switch uses the terms “on” and “off” as part of its design. Some <span> elements are provided for styling.

<h2>Notifications</h2> <ul> <li> Notify by email <button> <span>on</span> <span>off</span> </button> </li> <li> Notify by SMS <button> <span>on</span> <span>off</span> </button> </li> <li> Notify by fax <button> <span>on</span> <span>off</span> </button> </li> <li> Notify by smoke signal <button> <span>on</span> <span>off</span> </button> </li></ul> 
A list of notifications settings with associated buttons reading with either on or off highlighted, depending on the state

The virtue of lists is that, both visually and non-visually, they group items together, showing they are related. Not only does this help comprehension, but lists also provide navigational shortcuts in some screen readers. For example, JAWS provides the L (list) and I (list item) quick keys for moving between and through lists.

Each ‘label’ and button is associated by belonging to a common list item. However, not providing an explicit, unique label is dangerous territory — especially where voice recognition is concerned. Using aria-labelledby, we can associate each button with the list’s text:

<h2>Notifications</h2> <ul> <li> <span>Notify by email</span> <button aria-labelledby="notify-email"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by SMS</span> <button aria-labelledby="notify-sms"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by fax</span> <button aria-labelledby="notify-fax"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by smoke signal</span> <button aria-labelledby="notify-smoke"> <span>on</span> <span>off</span> </button> </li></ul> 

Each aria-labelledby value matches the appropriate span id, forming the association and giving the button its unique label. It works much like a <label> element’s for attribute identifying a field’s id.

The switch role

Importantly, the ARIA label overrides each button’s textual content, meaning we can once again employ aria-pressed to communicate state. However, since these buttons are explicitly “on/off” switches, we can instead use the WAI-ARIA switch role, which communicates state via aria-checked.

<h2>Notifications</h2> <ul> <li> <span>Notify by email</span> <button role="switch" aria-checked="true" aria-labelledby="notify-email"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by SMS</span> <button role="switch" aria-checked="true" aria-labelledby="notify-sms"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by fax</span> <button role="switch" aria-checked="false" aria-labelledby="notify-fax"> <span>on</span> <span>off</span> </button> </li> <li> <span>Notify by smoke signal</span> <button role="switch" aria-checked="false" aria-labelledby="notify-smoke"> <span>on</span> <span>off</span> </button> </li></ul> 

How you would style the active state is quite up to you, but I’d personally save on writing class attributes to the <span>s with JavaScript. Instead, I’d write some CSS using pseudo classes to target the relevant span dependent on the state.

[role="switch"][aria-checked="true"] :first-child, [role="switch"][aria-checked="false"] :last-child { background: #000; color: #fff;}

Traversing the settings

Now let’s talk about navigating through this settings section using two different strategies: by Tab key (jumping between focusable elements only) and browsing by screen reader (moving through each element).

Even when navigating by Tab key, it’s not only the identity and state of the interactive elements you are focusing that will be announced in screen readers. For example, when you focus the first <button>, you’ll hear that it is a switch with the label “Notify by email”, in its on state. “Switch” is the role and aria-checked="true" is vocalized as “on” where this role is present.

Switch role support

The switch role is not quite as well supported as aria-pressed. For example, it is not recognized by the ChromeVox screen reader extension for Chrome.

However, ChromeVox does support aria-checked. This means that, instead of “Switch, Notify by email, on” being announced, “Button, Notify by email, checked” is instead. This isn’t as evocative, but it is adequate. More than likely, it will simply be mistaken for a checkbox input.

Curiously, NVDA regards a button with role="switch" and aria-checked="true" as a toggle button in its pressed state. Since on/off and pressed/unpressed are equivalent, this is acceptable (though slightly disappointing).

But in most screen readers you’ll also be told you’ve entered a list of four items and that you’re on the first item — useful contextual information that works a bit like the group labelling I covered earlier in this post.

Importantly, because we have used aria-labelledby to associate the adjacent text to the button as its label, that is also available when navigating in this mode.

When browsing from item to item (for example, by pressing the down key when the NVDA screen reader is running), everything you encounter is announced, including the heading (“Notifications, heading level two”). Of course, browsing in this fashion, “Notify by email” is announced on its own as well as in association with the adjacent button. This is somewhat repetitive, but makes sense: “Here’s the setting name, and here’s the on/off switch for the setting of this name.”

How explicitly you need to associate controls to the things they control is a finer point of UX design and worth considering. In this case we’ve preserved our classic on/off switches for sighted users, without confusing or misleading either blind or sighted screen reader users no matter which keyboard interaction mode they are using. It’s pretty robust.

Conclusion

How you design and implement your toggle buttons is quite up to you, but I hope you’ll remember this post when it comes to adding this particular component to your pattern library. There’s no reason why toggle buttons — or any interface component for that matter — should marginalize the number of people they often do.

You can take the basics explored here and add all sorts of design nuances, including animation. It’s just important to lay a solid foundation first.

Checklist

  • Use form elements such as checkboxes for on/off toggles if you are certain the user won’t believe they are for submitting data.
  • Use <button> elements, not links, with aria-pressed or aria-checked.
  • Don’t change label and state together.
  • When using visual “on” and “off” text labels (or similar) you can override these with a unique label via aria-labelledby.
  • Be careful to make sure the contrast level between the button’s text and background color meets WCAG 2.0 requirements.
Smashing Editorial(ms, vf, il)

Uploading Directories At Once With webkitdirectory

If you’ve ever tried to implement a bulletproof, good-looking file uploader, you might have encountered an issue: uploading an entire folder or folders of files is usually quite a hassle, as files in each folder have to be selected manually. And then some folders might contain sub-folders as well.

Well, we can use webkitdirectory, a non-standard attribute that allows users to pick a directory via a file input. Currently supported in Chrome, Firefox and Edge.

input webkitdirectory
We can upload file directories, including sub-folders, at once. A demo by Šime Vidas.

For example, users could just pick a directory, and all files in that directory and its sub-folders would be listed below, represented by their relative path — a demo by Šime Vidas shows how it works. One click to choose them all is enough.

It’s important to note that the attribute is non-standard, so it will not work for everybody. However, it doesn’t break anything as browsers that don’t support it will just ignore it, so you can easily progressively enhance your file upload without relying on the feature being supported everywhere. Being useful in various scenarios, hopefully the attribute will be picked up by and standardized soon, landing in browsers as a directory attribute.

Ah, and if you want to design a slightly better drag’n’drop-experience, Alex Reardon has a few tips on rethinking drag’n’drop altogether. Worth reading!

Further Resources:

We send out this and other useful tips and tricks for designers and developers in our Smashing Email Newsletter — once every two weeks. (Once subscribed, you get a free eBook, too.)

How New Font Technologies Will Improve The Web

Words are the primary component of content for the web. However, until a short while ago, all we had at our disposal were but a few system fonts. Adding to that, those system typefaces weren’t necessarily coherent from operating system to operating system (OS). Fortunately, Windows, macOS and Linux made up font-wise, and since then, all modern fonts have been compatible across those OS’. There’s no question, the future of web typography looks promising.

And it’s looking more and more promising, too. At the 2016 ATypI conference, the world’s biggest type design conference, Microsoft, Google, Apple and Adobe announced that they have been working on a new iteration of the OpenType standard, called variable fonts. Because it gives a lot more control to the user to modify the typeface depending on the context and device, this new version opens new opportunities for web typography and will close the gap in quality between web and print.

Variable fonts and parametric fonts are tools that will undeniably revolutionize responsive web type. They will allow graphic and web designers to explore shapes and sizes on their own and to tailor typefaces to their needs. Let’s learn the ins and outs of these new tools and how to take control of our typography.

Creating Scalable, Fluid Typography

Fluid layouts have been a normal part of front-end development for years. The idea of fluid typography, however, is relatively new and has yet to be fully explored. Read a related article →

Web Is Not Print With Pixels

When a paradigm shift comes forth, such as a new medium for typography, the first thing it encounters is resistance. We feel like we need to push the status quo to its limit before it can break free and make room for a new way of thinking. Typography is no exception, and for a long time designers have considered screen as paper made of pixels instead of trees. Typefaces used on computers were, and still are for the most part, just a static embodiment of physical fonts. Sure, the screen medium brought with it a number of necessary and extra elements, such as hinting, but the legacy of physical fonts still resonate strongly in type design.

Still, it feels like digital typography is behind physical typography on a range of issues, not so much in the diversity or quality of design, but in the huge fragmentation of screen media. For print design, a cast of physical fonts could be optimized depending on the sizes and shapes of the letters to increase readability. Once the fonts were produced, the result was the same every time; you got exactly what you paid for.

On a screen, it’s a lot more complicated. Once you’re lost in a forest of DPI values and different renderers, what the user gets is all up in the air. And because type designers have little incentive to produce different optical sizes, a lot of digital typefaces include only a couple of them, which hinders the readability of web typography.

specimen of the Trianon typeface
Different optical sizes of the Trianon family from Production Type (Image: Production Type) (View large version)

When a graphic designer works on a poster, they already know how it will be displayed or distributed. They know the size of the poster, the size of the font, the colors they will use, etc. All of these are known variables that will contribute to their design choices. Also, the designer knows that, once it’s done and printed, the design will not change, and all viewers will experience the same poster.

example of good text rag and bad text rag
Atta rag! Oh, you’re such a good rag. (View large version)

Let’s look at another aspect that is difficult to fix in web typography: rags. Rags are easy to deal with in print: You can adjust the tracking a bit, insert line breaks or hyphenate to clean up the rags. Unfortunately, achieving this degree of detail in web typography is more complicated. The width changes, and the font size can be changed by the user. The dynamism of web pages makes it difficult to make the right choice of size, letter-spacing, etc.

Fortunately, it is possible to gather some data about the context in which your website will be browsed. Thanks to CSS and JavaScript, you can adapt the typography of a web page. However, as easy as it is to change the size of a typeface gradually, it is still impossible to easily change from one variant to another progressively. The only option left is to set up breakpoints, with one variant on one side and another on the other side.

Loading more variants has a price. Adding 150 KB of fonts might not seem like a bad trade-off, but it compounds every time you add a new font to the website. Because loading time is a major factor in the bounce rate of a page, you wouldn’t want users to bail just because your web page has too much to load.

Responsive Web Type Technologies

Having described the challenges of web typography, let’s dive into the heart of the matter. We’ll go deep into the two main technologies that help us make great typography for the web: variable fonts and parametric fonts.

Variable Fonts

With the ATypI 2016 conference on variable fonts, variable fonts have made a big entrance on the web. They’re pushed by the biggest names in web browsing (Google, Adobe, Apple and Microsoft), and they are here to stay.

If you want to see what people do with and say about variable fonts, we’ve gathered resources from around the web. You’ll have to use a browser that supports variable fonts, either Chrome from version 59.0 or Firefox from version 53.0:

The best source of news on variable fonts is, without question, the Twitter feed led by Nick Sherman, who collects everything on the web about variable fonts (and for which we should be grateful).

Thanks to the new variable fonts format, it will be possible to precisely adapt typography to its context. Variable fonts are based on a pretty simple idea: They contain several variants of a single typeface or, more precisely, a master variant and deltas from other ones, and the user is free to choose an interpolation of these different versions using only CSS. For example, the typeface could contain a light variant and a bold variant, and you would be able to choose a weight between these light and bold weights using CSS, like so:

 h2 { font-variation-settings: "wght" 200;}
two capital A of the same variable font
Simple interpolations (also known as multiple masters) (View large version)

Variable fonts are picky. For them to work, all masters of the font’s base variants must have exactly the same number of points. Morphing between two shapes will be smooth and unique only if the shape you start from and the shape you end up with are similar. Nevertheless, some type creators are used to designing for masters for variable fonts. A similar concept was used for Adobe’s “multiple master” format, and type designers use interpolation to create extended families with tools such as Superpolator. Yet font-variation-settings is still not prevalent in web browsers, and as of the time of writing, only Firefox has implemented the feature. But others should soon follow suit.

There are still a lot of hurdles to jump before variable fonts become an integral part of responsive web typography. Making them is a long endeavor, and type designers now have to think about variations from the get go in order to create typefaces that take full advantage of these new features. Even though converting old typefaces to variable fonts is possible, the old ways are not necessarily suited to the new and more relevant uses that we’ve discussed:

  • generating grades on the spot for screens with different DPI.
  • changing the width of a typeface depending on the way the user wants to fill lines,
  • modifying the optical size depending on the font’s size.

Unfortunately, variable fonts don’t solve every problem with responsive web typography. For example, how do we reduce the number of media queries? How do we handle outliers? How do we make the typeface a part of the web page?

Parametric fonts are intended to fix these issues. They differ from variable fonts in concept and production. They put customization logic at the heart of the font, instead of letting a software do the transformation. All typographic rules are inherently a part of the font, but the font is still easily customizable on the user’s side.

Parametric Fonts

Parametric fonts are an old idea that seems to be revisited regularly by people from different backgrounds. It looks to solve the same issues that variable fonts solve but coming from a more automated way of thinking. So, it has usually been a subject tackled by computer scientists who take an interest in type design.

As with variable fonts, we’ve gathered links from around the web that deal with parametric fonts and their history:

  • Metafont,” Wikipedia

    The father of all modern parametric typeface frameworks
  • Metaflop

    A Metafont graphics interface
  • Metapolator

    A parametric typeface creation tool based on Metaflop
  • Parametric TrueType Fonts,” TrueType Typography

    Information about the now discontinued FontChameleon, which is font software that let you merge fonts from a wide library
  • Elementar, Typotheque

    A bitmap parametric font

It’s been almost 40 years since Donald Knuth pioneered the concept of parametric fonts. By creating Metafont and Tex, Knuth opened up a new era of typography, in which typefaces were created using a series of steps and equations to describe each character.

That’s the big difference between variable fonts and parametric fonts. Variable fonts are interpolated, meaning that they are confined in a design space. The designer is not able to escape this space; moreover, adding dimensions to it requires the type designer to create a new master (i.e. a completely new font). Parametric fonts are extrapolated, meaning that they emerge from a single definition. The space in which they live is not limited because they behave like a mathematical object.

capital A designed with Metafont
An “A” created with Metafont (Image: MAlumni) (View large version)

Take the simple example of a circle. In a variable font world, the type designer would produce two circles and tell you, “Choose either of these circles.” In a parametric font world, the type designer would tell you, “Give the font a radius, and it will produce a circle of that radius.”

difference of design space between variable fonts and parametric fonts
Available design space of variable fonts and parametric fonts (View large version)

Adding a new dimension to your design space is easy with parametric fonts. For variable fonts, it would mean creating a new master. For a parametric font, you just have to bake the new dimension into the existing equations.

It is also easy to add constraints or to alter the rate of change of some points using parametric fonts. As well, you can add logic directly into the font.

animation of a lowercase g designed with prototypo
The “g”s ear will always stay on the curve.

How To Start Working With Parametric Fonts?

Parametric fonts are pretty easy to use, and the result can look gorgeous. As we’ll see in the examples, parametric fonts can mitigate optical differences between different colors of text. You can also create text that responds to its context or to any interface you can imagine.

the writer playing with a kinect hooked up to a parametric font
Feeding a Kinect’s data into a font

To make life easier for you, we’ve created Prototypo, a free web application for tweaking and adjusting parametric fonts. You’ll need a subscription to take full advantage of parametric fonts. But in the free version, you’ll be able to use subsetted fonts that contain lowercase and uppercase glyphs (no diacritics or figures). The paid subscription unlocks the full fonts.

animation of prototypo's ui with moving text spelling smashing magazine
Prototypo, a parametric font web app

Here’s how to start experimenting with parametric fonts:

  • Use our web preview extension to test your parametric font directly on your website.
  • Embed a parametric font on your website using our JavaScript library.

Prototypo Chrome Extension

The extension can be used to try out parameters for different display sizes and layouts. The extension lets you replace the typefaces on your website. All of the modifications you do in Prototypo are applied to your website in real time. This is the perfect tool to try out different optical weights and widths for your fonts in their final context.

a demonstration of prototypo web extension
The Prototypo web extension lets you visualize your customized font in real time.

Prototypo Parametric Typeface Library

The other option is to use Prototypo parametric technology directly. We’ll explain how you can add the Prototypo library to your website. You’ll be able to create parametric fonts on your website and make them interact as your users need. You can see examples of the parametric technology in our lab. For example, you can use a Kinect to generate fonts, or morph and switch letters based on the current timestamp. We’ll discuss how it works and how you can use it in your projects, including how to:

  • set up the project,
  • create a font on the fly,
  • use the created font in CSS,
  • modify the font with JavaScript.

Set Up the Project

This is the tag you will have to add to your HTML to import the Prototypo library.

<script type="application/javascript" src="https://library.prototypo.io/ptypo.js"></script>

You can also import this script asynchronously, but you’ll have to wait for its load event to use the library:

<script async type="application/javascript" src="https://library.prototypo.io/ptypo.js"></script><script type="application/javascript"> document.getElementById('script').addEventListener('load', function() { // You’ll have access to the Ptypo global variable here });</script>

So, what can this library do for you, you ask? Well, it will create a Ptypo global variable that we will use to create our parametric font.

Let’s look at an example to better understand how we can use the library.

Making a Light-Font Mode and a Dark-Font Mode

See the Pen bRKbxY by Francois Poizat (@FranzPoize) on CodePen.

For the first example, we will try to create a font whose weight looks the same whether written in dark on light or light on dark. Text tends to look bolder when written light on dark because light colors tend to bleed on dark colors, making the lighter font seem heavier.

We’ll make a simple HTML document that can be switched from light mode to dark mode, and we will change the parameters of the font accordingly. You could also have several color schemes and produce parameters that would look the same for each color scheme.

Let’s start by creating our font factory.

const ptypoFactory = new Ptypo.default();

Here, you can use your token if you subscribe to the Prototypo application. (You can find more information about that in our documentation.)

Once we have our font factory, it’s time to start creating fonts. For the dynamic part of this example, we’ll create two fonts — named titleFont and paragraphFont for the h1 heading and the paragraph, respectively.

ptypoFactory.createFont( 'titleFont', Ptypo.templateNames.ELZEVIR).then(function(font) { //Setting up the right parameters font.changeParam('thickness', 110);});ptypoFactory.createFont( 'paragraphFont', Ptypo.templateNames.GROTESK).then(function(font) { font.changeParams({thickness: 70, spacing: 0.5});});

The title font uses the Elzevir template, which is a serif template, and the paragraph font uses the Grotesk template, which is a sans-serif. We can set the parameters as we please (you can change the value if you want).

As you can see, we can modify the parameters in two ways:

font.changeParam('nameOfParameter', parameterValue)font.changeParams({ parameter1: parameter1Value, parameter2: parameter2Value, parameter3: parameter3Value …});

You can learn more about the different parameters available in our API documentation.

Now we need to write the HTML that goes with it and the CSS that will assign the correct font to the correct element.

<div> <h1> With Param </h1> <p> Lorem ipsum dolor sit amet.. </p></div>
h1 { font-size: 100px; font-family: 'titleFont'; font-weight: normal;}p { font-size: 18px; line-height: 24px; font-family: 'paragraphFont';}

Here, we’ve created a heading and a paragraph of text and attached the correct font to them: titleFont for the heading and paragraphFont for the paragraph.

We now need to create a button to switch between light and dark mode and create the functions that will modify the fonts.

<a href=”#”> Dark mode</a>

There are many ways to modify our fonts. What we will do is create an array that we will fill with an object literal containing our functions once the fonts are created.

const fontToggles = [];ptypoFactory.createFont( 'titleFont', Ptypo.templateNames.ELZEVIR).then(function(font) { //Setting up the right parameters font.changeParam('thickness', 110); //Storing the function that will be used to change from light to dark //and vice versa fontToggles.push({ lightMode: function() { font.changeParam('thickness', 110); }, darkMode: function() { font.changeParam('thickness', 107); }, });});ptypoFactory.createFont( 'paragraphFont', Ptypo.templateNames.GROTESK).then(function(font) { font.changeParams({thickness: 70, spacing: 0.5}); fontToggles.push({ lightMode: function() { font.changeParam('thickness', 70); }, darkMode: function() { font.changeParam('thickness', 50); }, });});

In this part, we start by creating a font using the ptypoFactory.createFont method.

Ptypo.templateNames.ELZEVIR).then(function(font) { ...});

Once the font is created, we put in default parameters for the thickness. We’ve decided to put a thickness of 110 for the heading font and a thickness of 70 and a spacing of 0.5 for the paragraph font.

font.changeParams({thickness: 70, spacing: 0.5});

For each font, we will add an object to the fontToggles array. This object will contain a lightMode and a darkMode property. These two functions are to be executed when the page enters light mode and dark mode, respectively, using our button.

fontToggles.push({ lightMode: function() { font.changeParam('thickness', 70); }, darkMode: function() { font.changeParam('thickness', 50); },});

Now we can add our listener on the click event of the button and use the functions contained in the array to modify our font according the mode we are in.

let button = document.getElementById('dark-button');button.addEventListener('click', function(e) { document.body.classList.toggle('dark'); fontToggles.forEach(function(toggle) { toggle[document.body.classList.contains('dark') ? 'darkMode' : 'lightMode'](); }); e.preventDefault();});

Thanks to this code, once we click on our dark-mode button, it will add the dark class to the body. It will loop through our font, modifying functions and executing the darkMode one if there a dark class on body and executing lightMode if there is no dark class on body.

In our example, we’ve included a font that does not change in dark mode, to show what the difference will be between the regular font and the slightly modified one.

Customize Fonts With Data

In this example, we’re going to create several fonts, one for each city’s weather that we want to display, customized using the temperature and wind speed of the given city. The thickness of the font will be tied to the temperature, and the slant will be tied to the wind speed.

See the Pen ayYevr by Francois Poizat (@FranzPoize) on CodePen.

First, we’ll create a list of the cities we want to display.

const cities = [ 'Lyon', 'Padova', 'Rennes', 'Tokyo', 'Johannesburg', 'Moscow', 'Beijing', 'San Francisco', 'Marrakech', 'Trondheim',];

We’ve chosen cities from around the world, to have a nice range of temperatures and wind speeds.

function yahooApiQuery(city, callback) { if (!city || !callback) { throw new Error('$.YQL(): Parameters may not be undefined'); } const encodedQuery = encodeURIComponent( `select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='${city}')`.toLowerCase() ); const url = `https://query.yahooapis.com/v1/public/yql?q=${encodedQuery}&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=?`; $.getJSON(url, callback);};

This function requests the Yahoo weather API (which comes with documentation). We’ll use jQuery’s getJson function to get the JSON from the API.

function getValueAndChangeFont(city, font) { yahooApiQuery( city, function(data) { font.changeParams({ thickness: parseInt(data.query.results.channel.item.condition.temp) * 2, slant: parseInt(data.query.results.channel.wind.speed), }); } );}

We’ve created a function that takes the name of a city and the font. Then, we’ve requested the weather for this city and changed the parameters of the font according to the temperature and wind speed.

font.changeParams({ thickness: parseInt(data.query.results.channel.item.condition.temp) * 2, slant: parseInt(data.query.results.channel.wind.speed),});
a demonstration of prototypo web extension
The Prototypo web extension lets you visualize your customized font in real time.

Prototypo Parametric Typeface Library

The other option is to use Prototypo parametric technology directly. We’ll explain how you can add the Prototypo library to your website. You’ll be able to create parametric fonts on your website and make them interact as your users need. You can see examples of the parametric technology in our lab. For example, you can use a Kinect to generate fonts, or morph and switch letters based on the current timestamp. We’ll discuss how it works and how you can use it in your projects, including how to:

  • set up the project,
  • create a font on the fly,
  • use the created font in CSS,
  • modify the font with JavaScript.

Set Up the Project

This is the tag you will have to add to your HTML to import the Prototypo library.

<script type="application/javascript" src="https://library.prototypo.io/ptypo.js"></script>

You can also import this script asynchronously, but you’ll have to wait for its load event to use the library:

<script async type="application/javascript" src="https://library.prototypo.io/ptypo.js"></script><script type="application/javascript"> document.getElementById('script').addEventListener('load', function() { // You’ll have access to the Ptypo global variable here });</script>

So, what can this library do for you, you ask? Well, it will create a Ptypo global variable that we will use to create our parametric font.

Let’s look at an example to better understand how we can use the library.

Making a Light-Font Mode and a Dark-Font Mode

See the Pen bRKbxY by Francois Poizat (@FranzPoize) on CodePen.

For the first example, we will try to create a font whose weight looks the same whether written in dark on light or light on dark. Text tends to look bolder when written light on dark because light colors tend to bleed on dark colors, making the lighter font seem heavier.

We’ll make a simple HTML document that can be switched from light mode to dark mode, and we will change the parameters of the font accordingly. You could also have several color schemes and produce parameters that would look the same for each color scheme.

Let’s start by creating our font factory.

const ptypoFactory = new Ptypo.default();

Here, you can use your token if you subscribe to the Prototypo application. (You can find more information about that in our documentation.)

Once we have our font factory, it’s time to start creating fonts. For the dynamic part of this example, we’ll create two fonts — named titleFont and paragraphFont for the h1 heading and the paragraph, respectively.

ptypoFactory.createFont( 'titleFont', Ptypo.templateNames.ELZEVIR).then(function(font) { //Setting up the right parameters font.changeParam('thickness', 110);});ptypoFactory.createFont( 'paragraphFont', Ptypo.templateNames.GROTESK).then(function(font) { font.changeParams({thickness: 70, spacing: 0.5});});

The title font uses the Elzevir template, which is a serif template, and the paragraph font uses the Grotesk template, which is a sans-serif. We can set the parameters as we please (you can change the value if you want).

As you can see, we can modify the parameters in two ways:

font.changeParam('nameOfParameter', parameterValue)font.changeParams({ parameter1: parameter1Value, parameter2: parameter2Value, parameter3: parameter3Value …});

You can learn more about the different parameters available in our API documentation.

Now we need to write the HTML that goes with it and the CSS that will assign the correct font to the correct element.

<div> <h1> With Param </h1> <p> Lorem ipsum dolor sit amet.. </p></div>
h1 { font-size: 100px; font-family: 'titleFont'; font-weight: normal;}p { font-size: 18px; line-height: 24px; font-family: 'paragraphFont';}

Here, we’ve created a heading and a paragraph of text and attached the correct font to them: titleFont for the heading and paragraphFont for the paragraph.

We now need to create a button to switch between light and dark mode and create the functions that will modify the fonts.

<a href=”#”> Dark mode</a>

There are many ways to modify our fonts. What we will do is create an array that we will fill with an object literal containing our functions once the fonts are created.

const fontToggles = [];ptypoFactory.createFont( 'titleFont', Ptypo.templateNames.ELZEVIR).then(function(font) { //Setting up the right parameters font.changeParam('thickness', 110); //Storing the function that will be used to change from light to dark //and vice versa fontToggles.push({ lightMode: function() { font.changeParam('thickness', 110); }, darkMode: function() { font.changeParam('thickness', 107); }, });});ptypoFactory.createFont( 'paragraphFont', Ptypo.templateNames.GROTESK).then(function(font) { font.changeParams({thickness: 70, spacing: 0.5}); fontToggles.push({ lightMode: function() { font.changeParam('thickness', 70); }, darkMode: function() { font.changeParam('thickness', 50); }, });});

In this part, we start by creating a font using the ptypoFactory.createFont method.

Ptypo.templateNames.ELZEVIR).then(function(font) { ...});

Once the font is created, we put in default parameters for the thickness. We’ve decided to put a thickness of 110 for the heading font and a thickness of 70 and a spacing of 0.5 for the paragraph font.

font.changeParams({thickness: 70, spacing: 0.5});

For each font, we will add an object to the fontToggles array. This object will contain a lightMode and a darkMode property. These two functions are to be executed when the page enters light mode and dark mode, respectively, using our button.

fontToggles.push({ lightMode: function() { font.changeParam('thickness', 70); }, darkMode: function() { font.changeParam('thickness', 50); },});

Now we can add our listener on the click event of the button and use the functions contained in the array to modify our font according the mode we are in.

let button = document.getElementById('dark-button');button.addEventListener('click', function(e) { document.body.classList.toggle('dark'); fontToggles.forEach(function(toggle) { toggle[document.body.classList.contains('dark') ? 'darkMode' : 'lightMode'](); }); e.preventDefault();});

Thanks to this code, once we click on our dark-mode button, it will add the dark class to the body. It will loop through our font, modifying functions and executing the darkMode one if there a dark class on body and executing lightMode if there is no dark class on body.

In our example, we’ve included a font that does not change in dark mode, to show what the difference will be between the regular font and the slightly modified one.

Customize Fonts With Data

In this example, we’re going to create several fonts, one for each city’s weather that we want to display, customized using the temperature and wind speed of the given city. The thickness of the font will be tied to the temperature, and the slant will be tied to the wind speed.

See the Pen ayYevr by Francois Poizat (@FranzPoize) on CodePen.

First, we’ll create a list of the cities we want to display.

const cities = [ 'Lyon', 'Padova', 'Rennes', 'Tokyo', 'Johannesburg', 'Moscow', 'Beijing', 'San Francisco', 'Marrakech', 'Trondheim',];

We’ve chosen cities from around the world, to have a nice range of temperatures and wind speeds.

function yahooApiQuery(city, callback) { if (!city || !callback) { throw new Error('$.YQL(): Parameters may not be undefined'); } const encodedQuery = encodeURIComponent( `select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='${city}')`.toLowerCase() ); const url = `https://query.yahooapis.com/v1/public/yql?q=${encodedQuery}&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=?`; $.getJSON(url, callback);};

This function requests the Yahoo weather API (which comes with documentation). We’ll use jQuery’s getJson function to get the JSON from the API.

function getValueAndChangeFont(city, font) { yahooApiQuery( city, function(data) { font.changeParams({ thickness: parseInt(data.query.results.channel.item.condition.temp) * 2, slant: parseInt(data.query.results.channel.wind.speed), }); } );}

We’ve created a function that takes the name of a city and the font. Then, we’ve requested the weather for this city and changed the parameters of the font according to the temperature and wind speed.

font.changeParams({ thickness: parseInt(data.query.results.channel.item.condition.temp) * 2, slant: parseInt(data.query.results.channel.wind.speed),});

We’ve multiplied the temperature by two because most temperatures in Fahrenheit are between 0 and 100 degrees, and we want the thickness to be between 0 and 200, so that the contrast is stronger. We’ve left the speed of the wind untouched because it can probably take values from 0 to 40, which would be great as an angle for the slant.

const ptypoFactory = new Ptypo.default();cities.forEach(function(city) { $('#city-names').append( `${city} ` ); ptypoFactory.createFont( `${city}WeatherFont`, Ptypo.templateNames.GROTESK).then( function(font) { getValueAndChangeFont(city, font); } );});

For each city, we create a span element that is styled with the right font family. We then create this font using Prototypo’s library. We go through the same process explained in the first example. Let’s create the factory:

const ptypoFactory = new Ptypo.default();

Then, for each city, we create the city’s font with the correct name, ${city}WeatherFont, using our getValueAndChangeFont function to customize the font.

This simple example shows how Prototypo can be very helpful for designing a new kind of data visualization: creating typefaces that are able to express more than the text, directly linked to data. Feel free to test this Codepen with your own city, to try others parameters (x-height, width, etc.) and to show us what you’ve achieved!

This concludes our examples. If you want to see more experiments we’ve created with the library, head over to our lab.

Conclusion

Parametric font technology will help us improve the user experience by enabling us to optimize how fonts are displayed on all sorts of devices. It also enables us to be more creative with fonts using context, outside variables and physical sensors to modify the input parameters. You just need to find ideas to tailor your typefaces to the experiences you want to provide:

  • Create data visualizations that combine text and content. Imagine that your client has a big website about sports. You will be able to produce a design in which the shapes and proportions of fonts used for players’ names could be linked to the number of touchdowns they’ve scored, the number of games they’ve played, etc.
  • Improve the user’s browsing experience with responsive fonts and even adaptive fonts. Because we can already set our text-size preferences, we can imagine a future when users have their own profile to fit their reading habits, especially those who have visual impairments.
  • Design storefronts that respond to passers by. Design theater plays whose words are shaped directly by the voices of the actors. Design screens that are capable of rendering letters according to the distance of the reader. Parametric fonts are made to interact with people.

Parametric font technology is both complex and powerful, and like every design tool, it goes awry when it’s used without constraint or perspective. But once you get the logic behind it, you will never go back to a simple breakpoint design.

The question now is, What would you do if you could morph typefaces to your every whim?

Smashing Editorial(md, il, al)