Introduction to Web Layout

Lecture notes — HTML and CSS basics for beginners

What is markup

Markup is the process of building a web page based on a design layout. The markup developer turns a graphic layout into code the browser understands, using two languages: HTML (structure) and CSS (appearance).

The overall site-building process

  1. Brief — the client describes what they need.
  2. Analysis — a technical specification is drafted, and the audience and niche are analyzed.
  3. Prototyping — a wireframe is created (the skeleton of the site made of black rectangles).
  4. Design — the designer draws each unique page as a full-fledged layout.
  5. Markup — the markup developer translates the layout into HTML + CSS.
  6. Backend development — the backend developer integrates the markup with server-side logic.
  7. Testing and launch.
The markup developer always gets the source data from the layout. Font names, sizes, colors, spacing — everything is taken from the layout, nothing is invented off the top of your head.

Layout formats

It depends on the studio and the designer: previously it was PSD (Photoshop), then Sketch. Today the absolute industry standard is Figma (Adobe XD stopped development in 2023).

HTML basics

HTML (HyperText Markup Language) is a language for describing the structure of a web page. HTML describes the skeleton only, never the appearance.

An HTML tag never defines an element’s appearance. Structure and styling are two different things. For example, the tag <strong> does not mean “make it bold” — it means emphasizing text for search engines and screen readers.

Types of tags

✅ Paired tags

They have an opening and a closing part. Between them is the content.

<p>Paragraph text</p>
<a href="https://example.com">Link</a>

The closing tag contains a slash before the name: </p>

📎 Unpaired tags

They have no content and no closing part.

<link rel="stylesheet" href="style.css">
<meta charset="UTF-8">
<img src="photo.jpg" alt="Photo">

Attributes

  • Written only in the opening tag.
  • Format: name="value" — no spaces around =
  • Always double quotes.
  • Attributes are separated from one another by a space.

Nesting tags

Tags can be nested inside one another, like boxes. The main rule: the inner tag must be entirely contained within the outer one.

✅ Correct

<body>
<a href="#">Link</a>
</body>

❌ Incorrect

<body>
<a href="#">Link
</body>
</a> <!-- overlap! -->

Minimal HTML page template

Every page on the internet contains the same set of mandatory tags:

<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>Page title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- The page content goes here -->
</body>
</html>
Tag Purpose
<!DOCTYPE html> Tells the browser the HTML version (the fifth, modern one)
<html lang="uk"> The root tag. The lang attribute is the page language (for SEO and screen readers)
<head> Meta information: encoding, tab title, linking styles
<meta charset="UTF-8"> The page encoding. Always UTF-8
<title> The text in the browser tab
<link> Linking a CSS stylesheet file
<body> All the visible content of the page
The main HTML file of a project is conventionally named index.html — it is the one the browser looks for by default when opening a folder on the server.

Browser inspector (DevTools)

The inspector is one of the markup developer’s main tools. It opens with:

  • F12 (Windows/Linux) or Fn + F12 (Mac with TouchBar)
  • Ctrl + Shift + I / Cmd + Option + I
  • Right click → “Inspect”

What you can do in the inspector

  • Elements tab — view and interact with the page’s HTML tree.
  • Styles tab — view the CSS styles of the selected element. You can temporarily disable or change properties.
  • Computed tab — all the actually applied styles, including inherited ones and the browser defaults.
Changes in the inspector are temporary. After you refresh the page, everything reverts to its original state. Edit the code in your editor, and use the inspector for debugging.

CSS basics

CSS (Cascading Style Sheets) is a language for describing appearance. First we build the skeleton in HTML, then we attach styles in CSS so the page looks the way the layout intends.

CSS syntax

body {
background-color: purple;
font-family: Arial, sans-serif;
color: white;
}
  • Selector (body) — specifies which element the styles apply to.
  • Property (background-color) — what exactly we are styling.
  • Value (purple) — the value we assign.
  • Each declaration ends with a semicolon ;
  • The curly brace { goes on the same line as the selector, after a space.
  • Each property goes on a new line, indented by 2 spaces.

Main CSS text properties

Property What it does Example values
font-family Font name Arial, Tahoma, sans-serif
font-size Font size 16px, 50px
font-weight Font weight normal (400), bold (700), 100900
font-style Typeface style normal, italic, oblique
color Text color white, #ffffff, #333
background-color Background color purple, #800080
text-decoration Text decoration none, underline, line-through
The text color is color, not font-color. This is a common stumbling block for beginners.

font-family: fallback fonts

Always specify several fonts separated by commas, with a family at the end:

font-family: Arial, Tahoma, sans-serif;
  • The browser tries the first font. If it doesn’t find it — the second, and so on.
  • sans-serif — a sans-serif font (Arial, Helvetica).
  • serif — a serif font (Times New Roman, Georgia).
  • monospace — a monospaced font (Courier, Consolas).

Colors in CSS

Colors can be set in several ways:

  • Keyword: white, black, purple
  • HEX format: #ff0000 — two characters for each component (R, G, B)
  • #ffffff — white (the maximum of all components)
  • #000000 — black (the minimum of all)
Color codes are always taken from the layout using the eyedropper. There’s no need to memorize them.

Cascade and inheritance

CSS stands for Cascading Style Sheets. This means that styles can override one another according to priority rules.

Three sources of styles (from lower to higher priority)

  1. Inherited styles — an element inherits some properties from its parent (for example, the font from body).
  2. Built-in browser styles — every tag has default styles from the browser developers (for example, links are blue with an underline).
  3. Your own styles — always have the highest priority.
The <a> link inherits color: white from body. But the browser style overrides it with blue. To make the link white, you need to explicitly set a {
color: white; }
— and your style will win.

Resetting default styles

Browser styles (spacing, fonts, sizes) often get in the way during markup — they can differ between browsers. That’s why styles are reset before starting work. There are several approaches:

Approach 1: The universal selector *

The simplest way is to reset the spacing for all elements at once:

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

The * selector (asterisk) is universal and applies to all elements on the page. Adding box-sizing: border-box makes width and height include padding and border (more on this in the lecture about the box model).

This is the minimal option, suitable for learning and small projects. In practice, more thorough solutions are used.

Approach 2: CSS Reset (Eric Meyer)

Reset CSS is a stylesheet that completely zeroes out all browser styles. After the reset is applied, every element looks the same — like plain text with no spacing, borders, or sizes.

/* Fragment of reset.css */
html, body, div, span, h1, h2, h3, h4, h5, h6,
p, a, img, ol, ul, li, form, label, table,
caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}

Advantage: full predictability — you start with a blank slate. Drawback: you have to re-declare styles for lists, headings, tables, and so on.

Approach 3: Normalize.css

Normalize.css works differently — it doesn’t reset styles completely, but aligns them across browsers. Useful styles (heading spacing, list markers) are preserved, but become the same in Chrome, Firefox, Safari, and others.

Advantages:

  • Preserves useful browser styles instead of destroying everything
  • Fixes known bugs and inconsistencies between browsers
  • Less work after applying it — basic elements already look fine

Comparison of approaches

Reset CSS

  • Zeroes out everything
  • Headings = plain text
  • Lists without markers
  • You need to style everything from scratch
Normalize.css

  • Aligns across browsers
  • Headings stay larger
  • Lists with markers
  • Less manual work

How to include it

Reset or Normalize is included as the first CSS file — before your styles:

<link rel="stylesheet" href="normalize.css">
<link rel="stylesheet" href="style.css">

The order matters: first we reset/align, then we write our own styles on top.

In practice, most modern projects use Normalize.css or its variations. A full reset is used less often, because after it you have to re-style even the basic elements. For learning, resetting via * is enough.

Links (the <a> tag)

The <a> tag creates a link. Its required attribute is href, which specifies where the link leads.

<a href="https://example.com">Go to the site</a>
  • Without href, the text won’t be clickable and the cursor won’t change to a “hand”.
  • By default, links are blue with an underline (browser styles).
  • To remove the underline: text-decoration: none;

Link protocols: tel: and mailto:

In the href attribute you can use special protocols for calls and email:

<!-- Call -->
<a href="tel:+380991234567">+38 (099) 123-45-67</a>
<!-- Email -->
<a href="mailto:info@example.com?subject=Request">Write to us</a>

tel: — the protocol for calls

It works well on mobile devices: tapping opens the dialer. On desktop, the behavior depends on the OS and the installed programs.

mailto: — the protocol for email

Drawbacks of mailto:

  • The email address is exposed to spam bots
  • The user leaves the site (switches to an email client)
  • You can’t track effectiveness (UTM tags, analytics)
  • Not everyone has an email client set up

A better alternative is a contact form on the site.

Data attributes

HTML5 lets you create arbitrary attributes with the data- prefix:

<div data-category="news"
data-user-id="42">...</div>
  • Can be added to any tag
  • The browser ignores them — they don’t affect rendering
  • Used to store additional data for JavaScript

Outputting a data attribute via CSS

<!-- HTML -->
<span data-tooltip="Tooltip">Hover the cursor</span>
/* CSS — outputting the value of a data attribute */
span::before {
content: attr(data-tooltip);
}

The attr() function works only in the content property of pseudo-elements.

CSS variables (custom properties)

CSS variables (custom properties) let you store values and use them across the whole page. This is one of the most useful features of modern CSS.

Declaration and use

:root {
--header-height: 50px;
--footer-height: 4rem;
--primary-color: #3498db;
}
.header {
height: var(--header-height);
}
.footer {
height: var(--footer-height);
}
.content {
min-height: calc(100vh - var(--header-height) - var(--footer-height));
}

Syntax

  • Declaration: starts with two dashes — --name: value
  • Use: the var(--name) function
  • The name is case-sensitive: --Color and --color are different variables

Scope

  • :root — the variables are available everywhere on the page (global)
  • If declared in a specific selector, the variables are available only inside that element and its descendants

Use with a style guide

The designer’s style guide defines all the colors, font sizes, and spacing. A minimal padding (for example, 10px) means that all spacing is a multiple of that number: 10, 20, 30px. CSS variables are perfect for storing such values:

:root {
--spacing-unit: 10px;
--font-heading: 24px;
--font-body: 16px;
--color-primary: #2c3e50;
--color-accent: #e74c3c;
}
CSS variables work at runtime — their values can be changed via JavaScript or media queries. This distinguishes them from preprocessor variables ($color in SCSS), which exist only at the compilation stage.

@supports — checking CSS support

The @supports rule checks whether the browser supports a particular CSS property, and applies styles only if it does.

Syntax

@supports (display: grid) {
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}

Logical operators

/* OR */
@supports (display: grid) or (display: flex) { ... }
/* AND */
@supports (display: grid) and (gap: 10px) { ... }
/* NOT — use with caution */
@supports not (display: grid) { ... }
A note about not: if the browser doesn’t support @supports itself, it will ignore the whole block, including the not variant. That’s why @supports not (...) is an unreliable option for older browsers.

Practical use

Use @supports when you want to apply a new CSS property but aren’t sure about support. Write the base styles without @supports, and the enhanced ones inside it:

/* Base version */
.layout {
display: flex;
flex-wrap: wrap;
}
/* Enhanced version for browsers that support grid */
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
}

Code editors

Free editors that don’t require complex setup:

  • Visual Studio Code — the most popular one, with a huge ecosystem of plugins. The industry standard.
  • Zed — modern, ultra-fast (written in Rust), free and open source. Built by former Atom developers.
  • Sublime Text — lightweight and fast, but paid ($99).

AI editors

A separate category of editors with deep artificial-intelligence integration. AI helps write code, find errors, and suggest solutions right in the editor:

  • Cursor — a fork of VS Code with deep AI integration. One of the first AI editors to gain mass popularity. There’s a free tier.
  • Windsurf — an AI editor based on VS Code (formerly called Codeium). There’s a free tier with unlimited autocomplete.
  • Antigravity — a new AI editor focused on fast development with the help of AI agents.

Professional IDEs

An IDE (Integrated Development Environment) is a full-fledged development environment with a built-in debugger, refactoring, framework support, and other tools:

  • WebStorm (JetBrains) — a powerful environment for JavaScript/TypeScript and front-end development.
  • PhpStorm (JetBrains) — an environment for PHP development. Includes all the features of WebStorm + support for PHP, databases, and frameworks (Laravel, Symfony, etc.).

All JetBrains IDEs are free for learning and personal projects (non-commercial license since 2024).

The best editor is the one you’re most productive in. For taking this course, the free VS Code is enough.

Sandboxes (online editors)

A sandbox is a website for quickly writing and previewing HTML/CSS without creating files.

Popular sandboxes

  • CodePen — the most popular, convenient for learning HTML/CSS
  • JSFiddle — lightweight, no registration required
  • CodeSandbox — for more complex projects with npm packages
  • StackBlitz — runs entirely in the browser, supports Node.js

How a sandbox differs from an editor

  • No minimal template needed — you work directly inside <body> right away.
  • The CSS file is automatically linked.
  • The result updates instantly without manually refreshing the page.
  • A unique link is generated — handy for sharing the result.

About preprocessors and other technologies

The browser works with exactly three technologies: HTML, CSS, and JavaScript. Everything else (SASS, SCSS, LESS, React, TypeScript, etc.) consists of add-ons and tools that speed up development. Preprocessor files cannot be linked to HTML directly — they need to be compiled into ordinary CSS.

Why preprocessors are needed

Plain CSS is powerful, but on large projects it becomes unwieldy. Preprocessors add features that aren’t (or previously weren’t) in standard CSS:

  • Variables — store colors, sizes, and fonts in one place
  • Nesting — you write selectors inside parent ones, like an HTML structure
  • Mixins — reusable blocks of styles that can be called in a single line
  • Math — arithmetic operations on values
  • Imports — splitting styles into separate files without extra HTTP requests

SASS / SCSS

SASS (Syntactically Awesome Stylesheets) is the most popular CSS preprocessor. It has two syntaxes:

  • .sass — the old syntax without curly braces and semicolons (indentation instead of braces)
  • .scss — the new syntax, fully compatible with ordinary CSS. Any CSS file is already valid SCSS

An example of SCSS using variables and nesting:

// Variables
$primary-color: #3498db;
$font-main: Arial, sans-serif;
// Nesting
.header {
background: $primary-color;
font-family: $font-main;
.nav {
display: flex;
a {
color: white;
&:hover {
opacity: 0.8;
}
}
}
}

After compilation, this code turns into ordinary CSS:

.header {
background: #3498db;
font-family: Arial, sans-serif;
}
.header .nav {
display: flex;
}
.header .nav a {
color: white;
}
.header .nav a:hover {
opacity: 0.8;
}

LESS

LESS (Leaner Style Sheets) is another preprocessor, similar to SCSS. The main difference is that variables start with @ instead of $:

@primary-color: #3498db;
.button {
background: @primary-color;
}

LESS was popular earlier (Bootstrap 3 used it), but now most projects have moved to SCSS.

PostCSS

PostCSS is not a preprocessor in the classic sense, but a tool for transforming CSS with the help of plugins. The best-known plugins:

  • Autoprefixer — automatically adds vendor prefixes (-webkit-, -moz-) for support of older browsers
  • cssnano — minifies CSS for production

PostCSS is often used together with SCSS: first SCSS compiles into CSS, and then PostCSS adds prefixes and minifies.

How compilation works

A .scss or .less file is compiled into ordinary .css using special tools. The HTML links the already compiled CSS:

<!-- In HTML we link only CSS, never SCSS -->
<link rel="stylesheet" href="style.css">

Compilation happens automatically during development — when you save a .scss file, the tool generates an updated .css.

Modern CSS is catching up with preprocessors

Many of the features preprocessors used to be chosen for are now in standard CSS:

Feature Preprocessor Native CSS
Variables $color: red (SCSS) --color: red (CSS Custom Properties)
Nesting Supported for a long time CSS Nesting — supported since 2023
Math $width / 2 calc(100% / 2)
CSS Custom Properties (--color) work at runtime — their values can be changed via JavaScript or media queries. Preprocessor variables ($color) exist only at the compilation stage and disappear in the final CSS. These are different tools for different tasks.
If you know basic CSS well, any preprocessor (SASS, LESS) can be learned in a few days. First the fundamentals, then the tools. In this course we work with plain CSS — that’s enough to understand all the concepts.

Tips for beginners

  • Learn English — all of markup is based on the English language. The more fluently you command it, the easier things will be.
  • Be attentive — every missed period or quotation mark can break the page.
  • Don’t stop at markup — a pure markup developer without JavaScript is in little demand these days. Learn JS, frameworks, and become a front-end developer.
  • Gain experience — after courses you need practice. Build markup for yourself, for friends, take small freelance projects.
  • Google properly — the point is not to copy a ready-made solution, but to understand why it works the way it does.

Vitalii Kaplia

Founder, Web Developer & WordPress Expert

I became interested in programming back in 1997. The first acquaintance with a future profession was using Visual Basic. In…

More about author

A digital product engineer and web solutions architect

Free consultation + cost calculation

Let’s discuss your project?

Free consultation + cost calculation

More interesting articles

Customer login

This site uses cookies

We use cookies to personalize content and ads, provide social media features, and analyze our traffic. We also share information about your use of our website with our social media, advertising, and analytics partners, who may combine it with other information you have provided to them or collected when you use their services. By continuing to use our site, you consent to our use of cookies and accept our Privacy Policy and Terms of Use.

Virtual assistant
Hi! I'm the KAPLIA.PRO virtual assistant! I can tell you about our services, portfolio projects, ballpark pricing, and how we work — from websites and eCommerce to web apps, CRMs, bots, and AI agents. Ask away!

By continuing with the AI assistant, I agree to the site’s terms of use and privacy policy.

AI assistant may make mistakes in responses