HTML & CSS Dorkshop

This website holds the content for the HTML & CSS Introduction tutorial/dorkshop. Here you will find each lecture’s content and description for you to accompany the classes.

Each lesson has material on GitHub, including an explanation example, a template, and an exercise to test the newly learned content.

Here you can find all the resources:

Lesson 01

Introduction in HTML

What is HTML? What do we use it for? And what is the difference between HTML and CSS?

So, to understand a website, we have to know how it is built. A website usually contains a lot of different files that all work together. Each file, therefore, has its purpose. The most important file is (you may have guessed it) the .html file.

The .html file includes all the information on a website. One could say the content. In comparison, the .css file contains information about the layout or the design. Like the .js file, other files contain other specific information.

If you see a website without any CSS data, it just looks white with some blue text. I guess you saw sites like this before. That means, without any CSS, any site somehow only looks the same, regardless if it is “Google,” “Twitter,” or “Wikipedia.” The style sheet defines the look. To better understand what that means, you should look at this site. Here you always have the same .html file but different .css ones. Clicking on the menu items, you can test all the other layouts without changing the content.

Website HTML Mock-Up


Website HTML Mock-Up


But what is HTML?

HTML stands for hypertext markup language1. It is not a programming language, more like specific content. Think of it like you wanted to explain to your grandma on the phone how a printed paper is structured: “At first there is this big headline Introduction in HTML’, then there is another smaller one, and then there is a paragraph with a lot of text…”

So this is how HTML code looks like:

Here is a text with a <a href="">link</a> and an <u>underlined</u> section.

How does it work?

You build HTML with tags. Each tag usually consists of the command you want to pass within greater-than < and less-than signs >, clutching the content you want to modify. The command is usually straightforward and often describes what you want to do. E.g., a paragraph is p, something that you want to have underlined is u, and something that you want to have bold is b. So, in conclusion, if you’re going to write something bold, you should write the command before and after the word you want to write bold: <b>bold text</b>, not bold text. Keep in mind the slash / symbol in the closing tag!

Some tags, like a link, contain attributes within their commands. Here you can include information that should be invisible to the user. E.g., if you write a link, you do not want the user to see the whole URL, as it would destroy the flow of reading. Instead, we can tell the website that one word should refer to the URL. We do that using the href attribute2. A link would then look like this: <a href=””>this is a link</a>.

That’s mostly it! You can write a whole text with paragraphs, different headlines, tables, lists, images, and of course, links just using HTML.3 Now, you only need to know what commands to use for the specific things you want to do!

Common commands:

For text:

<p></p> Paragraph
<h1></h1> Headlines (from 1 to 6)
<b></b> bold
<i></i> italic
<u></u> underline
<a href=""></a> link with target

Single tags:

<br/> break (new line)
<hr/> thematic break
<img src="" /> image (+ source)


<ul></ul> unordered list (dots)
<ol></ol> ordered list (numbers)
<li></li> list element


Very useful for coding is it to comment on things. Commenting is a way to write something in your code without having it displayed on the actual website. Commenting helps you know what you have coded and why, so I propose you get familiar with commenting.

Every programming or coding language, unfortunately, has its own commenting command. In HTML, it also needs to clasp the comment and looks like this:

<!-- a comment -->

How is a HTML file set up?

At the very beginning of the file, you need to tell the browser what to expect. We do that using this tag:4

<!DOCTYPE html>

Generally, an HTML file consists of two parts: The <head> and the <body>. The head contains the elements that should be invisible to the user but are important for the browser, like the character set you are using or the website title, which is visible in the tab or browser window title. It usually looks something like this:

	<title>My awesome website</title>
	<meta charset="utf-8" />

The body contains the content that should be visible to the user. Here goes the actual content you want to display.

Try it yourself!

Just use a simple text editor, e.g., “TextEdit” on macOS, create a file, name it index.html, and try out some simple commands! Be careful to save it as “raw text.” It could look like this:

<!DOCTYPE html>
	<title>My awesome website</title>
	<meta charset="utf-8" />
	<h1>Hello world!</h1>

		This is my very first attempt in writing some HTML code. I can write <b>bold</b> or <i>italic</i> texts.

	<h2>A list with music I like:<h2>
    <li>Laura Misch</li>
    <li>Kamasi Washington</li>

When you are done, simply open the file in a browser you like (e.g., Google Chrome) and have a look at the result.

  1. If you want to read more about the background of HTML, have a look at the MDN Web Docs

  2. href stands for hypertext reference

  3. Of course, there are many tags, but these are the most useful. Here you can find a list of all tags: HTML Element Reference

  4. If you want to learn more about doctypes, read about it on this page

Class Assets

📈 Open the presentation for Lesson 01 📄 Download the material for Lesson 01
Lesson 02

Introduction in CSS

The Cascading Style Sheet

Now that we know how basic HTML looks like and set up some content, we can now focus on changing a bit of the design. Like in every text editing software you are familiar with, we can change the text color, the font, or the line-height.

But first of all, we should have a look at how coding in CSS looks like. The following part is a bit of code you should now be familiar with:

	This is a random paragraph written in HTML. 

Coding in CSS refers to the tags you already know from HTML. That is how the browser knows which properties you want to give to which part of your content. E.g., we want to have the paragraph in a green font, with a size of 28px and written in a serif font. The CSS code would look like this:

p {
	color: #1ABC9C;
	font-size: 28px;
	font-family: Georgia, serif;

The result of this code would look like this:

<div class=”demo”> <p style=”color: #1ABC9C; font-size: 28px; font-family: Georgia, serif;”> This is a random paragraph, written in HTML. </p> </div>

As you can see, the code is straightforward. The properties are mostly self-explanatory, then you simply add the value you intend for your tags to have.

What are the usual properties to use?

What you have seen before are basic properties and values used in CSS. Because of the medium web, we think mostly of pixels. What was pt for fonts usually works, but get used to the px unit.

Every property we use in CSS has multiple values we can put in, e.g., you can have your text aligned left, centered, or right. You have to know them, but no worries, usually you can figure out most of them. If not, don’t hesitate to google the elements you are missing.

Like I said before, writing CSS is pretty much like using your text editing software like “Word” or “Pages.” You describe how you want your content to look like.


As you know now that HTML tags clutch one another, you often have tags that wrap other tags. We can make use of this architecture in CSS as well. The “C” in CSS stands for cascading, implying that values go from top to bottom. Elements that are nested in other elements inherit the properties of their parent. E.g., if you set the text color of a paragraph to “red”, the bold text pieces in it will also be rendered red unless you specify otherwise.

The <body> tag wraps our entire content. Hence, you can set your website’s overall style here, e.g., the general font-family. All HTML elements within your website will then inherit these values.

body {
	font-family: Verdana, Geneva, sans-serif;
	font-size: 18px;
	line-height: 24px;
	text-align: left;
	color: #222222;

If you want to apply a special style to just a specific type of command instead of all your website, than you just chose this HTML tag instead. E.g. you want all your website like written in the code before but just the headlines type 2 pop out a bit with some bigger font, underline and a different color:

h2 {
	font-size: 32px;
	line-height: 38px;
	text-decoration: underline;
	font-style: italic;
	color: #e67e22;

The body tag style applies to all of the content, so to the <h2> tags too. When styling the <h2> tag, the properties get added or overwrite the inherited ones. Everything else gets inherited from the parent elements, as usual.

What is that strange thing with the #?

You have multiple ways to define colors in CSS. You should be aware that we are on a computer, so our color range is in rgb.

There are multiple ways to show colors in rgb. The most common way is using the hex value, the one with the #. Other ways are writing colors as words (but only the very basic ones, like “red”1) or using a “real” rgb value. Here is an example of all the different spellings to get this green:

p {
	/* wordy (not the perfect color) */
	color: MediumAquaMarine;
	/* hex value */
	color: #1ABC9C;
	/* rgb value */
	color: rgb(26,188,156);
	/* hsl value */
	color: hsl(168,76,42);

As you may have guessed, commenting in a .css file looks a bit different than in HTML. Here you use /* a slash and a star */ to comment.

Now that you have seen the different writing of colors, you probably wonder what the letters in the hex code mean. Each letter defines a number between 1 and 16. 0 is logically the lowest while F (because of a lack of digits) is the highest. That means the value range goes like this: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.

Each pair of letters defines a color: The first two letters are the value for red, the second two for green, and the last two for blue. E.g,. the value #000000 is black, #FFFFFF white, and #FF0000 describes a 100% red.

But try it yourself! Change the hex value below to see how the color of the box changes:

Usually, you don’t have to bother thinking about how the hex values. You just copy them from your design tool, like “Figma” or “Photoshop,” or choose a color from some websites like ColorPicker or Adobe Color.

But where do I write this code?

Remember the head section in the .html file? Now, this part gets important! The CSS code is essential for the browser to know what it should do but not meant for the user to see.

There are multiple ways to implement a style sheet, but the cleanest way is to put it in a different document, then it is easier for you to keep your order. Therefore you just create a new file with the ending .css in the same directory as your .html file. In this file, you can instantly write the CSS code you want to have.

Now you have to tell your website to actually use this style-sheet. In between the <head></head> tags you have to put this specific line to implement your .css file into your site:

  1. You can have a look at more color words here

Class Assets

📈 Open the presentation for Lesson 02 📄 Download the material for Lesson 02
Lesson 03

More About CSS

Is that all to know about CSS?

Now you maybe ask yourself: “Is that all to know about CSS? But how do I do those fancy boxes and spacings between everything?” Of course not! There is way more about CSS!
Every element can be given informations about their sizes and background colors as well. As you may have guessed, the commands, therefore, are not that difficult to understand. For the background, you simply write background and the color you want it to have. The sizes are defined with width and height. An example for a paragraph would look like this:

p {
	width: 500px;
	height: 300px;
	background: #1ABC9C;

Those confusing spacings…

More difficult to understand is the thing about the spacing between elements. In CSS, you have two essential commands: margin and padding.

Margin describes the distance to other elements. It’s something like: “hey, paragraph, I want you to keep 50px away from me!” It is somehow like an invisible space-holder.

Padding, however, is a bit more tricky. Margin is the distance between the object and the next, whilst padding adds space to the object’s inner part. It could be imagined as some kind of protection wall the tag builds for itself.

This is how margin works.

It creates an invisible placeholder around the element.

This is how padding works.

It adds up the space to the element.

Now the question is, when do you need which one? Often, it does not make any difference, but you should always think of what you want to achieve. Multiple times you even need both in one element!

If you just want to put a bit of spacing between two elements, I would recommend using margin. If you have, e.g., a blue text-box and wish to have some more blue space between the text and the border of the element, you need padding.

In the beginning, the difference between these seems a bit odd, but with time and practice in using those two, you will get familiar with it and recognize the respective pros and cons.

p {
	/* This value will be added to every side. */
	padding: 30px;	
	/* While this one is only for one specific side. */
	margin-bottom: 50px;
	/* You can also write all four individually into one property. */
	margin: 10px 20px 50px 10px;
	/* The sides are top, right, bottom, and left. */

If you want to have something automatically horizontally centered, it has to have a set width. The browser then can calculate the space between the outer borders—left and right—using the command margin: auto;.


Okay, we have set a page with multiple paragraphs, and it looks like we wanted to. But now we want to create a new paragraph with another color, but there are no HTML tags left. So what now?

Here, classes come in very handy. Classes are some kind of variable you can create by yourself. So what does this mean? Let’s say you have three paragraphs, all with a specific color, but the last one you want to have in a different color, so it pops out a little more.

What do we need to create such a class? Actually, we just need to tell the browser that the HTML tag has a class. Therefore we write class="" inside of the brackets of the tag we want to add the class and write in between the quotation marks the name of our class, e.g., “ourClass”. Here is how this would look like in the .html file for our example:

	The first paragraph with some information.
	The second paragraph with some information as well.
<p class="ourClass">
	The third paragraph with really <b>important</b> information!

So far, nothing has changed. The third paragraph simply got a new class attribute. To define how our new class should look like, we have to give it some values in our .css file, of course. To do this, we simply write our class’s name into the file and declare the properties we want it to have like we are used to it with all the other HTML tags. The only thing that has changed is that we put a simple dot before the class’s name, so the browser knows that we want to declare a class in this line. That means we type .ourClass into the .css file. For our example, again, the CSS file would look like this:

p {
	background: #64d9c1;
	padding: 20px;
	margin-bottom: 20px;
	color: #FFFFFF;
.ourClass {
	background: #1abc9c;

What will happen now? Every paragraph in our HTML file will get all the CSS info we declared for it, but our third paragraph will get some additional information from .ourClass. Suppose (like in our case) the information is declared twice within the CSS file, e.g., the background property in the usual p tag and .ourClass. In that case, the class’s information has a higher priority and will overwrite the information you gave to the usual tags.

Here is how the code above would look like:

The first paragraph with some information.

The second paragraph with some information as well.

The third paragraph with really important information!

This annoying text editor…

Now you should be familiar with writing and understanding HTML and CSS code. You probably have realized that writing everything in the standard text editor is quite annoying. Luckily a couple of other programmers have thought so too!

There are a couple of programs that make it a lot easier to write HTML, CSS, and many other coding languages. One of the most common and simplest ones is Sublime. I propose you should download it here and thank those developers that they made coding for us so much easier! With text highlighting and suggestions on what you want to write, building websites gets a lot faster. But try it out yourself!

Class Assets

📈 Open the presentation for Lesson 03 📄 Download the material for Lesson 03
Lesson 04

The Box Model

Just Simple Boxes

With lesson 1, you got to know basic HTML, and with lessons 2 and 3, you got the primary and most essential commands in CSS. Mostly everything you need to know to build websites on your own.

But why does it not look like typical websites? What is missing? To understand that, we have to look at how websites are structured.

You may have noticed that every object in the last examples and exercises is very rectangular, especially regarding the CSS code, e.g. width, height, margin-left, and padding-right. All the commands specify only the four regular directions of a rectangle.

If you look at other websites, you will realize that every website is made entirely out of these rectangular shapes or boxes.

Organizing Our Drawer

Okay, but what is so special about those boxes now? Actually, nothing. You just have to get used to the way to layout with them. You always have to put a box inside a box inside a box to get the specific design you want to have. E.g., you have a big box, your website, and inside that box, you have another one representing the head of your website—let’s say an intro image and name of your site. After that, you have another box, your actual content, inside which are two more boxes, one with your article maybe and next to it is one containing your navigation. In your actual content box, there are some with images, some with possibly other articles. And so on and so on.

box model

this is how a website is built up

This sounds a bit confusing at the beginning but think of it as a large drawer you have and want to organize. You put in some big boxes, let’s say for your writing material, and you put in smaller boxes, e.g., for paperclips, in those big ones to give them even more structure.

The div Layer

Your question might now be: “How can I build those boxes?” You did it all the time! Every HTML tag builds a box. But all of them have a specific purpose. You know the <p></p> tag, for example, is for writing a paragraph. But is there something for an empty, not predefined box? And of course, there is!

This special tag is the <div></div> element.1

And this is the part where the classes come into the spotlight. To give those div layers a purpose, you can give them specific classes and parameters to declare their function for your website. E.g., you could have a div layer with the class “main” in which you describe your main content area’s values. The same you could do for a “navigation” and the actual “content.”

Now you write the “boxes” into each other like you want to arrange them. Clasp the boxes you want to contain with the tags of the box you want it to be contained, like the HTML-tags of a paragraph clasp the Text of your paragraph.

<div class="main">
	<div class="navigation">
				<a href="/home.html">
				<a href="/about.html">
				<a href="/work.html">
	<div class="content">
			The headline of my amazing content.
			<!-- Some content -->

Columns, or flex-box and grid

It is relatively clear how to structure websites piece-by-piece, layer-by-layer, but how can we layout columns? We can use the flex property to create more complex layouts.2

Flexbox is a smart tool to create layouts, well, flexibly. It allows setting a container where the boxes will be positioned in a row or column and automatically align within. We can set it by giving a layer the display: flex; property.

In code, it would look like this:

<!-- HTML -->
<div class="multiColumns">
	<div class="column">
	<div class="column">
/* CSS */
.multiColumns {
	display: flex;

That’s it! Now you already have created a two-column layout! But you could, of course, also insert multiple layers to create even more columns. The rest simply stays exactly as you are used to. Give them a specific width if you want or change the margin.

There are also a couple of other properties that help you find the correct setting for your layout. Here are just a few which might be helpful to you:

flex-direction set whether you want to have a column or row layout. Or even a row-reverse if the elements should sort inversed!
justify-content This allows you to define how the elements are distributed (the horizontal axis for a row layout, the vertical axis for a column layout). They could be in center, or have space-between. There are many more! Have a look here.
align-items It’s the counterpart for space-between, defining the other axis. This is, for example, helpful if you want to align elements vertically. You could give it values like center or start

Flexbox can take a while to understand. I also often play around with the properties until I have the settings I want. But you will get the hang of it!

I could also recommend having a look at grid! I won’t cover this in this class, but you can look at this guide.

The Hashtag

One more thing regarding HTML and CSS is using IDs. IDs work exactly the same way as classes do. The only different thing is that it is called “ID.”

But while classes are used for multiple elements, an ID should be used for only one specific element. E.g., you have numerous div-layers that are used as visible boxes, but one of those fungates as your header element, and therefore, you want to give it the unique ID: “header.”

Like the classes overwrite the usual HTML tags, an ID even overwrites the classes’ pieces of information. That is the hierarchy your browser reads out the information in CSS:

  1. ID
  2. Class
  3. HTML tag
  4. Inherited from the parent element

How do I add values to those IDs?

As I mentioned, it is basically like classes, except that you do not use a . but a # instead. Here is how it could look like in your code:

<!-- HTML file -->
<div id="header">
	My website's header.
/* CSS file */
#header {
	background: #bdc3c7;

Those Annoying CSS Presets

What you probably have realized is that each HTML tag already has some style values. Thus you have some margins or font-sizes where you do not want them, and you need to figure out at first where which values are pre-given.

To get rid of those presets, you can simply add a .css file that just resets all those pre-given values, allowing you to (really) start from scratch! Of course, some people did this as well, so you do not have to write this file yourself. Simply download this reset.css file and implement it in between your <head></head> tags—like you would do with your regular CSS file mentioned in lesson 2. But be careful to put it before your regular file; otherwise, your styles will be overwritten by the reset file, resetting your code!

  1. There are even more empty boxes that inherit semantic values, which get important when you intend to improve your website for search engines (SEO), such as header, footer, nav, and article. You can find all of them here

  2. Here, you can find a very detailed and helpful guide to flexboxes

Class Assets

📈 Open the presentation for Lesson 04 📄 Download the material for Lesson 04
Lesson 05

Important Stuff to Know

Domain, Webspace, Hosting — What do I have to do?

Everyone always talks about creating websites, but how do we actually publish them? You are probably all aware that a domain is a relatively good start (you know, that thingy with the .com or so at the top of your browser). Good! So we got one (for example here or most of the time with your webspace as well) and now what? Let’s start at the beginning.

Think of a website as your apartment. Every apartment has a location, the actual room in which you put your furniture in. This is the webspace.1 It is the online server that stores and hosts your website. You could go there if you would know the exact latitude and longitude (this would be the IP), but that is not a very helpful way to tell your friends where to go for the next pizza party. We use an address: a street, number, zip code, etc. That’s what the domain actually is. It is simply the address of your website, an alternate name of the location. Without the apartment, the address is quite useless and without the address, the apartment is hard to find. This address is also helpful to receive mail (aka email, duhh..).

Ok, we have the room, address on it, nice! So it’s time to move. Collecting our furniture (the code we are writing here, so the .html and .css files) and making our new home cozy. But how can we actually put the furniture from the storage van (your computer) to the apartment? We get help from a moving company. It’s called FTP (file transfer protocol). It helps us to transfer all the pieces to the server. Just insert your credentials (you will get them from your web hoster) and you are ready to upload your files!

The last bit to know is that the first info a browser searches—somehow the “welcome” mat of our apartment—is the index.html file. This file in the root (so in the first level of your server, not in a folder) is opened if nothing different is specified.

Talking about time

When it comes to actually building websites, a lot of data, e.g., images, are needed. All of you should be aware of how much storage space images can take on your hard-drive. When it comes to websites, this problem gets even worse.

We all have been on a website that took longer than a couple of milliseconds to load and then probably thought: “Naahhh, I won’t have a look on this one then.” You might say a couple of seconds is not that much, but try it out yourself. It will seem like an eternity to you!

But why are taking some websites so much longer? You know the answer already, of course. Too much data! It takes some time for the browser to download and read everything. The more data the browser has to get, the longer it takes.

Indeed, the provider’s speed, your internet connection, and many other factors have something to say here as well, but in the end, we want to make a website appealing for everyone, so we try to make it as small as possible.

What is about the right size?

Connections get faster and faster with time, which means the acceptable size of websites increases continuously. But to get this straight, when talking about sizes, we do not speak about gigabytes—we do not even talk about a high number of megabytes. An average website should have not more than 4 MB these days,1 and even that is a high value! (Just to get an impression, this website has less than 200 KB.)

That is impossible!

It is not! As you might know, there are many websites around the internet, and all of them keep their size very low. You might wonder how they get websites smaller than even one of those images you wanted to implement into your layout?

Therefore some tools are existing to shrink down the size of your images. Adobe Photoshop for example, has the function “save for web,” using this feature, you can save images in the exact size, quality, and format you need, so it shrinks to the lowest possible size.

I also recommend the tool “ImageOptim,” which efficiently minimizes the kilobytes of images. I usually run all my images through the software before uploading them. You can access it here.

Here is an example what difference this could make:


An image in its original size. 3,5 MB

Rotterdam Web

The same image shrank down to a width of 600px and saved for web. 0,13 MB

If you download both images, you will realize that the one on the right is way smaller in pixel and data size, but—compared to print—the visitor will not see the difference unless they download the image. Or would you have seen the difference in those pictures above? In most cases, we do not need or want the user to download the image, so why adding it in this big size?

Sometimes it is necessary to add big pictures or a lot of them. For those reasons, it is good to implement javascript files, such as lazyload. With such scripts, the images will get loaded when needed and not in advance. Therefore, the initial load will get a lot smaller.

The different formats

Using the function “save for web” in Photoshop, you get the option between .jpg, .png and .gif. I assume you have heard of all of these formats. But do you know which to use when? Are there differences, and if so, which?

First of all, look at what you want to achieve with your image. Does it need a transparent background? Should it move? Depending on what you need, you should use a specific format. There are a couple of these. Here I listed up when to use which one:

In most cases, you should use the .jpg format. It is the overall standard for all pictures. If you save it as a .jpg, you will not have transparency or movement, but a minimal size and good quality. You can even shrink down the quality to 80% without losing too much from the image, saving you again around half of the image data size.

If you need transparent parts, e.g., a cut-out object in front of your colorful background, you should use the .png format. It allows you to have an additional alpha value for each pixel. It does not change much for your workflow, but it adds up a couple of kilobytes.

The latest use of the internet showed us many those moving memes and the war about the pronunciation of the .gif. But for designing, it is only important to know that this format allows you to have a small sequence of images. It is important to know that each frame gives the final “image” a lot of extra data! Therefore, the .gif format is the biggest—they often get even multiple megabytes by only using three images. I just would propose to use as few gifs as possible.

I would even recommend using videos (.mp4) instead. The syntax for videos is a little different than for images. It looks like this:


One more type

Especially in times of responsive web design, images that are endlessly scalable are critical. You are familiar with such files: These vector files we work with all the time in Adobe Illustrator for example.

You can save files in different formats out of such programs, e.g., .ai, .dxf or .pdf, but there is one format that you probably read a lot but never cared this much about: .svg. Browsers can also read this format. It has multiple benefits: It is super small in storage, and it has no scale limit! But you can only use it—as all the shapes in Illustrator—with overall fill colors and not images. It is perfect for icons or logos.

How should I name my files?

By doing the last exercises, you probably got an impression of how annoying it is to write the exact name of a file, so it is readable by the browser. It is essential to name your documents and images the right way not to run into even more problems.

Especially in languages like German or Swedish, some of these unique letters like “ü,” “ö,” or “å.” Computers do not like those, meaning you should avoid them. But what is even more annoying, computers do not like spaces as well! Your operating system has a well-thought-through code to prevent this problem, but unfortunately, the web and browsers often have not. Therefore you should replace all your spacings with underscores _ or minus - symbols.

Another part is that some of your code languages look at the different spellings with capitals and other languages do not. Therefore I would propose to avoid using capitals as well.

Also, try to avoid dots. Nowadays, it should not be a problem anymore, but I always try to stay safe and not use them in names if some old browsers might have some troubles. But now that should finally be it!

Here is an example of how an image should be named: rotterdam_gruen_08-29-2015.jpg.

How to locate them?

Now that you can write websites from scratch, it probably gets essential to know how to locate files only using text, the URL.

Every time you wanted to link to a specific file, you usually wrote down the name of the file, because it was in the same folder, or you just copied a link out of your browser, looking like this: <a href="">My Link</a>.

If you want to keep your files in a better structure using folders, you only need to add your folder’s name to this link. Let’s say you have your HTML file in some directory, and in the same folder as your HTML file, you have the folder “images” in which you have that amazing picture of your cat: “mr_snuggles.jpg.” Now you write into your code of your img tag the folder as well, looking like this: <img src="images/mr_snuggles.jpg" />.

If you have something in a folder further above the one you are actually in with your file referring to, you simply add two dots, e.g. <a href="../home.html">Home</a>.

That is the way you navigate to files! Always keep in mind which file you are in right now and how often you need to step one folder back or which folder further in. That can be as complex as you want: <a href="../../works/year_one/portfolio.html">That is my portfolio</a>.

Referring to some other website, you add the https://. This snippet tells your browser to look into the world wide web and then the next directory. Your browser will think the file you are linking to is on the same directory as your website without these letters.

By just using the slash symbol (/) in an URL, your browser will start at the very first folder of your server. If you try this on a local file somewhere—e.g., on your desktop—it might confuse you, but this link would go to your hard drive of your computer and you would have to navigate to your desktop like shown before.

Therefore, I propose always using relative paths (referring to the file you are in and then dots or folders). Only use the absolute when it is impossible to use relative paths.

More than Comic Sans

Now that we talked about images and naming stuff, you probably want to know how to add other fonts than just those few save web fonts like “Verdana” or “Times New Roman.” As I wrote in the paragraph above, computers—and especially browsers—are very dumb and stubborn. Each browser has its format, and therefore you need to provide the font-face in every format to your website. Afterward, you need to tell your CSS file which files belong to the font.

In CSS3 there is a new function for implementing fonts, called @font-face. So how does it work? Here is an example:

@font-face {
	/* Here the name is defined we later use in our CSS. */
	font-family: "Source Code Pro";
	/* Then we add the files needed actually containing the font. */
	src: url("fonts/SourceCodePro.eot");
	src: url("fonts/SourceCodePro.eot?#iefix") format('embedded-opentype'),
	     url("fonts/SourceCodePro.woff") format("woff"),
	     url("fonts/SourceCodePro.ttf") format("truetype"),
	     url("fonts/SourceCodePro.svg") format("svg");
	/* Here we tell the browser what weight and style the font is. */
	font-weight: normal;
	font-style: normal;

Because exporting the font in all these different formats and implementing it for every font style is very annoying, cool tools such as a webfont generator exist. Simply upload the font you want to have, download the files, and implement them into your website.

Important: Be aware (as in every publishment) that you need to have permission to use this font! Otherwise, the generators will not generate the fonts for you, or even worse, you will have to pay a high fine for using the font.

Google Fonts has many fonts free to use and are already prepared to use on your website. Of course, they maybe do not have the exact font you wanted to use, but perhaps a font that is very similar to it, and it is free! So no worries about compatibility or using permissions.

The inspector

When doing the exercises, you must have realized that rebuilding websites without any information is very complicated. Of course, you could look into the source code and see in there what properties you need, but often the website’s code is messy and massive, making it hard to find what you are looking for.

Fortunately, some developers had been aware of that issue as well, and there is a tool implemented in every browser called “inspector.” With this tool, you simply click on the element you want to get information about, and the CSS properties will just plop up for you. Usually, the key combination to open it is: cmd + option + i (macOS) or ctrl + alt + i (Windows). Give it a try!

  1. There are soooo many web hosters. It differs from the region (e.g. EU vs the USA), pricing, and so on. Check for yourself, I would say every host provides for everything you need. Do not get fooled by the storage size! You do not need much! Maybe this list helps.  2

Class Assets

📈 Open the presentation for Lesson 05
Lesson 06

Even More About CSS

What there is more?

Oh yeah! There is way more about CSS! Until now, we just got an impression of what CSS is like and what to do with it.

Unfortunately, we will not learn everything about it—as if one would ever know everything about CSS. But with this basic knowledge, you are prepared for most websites!


One important thing about every box in CSS is that they have a position property. What does that mean? It is not about their distance from the edges. For that, you can use the margin property. No, the position property is more foundational. There are five different position states a box can be described with.

The default setting of every element is position: static;. This is how you will see it in the browser. It gets affected by the surrounding elements and can be “pushed” around. It merely flows in your code.

The relative only has some minor differences to static. However, it can be useful for parent elements of absolute or sticky elements. I tend to give all my elements the position: relative; property by default to not get issues with absolute or sticky. This would look like this:

/* The * selector selects every element. */
* {
	position: relative;

More exciting are the positions absolute, fixed, and sticky. Using position: absolute;, the element’s position is—oh wonder—absolute. It will not be affected by other elements. If you need an element at a specific place, no matter what, you can use the absolute, e.g., you need the logo of a company in the very top left corner of the page. Period. It will refer to the parent component if it is set to relative, otherwise to the webpage itself.

The position: fixed; is even more special. With this property, the element stays in the position you give it, like with absolute, but regarding your window, not the overall webpage or parent container! What does this mean? If you scroll down, the box will stay on this specific position, not regarding your other content. For example, this makes sense if you have some kind of navigation that you want to be always on the top so the user can click on it all the time.

position: sticky; is also quite exciting. It allows a box to follow the user’s scrolling behavior, but only until the parent container’s end is reached. Keep in mind that at least one directional property has to be set for this to work, e.g., top: 20px;.

The display property

Like the position property, the display property is already given to each element by default, but every HTML tag has a different value. E.g. an element like <i></i> for cursive texts has a display: inline;. You have already seen one of them in a previous lesson: flex.

What does that mean? There are many different ways to display elements. Apart from flex, the four most important ones are: inline, inline-block, block, and none.

Each of them handles your code differently. display: inline; for example, takes your code and puts it into your layout like text. Therefore breaks apply to it as well as text-align or similar. inline-block does basically the same but puts, in addition, a box around it. You know one element very well that—for whatever reason—uses this as default, the <img /> tag. Also, the properties for text elements apply, and you can add properties that usually only apply for boxes like a border-radius.

Now to them. The display: block; describes a box. That means it will be taken as a whole element where nothing can be wrapped around, even if it would be smaller. All div-layers are block elements, but, e.g., headlines or paragraphs are some too!

The most obvious display property is probably the none. It simply does not show the element. Sometimes this comes in very handy, but you will figure out reasons for this over time.

Pseudo classes

You know classes now very well and got familiar with using them. But what you probably did not realize that strange things as “pseudo-classes” exist. Why this strange name? “Pseudo”?
Pseudo-classes are classes that you do not actually give an element. The element somehow can have the class added by the browser. E.g., if you go with your mouse over a specific element, it will get a :hover pseudo-class.

Just as every other class, you can describe properties for those pseudo-classes. Have you ever wondered how links change their color while you are pointing them? That is the magic trick behind it!

a {
	color: #1ABC9C;
a:hover {
	color: #bdc3c7;

Like regular classes, you write them directly into your CSS code, but this time we use colons : instead of a simple dot. We put this pseudo-class directly after the tag that we want to change. If we do not do this, all elements will get affected, which would confuse our user.

There are a couple of pseudo-classes, some more useful, some not. Here is a list of these, but I think you need to try them out yourself:

:hover directly pointing at it with the cursor
:active directly at the moment it is clicked
:visited visited link
:first-child the first element of a series (e.g., lists)
:last-child the last element of a series
:nth-child(2n) the nth element of a list
:before before the element
:after after the element

Nice things for boxes

For a couple of years, we are glad to have CSS3. Since this huge development, it is possible to add small things, such as shadows or rounded corners. It might sound stupid to you, but when I started coding, I had to build at least three div-layers with different backgrounds to get a nice box with rounded corners!

Now we can simply add this command to our element, and it gets the new design. Significant additional benefits of this are that you save a lot of data storage, it works on every browser, and if not, it is down-gradable. If an older browser does not support the shadow command, for example, it simply does not show it instead of messing up all your code.

.superBox {
	background: #1ABC9C;
	border-radius: 3px;
	/* The values: distance-left distance-top blur spread color */
	box-shadow: 6px 6px 0px 0px #bdc3c7;

Here is an example how such a box could look like:


One of the most important things when it comes to styling websites is the background of boxes. As you know, there is the possibility of adding a specific background color to your elements, but aren’t there more possibilities? Yes, there are! Of course, you could use an image instead.

#wrapper {
	background: url("images/background.jpg") top left;

The background can easily be implemented using the url("") snippet. You simply refer to the image you want to use in the quotation marks by linking to it. If the image is smaller than the box, it automatically gets endlessly repeated or tiled. Of course, you can prohibit that by writing afterward no-repeat or add the property background-repeat: none;.

The optional values top left tell the browser where it should start using the background referring to the box that has this property. right and bottom are an option as well, but more interesting is the value center which puts the image in the middle of the box. Be aware that values that would collide with each other are not possible, and always the last one would be taken (like top and bottom).

Since the development of CSS3, we have even more properties to give that often come in handy. Concerning the background, the most important is—in my opinion—the background-size property. Here we can define values as we do with width and height, so going for pixels, but more interesting are the values contain and cover.

While contain automatically scales the image into a size that it fits into the box so that you can see all of it, cover is the sibling that scales the image automatically into a size, so the image is covering the whole box. This gets very important when you, e.g., want to build a website that has a header in which you want to have an image that fills up the whole box:

#header {
	background: url("images/clouds.jpg") center center;
	background-size: cover;

transition, animation, and transform

Since this development, it is also possible to do small animations without using additional code like javascript. Therefore we simply need to write down transition and then the property we want to transition with and the duration. You could think of it as two keyframes set in AfterEffects and the time between the keyframes. By default, the transitions are set to ease. E.g. you want links to change their color smoothly:

a {
	color: #1ABC9C;
	transition: color 0.5s;
a:hover {
	color: #bdc3c7;

If you want to do repeating animations, which should happen automatically, not on interaction, you can use the animation property. Here you need to define the animation separately, but it’s the same principle of keyframes. It could look like this:1

.mpBox {
	height: 20px;
	background: #1ABC9C;
	/* the name of the animation, the duration, the timing, the number of repeats, the direction */
	animation: barSizeChange 15s ease infinite alternate-reverse;    

@keyframes barSizeChange {
	0% {
		width: 10px;
	100%  {
		width: 100px;

Also, it got relatively easy to transform elements, meaning to rotate or skew them. Simply use the transform property.2

.myImage {
	transform: rotate(35deg);

Old browsers

Using the new commands is always a bit tricky when it comes to old browsers. Some of them, maybe only one year old, just can not understand this code unless you add a small prefix to those commands. Very old browsers will never get these commands, no matter how hard you try adding it up using CSS.

Those prefixes differ from browser-type to browser-type. To be sure it works in every browser you should add all of them, it could look like this:

a {
	color: #1ABC9C;
	/* Overall / new browsers */
	transition: color 0.5s;
	/* Mozilla Firefox */
	-moz-transition: color 0.5s;
	/* Opera */
	-o-transition: color 0.5s;
	/* Apple Safari / Google Chrome */
	-webkit-transition: color 0.5s;
	/* Microsoft Internet Explorer */
	-ms-transition: color 0.5s;

And more, and more, and more…

CSS is constantly developing. I often stumble upon new properties or values like the value currentColor, enabling the current text color for other properties like border-color. Also, CSS supports now filters, which might be interesting.

There are simply too many exciting things happening, so keep your eyes open! I recommend following Josh W. Comeau on Twitter. He often posts interesting new tiny snippets.

  1. Find more about animations here

  2. Find all transform properties here

Class Assets

📈 Open the presentation for Lesson 06 📄 Download the material for Lesson 06
Lesson 07

Responsive Design and Dark Mode

The thing with the different screens

In the world we live in right now, it is expected that everyone has at least a computer and a smartphone. Many have even a tablet on top! The problem with this fact is that web developers and designers should work with every screen size.

This is the part where responsive websites take their place. What does it mean: responsive? Responsive means the website responds to the screen/device size—it automatically adapts to the screen. That means widths adjust themselves, and things should be arranged in a different position, maybe.

We should not have to write whole new websites for each device but write it intelligently so it fits all of them. You could try it out with this website! It will fit regardless of which device you access it.

responsive design

Tricks to do so

Fortunately, some HTML and CSS tricks allow us to do this more or less automatically. As you know, we can define widths and heights and all the other things that need values for distances with the unit px. But why would we have to define it if there would not be another unit? Exactly! There are other ones! For this responsive design thing, other units are relevant.

The % unit refers to the width of the parent layer. That means if you have one box with a width of 1000px and within this box, another one with a width of 90%, it will have the final width of 900px. With this unit, you can adjust columns regardless of the width of your window. You could always have a column with the width of 50% and therefore two columns next to each other.

Here is a list of important units:

px one pixel
em the current size of the component’s text
rem the root size of the website’s text
% percent of the parent component
vw ”viewport width,” so the width of your window
vh ”viewport height,” so the height of your window

min and max

O.K., now we come to the fun part. You, of course, got familiar with the properties width and height. These properties are fundamental, but they are absolute! Even if you say you want your #wrapper always be 95% of the overall window, at some point, it might be too big! Just think of a full HD screen with a width of 1920px.

Again CSS offers us a very nice opportunity to solve this problem: min-width and max-width. You can add these two commands into your class or ID without destroying, but helping your actual width. Here is an example:

#wrapper {
	margin: auto;
	width: 90%:
	max-width: 1200px;

What does this code do? We have our #wrapper and want it to be aligned in our page’s center. Therefore we give it a specific width of 90% and a margin of auto margin. But we do not want it to get any bigger than 1200px. Now, what happens. If the Website is smaller than around 1340px, our #wrapper will have a 90% width with a 5% margin on the left and right. Let’s say our window has a width of 1000px, then the #wrapper will have a width of 900px and margin left and right of 50px.

Is the window wider than this—let’s say it has a width of 1500px—then our #wrapper will “only” have the width of 1200px, because that is the maximum width, even though 90% of our window would be 1350px.

The same principle applies, of course, also for max-height.

The Viewport

By default, smartphones simply scale down a website. This is helpful for websites that are not responsive but destroy the experience of those that are. We can tell the browser to not scale the website. We do that by simply adding this line into between the <head> tags of our .html file:



calc() allows you to use simple calculations of values, even if they do not belong to the same unit category. Here is an example:

#wrapper {
	width: calc( 100vw - 60px );
	margin: 60px auto;

The media query

Those are nice things to have while designing websites for every device. But what happens if we have three columns but only an iPhone screen with 375px of width? Will those columns not get really, really small? Yes, they will! But there is a way to prevent the browser from doing so.

In our CSS file, we can add a simple section of code that allows us to specify different screen sizes. In these parts of our file, we can then redefine all classes, IDs, and elements and change specific values that we need to change:

	/* Change values over here */

This code snippet adds or changes CSS properties while a screen is smaller than 720px. If your using device does not fulfill those queries, then code between the brackets will not be added.

Of course, you can have multiple of the @media queries, all with different screen sizes, but then again, you would have to write all the time whole new CSS files. So use the other commands smartly!

Dark Mode and Variables

Using the media query, we can read the device’s width but also the user’s preference for a light or dark mode. The query looks like this:

@media (prefers-color-scheme: dark) {
	/* dark mode values go over here */

This can also be similarly annoying to change all the elements’ colors accordingly, so the last trick I am going to give you at hand is the use of variables. In CSS, you can use variables like this: var(--color-background). However, you still need to define them. To do so, add the variables into the :root selector. When using the variables, you only need to change the color for the different modes once. Here is an example of such a CSS file:

:root {
	--color-background: #FFF;
	--color-text: #333;

body {
	background: var(--color-background);
	color: var(--color-text);

@media (prefers-color-scheme: dark) {
	:root {
		--color-background: #222;
		--color-text: #EEE;

Class Assets

📈 Open the presentation for Lesson 07

Helpful Links


There are a couple of text editors. Here’s a list of some:

  • Sublime Text — A very minimalistic text editor.
  • Visual Studio Code — A very powerful editor, which also includes a terminal.
  • Atom — A very hackable text editor.
  • Glitch — An online editor, perfect for learners

Font Libraries

A list of libraries with a lot of fonts ready to use for web.

Helpful Scripts and Code Snippets

Here you will find a list of useful, open-source files that might help you with developing your website.

Helpful Guides

Here you will find a list of useful websites, going into more detail than I did.

Helpful Tools

Here you will find a list of tools that can help you making websites.

Domains, Hosting, etc.

Here you will find a list of tools and links, which become relevant when it comes to publishing your website.

Inspiration and Interesting Code Pieces

Here you will find a list of inspiring stuff, done with HTML & CSS, or people to follow. They often post some smaller snippets that can come in quite handy!