Coming from a design background, as I make my way into the tech world, I constantly hear friends, fellow students, and even successful web developers claim that they “just don’t have an eye for design”. Let’s try to do something about that.
The purpose of this article is to give a helping hand to any web-dev that finds themselves having to both design and code a project. It is in no way an “All you need to know” kind of thing, and I really encourage everyone to read The Non-Designer’s Design Book by Robin Williams which is a great resource to learn more than just some basics.
The way we’ll go through each principle is fairly simple, the topic will be explained, and example shown, and a nice snippet will be provided so it’s clear how to apply it. For the sake of simplicity, we’ll use vanilla CSS.
Without further ado, let’s dive in.
Just as organisms, elements in a webpage need space to exist, whatever box model you choose to use, you can use the margin property to make sure everything has enough room and is eye-pleasingly spaced.
A good rule of thumb is to keep a clear relationship between vertical and horizontal spacing like 1 vertical unit will always be three horizontal ones. Though my go-to choice is more often than not just doubling one.
In this first example we see nine blue squares randomly spaced, it looks out of order and out of place.
This is the HTML that creates the first example:
<!-- Example One -->
<h2 class="title">Example One</h2>
<h3 class="subtitle">Assigns spacing to each element individually.</h3>
<div class="example-one">
<div class="example-one-element element-1"></div>
<div class="example-one-element element-2"></div>
<div class="example-one-element element-3"></div>
<div class="example-one-element element-4"></div>
<div class="example-one-element element-5"></div>
<div class="example-one-element element-6"></div>
<div class="example-one-element element-7"></div>
<div class="example-one-element element-8"></div>
<div class="example-one-element element-9"></div>
</div>
This is the CSS that styles it:
/* Example One */
.example-one {
display: grid;
grid-template-columns: repeat(3, 1fr);
margin-bottom: 100px;
}
.example-one-element {
width: 200px;
height: 200px;
background-color: blue;
}
.element-1 {
margin: 10px 45px;
}
.element-2 {
margin: 30px 5px;
}
.element-3 {
margin: 5px 45px;
}
.element-4 {
margin: 17px 10px;
}
.element-5 {
margin: 15px 15px;
}
.element-6 {
margin: 5px 5px;
}
.element-7 {
margin: 35px 35px;
}
.element-8 {
margin: 15px 45px;
}
.element-9 {
margin: 15px 35px;
}
Not only is it repetitive and ugly code, it looks terrible.
Let's see a few ways to fix this.
The second example shows 12 red squares, spaced using the
grid-gap
property.This is the HTML that creates the second example:
<!-- Example Two -->
<h2 class="title">Example Two</h2>
<h3 class="subtitle">Assigns the same vertical and horizontal spacing.</h3>
<div class="example-two">
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
<div class="example-two-element"></div>
</div>
This is the CSS that styles it:
/* Example Two */
.example-two {
margin: 0 50px;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 50px;
}
.example-two-element {
width: 200px;
height: 200px;
background-color: red;
}
As we can see, the CSS is a lot shorter.
The third example shows ten green squares that have been spaced so that the vertical space is larger than the horizontal one, still, by keeping a clear and constant proportion, it looks nice. In this case, we're using
margin
for spacing.This is the HTML that creates the third example:
<!-- Example Three -->
<h2 class="title">Example Three</h2>
<h3 class="subtitle">Assigns more vertical than horizontal.</h3>
<div class="example-three">
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
<div class="example-three-element"></div>
</div>
This is the CSS that styles it:
/* Example Three */
.example-three {
margin: 0 50px;
display: grid;
grid-template-columns: repeat(5, 1fr);
}
.example-three-element {
width: 200px;
height: 200px;
background-color: green;
margin: 0 40px 160px 0;
}
The fourth example is similar to the third but we have more horizontal than vertical space. We used the
grid-row-gap
and grid-column-gap
properties for spacing.This is the HTML that creates the fourth example:
<!-- Example Four -->
<h2 class="title">Example Four</h2>
<h3 class="subtitle">Assigns more horizontal than vertical space.</h3>
<div class="example-four">
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
<div class="example-four-element"></div>
</div>
This is the CSS that styles it:
/* Example Four */
.example-four {
margin: 0 50px;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-column-gap: 60px;
grid-row-gap: 30px;
}
.example-four-element {
width: 200px;
height: 200px;
background-color: purple;
}
This is fairly simple, no dark elements on top of other dark elements, no light elements on top of light elements. Think of a zebra, a zebra has very nice contrast, and if it were a webpage it’d have nice visual accessibility. I understand this might be tricky, so when in doubt, increase the contrast. Remember that content should be easy to recognize.
For the following examples, we're going to skip the HTML and CSS snippets since it's a rather simple concept.
Example 5
Shows little contrast between a light element and a light background.
Example 6
Shows little contrast between a dark element and a dark background.
Example 7
Shows great contrast between a light element and a dark background.
Example 8
Shows great contrast between a dark element and a dark background.
I cannot stress this enough, we must keep it regular, and, if possible, simple.
The core concept here is that if we use a typeface for a piece of text, say a
<p>
element, we use the same typeface for all, or at least most <p>
elements. On principle, we don’t use more than three different fonts unless we really have a great reason for it.Another great example of this is alignment, it likes commitment, so once we choose, we’re there for good.
Same with colors, we should always resist the urge to have a thousand colors around, as fun as making great palettes is, simple is the word we need to remember, each color must serve a purpose. A color for text, a color for titles, a color for contrast and, yes, a color might serve more than one purpose.
Lastly, the shape of elements is important, border-radius should be the same, or, as spacing, proportional. Same with shadows.
Our ninth example shows how horrible things look when every element follows its own rules, and there is no uniformity.
This is the HTML that creates the ninth example:
<!-- Example Nine -->
<h2 class="title">Example Nine</h2>
<h3 class="subtitle">Shows how irregular elements look bad.</h3>
<div class="example-nine">
<div class="example-nine-container-1">
<p class="example-nine-container-1-text">This says something neutral</p>
</div>
<div class="example-nine-container-2">
<p class="example-nine-container-2-text">This says something better</p>
</div>
<div class="example-nine-container-3">
<p class="example-nine-container-3-text">This says something worse</p>
</div>
</div>
This is the CSS that styles it:
/* Example Nine */
.example-nine {
width: 100%;
height: 300px;
background-color: rgb(205, 232, 248);
display: flex;
flex-direction: row;
}
.example-nine-container-1 {
background-color: lightblue;
width: 150px;
height: 75px;
text-align: right;
padding: 15px;
}
.example-nine-container-2 {
background-color: lightgreen;
width: 200px;
height: 200px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
text-align: center;
margin: 50px 0 20px 150px;
border-radius: 10%;
border: 3px solid green;
box-shadow: 0px 0px 7px 7px rgba(10, 107, 2, 0.3);
}
.example-nine-container-3 {
background-color: lightpink;
width: 800px;
height: 200px;
text-align: center;
border-radius: 2px;
margin-top: 50px;
margin-left: 70px;;
}
.example-nine-container-1-text {
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 15px;
color: blue
}
.example-nine-container-2-text {
font-family: Arial, Helvetica, sans-serif;
font-size: 30px;
color: green;
}
.example-nine-container-3-text {
font-family: 'Times New Roman', Times, serif;
font-size: 60px;
color: purple
}
We know that it's an exaggerated example, but it does look bad, right?
Our tenth and last example shows how we could correct the ninth example, making sure uniformity is achieved.
This is the HTML that creates the tenth example:
<!-- Example Ten -->
<h2 class="title">Example Ten</h2>
<h3 class="subtitle">Shows how much better the previous example looks when uniformity is applied.</h3>
<div class="example-ten">
<div class="example-ten-container">
<p class="example-ten-container-text">This says something amazing!</p>
</div>
<div class="example-ten-container">
<p class="example-ten-container-text">This says something amazing!</p>
</div>
<div class="example-ten-container">
<p class="example-ten-container-text">This says something amazing!</p>
</div>
<div class="example-ten-container">
<p class="example-ten-container-text">This says something amazing!</p>
</div>
</div>
This is the CSS that styles it:
/* Example Ten */
.example-ten {
width: 100%;
height: 300px;
background-color: rgb(169, 252, 206);
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
}
.example-ten-container {
background-color: lightgreen;
width: 200px;
height: 200px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
text-align: center;
border-radius: 10%;
border: 3px solid green;
box-shadow: 0px 0px 7px 7px rgba(10, 107, 2, 0.3);
}
.example-ten-container-text {
font-family: Arial, Helvetica, sans-serif;
font-size: 30px;
color: green;
}
At this point, it’s worth mentioning that having a document with the exact colors, which typefaces to use (how, when and where) is always a great idea, many companies have them (shame if they don’t) and it’s commonly called a brand book.
In my work, I combine brand books with Sass in order to use variables for colors, font-sizes, but that’s a topic for another day.
I hope you find this article useful, and you can find all the code for all examples in this Github repo.
Happy coding!