Leonardo da Vinci said, “Simplicity is the ultimate form of sophistication.” Whatever I’m designing, that is my mantra. It’s also one of the basic requirements for effective UI design. In order to attract, convert and retain, user interface must satisfy three criteria: It should be engaging, beautiful and elicit an emotional response from the user. The same applies to almost every other work of art; the only difference is, art can endure a certain dose of complexity. UI can’t. Being a vital part of UX, UI is one of the key factors that influence conversion rates. Conversion, on the other…
How To Create A Flat Vector Illustration In Affinity Designer
(This is a sponsored post.) If you are in the design world, chances are that you’ve already heard about Affinity Designer, a vector graphics editor for Apple’s macOS and Microsoft Windows.
It was July 2015 when Serif Europe launched the amazing software that many designers and illustrators like me are using now as their main tool for professional work. Unlike some other packages, its price is really affordable, there’s no subscription model and, as mentioned already, it’s available for both Macs and PCs.
In this article, I would like to walk you through just some of its very user-friendly main tools and features as an introduction to the software and to show you how we can create a nice flat vector illustration of a Volkswagen Beetle. The illustration will scale up to whatever resolution and size needed because no bitmaps will be used.
Note: As of today, July 11, Affinity Designer is also available for the iPad. Although the iPad app’s features and functionality almost completely match the desktop version of Affinity Designer, it relies much more on using the touch screen (and the Apple Pencil) and because of that, you may expect to find some differences in the workflows.
I will also explain some of the decisions I take and methods I follow as I work. You know the old saying, “All roads lead to Rome”? In this case, many roads will take us where we’d like to get to, but some are better than others.
We will see how to work with the Pen tool to trace the main car outline, how to break curves and segments, how to convert objects into curves, and how to use the wonderful Corner tool. We will also, among other things, learn how to use the Gradient tool, what is a “Smart copy”, how to import a color palette from an image that we can use as a reference for our artwork, how to use masks, and how to create a halftone pattern. Of course, along the way, you will also learn some helpful keyboard shortcuts and commands.
Note:Affinity Designer has three work environments, referred to as “personas”. By default, Affinity Designer is set to the draw persona. To switch from the draw persona to the pixel persona or to the export persona, you have to click on one of the three icons located in the top-left corner of the main window. You can start working in the draw persona and switch to the pixel persona at any time, when you need to combine vectors and bitmaps.
Introduction: The Flat Design Era
In recent years, we’ve seen the rise of “flat design”, in contrast to what is known as skeuomorphic representation in design.
To put it simply, flat design gets rid of the metaphors that skeuomorphic design uses to communicate with users, and we’ve seen these metaphors in design, especially in user interface design, for years. Apple had some of the best examples of skeuomorphism in its early iOS and app designs, and today it is widely used in many industries, such as music software and video games. With Microsoft’s (with Metro) and later Google’s material design and Apple’s iOS 7, mobile apps, user interfaces and most systems and OS’ have moved away from skeuomorphism, using it or elements of it as mere enhancements to a new design language (including gradients and shadows). As you can imagine, illustrations on these systems were also affected by the new design currents, and illustrators and designers started creating artwork that would be consistent with the new times and needs. A whole new world of flat icons, flat infographics and flat illustrations opened in front of our eyes.
Let’s Draw A Flat Illustration!
I am providing here the source file for this work, so you can use it to explore it and to better follow along as we design it. If you do not yet have a copy of Affinity Designer, you can download a trial.
1. Canvas Settings
Open Affinity Designer, and create a new document by clicking Cmd + N (Mac) or Ctrl + N (Windows). Alternatively, you can go to “Menu” → “File” → “New”. Be sure not to check the “Create Artboard” box.
Set the type to “Web”, which will automatically set the field DPI to 72. It should be understood now as PPI, but we won’t dive into the details here. If you want to learn more on the topic, check the following two resources:
Also, remember that you can change this setting at any time. The vectors’ quality won’t be affected by scaling them.
Set the size to 2000 × 1300 pixels, and click “OK”.
Our white canvas is now set, but before we start, I’d suggest you first save this file and give it a name. So, go to “File” → “Save”, and name it “Beetle”.
2. Importing A Color Palette From An Image
One of the things I use a lot in Affinity Designer is its ability to import the colors contained in an image and creating a palette from them.
Let’s see how this is done.
For the illustration I want to draw, I thought of warm colors, like in a sunset, so I searched Google with this query: “warm colors yellows oranges reds palette”. From all the images it found, I chose one that I liked and copied it into Affinity Designer in my recently created canvas. (You can copy and paste the image to the canvas directly from the browser.)
If the Swatches panel isn’t open yet, use menu “View” → “Studio” → “Swatches”. Click the menu in the top-right corner of the panel, and select the option “Create Palette From Document”, and then click on “As Document Palette”. Click “OK” and you’ll see the colors contained in the image form a new palette in the Swatches panel. The default name for it will be “Palette” if you still haven’t saved your file with a name. In case you have, the name of this palette will be the same as your document, but if you want to rename it, simply go to the menu on the right in the Swatches panel again and select the option “Rename Palette”.
I will call it “Beetle Palette”.
We can now get rid of that reference image, or simply hide it in the Layers panel. We will be using this palette as a guide to create our artwork with harmonious colors.
Interface: Before we continue, I will present a quick overview of the main sections of the user interface in Affinity Designer, and the names of some of the most used tools.
3. Creating The Background With The Gradient Tool
The next thing is to create a background. For this, go to the tools displayed on the left side, and select the Rectangle tool. Drag it along the canvas, making sure to give it an initial random fill color so that you can see it. The fill color chip is located in the top toolbar.
Next, select the Fill tool (the color wheel icon, or press G on the keyboard), and in the top Context toolbar, select the type: “Linear”.
We have several options here: “None” removes the fill color, “Solid” applies one solid color, and all of the rest are different types of gradients.
To straighten the gradient and make it vertical, place your cursor over one of the ends and pull. When you are near the vertical line, press Shift: This will make it perfectly vertical and perpendicular to the base of the canvas.
Next, in the Context toolbar, click on the color chip, and you’ll see a dialog that corresponds exactly with the gradient we just applied. Click now on the color chip, and an additional dialog will open.
In the combo, click on the “Color” tab, and then select “RGB Hex Sliders”; in the field marked with a #, input the value: FE8876. Press “OK”. You’ll see now how the gradient has been updated to the new color. Repeat this action with the other color stop in the gradient dialog, and input this value: E1C372.
You should now have something like this:
Let’s go to the Layers panel and rename the layer to “Background”. Double-click on it to rename it, and then lock it (by clicking on the little lock icon in the top-right corner).
4. Drawing The Car Outline With The Pen Tool
The next thing we need to do is look for an image that will serve as our reference to draw the outline of the car. I searched Google for “Volkswagen Beetle side view”. From the images I found, I selected one of a green Beetle and copied and pasted it into my document. (Remember to lock the layer with the reference image, so that it doesn’t move accidentally.)
Next, in the side toolbar, select the Pen tool (or press P), zoom in a bit so that you can work more comfortably, and start tracing a segment, following the outline of the car in the picture. Give the stroke an 8-pixel width in the Stroke panel.
Note:You won’t need to create a layer, because the segments you trace will be automatically placed on top of the image.
The Pen tool is one of the most daunting tools for beginners, and it is obviously one of the most important tools to learn in vector graphics. While practice is needed to reach perfection, it is also a matter of understanding some simple actions that will help you use the tool better. Let’s dive into the details!
As you trace with the Pen tool in Affinity Designer, you will see two types of nodes: squared nodes appear first, and as you pull the handles, they will turn into rounded nodes.
Affinity Designer comes with several pen modes, but we will only be using the default one, called “Pen Mode”, and as we trace the car, we will get rid of one of the handles by clicking Alt in such a way that the next section of the segment to be traced will be independent of the previous one, even if connected to it.
Here’s how to proceed. Select the Pen tool, click once, move some distance away, click a second time (a straight line will be created between nodes 1 and 2), drag the second node (this will create a curve), Alt-click the node to remove the second control handle, then proceed with node 3, and so on.
An alternative way would be to select the Pen tool, click once, move some distance away, click a second time (a straight line will be created between nodes 1 and 2), drag the second node (this will create a curve), then, without moving the mouse, Alt-click the second handle’s point to remove this handle, then proceed with node 3, and so on.
Note:Don’ be afraid to trace segments that are not perfect. With time, you’ll get a better grip of the Pen tool. For now, it’s not very important that each node and line looks as we want it to look in the end. In fact, Affinity Designer makes it really easy to amend segments and nodes, so tracing a rough line to start is just fine. For more insight on how to easily use the Pen tool (for beginners), check out Isabel Aracama’s video tutorial.
5. Resculpting Segments And Using The Corner Tool
What we need now is to make all of those rough lines look smooth and curvy. First, we will pull the straight segments to smoothen them, and then we will improve them using the Corner tool.
Click the Node tool in the side toolbar, or select it by pressing A on your keyboard. Now, start pulling segments to follow the lines of your reference picture. You can also use the handles to help make the line take the shape you need by moving and pulling them accordingly. Just do it in such a way that it all fits the reference image, but don’t bother much if it’s not yet perfect. With the Node tool (A), you can both select and move nodes, but you can also click and drag the curves themselves to change them.
Once all of the segments are where we need them, we are going to smoothen their corners using the Corner tool (shortcut: C). This is one of my favorite tools in Affinity Designer. The live Corner tool allows you to adjust your nodes and segments to perfection. Select it by pressing C, or select it from the Tools sidebar. The method is pretty simple: Pass the corner tool over the sharp nodes (squared nodes) that you want to smoothen. If you need to, switch back to the Node tool (A) to adjust a section of a segment by pulling it or its handles. (Smooth nodes (rounded nodes) don’t allow for more softening, and they will display a smaller circle the moment you select the Corner tool.)
Once our corners and segments look good, we’ll want to fill the shape and change the color of the stroke. Select the closed curve line that we just created for the car, click on the fill color chip, and in the HEX color field input FFCF23. Click on the stroke color chip beside it and input 131000.
Create now a shape with the Pen tool, and fill it with black (000000). Place it behind the car’s bodywork (the yellow shape). The exact shape of the new object that you will create does not really matter, except that its bottom side needs to be straight, as in the image below. Place it behind the main bodywork (the yellow shape) via either the Layers panel or through the menu “Arrange” → “Back One”.
6. Creating The Wheels Using Smart Copy
We need to put the wheels in place next. In the Tools, pick the Ellipse tool, and drag over the canvas, creating a circle the same size as the wheel in the reference picture. Click Shift as you drag to make the circle proportionate. Additionally, holding Ctrl (Windows) or Cmd (Mac), you can create a perfect circle from the center out.
Note:If you need to, hide the layers created thus far to see better, or simply reduce their opacity temporarily. You can change the opacity by selecting any shape and pressing a number on the keyboard, from 1 to 9, where 1 will apply a 10% opacity and 9 a 90% opacity value. To reset the opacity to 100%, press 0 (zero).
Choose a random color that contrasts with the rest. I like to do so initially just so that I can see the shapes well contrasted and differentiated. When I am happy with them, I apply the final color. Set the opacity to 50% (click 5 on the keyboard) to be able to see through as you draw it.
Zoom into your wheel shape. Press Z to select the Zoom tool, and drag over the shape while holding Alt key, or double-click on the thumbnail corresponding to it in the Layers panel. (It doesn’t need to be previously selected, although this will help you to visually locate it in the Layers panel.)
We will now learn how to use Smart copy, and we will paste some concentric circles.
Select the circle and press Cmd + J (Mac) or Ctrl + J (Windows). A new circle will be placed on top of the original one. Select it. This command is found under “Edit” → “Duplicate”, and it’s also known as Smart copy or Smart duplicate.
Click Shift + Cmd (Mac) or Shift + Ctrl (Windows), and drag in to transform it into a smaller concentrical circle. Repeat three times, reducing a bit more in size each time, to fit your reference. Smart duplicating a shape by pressing Shift + Cmd (Mac) or Shift + Ctrl (Windows) will make the shape transform in a relative way. This will happen from your third smart-duplicated shape onwards.
So, we have our concentric circles for the wheel, and now we have to change the colors. Go to the Swatches panel, and in the previously created palette, choose colors that work well with the yellow that we have applied to the car’s bodywork. You can select a color and modify it slightly to adapt to what you think works best. We need to apply fill and stroke colors. Remember to give the stroke the same width as the rest of the car (8 pixels) except for the innermost circle, where we will apply a stroke of 11.5 pixels. Also, remember to put back to 100% the opacity of each concentric circle.
I chose these colors, from the outer to inner circles: 5D5100, 918A00, CFA204, E5DEAB.
Now we want to select and group all of them together. Select them all and press Cmd + G (Mac) or Ctrl + G (Windows). Name the new group “Front Wheel” in the Layers panel. Duplicate this group and, while pressing Shift, select it and drag along the canvas until it overlaps with the back wheel. Name the layer accordingly.
7. Breaking Curves And Clipping Masks To Draw The Inner Lines Of The Car’s Bodywork
To keep working, either hide all layers or bring down the opacity so that they don’t get in your way. We need to trace the front and back fenders. We have to do the same as what we did for the main bodywork. Pick the Pen tool and trace an outline over it.
Once it is traced, modify it by using the handles, nodes and Corner tool. I also modified the black shape behind the car a bit, so that it shows a bit more in the lower part of the body work.
Now we want to trace some of the inner lines that define the car. For this, we will duplicate the main yellow shape, remove its fill color and place it onto our illustration in the canvas.
Press A on the keyboard, and click on any of the bottom nodes of the segment. In the top Context toolbar, click on “Action” → “Break Curve”. You will see now that the selected node has turned into a red-outlined squared node. Click on it and pull anywhere. As you can see, the segment is now open. Click the Delete or Backspace key (Windows) or the Delete key (Mac), and do the same with all of the bottom nodes, leaving just the leftmost and rightmost ones, and also being very careful that what is left of the top section of the segment is not deformed at all.
I use this method for one main reason: Duplicating an existing line allows for a more consistent look and for more harmonious lines.
Select now the newly opened curve, and make it smaller in such a way that it fits into the main yellow shape when you place them on top of one another. In the Layers panel, drag this curve into the yellow shape layer to create a clipping mask. The reason for creating a clipping mask is simple: We want an object inside another object so that they do not overlap (i.e. both objects are visible), but one nested inside the other. Not doing so would result in some bits of the nested object being visible, which is not what we want; we need perfect, clean-cut lines.
Note:Clipping masks are not to be mistaken for masks. You will know you’re clipping and not masking because of the thumbnail (masks show a crop-like icon when applied) and because when you are about to clip, a blue stripe is displayed horizontally, a bit more than halfway across the layer. Masks, on the other hand, display a small vertical blue stripe beside the thumbnail.
Now that we have applied our clipping mask to insert the newly created segment inside the main shape of the car, I’ve broken some nodes and moved some others around a bit in order to place them exactly how I want. I’ve stretched the width a bit, and separated the front from the rest of the segment using exactly the same methods we’ve already seen. Then, I applied a bit more Corner tool to soften whatever I felt needed to be softened. Finally, with the Pen tool, I added some extra nodes and segments to create the rest of the inner lines that define the car.
Note:In order to select an object in a mask, a clipping mask or a group when not selecting the object directly in the Layers panel, you have to double-click until you select the object, or hold Ctrl (Windows) or Cmd (Mac) and click.
After some amendments and tweaking using the mentioned methods, our car looks like this:
8. Drawing The Windows Using Some Primitive Shapes
In the side Toolbar, select the Rounded Rectangle tool. Drag on the canvas to create a shape. The size of the shape should fit in the car’s bodywork and look proportionate. No matter how you create it, you will be able to resize it later, so don’t worry much.
Note:When you create a shape with strokes and resize it, be sure to check “Scale with object” in the Stroke panel if you want the stroke to scale in proportion with the object. I recommend that you visually compare the difference between having this option checked and unchecked when you need to resize an object with a stroke.
Once you have placed your rounded rectangle on the canvas, fill it with a blue-ish colour. I’ve used #93BBC1. Next, select it with the Node tool (press A). You will now see a little orange circle in the top-left corner. If you pull outwards or inwards, you’ll see how the angle in that corner changes. In the top Context toolbar, you can uncheck “Single radius”, and apply the angle you want to each corner of the rectangle individually. Uncheck it, and pull inwards on the tiny orange circle in the top-left corner. If you pull, you will be able to round it to a certain percentage, but you can also input the desired value in the input field for it, or even use the slider it comes with (it will show whether you’ve clicked on the little chevron). Let’s apply a value of 100%.
Primitive shapes are not so flexible in terms of vector manipulation (compared to curves and lines), so, in order to apply further changes to such a shape (beyond fill, stroke, corners, width and height), we will need to convert it to curves.
Note:Once you convert a primitive shape into curves, there is no way to go back, and there will be no option to manipulate the shape through the little orange stops. If you need further tweaking, you will need to do it with the Corner tool.
Select the rectangle with the Node tool (A), and in the top Context toolbar, click the button “Convert to Curves”. The bounding box will disappear, and all of the nodes forming the shape will be shown. Also, note how in the Layers panel, the name of the object changes from “Rounded Rectangle” to “Curve”.
Now you need to manipulate the shape in order to create an object that looks like a car window. Look at the reference picture to get a better idea of how it should look. Also, tweak the rest of the drawn lines in the car, so that it all fits together nicely. Don’t worry if the shapes don’t look perfect (yet). Getting them right is a matter of practice! Using the Pen tool, help yourself with the Alt and Shift keys and observe how differently the segment nodes behave. After you have created the front window, go ahead and create the back one, following the same method.
We also need to create the reflections of the window, which we’ll do by drawing three rectangles, filling them with white color, overlapping them with a bit of offset from one another, and setting the opacity to 50%.
Place the cursor over the top bounding-box white circle, and when it turns into a curved arrow with two ends, move it to give the rectangles an angle. Create a clipping mask, dragging it over the window shape in the Layers panel as we saw before. You can also do this by following the following alternative methods:
Under the menu “Layer” → “Insertion” → “Insert Inside” the selected window object.
With the keyboard shortcut Ctrl + X (Windows) and Cmd + X (Mac), select your window object → “Edit” → “Paste Inside” (Ctrl/Cmd + Alt + V).
Repeat this for the back window. To add visual interest, you can duplicate the reflections and slightly change the rectangles’ opacities and widths.
9. Adding Visual Interest: Halftone Pattern, Shadows And Reflections
Before we start with the shadows and reflections, we need to add an extra piece onto the car so that all of the elements look well integrated. Let’s create the piece that sits below the doors. It is a simple rectangle. Place it on the corresponding layer order, so that it looks like the picture below, and keep inserting all of the pieces together so that it looks compact. I will also move a bit the front fender to make the front shorter.
Now let’s create the halftone pattern.
Grab the Pen tool (P) and trace a line on your canvas. In the Stroke panel (you can also do this in the Pen tool’s Context toolbar section for the stroke, at the top), set the size to something like 7 pixels. We can easily change this value later if needed. Select the “Dash” line style, and the rest of the dialog settings should be as follows:
Now, duplicate this line, and place the new one below with a bit of an offset to the left.
Group both lines, duplicate this group with a Smart copy, and create something like this:
When you drag a selection in Affinity Designer, only objects that are completely within the selection area will be selected. If you want to select all objects without having to drag over all of them completely, you have the following options:
Mac: Holding the ⌃ (Ctrl) key will allow you to select all objects touching the selection marquee as you draw it.
Windows: Click and hold the left mouse button, start dragging a selection, and then click and hold the right mouse button as well. As you are holding both buttons, all objects touching the selection marquee will be selected.
Alternatively, you can make this behavior a global preference. On Mac, go to “Affinity Designer” → “Preferences” → “Tools”, and check “Select object when intersects with selection marquee”. On Windows, go to “Edit” → “Preferences” → “Tools”, and check “Select object when intersects with selection marquee”.
To make the illustration more interesting, we are going to vary the beginning and end of some of the lines a bit. To do this, we select the Node tool (A), and move the nodes a bit inwards.
It should now look like this:
To apply the pattern to our design, make sure everything is grouped, copy and paste it into our car artwork, reduce its opacity to 30%, and also reduce the size (making sure “Scale with object” is checked in the Stroke panel). We will then create a clipping mask. It is important to keep consistency in the angle, color and size of this pattern throughout the illustration.
Now, apply the halftone pattern to the back fender and to the car’s side; make sure to create a placeholder for it first, be it the fender itself or a new shape. Make some tweaks if you need to adapt the pattern to your drawing in a harmonious way. You can change the overall size, the dots’ size, the transparency, the angle and so on, but try to be consistent when applying these changes to the pattern bits.
For the shadow below the windows, I drew a curve to be the placeholder, and applied the color #CFA204 so that it looks darker.
10. Creating The Remaining Elements Of The Car
Now, it’s all about creating the rest of the elements that make up the car: the bumpers, the back wheel and the surf board, plus the design stickers.
The front and back lights
For the front light, switch to the Segment tool and draw the shape. Then we need to rotate it a bit and place it somewhere below the car’s main bodywork. The same can be done for the back light but using the Rectangle tool. The colors are #FFDA9D for the front light and #FF0031 for the back light.
To create the surfboard, we will use the Ellipse tool and draw a long ellipse. Convert it to curves and pull up the lower segment, adjusting a bit the handles to give it the ideal shape.
Now, just create two small rounded rectangles, with a little extra line on top for the board’s rack. Place them in a layer behind the car’s main body shape.
With the Pen tool, add the rudder. Its color is #B2E3EF. And for the stroke, use a 6-pixel width and set the color to #131000.
Now let’s create the the spare wheel! Switch to the Rounded Rectangle tool. Drag over the canvas to draw a shape. Color it #34646C, and make the stroke #131000 and 8 pixels in size. The size of the spare wheel should fit the proportions of your car and should have the same diameter as the other wheels, or perhaps just a bit smaller. Pull the orange dots totally inwards, and give it a 45-degree angle. For the rack that holds the wheel, create a small piece with the Rectangle tool, and give it the same 45-degree angle, color it #4A8F99, and make the stroke #131000 and 4.5 pixels in size. Create the last piece that rests over the car in the same way, with a color of #34646C, and a stroke that is #131000 and 4.5 pixels in size.
Lastly, let’s create a shadow inside the wheel to add some more interest. For this, we’ll create a clipping mask and insert an ellipse shape with a color of #194147, without a stroke.
Note:We may want to create the same shadow effect for the car wheels. Use the Rectangle tool and a color of #312A00, create a clipping mask, and insert it in the wheel shape, placing it halfway.
For the bumpers, we will apply the boolean operation “add” to two basic shapes and then clip-mask a shadow, just as we did for the wheels.
Boolean operations are displayed in the section of icons labeled “Geometry” (Mac) and “Operations” (Windows). (Yes, the label names are inconsistent, but the Affinity team will likely update them in the near future, and one of the labels will become the default for both operating systems.) If you don’t see them in the upper toolbar, go to “View” → “Customize Toolbar”, and drag and drop them into the toolbar.
Important: If you want the operation to be non-destructive, hold the Alt key while clicking on the “Add” icon (to combine the two basic shapes).
Note:If you try to paste the “shadow” object inside the bumper, it will only work if the bumper is one whole object (a destructive operation). So, if you used Alt + “Add”, this will not work now. However, you can still work around this by converting the Compound shape (the result of a non-destructive operation that is a group of two objects) to one Curve (one whole vector object). You just need to click on the Compound shape, then in the menu go to “Layer” → “Convert to Curves” (or use the key combination Ctrl + Enter).
We are still missing the back window, which we will create with the Pen tool, and the decoration for the car. For the two colored stripes, we need the Square tool and then clip-mask these two rectangles into the main bodywork. The size is 30 × 380 pixels, and the colors are #0AC8CE and #FF6500. Clip them by making sure you’ve put them on the right layer, so that the dark lines we drew before are above them.
For the number “56” decoration, use the Artistic Text tool (“T”), and type in “56”. Choose a nice font that matches the style of the illustration, or try the one I’ve used.
The color for the text object is #FFF3AD.
(I added an extra squared shape behind the back fender, which will look like the end of the exhaust pipe. The color is #000000.)
Now that we’ve done this, check the color stripes and the window they overlap with. As you can see (and because we put some transparency in the window glass), the orange stripe is visible through it. Let’s use some Boolean power again to fix this.
Duplicate the window object. Select both the window object (the one you just duplicated) and the orange stripe in the Layers panel. Apply a “subtract” operation.
Now, the orange stripe has the perfect shape, fitting the window in such a way that they don’t overlap.
To create the smoke from the exhaust, draw a circle with a white stroke, 5.5 pixels in size and no fill. Transform it to curves and break one of its points. From the bottom node, trace a straight line with the Pen tool.
Duplicate this “broken” circle, and resize to smaller circles, and flip and place them so that they look like this:
Note:Now that the car is finished, group all of its layers together. It will be much easier to keep working if you do so!
11. Creating The Ground And The Background Elements.
Let’s trace a simple line for the ground, and add two bits breaking it in order to create visual interest and suggest a bit of movement. We also want to add an extra piece to create the ground. For this, we will use the Rectangle tool and draw a rectangle with a gradient color of #008799 for the left stop and #81BEC7 for the right stop. Give it 30% opacity.
For the clouds, select the Cloud tool from the list of (primitive) vector shapes. Draw a cloud by holding Shift to keep the proportions. Make it white. Transform it into curves, and with the Node tool (A) select the bottom nodes and delete them. Sub-select the bottom-left and bottom-right nodes (after deleting all of the others), and then in the Context toolbar, select “Convert to Sharp” in the Convert section. This will make your bottom segment straight. Apply some transparency with the Transparency tool (Y), and duplicate this cloud. Place the clouds in your drawing, spread apart as you wish and in different sizes.
My clouds have 12 bubbles and an inner radius of 82%. You can do the same or change these values to your liking.
To create the palm trees, use the Crescent tool from the list of primitive shapes on the left. Give it a gradient color, with a left stop of #F05942 and a right stop of #D15846.
Drag to draw the crescent shape. Move its center of rotation to the bottom of the bounding box, and give it a -60-degree angle.
The center of rotation can be made visible in the Contextual toolbar section for the Move (and Node) tool. It looks like a little crosshair icon. When you click on it, the crosshair for moving the rotation center of an object will show. Duplicate it, either via Cmd + C and Cmd + V (Mac) or Ctrl + C and Ctrl + V (Windows), or by clicking and then Alt + dragging on the object, and move the angle of the new crescent to -96 degrees. Make it a bit smaller. Copy the two shapes and flip them horizontally.
I also created and extra crescent.
To create the indentations on the leaves, transform the object to curves, add a node with the Node tool, and pull inwards. To make the vortex sharp, use “Convert” → “Sharp”.
Create the trunk of the palm tree with the Pen tool, group all of the shapes together, and apply an “add” boolean. This way, all of the shapes will transform into just one. Apply a 60% opacity to it.
Duplicate the tree shape several times, changing the sizes and tweaking to make the trees slightly different from one another. (Making them exactly the same would result in a less interesting image.)
The last thing we need to make is the sun.
For this, simply draw an ellipse and apply a color of #FFFFBA to it. Apply a transparency with the Transparency tool (Y), where the bottom is transparent and gets opaque at the top.
Now we will add some detail by overlapping several rounded rectangles over the sun circle and subtracting them (click Alt for a non-destructive action, if you prefer).
Place your sun in the scene, and we are done!
12. A Note On The Stacking Order (And Naming Of Layers)
While you work, and as the number of objects (layers) grows, which will also make your illustration more and more complex, keep in mind the stacking order of your layers. The sooner you start naming the layers and placing them in the right order, the better. Also, lock those layers that you’re done with (especially for things such as the background), so that they don’t get in the way as you work.
In this illustration, the order of elements from bottom to top is:
I hope you could follow all of the steps with no major problems and now better understand some of Affinity Designer’s main tools and actions. (Of course, if you have some questions or need help, leave a comment below!)
These tools will allow you to create not only flat illustrations, but many other kinds of artwork as well. The tools, actions and procedures we’ve used here are some of the most useful and common that designers and illustrators use daily (including me), be it for simple illustration projects or much more complex ones.
However, even my most complex illustrations usually need the same tools that we’ve seen in action in this tutorial! It’s mainly a matter of understanding how much you can get out of each tool.
Remember the few important tips, such as locking the layers that could get in your way (or using half-transparency), stacking the layers in the right order, and naming them, so that even the most complex of illustrations are easy to organize and work with. Practice often, and try to organize things so that your workflow improves — this will lead to better artwork and better time management as well.
Also, to learn more about how to create this type of illustration, check out the video tutorial that I posted on my YouTube channel.
Introduced as part of the HTML5 specification, the placeholder attribute “represents a short hint (a word or short phrase) intended to aid the user with data entry when the control has no value. A hint could be a sample value or a brief description of the expected format.”
This seemingly straightforward attribute contains a surprising amount of issues that prevent it from delivering on what it promises. Hopefully, I can convince you to stop using it.
Inputs are the gates through which nearly all e-commerce has to pass. Regardless of your feelings on the place of empathy in design, unusable inputs leave money on the table.
The presence of a placeholder attribute won’t be flagged by automated accessibility checking software. However, this doesn’t necessarily mean it’s usable. Ultimately, accessibility is about people, not standards, so it is important to think about your interface in terms beyond running through a checklist.
Call it remediation, inclusive design, universal access, whatever. The spirit of all these philosophies boils down to making things that people—all people—can use. Viewed through this lens, placeholder simply doesn’t hold up.
One of the attributes skipped over by browsers is placeholder. Because of this, placeholder content won’t be translated and will remain as the originally authored language.
If a person is requesting a page to be translated, the expectation is that all visible page content will be updated. Placeholders are frequently used to provide important input formatting instructions or are used in place of a more appropriate label element (more on that in a bit). If this content is not updated along with the rest of the translated page, there is a high possibility that a person unfamiliar with the language will not be able to successfully understand and operate the input.
This should be reason enough to not use the attribute.
While we’re on the subject of translation, it’s also worth pointing out that location isn’t the same as language preference. Many people set their devices to use a language that isn’t the official language of the country reported by their browser’s IP address (to say nothing of VPNs), and we should respect that. Make sure to keep your content semantically described—your neighbors will thank you!
Interoperability is the practice of making different systems exchange and understand information. It is a foundational part of both the Internet and assistive technology.
Semantically describing your content makes it interoperable. An interoperable input is created by programmatically associating a label element with it. Labels describe the purpose of an input field, providing the person filling out the form with a prompt that they can take action on. One way to associate a label with an input, is to use the for attribute with a value that matches the input’s id.
Without this for/id pairing, assistive technology will be unable to determine what the input is for. The programmatic association provides an API hook that software such as screen readers or voice recognition can utilize. Without it, people who rely on this specialized software will not be able to read or operate inputs.
The reason I am mentioning this is that placeholder is oftentimes used in place of a label element. Although I’m personally baffled by the practice, it seems to have gained traction in the design community. My best guess for its popularity is the geometrically precise grid effect it creates when placed next to other label-less input fields acts like designer catnip.
The floating label effect, a close cousin to this phenomenon, oftentimes utilizes the placeholder attribute in place of a label, as well.
A neat thing worth pointing out is that if a label is programmatically associated with an input, clicking or tapping on the label text will place focus on the input. This little trick provides an extra area for interacting with the input, which can be beneficial to people with motor control issues. Placeholders acting as labels, as well as floating labels, cannot do that.
The 2016 United States Census lists nearly 15 million people who report having cognitive difficulty — and that’s only counting individuals who choose to self-report. Extrapolating from this, we can assume that cognitive accessibility concerns affect a significant amount of the world’s population.
Self-reporting is worth calling out, in that a person may not know, or feel comfortable sharing that they have a cognitive accessibility condition. Unfortunately, there are still a lot of stigmas attached to disclosing this kind of information, as it oftentimes affects things like job and housing prospects.
Cognition can be inhibited situationally, meaning it can very well happen to you. It can be affected by things like multitasking, sleep deprivation, stress, substance abuse, and depression. I might be a bit jaded here, but that sounds a lot like conditions you’ll find at most office jobs.
The umbrella of cognitive concerns covers conditions such as short-term memory loss, traumatic brain injury, and Attention Deficit Hyperactivity Disorder. They can all affect a person’s ability to recall information.
When a person enters information into an input, its placeholder content will disappear. The only way to restore it is to remove the information entered. This creates an experience where guiding language is removed as soon as the person attempting to fill out the input interacts with it. Not great!
When your ability to recall information is inhibited, it makes following these disappearing rules annoying. For inputs with complicated requirements to satisfy—say creating a new password—it transcends annoyance and becomes a difficult barrier to overcome.
While more technologically-sophisticated people may have learned clever tricks such as cutting entered information, reviewing the placeholder content to refresh their memory, then re-pasting it back in to edit, people who are less technologically literate may not understand why the help content is disappearing or how to bring it back.
Considering that more and more of the world’s population is coming online, the onus falls on us as responsible designers and developers to make these people feel welcomed. Your little corner of the Internet (or intranet!) could very well be one of their first experiences online — assuming that the end user “will just know” is simple arrogance.
For someone who has never encountered it before, placeholder text may look like entered content, causing them to skip over the input. If it’s a required field, form submission will create a frustrating experience where they may not understand what the error is, or how to fix it. If it’s not a required field, your form still runs the unnecessary risk of failing to collect potentially valuable secondary information.
Placeholder help content is limited to just a string of static text, and that may not always be sufficient to communicate the message. It may need to have additional styling applied to it, or contain descriptive markup, attributes, images, and iconography.
This is especially handy in mature design systems. The additional styling options created by moving the string of text out of the input element means it can take advantage of the system’s design tokens, and all the benefits that come with using them.
Placeholder text’s length is also limited to the width of the input it is contained in. In our responsive, mobile-first world, there stands a very good chance that important information could be truncated:
The major browsers’ default styles for placeholder content use a light gray color to visually communicate that it is a suggestion. Many custom input designs follow this convention by taking the color of input content and lightening it.
Unfortunately, this technique is likely to run afoul of color contrast issues. Color contrast is a ratio determined by comparing the luminosity of the text and background color values; in this case, it’s the color of the placeholder text over the input’s background.
If the placeholder content has a contrast ratio that is too low to be perceived, it means that information critical to filling out a form successfully may not be able to be seen by people experiencing low vision conditions. For most common input font sizing, the ratio is 4.5:1.
Like all accessibility concerns, low vision conditions can be permanent or temporary, biological or environmental, or a combination. Biological disabilities include conditions like farsightedness, color blindness, dilated pupils, and cataracts. Environmental conditions include circumstances such as the glare of the mid-day sun, a battery-saving low brightness setting, privacy screens, grease and makeup left on your screen by your last phone call, and so on.
This ratio isn’t some personal aesthetic preference that I’m trying to force onto others arbitrarily. It’s part of a set of painstakingly-developed rules that help ensure that the largest possible swath of people can operate digital technology, regardless of their ability or circumstance. Consciously ignoring these rules is to be complicit in practicing exclusion.
And here’s the rub: In trying to make placeholder attributes inclusive, the updated higher contrast placeholder content color may become dark enough to be interpreted as entered input, even by more digitally literate people. This swings the issue back into cognitive concerns land.
High Contrast Mode
The Windows operating system contains a feature called High Contrast Mode. When activated, it assigns new colors to interface elements from a special high contrast palette that uses a limited number of color options. Here’s an example of what it may look like:
In High Contrast Mode, placeholder content is assigned one of those high contrast colors, making it look like pre-filled information. As discussed earlier, this could prevent people from understanding that the input may need information entered into it.
You may be wondering if it’s possible to update the styling in High Contrast Mode to make a placeholder more understandable. While it is possible to target High Contrast Mode in a media query, I implore you not to do so. Front-end developer Hugo Giraudel said it best:
“High contrast mode is not about design anymore but strict usability. You should aim for highest readability, not color aesthetics.”
The people that rely on High Contrast Mode use it because of how predictable it is. Unduly altering how it presents content may interfere with the only way they can reliably use a computer. In the case of lightening the color of placeholder content to make it appear like its non-High Contrast Mode treatment, you run a very real risk of making it impossible for them to perceive.
To recap, the placeholder attribute:
Can’t be automatically translated;
Is oftentimes used in place of a label, locking out assistive technology;
Can hide important information when content is entered;
Can be too light-colored to be legible;
Has limited styling options;
May look like pre-filled information and be skipped over.
Eesh. That’s not great. So what can we do about it?
Move the placeholder content above the input, but below the label:
Communicates a visual and structural hierarchy:
What this input is for,
Things you need to know to use the input successfully, and
the input itself.
Can be translated.
Won’t look like pre-filled information.
Can be seen in low vision circumstances.
Won’t disappear when content is entered into the input.
Can include semantic markup and be styled via CSS.
Additionally, the help content will be kept in view when the input is activated on a device with a software keyboard. If placed below the input, the content may be obscured when an on-screen keyboard appears at the bottom of the device viewport:
Here’s how to translate our designed example to code:
Your employee ID number
Can be found on your employee intranet profile. Example: <samp>a1234567-89</samp>.
This isn’t too much of a departure from a traditional accessible for/id attribute pairing: The label element is programmatically associated with the input via its id declaration of “employee-id”. The p element placed between the label and input elements acts as a replacement for a placeholder attribute.
“So,” you may be wondering. “Why don’t we just put all that placeholder replacement content in the label element? It seems like it’d be a lot less work!” The answer is that developer convenience shouldn’t take priority over user experience.
By using aria-describedby to programmatically associate the input with the p element, we are creating a priority of information for screen readers that has parity with what a person browsing without a screen reader would experience. aria-describedby ensures that the p content will be described last, after the label’s content and the kind of input it is associated with.
In other words, it’s what content the input is asking for, what type of input it is, then additional help if you need it — exactly what someone would experience if they look at form input.
User experience encompasses all users, including those who navigate with the aid of screen readers. The help content is self-contained and easy to navigate to and from, should the person using a screen reader need to re-reference it. As it is a self-contained node, it can also be silenced (typically with the Control key) without risking muting other important information.
Including the help content as part of the label makes it unnecessarily verbose. labels should be meaningful, but also concise. Adding too much information to a label may have the opposite of the desired effect, making it too long to recall or simply too frustrating to listen to all the way through. In fact, the Web Content Accessibility Guidelines has rules that specifically address this: Success Criteria 2.4.6 and 3.3.2.
Good copywriting creates labels that clearly and succinctly describe the input’s purpose. Do a good enough job here and the label cuts through the ambiguity, especially if you test it beforehand.
Good user experience is all about creating intelligent flows that preempt people’s needs, wants, and desires by capitalizing on existing information to remove as many unnecessary questions as possible.
Accommodating the people who use your website or web app means taking a critical eye at what you take for granted when you browse the Internet. By not making assumptions about other people’s circumstances — including the technology they use — you can do your part to help prevent exclusion.
Take some time to review your design and code and see what doesn’t stand up to scrutiny — checking to see if you use the placeholder attribute might be a good place to start.
Landing The Concept: Movie High-Concept Theory And UX Design
Steven Spielberg once famously said, “If a person can tell me the idea in 25 words or less, it’s going to make a pretty good movie.” He was referring to the notion that the best mass-appeal ‘blockbuster’ movies are able to succinctly state their concept or premise in a single short sentence, such as Jaws (“It’s about a shark terrorizing a small town”) and Toy Story (“It’s about some toys that come to life when nobody’s looking”).
What if the same were true for websites? Do sites that explain their ‘concept’ in a simple way have a better shot at mass-appeal with users? If we look at the super simple layout of Google’s homepage, for example, it gives users a single clear message about its concept equally as well as the Jaws movie poster:
Being aware of the importance of ‘high-concept’ allows us — as designers — to really focus on user’s initial impressions. Taking the time to actually define what you want your simple ‘high-concept’ to be before you even begin designing can really help steer you towards the right user experience.
What Does High-Concept Theory Mean For UX Design?
So let’s take this seriously and look at it from a UX Design standpoint. It stands to reason that if you can explain the ‘concept’ or purpose of your site in a simple way you are lowering the cognitive load on new users when they try and understand it and in doing so, you’re drastically increasing your chances of them engaging.
The parallels between ‘High-Concept’ theory and UX Design best practice are clear. Blockbuster audiences prefer simple easy to relate concepts presented in an uncomplicated way. Web users often prefer simpler, easy to digest, UI (User Interface) design, clean layouts, and no clutter.
Regardless of what your message is, presenting it in a simple way is critical to the success of your site’s user experience. But, what about the message itself? Understanding if your message is ‘high-concept’ enough might also be critical to the site’s success.
What Is The Concept Of ‘High-Concept’ In The Online World?
What do we mean when we say ‘high-concept’? For movies it’s simple — it’s what the film is about, the basic storyline that can be easy to put into a single sentence, e.g. Jurassic Park is “about a theme park where dinosaurs are brought back to life.”
When we look at ‘high-concept’ on a website, however, it can really apply to anything: a mission statement, a service offering, or even a new product line. It’s simply the primary message you want to share through your site. If we apply the theory of ‘high-concept’, it tells us that we need to ensure that we convey that message in a simple and succinct style.
What Happens If You Get It Right?
Why is ‘high-concept’ so important? What are the benefits of presenting a ‘high-concept’ UX Design? One of the mistakes we often fall foul of in UX Design is focussing in on the specifics of user tasks and forgetting about the critical importance of initial opinions. In other words, we focus on how users will interact with a site once they’ve chosen to engage with it and miss the decision-making process that comes before everything. Considering ‘high-concept’ allows us to focus on this initial stage.
The basic premise to consider is that we engage better with things we understand and things we feel comfortable with. Ensuring your site presents its message in a simple ‘high-concept’ way will aid initial user engagement. That initial engagement is the critical precursor to all the good stuff that follows: sales, interaction, and a better conversion rate.
How Much Concept Is Too Much Concept?
The real trick is figuring out how much complexity your users can comfortably handle when it comes to positioning your message. You need to focus initially on presenting only high-level information rather than bombarding users with everything upfront. Give users only the level of understanding they need to engage initially with your site and drive them deeper into the journey disclosing more detail as you go.
Netflix does a great job at this. The initial view new users are presented with on the homepage screen is upfront with its super high-concept — ‘we do video content’ once users have engaged with this premise they are taken further into the proposition — more information is disclosed, prices, process, and so on.
When To Land Your High-Concept?
As you decide how to layout the site, another critical factor to consider is when you choose to introduce your initial ‘high-concept’ to your users. It’s key to remember how rare it is that users follow a nice simple linear journey through your site starting at the homepage. The reality is that organic user journeys sometimes start with search results. As a result, the actual interaction with your site begins on the page that’s most relevant to the user’s query. With this in mind, it’s critical to consider how the premise of your site appears to users on key entry pages for your site wherever they appear in the overall hierarchy.
Another key point to consider when introducing the message of your site is that in many scenarios users will be judging whether to engage with you way before they even reach your site. If the first time you present your concept to users is via a Facebook ad or an email campaign, then implementation is drastically different. However, the theory should be the same, i.e. to ensure you present your message in that single sentence ‘high-concept’ style way with potential users.
How To Communicate Your High-Concept
Thus far, we’ve talked about how aiming for ‘high-concept’ messages can increase engagement — but how do we do this? Firstly, let’s focus on the obvious methods such as the wording you use (or don’t use).
Before you even begin designing, sit down and focus in on what you want the premise of your site to be. From there, draw out your straplines or headings to reflect that premise. Make sure you rely on content hierarchy though, use your headings to land the concept, and don’t bury messages that are critical to understanding deep in your body copy.
Here’s a nice example from Spotify. They achieve a ‘high-concept’ way of positioning their service through a simple, uncluttered combination of imagery and wording:
Single Sentence Wording
It’s key to be as succinct as possible: the shorter your message is, the more readable it becomes. The true balancing act comes in deciding where to draw the line between too little to give enough understanding and too much to make it easily readable.
If we take the example of Google Drive — it’s a relatively complex service, but it’s presented in a very basic high-concept way — initially a single sentence that suggests security and simplicity:
Then the next level of site lands just a little more of the concept of the service but still keeping in a simple single sentence under 25 words (Spielberg would be pleased):
It doesn’t just stop with your wording as there is a myriad of other elements on the page that you can leverage to land your concept. The explainer video is used to great effect by Amazon to introduce users to the concept of Amazon Go. In reality, it’s a highly complex technical trial of machine learning, computer visual recognition, and AI (artificial intelligence) to reimagine the shopping experience. As it’s simply framed on the site, it can be explained in a ‘high-concept’ way.
Amazon gives users a single sentence and also, crucially, makes the whole header section a simple explainer video about the service.
The imagery you use can be used to quickly and simply convey powerful messages about your concept without the need to complicate your UI with other elements. Save the Children use imagery to great effect to quickly show the users the critical importance of their work arguably better than they ever could with wording.
Font And Color
It’s key to consider every element of your site as a potential mechanism for helping you communicate your purpose to your users, through the font or the color choices. For example, rather than having to explicitly tell users that your site is aimed at academics or children you can craft your UI to help show that.
Users have existing mental models that you can appeal to. For example, bright colors and childlike fonts suggest the site is aimed at children, serif fonts and limited color use often suggest a much more serious or academic subject matter. Therefore, when it comes to landing the concept of your site, consider these as important allies to communicate with your users without having to complicate your message.
So far, we’ve focused primarily on using messaging to communicate the concept to users. Still, what if the primary goal of your page is just to get users to interact with a specific element? For example, if you offer some kind of tool? If that’s the case, then showing the interface of this tool itself is often the best way to communicate its purpose to users.
This ties in with the concept of ‘Design Affordance’ — the idea that the form of a design should communicate its purpose. It stands to reason that sometimes the best way to tell users about your simple tool with an easy to use interface — is to show them that interface.
If we look at Airbnb, a large part of the Airbnb concept is the online tool that allows the searching and viewing of results; they use this to great effect on this landing page design by showing the data entry view for that search. Showing users how easy it is to search while also presenting them the with simple messaging about the Airbnb concept.
How To Test You’ve Landed It
Now that you’ve designed your site and you’re happy that it pitches its concept almost as well as an 80s blockbuster — but how can you validate that? It would be lovely to check things over with a few rounds of in-depth lab-based user research, but in reality, you’ll seldom have the opportunity, and you’ll find yourself relying on more ‘guerilla’ methods.
One of the simplest and most effective methodologies to check how ‘high-concept’ your site is is the ‘5 second’ or ‘glance’ test. The simple test involves showing someone the site for 5 seconds and then hiding it from view. Then, users can then be asked questions about what they can recall about the site. The idea being that in 5 seconds they only have the opportunity to view what is immediately obvious.
Here are some examples of questions to ask to get a sense of how well the concept of your site comes across:
Can you remember the name of the site you just saw?
What do you think is the purpose of the page you just saw?
Was it obvious what the site you just saw offers?
Do you think you would use the site you just saw?
Using this test with a decent number of people who match your target users should give some really valuable insight into how well your design conveys the purpose of your site and if indeed you’ve managed to achieve ‘high-concept’.
Putting It All Into Practice
Let’s try implementing all this knowledge in the real world? In terms of taking this and turning it into a practical approach, I try and follow these simple steps for every project:
Aim For High-Concept When you’re establishing the purpose of any new site (or page or ad) try and boil it down to a single, simple, overarching ‘High-Concept.’
Write It Down Document what you want that key concept to be in 25 words or less.
Refer Back Constantly refer back to that concept throughout the design process. From picking your fonts and colors to crafting your headline content — ensure that it all supports that High-Concept you wrote down.
Test It Once complete use the 5-second test on your design with a number of users and compare their initial thoughts to your initial High-Concept. If they correlate, then great, if not head back to step 3 and try again.
In this article, we have discussed the simple rule of making blockbuster movies, and we have applied that wisdom to web design. No ‘shock plot twist’ — just some common sense. The first time someone comes into contact with your website, it’s vital to think about what you want the initial message to be. If you want mass market appeal, then craft it into a ‘high-concept’ message that Spielberg himself would be proud of!
CSS Custom Properties (sometimes known as ‘CSS variables’) are now supported in all modern browsers, and people are starting to use them in production. This is great, but they’re different from variables in preprocessors, and I’ve already seen many examples of people using them without considering what advantages they offer.
How Are They Similar To Variables In Preprocessors?
Custom Properties are a little bit like variables in preprocessors but have very some important differences. The first and most obvious difference is the syntax.
With SCSS we use a dollar symbol to denote a variable:
In Less we use an @ symbol:
Custom properties follow a similar conventions and use a -- prefix:
One important difference between custom properties and variables in preprocessors is that custom properties have a different syntax for assigning a value and retrieving that value. When retrieving the value of a custom property we use the var() function.
The next most obvious difference is in the name. They are called ‘custom properties’ because they really are CSS properties. In preprocessors, you can declare and use variables almost anywhere, including outside declaration blocks, in media rules, or even as part of a selector.
Most of the examples above would be invalid using custom properties.
Custom properties have the same rules about where they can be used as normal CSS properties. It’s far better to think of them as dynamic properties than variables. That means they can only be used inside a declaration block, or in other words, custom properties are tied to a selector. This can be the :root selector, or any other valid selector.
You can retrieve the value of a custom property anywhere you would otherwise use a value in a property declaration. This means they can be used as a single value, as part of a shorthand statement or even inside calc() equations.
However, they cannot be used in media rules, or selectors including :nth-child().
There is probably a lot more you want to know about the syntax and how custom properties work, such as how to use fallback values and can you assign variables to other variables (yes), but this basic introduction should be enough to understand the rest of the concepts in this article. For more information on the specifics of how custom properties work, you can read “It’s Time To Start Using Custom Properties” written by Serg Hospodarets.
Dynamic vs. Static
Cosmetic differences aside, the most significant difference between variables in preprocessors and custom properties is how they are scoped. We can refer to variables as either statically or dynamically scoped. Variables in preprocessors are static whereas custom properties are dynamic.
Where CSS is concerned static means that you can update the value of a variable at different points in the compilation process, but this cannot change the value of the code that came before it.
Once this is rendered to CSS, the variables are gone. This means that we could potentially read an .scss file and determine it’s output without knowing anything about the HTML, browser or other inputs. This is not the case with custom properties.
Preprocessors do have a kind of “block scope” where variables can be temporarily changed inside a selector, function or mixin. This changes the value of a variable inside the block, but it’s still static. This is tied to the block, not the selector. In the example below, the variable $background is changed inside the .example block. It changes back to the initial value outside the block, even if we use the same selector.
Custom properties work differently. Where custom properties are concerned, dynamically scoped means they are subject to inheritance and the cascade. The property is tied to a selector and if the value changes, this affects all matching DOM elements just like any other CSS property.
@media screen and (min-width: 600px)
We don’t have to change where the custom property is used — we change the value of the custom property with CSS. This means using the same custom property, we can have different values in different places or context on the same page.
Global vs. Local
CSS is similar. We have some things that are applied globally and some things that are more local. Brand colors, vertical spacing, and typography are all examples of things you might want to be applied globally and consistently across your website or application. We also have local things. For example, a button component might have a small and large variant. You wouldn’t want the sizes from these buttons to be applied to all input elements or even every element on the page.
CSS Custom Properties are by default locally scoped to the specific selectors we apply them to. So they are kinda like local variables. However, custom properties are also inherited, so in many situations they behave like global variables — especially when applied to the :root selector. This means that we need to be thoughtful about how to use them.
So many examples show custom properties being applied to the :root element and although, this fine for a demo, it can result in a messy global scope and unintended issues with inheritance. Luckily, we’ve already learned these lessons.
Global Variables Tend To Be Static
There are a few small exceptions, but generally speaking, most global things in CSS are also static.
Global variables like brand colors, typography and spacing don’t tend to change much from one component to the next. When they do change this tends to be a global rebranding or some other significant change that rarely happens on a mature product. It still makes sense for these things to be variables, they are used in many places, and variables help with consistency. But it doesn’t make sense for them to be dynamic. The value of these variables does not change in any dynamic way.
For this reason, I strongly recommend using preprocessors for global (static) variables. This not only ensures that they are always static, but it visually denotes them within the code. This can make CSS a whole lot more readable and easier to maintain.
Local Static Variables Are OK (Sometimes)
You might think given the strong stance on global variables being static, that by reflection, all local variables might need to be dynamic. While it’s true that local variables do tend to be dynamic, this is nowhere near as strong as the tendency for a global variable to be static.
Locally static variables are perfectly OK in many situations. I use preprocessors variables in component files mostly as a developer convenience.
Consider the classic example of a button component with multiple size variations.
Obviously, this example would make more sense if I was using the variables multiple times or deriving margin and padding values from the size variables. However, the ability to quickly prototype different sizes might be a sufficient reason.
Because most static variables are global, I like to differentiate static variables that are used only inside a component. To do this, you can prefix these variables with the component name, or you could use another prefix such as c-variable-name for component or l-variable-name for local. You can use whatever prefix you want, or you can prefix global variables. Whatever you choose, it’s helpful to differentiate especially if converting an existing codebase to use custom properties.
When To Use Custom Properties
I suspect we will always use some form of static variables, although we might need fewer in future, as custom properties offer new ways to organise logic and code. Until then, I think in most situations we are going to be working with a combination of preprocessor variables and custom properties.
It’s helpful to know that we can assign static variables to custom properties. Whether they are global or local, it makes sense in many situations to convert static variables, to locally dynamic custom properties.
Note: Did you know that $var is valid value for a custom property? Recent versions of Sass recognize this, and therefore we need to interpolate variables assigned to custom properties, like this: #$var. This tells Sass you want to output the value of the variable, rather than just $var in the stylesheet. This is only needed for situations like custom properties, where a variable names can also be a valid CSS.
If we take the button example above and decide all buttons should use the small variation on mobile devices, regardless of the class applied in the HTML, this is now a more dynamic situation. For this, we should use custom properties.
Here I create a single custom property: --button-size. This custom property is initially scoped to all button elements using the btn class. I then change the value of --button-size above 600px for the classes btn-med and btn-lrg. Finally, I apply this custom property to all button elements in one place.
Don’t Be Too Clever
The dynamic nature of custom properties allows us to create some clever and complicated components.
With the introduction of preprocessors, many of us created libraries with clever abstractions using mixins and custom functions. In limited cases, examples like this are still useful today, but for the most part, the longer I work with preprocessors the fewer features I use. Today, I use preprocessors almost exclusively for static variables.
Custom properties will not (and should not) be immune from this type of experimentation, and I look forward to seeing many clever examples. But in the long run, readable and maintainable code will always win over clever abstractions (at least in production).
I read an excellent article on this topic on the Free Code Camp Medium recently. It was written by Bill Sourour and is called “Don’t Do It At Runtime. Do It At Design Time.” Rather than paraphrasing his arguments, I’ll let you read it.
One key difference between preprocessor variables and custom properties is that custom properties work at runtime. This means things that might have been borderline acceptable, in terms of complexity, with preprocessors might not be a good idea with custom properties.
One example that illustrated this for me recently was this:
This generates a modular scale. A modular scale is a series of numbers that relate to each other using a ratio. They are often used in web design and development to set font-sizes or spacing.
In this example, each custom property is determined using calc(), by taking the value of the previous custom property and multiplying this by the ratio. Doing this, we can get the next number in the scale.
This means the ratios are calculated at run-time and you can change them by updating only the value of the --font-scale property. For example:
@media screen and (min-width: 800px)
This is clever, concise and much quicker than calculating all the values again should you want to change the scale. It’s also something I would not do in production code.
Although the above example is useful for prototyping, in production, I’d much prefer to see something like this:
Similar to the example in Bill’s article, I find it helpful to see what the actual values are. We read code many more times than we write it and global values such as font scales change infrequently in production.
The above example is still not perfect. It violates the rule from earlier that global values should be static. I’d much prefer to use preprocessor variables and convert them to locally dynamic custom properties using the techniques demonstrated earlier.
It is also important to avoid situations where we go from using one custom property to a different custom property. This can happen when we name properties like this.
Change The Value Not The Variable
Change the value not the variable is one of the most important strategies for using custom properties effectively.
As a general rule, you should never change which custom property is used for any single purpose.
It’s easy to do because this is exactly how we do things with preprocessors, but it makes little sense with custom properties.
In this example, we have two custom properties that are used on an example component. I switch from using the value of --font-size-small to --font-size-large depending on the screen size.
Finally, in a single place, I use the value of this custom property:
In this example and others before it, media queries have only been used to change the value of custom properties. You might also notice there is only one place where the var() statement is used, and regular CSS properties are updated.
This separation between variable declarations and property declarations is intentional. There are many reasons for this, but the benefits are most obvious when thinking about responsive design.
Responsive Design With Custom Properties
One of the difficulties with responsive design when it relies heavily on media queries is that the no matter how you organize your CSS, styles relating to a particular component become fragmented across the stylesheet.
It can be very difficult to know what CSS properties are going to change. Still, CSS Custom Properties can help us organize some of the logic related to responsive design and make working with media queries a lot easier.
If It Changes It’s A Variable
Properties that change using media queries are inherently dynamic and custom properties provide the means to express dynamic values in CSS. This means that if you are using a media query to change any CSS property, you should place this value in a custom property.
You can then move this, along with all the media rules, hover states or any dynamic selectors that define how the value changes, to the top of the document.
Separate Logic From Design
When done correctly, separation of logic and design means that media queries are only be used to change the value of custom properties. It means all the logic related to responsive design should be at the top of the document, and wherever we see a var() statement in our CSS, we immediately know that this property that changes. With traditional methods of writing CSS, there was no way of knowing this at a glance.
Many of us got very good at reading and interpreting CSS at a glance while tracking in our head which properties changed in different situations. I’m tired of this, and I don’t want to do this anymore! Custom properties now provide a link between logic and its implementation, so we don’t need to track this, and that is incredibly useful!
The Logic Fold
The idea of declaring variables at the top of a document or function is not a new idea. It’s something we do in most languages, and it’s now something we can do in CSS as well. Writing CSS in this way creates a clear visual distinction between CSS at the top of the document and below. I need a way to differentiate these sections when I talk about them and the idea of a “logic fold” is a metaphor I’ve started using.
Above the fold contains all preprocessor variables and custom properties. This includes all the different values a custom property can have. It should be easy to trace how a custom property changes.
CSS below the fold is straightforward and highly declarative and easy to read. It feels like CSS before media queries and other necessary complexities of modern CSS.
Take a look at a really simple example of a six column flexbox grid system:
We immediately know --row-display is a value that changes. Initially, it will be block, so the flex values will be ignored.
This example is fairly simple, but if we expanded it to include a flexible width column that fills the remaining space, it’s likely flex-grow, flex-shrink and flex-basis values would need to be converted to custom properties. You can try this or take a look at a more detailed example here.
Custom Properties For Theming
I’ve mostly argued against using custom properties for global dynamic variables and hopefully implied that attaching custom properties to the :root selector is in many cases considered harmful. But every rule has an exception, and for custom properties, it’s theming.
Limited use of global custom properties can make theming a whole lot easier.
Theming generally refers to letting users customize the UI in some way. This could be something like changing colors on a profile page. Or it might be something more localized. For example, you can choose the color of a note in the Google Keep application.
Theming usually involves compiling a separate stylesheet to override a default value with user preferences, or compiling a different stylesheet for each user. Both of these can be difficult and have an impact on performance.
With custom properties, we don’t need to compile a different stylesheet; we only need to update the value of properties according to the user’s preferences. Since they are inherited values, if we do this on the root element they can be used anywhere in our application.
Capitalize Global Dynamic Properties
Custom properties are case sensitive and since most custom properties will be local, if you are using global dynamic properties, it can make sense to capitalize them.
Capitalization of variables often signifies global constants. For us, this is going to signify that the property is set elsewhere in the application and that we should probably not change it locally.
Avoid Directly Setting Global Dynamic Properties
Custom properties accept a fallback value. It can be a useful to avoid directly overwriting the value of a global custom properties and keep user values separate. We can use the fallback value to do this.
The example above sets the value of --THEME-COLOR to the value of --user-theme-color if it exists. If --user-theme-color is not set, the value of #d33a2c will be used. This way, we don’t need to provide a fallback every time we use --THEME-COLOR.
You might expect in the example below that the background will be set to green. However, the value of --user-theme-color has not been set on the root element, so the value of --THEME-COLOR has not changed.
--THEME-COLOR: var(--user-theme-color, #d33a2c);
Indirectly setting global dynamic properties like this protects them from being overwritten locally and ensures user settings are always inherited from the root element. This is a useful convention to safeguard your theme values and avoid unintended inheritance.
If we do want to expose specific properties to inheritance, we can replace the :root selector with a * selector:
--THEME-COLOR: var(--user-theme-color, #d33a2c);
Now the value of --THEME-COLOR is recalculated for every element and therefore the local value of --user-theme-color can be used. In other words, the background color in this example will be green.
Here I set a default value for --note-color and scope this to the .note component. I keep the variable declaration separate from the property declaration, even in this simple example.
const elm = document.querySelector('#note-uid');
I then target a specific instance of a .note element and change the value of the --note-color custom property for that element only. This will now have higher specificity than the default value.
You can see how this works with this example using React. These user preferences could be saved in local storage or in the case of a larger application perhaps in a database.
Manipulating Color With Custom Properties
In addition to hex values and named colors, CSS has colors function such as rgb() and hsl(). These allow us to specify individual components of a color such as the hue or lightness. Custom properties can be used in conjunction with color functions.
background: hsl(var(--hue), 80%, 50%);
This is useful, but some of the most widely used features of preprocessors are advanced color functions that allow us to manipulate color using functions like lighten, darken or desaturate:
It would be useful to have some of these features in browsers. They are coming, but until we have native color modification functions in CSS, custom properties could fill some of that gap.
We’ve seen that custom properties can be used inside existing color functions like rgb() and hsl() but they can also be used in calc(). This means that we can convert a real number to a percentage by multiplying it, e.g. calc(50 * 1%) = 50%.
background: hsl(25, 80%, calc(var(--lightness) * 1%));
The reason we want to store the lightness value as a real number is so that we can manipulate it with calc before converting it to a percentage. For example, if I want to darken a color by 20%, I can multiply its lightness by 0.8. We can make this a little easier to read by separating the lightness calculation into a locally scoped custom property:
Custom properties also allow as to move some of the complexity of theming into the CSS and this complexity can have a negative impact on the maintainability of your CSS, so remember to keep it simple wherever possible.
Using Custom Properties Today
Even if you’re supporting IE10 and 11, you can start using custom properties today. Most of the examples in this article have to do with how we write and structure CSS. The benefits are significant in terms of maintainability, however, most of the examples only reduce what could otherwise be done with more complex code.
I use a tool called postcss-css-variables to convert most of the features of custom properties into a static representation of the same code. Other similar tools ignore custom properties inside media queries or complex selectors treating custom properties much like preprocessor variables.
Loading The Correct Stylesheet
There are many ways you can use postCSS. I use a gulp process to compile separate stylesheets for newer and older browsers. A simplified version of my gulp task looks like this:
import gulp from "gulp";
import sass from "gulp-sass";
import postcss from "gulp-postcss";
import rename from "gulp-rename";
import cssvariables from "postcss-css-variables";
import autoprefixer from "autoprefixer";
import cssnano from "cssnano";
gulp.task("css-no-vars", () =>
.pipe(rename( extname: ".no-vars.css" ))
gulp.task("css", () =>
.pipe(rename( extname: ".css" ))
This results in two CSS files: a regular one with custom properties (styles.css) and one for older browsers (styles.no-vars.css). I want IE10 and 11 to be served styles.no-vars.css and other browsers to get the regular CSS file.
Normally, I’d advocate using feature queries but IE11 doesn’t support feature queries and we’ve used custom properties so extensively that serving a different stylesheet makes sense in this case.
Intelligently serving a different stylesheet and avoiding a flash of unstyled content is not a simple task. If you don’t need the dynamic features of custom properties, you could consider serving all browser styles.no-vars.css and using custom properties simply as a development tool.
If you want to take full advantage of all the dynamic features of custom properties, I suggest using a critical CSS technique. Following these techniques, the main stylesheet is loaded asynchronously while the critical CSS is rendered inline. Your page header might look something like this:
We can extend this to load either styles.css or styles.no-vars.css depending on whether the browser supports custom properties. We can detect support like this:
if ( window.CSS && CSS.supports('color', 'var(--test)') )
If you’ve been struggling to organize CSS efficiently, have difficulty with responsive components, want to implement client-side theming, or just want to start off on the right foot with custom properties, this guide should tell you everything you need to know.
It comes down to understanding the difference between dynamic and static variables in CSS as well as a few simple rules:
Separate logic from design;
If a CSS property changes, consider using a custom property;
Change the value of custom properties, not which custom property is used;
Global variables are usually static.
If you follow these conventions, you will find that working with custom properties is a whole lot easier than you think. This might even change how you approach CSS in general.
(This is a sponsored article.) Color has the potential to make or break product. Today you’ll learn how to use gradients for a website in Adobe XD through a very useful tutorial. In the last Adobe XD release, radial gradients were added so that designers can easily create unique color effects by simulating a light source or applying a circular pattern. Designers can add, remove and manipulate color stops with the same intuitive interface as linear gradients.
The global economy has expanded your potential market in a way that was not possible even ten years ago, leveling the playing field for small and big businesses. However, it does come with some issues. One of them is the language barrier. If your website is in English, you will get your message across to about 27% of the market. Put another way, about 73% of the global market prefers websites with content in their native language. If people don’t understand the content of your website, you cannot hope to make a sale. You need to give your visitors the…
Don’t know exactly where to put your CTA? Should it go up top? Or at the bottom? Is my web page too long? With Scrollmap not only can you determine the best length for your landing page to receive more conversions but you can also know exactly where to place your calls-to-action. Easy to Understand Color Coded Data When looking at Scrollmap you’ll see the hottest area on the map in white, so with the help of the color meter, you’ll be able to see the amount of impressions coinciding with each color on the report. No more not knowing…
Creating large, harmonious and uniform color palettes can be a challenge. Good intentions and confident plans can be abandoned when things get a little unwieldy. But you can equip yourself with some tools to manage the complexity. With the right techniques, large color palettes can be created, refined and refactored at will. Large color palettes can be tamed.
Creating Color Palettes Using Adjustment Layers Quite a few techniques can be used to create large color palettes from a few base colors.
For many people, a map of a transportation network is a given, an expected part of the system, something that just is — like a fire-escape plan in a building. So, when I say that I design transportation maps, they don’t understand. What is there to design even?
Well, let’s take the London underground map as an example. Designed by Harry Beck, it was the world’s first transportation map to use the principles of electrical circuit drawings.