Registered non-governmental non-profit organisation certificate No. 1052p

Articles

How a web page is built: HTML and CSS

15 min read

HTML and CSS basics: your first HTML file, core tags, selectors, the box model, Flexbox, mobile layouts, free hosting and a hands-on project.

The websites you open every day, whether news, an online shop or a school page, start out as plain text files. Learning to write them needs neither an expensive computer nor special training: a free program, a browser and a few evenings of practice are enough. In this guide we look at how a browser displays a page, which tools you need, your first HTML file, core tags and attributes, semantic HTML and accessibility, linking CSS, selectors, colours and fonts, the box model and Flexbox basics, mobile layouts and putting a page online. Then we build a “personal introduction page” step by step with the full code, go through common mistakes and finish with a practice exercise and a checklist.

How a browser displays a page

When you type an address, your browser downloads several files from a server, reads them and draws the page on screen. A website is a collection of such pages. Every page has three layers, and a house is a handy comparison:

  • HTML is the structure. The walls and rooms: where the heading, text, image, list and button go.
  • CSS is the look. Paint, furniture and decoration: colours, fonts, spacing and the position of elements.
  • JavaScript is the behaviour. Electricity and the doorbell: something happens when a button is pressed, a menu opens, a form is checked.

This article covers the first two layers. HTML and CSS are not programming languages but markup and style languages, which makes them the easiest way into the web. The part users see is called the frontend, while working with data on the server side is the backend.

The tools you need

All of them are free:

  1. A text editor. Code is plain text, but you cannot write it in Word, which adds hidden formatting. The most convenient choice is the free Visual Studio Code (VS Code): it colours your code, closes tags automatically and points out mistakes. On a slow computer, Notepad++ will do.
  2. A browser. Chrome, Firefox or Edge. It is useful to check the result in two different browsers.
  3. DevTools (developer tools). Built into the browser. Press F12, or right-click any element on the page and choose Inspect (on macOS, Cmd + Option + I). The Elements tab shows the page’s HTML, and the panel on the right shows the CSS applied to the selected element. You can change values right there and see the result immediately; the changes disappear when you reload, and your original file stays untouched.

Start tidily: create a folder called tanishuv inside Documents and open it in VS Code via File → Open Folder. All your files will live there.

Your first HTML file and core tags

Create a file called index.html in the folder. The name index is not random: when a folder is opened, the server looks for exactly this file. Type the following:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>My first page</title>
</head>
<body>
  <h1>Hello, world</h1>
  <p>I wrote this page myself.</p>
</body>
</html>

Save it (Ctrl + S), then drag the file into a browser window or double-click it. What each line does:

  • <!DOCTYPE html> tells the browser this is modern HTML.
  • <html lang="en"> wraps the whole page, and lang states the language of the text, which matters for screen readers and translation tools.
  • <head> is the behind-the-scenes part that does not appear on screen.
  • <meta charset="UTF-8"> makes letters display correctly. Without it, the Uzbek apostrophe or Russian letters can turn into little boxes.
  • <meta name="viewport"> stops phones from shrinking the page and makes it fit the screen width instead.
  • <title> is the name on the browser tab and in search results.
  • <body> holds everything the user sees.

Most tags come in pairs: an opening <p> and a closing </p>, with the content in between. A few, such as <img> and <meta>, are not closed.

Core tags

<h1>Page heading</h1>
<h2>Section heading</h2>
<h3>Subsection</h3>
<p>An ordinary paragraph of text.</p>
<a href="https://example.com">Link text</a>
<img src="images/samarqand.jpg" alt="Registan Square in the evening">
<ul>
  <li>Bulleted list item</li>
</ul>
<ol>
  <li>Numbered list item</li>
</ol>
<button type="button">Button</button>
  • h1–h3 are heading levels. A page has a single h1.
  • p is a paragraph, a is a link and img is an image.
  • ul is an unordered (bulleted) list and ol an ordered (numbered) one; in both, the items are li.
  • div is a “box” with no meaning of its own, used to group and style elements.
  • button is a clickable button. To go to another page, use a instead.

Attributes

An attribute is extra information inside an opening tag: name="value". The most common ones are href (link address), src (image file), alt (image description), class (a name for CSS), id (a unique name on the page) and lang. Always put the value in double quotes.

Semantic HTML and accessibility

You could build everything out of div, but you should not. Semantic tags carry meaning: header is the top of a page or section, nav a menu, main the main content, section a themed section and footer the bottom part. They help search engines, and the screen readers used by blind and partially sighted people, make sense of the page.

Accessibility rules:

  • Give every meaningful image an alt: not “image1” but what the picture actually shows. For a purely decorative image, leave alt="".
  • Keep headings in order: h1, then h2, then h3. Do not pick a heading just to get bigger text; that is a job for CSS.
  • Make link text clear: not “click here” but “List of programmes”.

CSS: linking, selectors, colours and fonts

The best approach is to write styles in a separate style.css file, so one file styles every page. Add this inside head:

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

A CSS rule has three parts: a selector (which element), a property and a value:

p {
  color: #333333;
  font-size: 18px;
}

.izoh {
  background-color: #fff4d6;
}

#asosiy-rasm {
  width: 100%;
}
  • A tag selector (p) applies to every paragraph.
  • A class selector (.izoh) applies to any element with class="izoh". One class can be given to many elements.
  • An id selector (#asosiy-rasm) applies to a single element only.

In practice, prefer classes: they can be reused, whereas an id is very “strong” and later makes styles harder to change. Write class names in Latin letters without spaces: skills-list or konikmalar.

Colours can be given as a name (red), a hex code (#1c3d86) or rgb(28, 61, 134). Make sure there is enough contrast between text and background: nobody can read light grey text on a light grey background.

Fonts are set with font-family, ending with a fallback family: font-family: Arial, Helvetica, sans-serif;. If the first font is missing on the computer, the next one is used. For body text, a size of 16–18px and a line height of around line-height: 1.5 are easy to read.

The box model and Flexbox basics

The box model

To a browser, every element is a rectangular box. Its layers, from the inside out, are:

  1. Content: the text or image itself.
  2. Padding: the inner space between the content and the border.
  3. Border: the border line.
  4. Margin: the outer space between the box and neighbouring elements.
.card {
  padding: 20px;
  border: 1px solid #dddddd;
  margin-bottom: 16px;
}

By default, padding and border are added on top of an element’s width, which muddles the maths. To avoid this, people put * { box-sizing: border-box; } at the top of the file, so width now means the width of the whole box. In DevTools, the Computed tab shows the box model as a colour-coded diagram.

Flexbox

Flexbox lines elements up in a row or a column. For example, to put menu items side by side:

.menu {
  display: flex;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
}
  • display: flex turns the parent into a flex container, and its direct children line up in a row.
  • gap sets the space between the children (no fiddling with margins).
  • justify-content controls placement along the main axis: flex-start, center, space-between.
  • align-items aligns along the cross axis; center lines up elements of different heights through the middle.
  • flex-direction: column stacks elements in a column; flex-wrap: wrap moves them onto the next line when space runs out.

Mobile layouts and putting a page online

Media query basics

Many people open websites on their phones, so a page has to work on a narrow screen too. The first step is the viewport meta tag shown above. The second is a media query: extra rules for screens narrower than a certain width:

@media (max-width: 600px) {
  .menu {
    flex-direction: column;
  }
}

To test it, click the phone icon in DevTools (Toggle device toolbar, Ctrl + Shift + M) and try different screen sizes. Using max-width and percentages instead of fixed widths also helps a page adapt.

Going online

To share your finished page with friends via a link, you need hosting. Several services offer a free option for static pages:

  • GitHub Pages. You create a repository on GitHub, upload your files, then go to Settings → Pages, choose main as the Branch and click Save. After a few minutes the page opens at username.github.io/repository-name/. You can learn how to work with Git from our Git basics article.
  • Netlify. Just sign up and drag your folder onto the site window; the service gives you an address with a temporary name.

On both, the home page file must be called index.html.

Hands-on project: a personal introduction page

Our fictional heroine is Aziza Yusupova from Namangan. She used to work in a library, is now learning frontend development and wants a page about herself to send to employers. You will put in your own details.

Step 1. Folder structure. Inside the tanishuv folder: index.html, style.css and an images folder containing a portrait named aziza.jpg in lower case. If you have no photo, delete the img line.

Step 2. HTML. Write this in index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Aziza Yusupova - personal page</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header class="hero">
    <img class="hero-photo" src="images/aziza.jpg" alt="Portrait of Aziza Yusupova">
    <div>
      <h1>Aziza Yusupova</h1>
      <p class="hero-role">Junior frontend developer, Namangan</p>
    </div>
  </header>
  <main>
    <section class="card">
      <h2>About me</h2>
      <p>I spent two years working at our district library. Now I am learning to build web pages: my goal is to create a friendly website for readers.</p>
    </section>
    <section class="card">
      <h2>My skills</h2>
      <ul class="skills">
        <li>HTML</li>
        <li>CSS</li>
        <li>Flexbox</li>
        <li>Git basics</li>
      </ul>
    </section>
    <section class="card">
      <h2>Contact</h2>
      <p>If you have an offer or a question, write to me:</p>
      <a class="button" href="mailto:aziza@example.com">Send an email</a>
    </section>
  </main>
  <footer class="footer">
    <p>2026, Aziza Yusupova</p>
  </footer>
</body>
</html>

Clicking a mailto: link opens the email program. Replace example.com with your own address.

Step 3. CSS. Write this in style.css:

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 18px;
  line-height: 1.6;
  color: #1f2937;
  background-color: #f7f5f0;
}

.hero {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 40px 24px;
  background-color: #1c3d86;
  color: #ffffff;
}

.hero-photo {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
  border: 4px solid #ffffff;
}

.hero h1 {
  margin: 0;
  font-size: 32px;
}

.hero-role {
  margin: 4px 0 0;
}

main {
  max-width: 720px;
  margin: 0 auto;
  padding: 24px 16px;
}

.card {
  background-color: #ffffff;
  border: 1px solid #e5e0d6;
  border-radius: 12px;
  padding: 20px 24px;
  margin-bottom: 20px;
}

.card h2 {
  margin-top: 0;
  color: #1c3d86;
}

.skills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0;
  list-style: none;
}

.skills li {
  padding: 4px 14px;
  border-radius: 999px;
  background-color: #e0f2f1;
  color: #0b5f5c;
}

.button {
  display: inline-block;
  padding: 12px 20px;
  border-radius: 8px;
  background-color: #0e8581;
  color: #ffffff;
  text-decoration: none;
  font-weight: bold;
}

.button:hover {
  background-color: #0b6b68;
}

.footer {
  text-align: center;
  padding: 16px;
  color: #6b7280;
}

@media (max-width: 600px) {
  .hero {
    flex-direction: column;
    text-align: center;
  }

  .hero h1 {
    font-size: 26px;
  }
}

Step 4. How it works. .hero h1 means “an h1 inside .hero”. The max-width and margin: 0 auto on main centre the content and stop lines from stretching too far on wide screens. Flexbox turns the skills list into “badges”, and flex-wrap moves them onto a new line on narrow screens. :hover is the state when the mouse pointer is over an element. On phones, the media query stacks the photo and the name on top of each other.

Step 5. Check and publish. Test the phone view in DevTools, then put the page on GitHub Pages or Netlify. You can add the finished link to your CV; our article on building a portfolio explains more.

Common mistakes

  • An unclosed tag. Forget a </p> or </section> and the following elements “fall inside” it, so the page looks unexpected. Tidy indentation (Format Document in VS Code) makes the mistake easier to find.
  • A wrong file path. src and href give the file’s location relative to the HTML file. If the image is in the images folder, you need images/aziza.jpg, not just aziza.jpg. If an image does not appear, look for a “404” message on the Console tab in DevTools.
  • Capital letters in file names. Windows treats Aziza.JPG and aziza.jpg as the same file, but a hosting server does not: an image that worked on your computer goes missing online. Name files and folders in lower-case Latin letters without spaces.
  • The cache. You changed the CSS but the page looks the same. The browser has remembered the old file: do a full reload with Ctrl + F5 or Ctrl + Shift + R.
  • Small CSS slips. A forgotten semicolon, a class name without its dot (card instead of .card), or class="card" in the HTML not matching .cards in the CSS. DevTools shows a broken rule crossed out or with a warning icon.
  • Forgetting to save. A white dot on a VS Code tab means the file is unsaved. You can switch on File → Auto Save.

Practice exercise and checklist

Adapt the project to yourself:

  1. Write your own name, town and 3–4 sentences about yourself.
  2. Add at least five items to the skills list.
  3. After “About me”, add a new section with an h2 heading: “My interests” or “Courses I am taking”.
  4. Change the main colour: replace #1c3d86 with another one and check the text is still readable.
  5. Add a second link to the contact section (for example, your social media profile) and place both links side by side with Flexbox.
  6. View the page in DevTools at a width of 375px.
  7. Put the page on free hosting, send the link to someone close to you and ask them to open it on their phone.

Checklist

  • DOCTYPE, lang, charset and viewport are in place.
  • There is one h1 on the page and the headings are in order.
  • Every meaningful image has a clear alt.
  • Styles are in a separate style.css file and use class selectors.
  • File names are in lower case and the paths are correct.
  • No horizontal scrolling appears on a phone.
  • All links work and the page opens online.

HTML and CSS are the alphabet of web development. Let this page be your first project: add one new thing to it every week and watch your knowledge grow. Our article on getting started with programming will help you choose your next step.

If you would like to learn web development systematically with a teacher, take a look at our association’s free programming track and other training programmes. When you are ready, submit an application and our specialists will get in touch.

Back to articles

More articles

14 min read

Using AI tools responsibly at work

What AI chat assistants are good for at work, how to write a good prompt, how to check the output and which data never to type in.

15 min read

Algorithmic thinking: the step before coding

Breaking problems down, patterns and abstraction, conditions and loops, pseudocode and flowcharts, simple tasks and tracing by hand, plus practical exercises.

Start learning today

Enrollment is open. Leave an application — our specialists will contact you and help you choose the right field.

Message us on Telegram