← Front-End Developer — all chapters  ·  Kelick Tech Hub

Chapter 1 — The Web, Browsers and Your First Page

Section 1 — What a front-end developer does

A front-end developer builds the part of a website that people see and touch. That includes the layout of the page, the words on it, the buttons, the menus, the forms, the pictures, and the way the page responds when someone clicks, types, scrolls, or resizes the window. If a user can see it, read it, or interact with it directly, a front-end developer probably built it, or at least shaped how it behaves. This is different from back-end development, which deals with databases, servers, and business logic that usually run out of sight. The two sides work together: the back end may supply a list of products, but the front end decides how that list is presented, filtered, and searched on screen.

The job is much broader than making things pretty. A front-end developer has to think about clarity first. Can a visitor understand, within a few seconds, what this page is for and what to do next? Is the most important action easy to find? Does the text read well on a small phone screen as well as on a large monitor? Good front-end work answers those questions before it worries about decoration. A beautiful page that confuses people has failed at its main job, while a plain page that guides people smoothly has succeeded at the core of the work.

Front-end developers also care about how a page feels in use. Does a button give feedback when it is pressed? Does a form tell the user clearly what went wrong, instead of silently failing? Does the page stay usable when the network is slow, or when an image fails to load? These details are not cosmetic extras. They decide whether people trust a site enough to complete a purchase, submit an application, or return another day. Much of the craft is therefore about anticipating real human behaviour, including mistakes, impatience, distraction, and different levels of technical confidence.

Another large part of the role is translation. Designers provide mock-ups or design systems, product teams describe goals, and back-end developers provide data through interfaces. The front-end developer turns those inputs into working code that runs in real browsers, on real devices, with real constraints. That means checking that a design still works when a heading is longer than expected, when a user zooms the text larger, or when content arrives in another language. It also means testing in more than one browser, because browsers do not always behave identically.

Finally, the role keeps changing, which is part of its appeal. New browser features, devices, and tools appear regularly, but the fundamentals stay stable: structure, presentation, behaviour, accessibility, and performance. A front-end developer who understands those fundamentals can learn new tools without starting again. If you enjoy building things people actually use, solving visible problems, and getting immediate feedback when your code works, this is a rewarding field to enter.

Check: In one sentence, what does a front-end developer build?

Section 2 — The three languages of the front end

The front end is built from three core languages, and each one has a distinct job. HTML gives a page its structure, CSS gives it its look, and JavaScript gives it its behaviour. A useful way to remember this is the skeleton, clothing, and movement analogy. HTML is the skeleton: it defines the bones of the page, such as headings, paragraphs, lists, links, and images. CSS is the clothing: it decides colours, fonts, spacing, and layout. JavaScript is the movement: it lets the page respond, change, and interact after it has loaded. When these three are kept in their proper roles, a page is easier to read, fix, and extend.

HTML comes first because without structure there is nothing to style or interact with. It describes meaning, not appearance. A heading element says "this is a heading," a paragraph element says "this is a paragraph," and a navigation element says "this is navigation." That meaning matters for more than neatness. Search engines use it to understand content, screen readers use it to help blind users navigate, and browsers use it to build the document model that JavaScript later manipulates. If you mark up a heading as a paragraph and then make it big with CSS, it may look like a heading, but it will not behave like one for assistive technology.

CSS comes second because it controls presentation without changing the underlying meaning. A single stylesheet can restyle an entire site, changing fonts and colours everywhere at once. That separation is powerful. It means a designer can update the look of a site without rewriting every page, and it means the same HTML can be presented differently on a phone, a tablet, and a printed page. CSS also handles layout: where elements sit, how they wrap, and how space is distributed. Learning CSS well is often what separates a page that merely works from one that feels polished and professional.

JavaScript comes third because it adds behaviour. It can respond to a click, validate a form before it is sent, show or hide content, fetch new data without reloading the page, and update the display in real time. Unlike HTML and CSS, JavaScript is a full programming language, with variables, conditions, loops, and functions. That power brings responsibility: badly written JavaScript can slow a page, break it entirely, or make it inaccessible. Used well, however, it turns a static document into an application.

Beginners sometimes ask which language to learn first. The answer is in this order: HTML, then CSS, then JavaScript. Each layer builds on the previous one, and you will understand JavaScript far better once you can read the document it manipulates. Keep the layers separate in your projects too. Avoid styling everything inline in HTML, and avoid putting large amounts of behaviour directly into HTML attributes. Separation keeps each language doing what it does best.

Check: Which language handles structure, which handles look, and which handles behaviour?

Section 3 — What HTML actually is

HTML stands for HyperText Markup Language. The word "hypertext" refers to text that contains links to other text, which was the revolutionary idea behind the early web: documents did not have to be read in a straight line, because a reader could jump from one document to another by clicking a link. The word "markup" refers to the way HTML works: you write annotations, called tags, around your content to describe what each piece is. The word "language" here does not mean a programming language in the usual sense. HTML has no variables, loops, or logic of its own. It is a language for describing documents.

To see the difference, compare HTML with JavaScript. JavaScript can make decisions: if a user enters an age below eighteen, show one message; otherwise, show another. It can repeat actions, store values, and calculate results. HTML cannot do any of that. It simply declares structure: this is a heading, this is a paragraph, this is a list item, this is an image with a description. The browser reads those declarations and builds a document from them. That limitation is actually a strength. Because HTML is declarative and simple, it is easy to learn, easy to read, and forgiving when small mistakes occur.

An HTML document is made of elements, and most elements have an opening tag, some content, and a closing tag. For example, <p>This is a paragraph.</p> uses the paragraph element to declare that the text inside is one paragraph. The tags themselves are not shown to the visitor; they are instructions to the browser. Some elements, such as images and line breaks, do not wrap content in the same way and do not need a closing tag. Attributes, which you will meet in detail later, add extra information to an element, such as where a link points or what an image shows.

HTML also carries meaning, and meaning is more important than appearance. A screen reader does not care whether your heading is large and bold; it cares whether you used a heading element, because that tells it the text is a heading. A search engine similarly uses headings, lists, and links to understand the structure of a page. That is why you should always choose elements for what content is, not for how you want it to look. If you want a paragraph to look larger, change it with CSS. Do not misuse a heading element just to get bigger text.

Modern HTML is the living standard maintained through the WHATWG and implemented by browsers, and it is often called HTML5. You do not need to memorise every element before you start. Learn the common ones well — headings, paragraphs, links, images, lists, and the structural elements for headers, navigation, main content, and footers — and look up the rest as you need them. Reading HTML is a skill in itself: a well-written page reads almost like an outline of its own content.

Check: Why is HTML called a markup language rather than a programming language?

Section 4 — What CSS actually is

CSS stands for Cascading Style Sheets. A stylesheet is a collection of rules, and each rule says how certain HTML elements should look. A rule names a selector, which picks out the elements it applies to, and a declaration block, which lists properties and values, such as colour, font size, spacing, and layout. For example, a rule might say that all level-one headings should be dark blue and centred, or that paragraphs should use a particular font and line height. The browser applies those rules to the HTML document to produce the visual result you see.

The word "cascading" is important and deserves attention early, even though you will study it in depth later. It means that styles can come from several sources — the browser's own defaults, an external stylesheet, a style block in the page, and inline styles — and that when rules conflict, the browser follows a defined order to decide which one wins. It also means that some properties are inherited: if you set a font on the body element, paragraphs inside it will generally inherit that font unless a more specific rule overrides it. Understanding the cascade saves you from a common beginner frustration: writing a rule, seeing nothing change, and not knowing why another rule took precedence.

CSS controls far more than colours and fonts, though those are the obvious starting points. It controls spacing inside and around elements, borders, backgrounds, alignment, and the overall layout of the page: whether items sit side by side or stack vertically, how they wrap on narrow screens, and how much space sits between them. Modern CSS includes powerful layout systems such as Flexbox and Grid, which you will learn in later chapters. For now, the key idea is that CSS is the language of presentation, and presentation includes layout and spacing, not just decoration.

One of the greatest benefits of CSS is separation. Because styles live apart from content, you can change the look of an entire site by editing one file, rather than editing every page by hand. You can also adapt the same content to different contexts: a stylesheet for small screens, another for large screens, and another for printing. This separation also helps accessibility. A user who needs larger text or higher contrast can override your styles with their own, and the content still makes sense because its meaning lives in the HTML, not in the styling.

When writing CSS, aim for rules that are clear and reusable. Prefer classes that describe purpose, such as a class for warning messages, over rules that target every element of a type in a way you will later regret. Keep your stylesheet organised, group related rules together, and comment anything that is not obvious. CSS is easy to start and takes time to master, but its core idea never changes: selectors pick elements, declarations describe how they should look, and the cascade resolves conflicts.

Check: What does a CSS rule control?

Section 5 — What JavaScript actually is

JavaScript is a real programming language that runs in the browser. It was created to make web pages interactive, and it has since grown into one of the most widely used languages in the world, running on servers as well as in browsers. In the browser, its most important job is to work with the page after it has loaded: it can change text, show or hide elements, respond to clicks and key presses, check what a user typed, and fetch new data from a server without reloading the whole page. Without JavaScript, a page is essentially a static document. With it, a page can become an interactive application.

JavaScript works through the Document Object Model, or DOM, which is the browser's live representation of the page. When you write JavaScript that changes a heading's text, you are not editing the HTML file on the server; you are changing the DOM in the visitor's browser. That distinction matters. Reload the page, and the change disappears, because the browser rebuilds the DOM from the original HTML. This live, in-memory model is what makes interactivity possible: the page you see is not a fixed picture, but a structure your code can read and modify at any time.

As a programming language, JavaScript has all the usual building blocks. Variables store values, such as a user's name or a running total. Conditions let code take different paths depending on what is true. Loops repeat actions. Functions package reusable blocks of code that can be called whenever they are needed. You will learn each of these in this chapter and in later chapters, and you do not need to master them all before writing your first useful script. Even a few lines of JavaScript can make a page noticeably more responsive.

It is worth clearing up a common confusion: JavaScript is not Java. The names are similar for historical reasons, but they are different languages with different designs and uses. JavaScript is also not the only language that can run in the browser today — WebAssembly allows other languages to run compiled code in the browser — but JavaScript remains the standard language of the web, built into every browser, and the language every front-end developer needs to know.

Beginners sometimes overuse JavaScript, adding scripts where HTML or CSS would do the job more simply and more reliably. A good rule is to use the simplest tool that works: HTML for content, CSS for presentation and simple state changes such as hover effects, and JavaScript for genuine behaviour and interaction. When JavaScript fails or is disabled, a page built this way still shows its content and remains usable. That resilience is a hallmark of good front-end development, and it starts with understanding what JavaScript is for — and what it is not for.

Check: Name two things JavaScript can do after a page loads.

Section 6 — The browser is your workshop

A browser is a program that reads HTML, CSS, and JavaScript and turns them into a page you can see and use. Chrome, Firefox, Edge, and Safari are all browsers, and each one contains a rendering engine that interprets your code and paints the result on screen, plus a JavaScript engine that runs your scripts. When you open a page, the browser fetches the files, parses the HTML into a document model, applies the CSS, runs the JavaScript, and draws the final result. You already have the main tool you need to start learning front-end development, because a browser is free and almost certainly already installed on your device.

Think of the browser as your workshop rather than just a viewer. It does not only display finished pages; it gives you tools to inspect and experiment with them. Every major browser includes developer tools, usually opened with F12 or by right-clicking and choosing Inspect. Those tools let you see the live document structure, examine which CSS rules apply to an element, run JavaScript in the Console, and watch network requests as they happen. Learning to use developer tools early will save you hours of guessing later, because most front-end problems become obvious once you can see what the browser actually received and what it actually built.

Browsers are not all identical, and that is an important professional reality. They may render a page slightly differently, support new features at different times, or handle edge cases in their own way. Most modern browsers follow web standards closely, so differences are smaller than they once were, but they have not disappeared. A responsible developer therefore tests in more than one browser and on more than one device, rather than assuming that what works in one browser works everywhere. The standards themselves are developed in the open by organisations such as the World Wide Web Consortium and the WHATWG, and browsers aim to implement them consistently.

The browser also enforces important safety rules. For example, a page from one website is generally not allowed to read data from another website without permission, a rule known as the same-origin policy. The browser manages cookies, storage, and permissions for location, camera, and notifications, and it warns users about insecure connections. Understanding that the browser is a gatekeeper, not just a display, helps you understand why some things that seem simple — such as loading data from another site — require the cooperation of both sites.

Finally, remember that the browser is where your users actually experience your work. Your code editor may show you source files, and your design tool may show you a mock-up, but neither is the final product. The browser is. Get comfortable opening it, breaking things in it, inspecting them, and fixing them. That cycle — write, view, inspect, adjust — is the daily rhythm of front-end development, and the browser is where it happens.

Check: What job does a browser do with your code?

Section 7 — A page is a document

Think of a web page as a document, not a picture. That distinction shapes almost every good decision in front-end development. A picture of text looks like text, but the browser cannot select it, search engines cannot index it reliably, and screen readers cannot read it aloud. Real text in HTML can do all of those things. A visitor can copy a paragraph, use the browser's find function to locate a word, translate the page, or increase the text size without it turning blurry. When you treat a page as a document, you preserve all of those abilities.

This is why headings should be real text marked up with heading elements, not words baked into an image. A screen reader user navigates a page by its headings, jumping from section to section in the same way a sighted user scans a page visually. If your headings are inside images, that navigation disappears, and the page becomes a wall of inaccessible content. The same principle applies to buttons, navigation menus, and form labels. Whenever something is meant to be read, clicked, or filled in, it should be real HTML, not a picture of the thing.

The document idea also explains why structure matters. A well-structured document has a title, headings in order, paragraphs, lists, and sections that follow a logical outline. That outline helps everyone, not only users of assistive technology. Search engines use it to understand what a page is about. Browsers use it to offer features such as reader mode. Developers use it to navigate and maintain code. A page whose HTML reads like a clear outline is easier to style, easier to debug, and easier to extend than one whose HTML is a tangle of generic containers with no meaning.

Images still have a role, but it is a supporting one. Photographs, illustrations, diagrams, and charts add value that text alone cannot provide. The rule is simple: use images for visual content, and use text for textual content. When an image does contain important information, describe it with alt text so that people who cannot see the image still receive the information. When a diagram is complex, provide the same information in text nearby as well. Accessibility and good design point in the same direction here.

Finally, thinking of a page as a document helps you make better decisions about content itself. Documents are meant to be read, searched, printed, and revisited. Write headings that describe what follows, keep paragraphs focused, and use lists for sets of items. A page built this way will age better than one built as a collection of visual tricks, because its content remains accessible and meaningful even as designs and tools change.

Check: Why should headings be real text, not part of an image?

Section 8 — The internet in one paragraph

The internet is a network of computers connected together, spanning homes, offices, data centres, and undersea cables around the world. At its simplest, the story of the web goes like this: your browser asks another computer, called a server, for a page, and the server sends the files back over the network, and your browser turns those files into the page you see. That short story hides a great deal of machinery, but it is worth understanding the machinery at least in outline, because it explains many things you will encounter as a developer, from slow pages to error messages.

Before your browser can ask for anything, it needs to find the server. It does this using the domain name in the address you typed, such as example.com. A system called DNS, the Domain Name System, translates that human-readable name into a numeric IP address that computers use to locate each other on the network, much like a phone book translates a name into a number. Your request then travels across the network, often through several intermediate computers and routers, each forwarding it closer to its destination. The internet is packet-switched, meaning your request and the response are broken into small packets that travel independently and are reassembled at the other end.

The web itself is one service that runs on top of the internet, not the same thing as the internet. Email, video calls, file transfers, and many other services also use the internet, but they follow different rules. The web uses HTTP and HTTPS, the protocols you will study shortly, and it is built around documents linked to each other. That linking is what makes it a web rather than a collection of isolated files: every page can point to others, and following a link is simply asking a server for another document.

For a front-end developer, the practical lesson is that your page does not live on the visitor's computer until it is requested and delivered. Its speed depends on the size of its files, the distance to the server, and the quality of the visitor's connection. A page that loads instantly on your fast office connection may crawl on a slow mobile connection. That is why performance matters, and why you will learn to keep files reasonably small, to avoid unnecessary requests, and to test under realistic conditions rather than only on your own machine.

It also helps to understand that the internet is decentralised. No single computer controls it, and your site can be hosted anywhere in the world and still be reachable from anywhere else, provided the network path exists and the server is running. That openness is what makes the web a powerful publishing platform — and also why security, privacy, and reliability are responsibilities you will need to take seriously as you build for it.

Check: When you open a site, which computer sends the files to you?

Section 9 — What a server does

A server is a computer whose job is to store website files and hand them out when asked. It does not need a screen, a keyboard, or a mouse — in fact, most servers run in data centres without any of those, managed remotely. What makes a computer a server is not its shape but its role: it waits for requests from browsers and other clients, and it responds to them. When you type an address and press Enter, your browser sends a request, and a server somewhere answers it by sending back the files for that page, such as HTML, CSS, JavaScript, and images.

Servers come in different kinds, and the distinction matters as your projects grow. A static file server simply hands out files exactly as they are stored. If you ask for index.html, you get that file, unchanged. A dynamic server, by contrast, builds a response on the fly: it might fetch data from a database, assemble a page for the specific user who asked, and send back HTML that did not exist as a single file beforehand. Many real sites combine both approaches, serving static assets such as stylesheets and images directly, while generating personalised content dynamically. As a front-end developer, you will mostly work with what the server sends you, but understanding this distinction helps you debug problems and communicate with back-end developers.

A server also does more than hand out files. It decides which requests to accept and which to refuse, based on rules and authentication. It may require a login before serving private content, limit how often a single visitor can ask for things, or redirect an old address to a new one. When something goes wrong, the server communicates through status codes: 404 means the requested resource was not found, 500 means something went wrong on the server's side, and 200 means the request succeeded. You will recognise these numbers often, and knowing what they mean turns a confusing error page into a useful clue.

Reliability is a central concern for servers. A personal computer that serves a site from a bedroom may work, but if it is switched off, loses power, or loses its connection, the site disappears. Professional hosting therefore uses data centres with backup power, redundant connections, and monitoring, so that servers stay available around the clock. Servers are also typically more powerful than ordinary desktops, with faster storage and network connections, because they may serve thousands of visitors at once.

For your early learning, you do not need a server at all. You can open an HTML file directly from your own computer and the browser will render it. That is how this chapter begins. Later, when you want others to see your work, you will put your files on a server or a hosting service, and the same files you tested locally will be served to the world. The server's job, in the end, is simple to state and demanding to do well: be there, be fast, and give the right files to the right requesters.

Check: What is a server's main job?

Section 10 — What a URL means

A URL, or Uniform Resource Locator, is an address for something on the web. In https://example.com/about, each part has a meaning, and learning to read a URL is a basic literacy skill for a developer. The first part, "https", is the scheme or protocol: it tells the browser how to communicate with the server. The next part, "example.com", is the domain, which names the server or site you want. The final part, "/about", is the path, which names a particular page or resource on that site. Put together, the URL says: use HTTPS to ask the server at example.com for the resource at /about.

URLs can carry more than those three parts. After the domain, there may be a port number, such as :8080, which specifies a particular doorway on the server; browsers use default ports for HTTP and HTTPS, so you rarely see them in everyday addresses. After the path, there may be a query string, beginning with a question mark, which passes extra information to the server, such as a search term: ?q=books. After that, there may be a fragment, beginning with a hash, such as #chapter-2, which points to a particular part of the page and is handled by the browser rather than sent to the server. Understanding these parts helps you read links, debug problems, and build pages that link correctly.

The domain itself has structure. Reading from right to left, the top-level domain, such as .com or .org, comes last, followed by the registered name, such as example. A subdomain, such as www or blog, may appear before that, naming a particular section or service: blog.example.com is a different host from www.example.com, even though both belong to the same domain. Domains must be unique, which is why registering a domain name involves checking availability and paying a registrar. For learning, you can use example.com, a domain reserved specifically for documentation, so that examples never point to a real site by accident.

Paths work like folders on a computer. The path /about might correspond to a file called about.html, or to a folder containing an index file, depending on how the server is set up. A trailing slash can matter: /about/ and /about may be treated differently by some servers. Paths are case-sensitive on many servers, so /About and /about may be different resources, a common source of broken links when files are moved between systems that handle case differently. Keep your file names lowercase, simple, and consistent, and your paths will cause you far fewer problems.

Finally, treat URLs as part of your user interface. A clear, readable URL such as /guides/beginner-html is more trustworthy and more shareable than a cryptic string of numbers. Users copy URLs, bookmark them, and judge them for safety. As a developer, you will create links, organise files so that paths make sense, and fix broken links when they appear. Reading a URL fluently is the first step in all of that work.

Check: In a URL, what is the domain and what is the path?

Section 11 — HTTP and HTTPS

HTTP, the HyperText Transfer Protocol, is the protocol browsers and servers use to talk to each other on the web. A protocol is simply an agreed set of rules for a conversation: what kinds of messages can be sent, what they mean, and what responses are expected. When you visit a page, your browser sends an HTTP request, typically asking for a resource, and the server sends back an HTTP response containing that resource plus a status code and headers that describe it. This request-and-response pattern underlies almost everything you do on the web, from loading a page to submitting a form or fetching data for an interactive feature.

An HTTP request includes a method, which says what kind of action is being requested. The most common method is GET, used when asking to retrieve a resource, such as a page or an image. Another common method is POST, used when sending data to the server, such as the contents of a form. The response includes a status code, a three-digit number that summarises the outcome: codes in the 200s mean success, 300s mean redirection, 400s mean a client error such as a missing page, and 500s mean a server error. Headers in both requests and responses carry extra information, such as the type of content being sent or instructions about caching.

HTTPS is the same protocol with encryption added, and the S stands for Secure. With plain HTTP, the conversation between browser and server travels in a form that anyone positioned in the middle — for example, on the same public Wi-Fi network — could potentially read or alter. With HTTPS, the conversation is encrypted using TLS, Transport Layer Security, so that even if someone intercepts the traffic, they cannot easily read it. Encryption also provides authentication: a certificate, issued by a trusted authority, helps the browser verify that it is really talking to the site named in the address, not an impostor.

Modern browsers make the difference visible. A site served over HTTPS typically shows a padlock icon in the address bar, while a site served over plain HTTP may be labelled "Not Secure," especially if it contains a form. Search engines also prefer secure sites. For these reasons, the rule is simple: prefer HTTPS always, for every site, even if it seems to contain nothing sensitive. A page that looks harmless can still be tampered with in transit over HTTP, for example by injecting unwanted content, and visitors have no way to tell the difference without encryption.

For a beginner, the practical steps are straightforward. When you eventually host a site, choose a host that provides HTTPS by default — many do, often free of charge through automated certificate providers. When you link to other sites, use https addresses. When you test locally by opening a file directly, you are not using HTTP at all, which is fine for early learning, but remember that real deployment means HTTPS. The protocol may seem like background detail now, but it is the reason your visitors can trust that the page they receive is the page you sent.

Check: What does the S in HTTPS add?

Section 12 — Your first HTML file

Create a file called index.html and write a complete, minimal page in it. A good first version looks like this:

<!DOCTYPE html>
<html>
<head>
  <title>My Page</title>
</head>
<body>
  <h1>Hello</h1>
</body>
</html>

Save the file, then open it in a browser, either by double-clicking it or by using your browser's Open File command. You should see the word "Hello" displayed as a large heading, and the browser tab should show "My Page." If you see that, you have made a web page. It is simple, but it is real: the same structure underlies every page on the web, however large or complex it later becomes.

The file name matters. Browsers and servers look for index.html first when they are given a folder rather than a specific file. That is why the main page of a site is almost always called index.html: when a visitor asks for the site's root address, the server serves that file automatically, without the visitor needing to type its name. Keep the name exactly as shown, all lowercase, with no spaces. A file called Index.html or index.HTML may work on your own computer but fail on a server that treats file names as case-sensitive, so build the lowercase habit from day one.

Use a proper code editor for this work rather than a word processor. A word processor adds hidden formatting that will corrupt your code. A code editor, such as Visual Studio Code or any plain-text editor, saves exactly what you type. Create a folder for your project first, save index.html inside it, and keep all related files in that same folder or in subfolders you create deliberately. That tidy habit pays off immediately: when you add a stylesheet or an image later, you will know exactly where it belongs and how to refer to it.

When you open the file, notice what the browser does with each part. The doctype tells it this is a modern HTML document. The head contains the title, which appears in the tab but not on the page itself. The body contains the visible heading. If something does not look right, check the basics first: is the file saved, does it end in .html, are all tags closed, and did you open the saved copy rather than an older one? Most first-page problems are one of those four things, and learning to check them calmly is itself a developer skill.

From here, every new idea in this chapter can be tried in this same file. Add a paragraph, add a link, change the heading text, save, and refresh the browser. That short loop — edit, save, refresh, observe — is how front-end development is learned. Do not worry about making your first page impressive. Worry about making it, understanding each line, and changing one thing at a time so you can see what each change does.

Check: What file name do browsers look for first in a folder?

Section 13 — The doctype line

The first line of a modern HTML document is <!DOCTYPE html>. It tells the browser that this is a modern HTML document, so it should render the page in standards mode instead of falling back to an old quirks mode. Standards mode means the browser follows current web standards for layout and rendering, which is what you want: your page will behave predictably and consistently with other modern pages. Quirks mode, by contrast, is a compatibility mode in which browsers imitate the buggy behaviour of very old browsers, and it can make layout behave in surprising ways, particularly around element sizing and spacing.

The doctype is not an HTML tag in the usual sense. It has no closing tag, it contains no content, and you do not put anything inside it. It simply sits at the very top of the file, before the html element, as a declaration to the browser. It is also not case-sensitive in practice, but writing it exactly as <!DOCTYPE html> is the universal convention, and conventions matter when other developers read your code. Its simplicity is deceptive: this single line prevents a whole class of layout mysteries that once plagued developers.

What happens if the doctype is missing? The browser does not refuse to show the page. Instead, it guesses, and it usually guesses quirks mode for a document without a doctype. Your page may still look roughly right at first glance, which makes the problem insidious: everything seems fine until you try a layout technique that behaves differently in quirks mode, and then you spend a long time debugging CSS that was never the problem. The fix is trivial — add the line — but finding the cause is not, which is why every template and every example in this book starts with it.

It is worth knowing a little history here, because it explains why such a strange-looking line exists. Early HTML had several versions, each with a long, complicated doctype that named a specific document type definition. HTML5 simplified all of that to this one short declaration. You do not need to learn the old forms, and you should not copy them from old tutorials. The modern doctype is deliberately minimal: it says, in effect, "this is HTML, render it by today's rules."

Make it a habit to check for the doctype whenever you start a file or copy an example. If you use an editor that generates a starter template, it will include the doctype automatically, and you should leave it there. If you ever open a page that behaves oddly in ways you cannot explain, checking whether the doctype is present and is the first line of the file is a quick, worthwhile step. One line, at the top, every time — that is the whole rule, and it protects everything that follows.

Check: What happens if the doctype line is missing?

Section 14 — The html element

Everything on the page goes inside one <html> element. It is the root of the document, and every other element lives inside it, either directly or nested within another element. Think of it as the container for the entire document: the head and the body are its two children, and everything else descends from one of those two. When the browser parses your HTML, it builds a tree, and the html element is the top of that tree. JavaScript refers to it as the document element, and CSS can target it when you need a rule that applies to the whole page.

A typical opening looks like <html lang="en">. The lang attribute is worth adding from the start, even though this chapter does not dwell on attributes. It tells the browser, search engines, and screen readers which language the page is written in, so that screen readers pronounce the text correctly and translation tools behave sensibly. Change the value to match your page's language — for example, "fr" for French — if you write in another language. It is a small detail that signals care and professionalism, and it costs nothing to include.

Because the html element contains everything, mistakes involving it tend to be structural. Content placed outside the html element, or a missing closing </html> tag, can confuse the browser's parser. Browsers are forgiving and will often repair such mistakes silently, which is both a blessing and a curse: your page may look fine while its underlying structure is not what you intended. Using an editor with tag matching, and validating your HTML occasionally with a checker, helps you catch these issues before they become habits.

The html element also plays a role in styling. Rules applied to html, such as setting a base font size or a background, affect the document as a whole, and some properties set on html are inherited by the body and everything inside it. You will rarely style html heavily in a beginner project — most of your styling will target the body and the elements within it — but understanding that html is the ancestor of everything explains why certain inherited styles seem to spread across the whole page.

In short, the html element is the frame around your entire document. It does not produce visible content by itself, but it gives the document its root, its language, and its overall structure. Every page you write will have exactly one of them, wrapping the head and the body, and keeping that structure clean is the foundation on which everything else in this book is built. When you validate a page or inspect its tree, start at this root and work downwards: if the root is correct, the branches are far easier to check, and if it is wrong, every later diagnosis will be confused until it is fixed.

Check: What is the root element of an HTML document?

Section 15 — Head versus body

An HTML document is divided into two main parts: the head and the body, both nested inside the html element. The head holds information about the page that visitors do not see directly, while the body holds everything visitors do see and interact with. Understanding this division is essential, because placing content in the wrong part is one of the most common beginner mistakes, and it produces confusing results: content that should be visible does not appear, or metadata ends up displayed in unexpected ways.

The head contains metadata and resources. The most familiar item is the title element, which sets the text shown in the browser tab and used as the page's name in bookmarks and search results. The head also commonly contains a character encoding declaration, which tells the browser how to interpret the text in the file, links to external stylesheets, and meta elements that describe the page for search engines and social media. It may also contain a script element for JavaScript that needs to load early, though scripts are often placed at the end of the body instead, for reasons you will learn later. None of this appears as content on the page itself, but all of it affects how the page is displayed, found, and shared.

The body, by contrast, is the page. Every heading, paragraph, image, link, list, form, and button belongs in the body. When a visitor scrolls, reads, clicks, or types, they are interacting with the body. If you accidentally put a heading in the head, the browser may still display it — browsers are forgiving — but it will not be in the right place in the document structure, and it may behave unpredictably. The rule is simple and absolute: visible content goes in the body, always.

A useful mental model is to think of the head as the cover and cataloguing information of a book, and the body as the book's actual text. The cover tells you the title and the author, but you do not read the story on the cover. Similarly, the head tells the browser about the page, while the body is the page. Keeping that distinction clear helps you organise your code: when you need to change what a page says, you look in the body; when you need to change its title, its stylesheet, or its description, you look in the head.

As your pages grow, both parts will grow too. The head will accumulate links to stylesheets and scripts and meta information. The body will accumulate sections, articles, navigation, and footers. The division remains the same no matter how large the page becomes, and it is the first structural decision the browser makes when it reads your document. Get it right from the start, and the rest of your HTML will fall into place more easily.

Check: Where does a visible heading belong — head or body?

Section 16 — Tags, elements and attributes

Three words are used constantly in HTML, and beginners often mix them up: tag, element, and attribute. Getting them straight early will make every later explanation easier to follow, because tutorials, documentation, and error messages all use these terms precisely. A tag is the marker written in angle brackets, such as <p> or </p>. An element is the whole thing: the opening tag, the content, and the closing tag together. An attribute adds extra information to an element's opening tag, written as a name and a value.

Consider a paragraph: <p>This is a paragraph.</p>. The opening tag is <p>, the closing tag is </p> — note the forward slash — and the content is "This is a paragraph." The element is all three parts combined. If you say "the p tag," you technically mean just the marker; if you say "the p element," you mean the complete paragraph, content included. In casual conversation people blur this distinction, and usually no harm is done, but when you are debugging or reading documentation, precision helps. An error that says an element is unclosed means you are missing a closing tag somewhere, not that a tag itself is broken.

Attributes live inside the opening tag, after the element name, and they provide information that the content alone does not carry. In a link, for example, <a href="https://example.com">Visit</a>, the href attribute says where the link goes, while the content, "Visit," is the text the visitor clicks. In an image, the src attribute says which file to display, and the alt attribute provides a text description. Attributes are written as name="value", with the value in double quotes by convention. Some attributes, such as disabled on a button, do not need a value at all; their mere presence switches something on.

A few practical rules will save you trouble. Always close elements that require a closing tag, and nest them properly: if you open a strong element inside a paragraph, close it before you close the paragraph, like nesting boxes inside each other rather than crossing them over. Use double quotes for attribute values consistently, even when a value is a single word, because values often contain characters that would break without quotes. Use lowercase for element and attribute names, which is the universal convention in HTML. And remember that some elements, known as void elements, such as img, br, and hr, do not have closing tags or content; they stand alone.

Once these three terms are clear, HTML becomes much easier to read. You will look at a page's source and see it as a collection of elements, each marked by tags and qualified by attributes, nested into a tree. That tree is exactly what the browser builds, and it is what CSS styles and JavaScript manipulates. Tags, elements, and attributes are not just vocabulary — they are the anatomy of every page you will ever build.

Check: What is the difference between a tag and an element?

Section 17 — Headings have levels

HTML has six heading levels, from <h1> to <h6>. They form an outline of your page, much like the headings in a book or a report. Use one <h1> for the page's main title, then <h2> for its major sections, <h3> for sub-sections within those, and so on, in order, without skipping levels. This hierarchy is about structure and meaning, not about size. Browsers do display higher-level headings larger by default, but that default styling is incidental; the level's real job is to say where the heading sits in the document's outline.

Why does the order matter? First, for accessibility. Screen reader users often navigate a page by jumping between headings, building a mental map of its contents before reading in detail. If your headings jump from an h1 straight to an h4, or if you use headings out of order, that map becomes confusing, and a section that should appear as a sub-section appears as something else entirely. Second, for search engines, which use heading structure as one signal of what a page is about and how its topics relate. Third, for your own maintenance: a page with a clean heading outline is easier to skim, edit, and restyle than one whose headings were chosen for appearance.

The rule "never pick a level just because you like its size" deserves emphasis, because it is one of the most common beginner mistakes. Suppose you want a small heading. Reaching for an h4 because it renders smaller may look right, but it tells every tool that reads your page that this is a fourth-level heading, subordinate to sections that may not exist. The correct approach is to use the heading level that reflects the content's place in the outline, and then use CSS to adjust its size. CSS exists precisely so that appearance can be controlled independently of meaning.

In practice, most pages need only h1, h2, and h3. Deeper levels are available for complex documents, such as long guides or documentation, but if you find yourself regularly needing h5 and h6, your page may be trying to do too much, or your outline may need reorganising. A single h1 per page is the standard convention; it gives the page one clear main title, which helps both readers and search engines. Exceptions exist, such as when a page contains several independent articles, but as a beginner, one h1 is a safe and correct rule.

To practise, take any page you write and read its headings alone, ignoring everything else. Do they form a sensible table of contents? Would a stranger understand the page's structure from them? If the answer is yes, your heading levels are doing their job. If not, rearrange them before you worry about fonts or colours. Structure first, styling second — that order will serve you throughout front-end development.

Check: Why should you not use an h4 just because it looks smaller?

Section 18 — Paragraphs and line breaks

The paragraph element, <p>, marks a paragraph of text: a coherent block of writing about one idea. Browsers add space around paragraphs automatically, separating one block from the next so that text does not run together into an unreadable wall. That automatic spacing is part of the browser's default stylesheet, and you can adjust it with CSS later, but the principle is already in place: paragraphs are the basic unit of prose on the web, and using them correctly makes your content readable with no extra effort.

The line break element, <br>, is a different tool. It forces a line break at a specific point, without starting a new paragraph. Because it is a void element, it has no closing tag and no content; you simply write <br> where you want the break. Legitimate uses exist: the lines of a poem, the lines of an address, or the lines of a song lyric are genuinely single units broken across lines, and a line break expresses that structure. In those cases, the break is part of the content's meaning, not just a visual trick.

The mistake to avoid is using line breaks to fake paragraphs or to create spacing. Writing a block of text, adding two or three <br> elements, and then writing another block may look like two paragraphs, but it is not. To a screen reader, to a search engine, and to your own CSS, it is one paragraph with arbitrary breaks inside it. That matters because you cannot style those fake paragraphs independently, you cannot navigate them as separate blocks, and if you later change the design, you will have to hunt through your content removing breaks by hand instead of adjusting one CSS rule. The same warning applies to using breaks to push content down the page: that is spacing, and spacing is CSS's job, through margins and padding.

A related point is that HTML normally collapses whitespace. Pressing Enter in your source code, or typing several spaces in a row, does not create visible line breaks or extra spaces in the rendered page. That is why the paragraph and line break elements exist: they are the explicit, meaningful ways to control text structure, rather than relying on how your source file happens to be laid out. If you want a new paragraph, write a new <p> element. If you want a line break within a paragraph for a genuine reason, use <br>. If you want more space between paragraphs, adjust the margin with CSS.

Good paragraph writing matters too, not just the markup. Keep paragraphs focused on one idea, and break long passages into shorter ones. Web readers scan more than they read word by word, and a page of short, well-separated paragraphs is far more inviting than a dense block. The paragraph element gives you the tool; clear writing gives you the result.

Check: When is a line break the wrong tool for spacing?

Section 19 — Links

Links are what make the web a web. A link, created with the anchor element <a>, connects one document to another, allowing a reader to jump from your page to a different page, a different site, a file, or even a specific part of the same page. The basic form is <a href="https://example.com">Visit</a>. The href attribute — short for hypertext reference — says where the link goes, and the text between the opening and closing tags is what the visitor sees and clicks. Without href, an anchor is not a link at all; it is just a placeholder, so href is the attribute that gives the element its purpose.

The destination of a link can take several forms. An absolute URL, with the full address including https, points to a specific site anywhere on the web. A relative link, such as about.html, points to a page on the same site, relative to the current page's location; you will study relative links in detail later in this chapter. A link can also point to a fragment within a page, using a hash and an id, such as #contact, which scrolls the browser to the element with that id. It can point to an email address using mailto:, or to a file for download. Understanding these forms lets you build navigation, references, and calls to action with the right tool each time.

The visible text of a link, often called the link text, deserves as much care as its destination. Link text should describe where the link goes, in a way that makes sense even out of context. "Read our guide to HTML" is good link text. "Click here" is poor link text, because a screen reader user who lists all the links on a page will hear "click here, click here, click here" with no idea where any of them lead, and a sighted user scanning quickly gains nothing either. Search engines also use link text to understand the linked page, so descriptive text helps there too. Make the text concise but informative, and make sure the whole phrase, not just one word, is the link.

A few behaviours are worth knowing. By default, a link to another site opens in the same tab, replacing your page; you can change this with the target attribute, but opening new tabs should be used sparingly, because it takes control away from the user, who can already choose to open a link in a new tab themselves. Links are styled by default — blue and underlined — and browsers change their colour once visited, which helps users keep track of where they have been. You can restyle links with CSS, but keep them recognisable as links: if a visitor cannot tell what is clickable, your navigation has failed, however elegant it looks.

Finally, test your links. Click every link on a page you build, and check that it goes where you intended. Broken links frustrate visitors and damage trust, and they are easy to create by mistyping a file name or moving a file without updating its references. A link is a promise to the reader that something useful waits at the other end. Keep that promise.

Check: What does the href attribute do?

Section 20 — Images

Images are added to a page with the <img> element, for example <img src="photo.jpg" alt="A description">. The src attribute, short for source, tells the browser which image file to fetch and display. The alt attribute provides alternative text: a description of the image for people who cannot see it, and for situations where the image fails to load. Because img is a void element, it has no closing tag and no content; all of its information lives in its attributes. That makes choosing those attributes well especially important, because there is nowhere else to put the information.

Alt text is not a formality. Screen reader users rely on it to understand images that carry meaning. If a page shows a chart, a product photo, or a diagram, and the alt text is missing or vague, that information is simply lost to those users. Search engines also use alt text to understand images, since they cannot see a picture in the human sense. And when an image fails to load — because of a slow connection, a broken file reference, or a user choice to block images — the alt text appears in its place, so the page still communicates. Never leave alt empty on a meaningful image, and never write alt text that merely repeats nearby text or says "image of" — describe what matters about the image.

There is one legitimate case for empty alt text: a purely decorative image, one that adds visual flavour but no information. In that case, writing alt="" tells assistive technology to skip the image entirely, which is the correct behaviour. The judgement call is yours as the author: if removing the image would lose information, it is meaningful and needs descriptive alt text; if removing it would change nothing about the message, it is decorative and empty alt is right. When in doubt, describe it — an unnecessary description is a minor annoyance, while a missing one can be a real barrier.

Beyond alt text, several practical points matter. Use image files that are appropriately sized: a huge photograph scaled down by CSS still downloads at full size and slows your page. Choose a suitable format — JPEG for photographs, PNG for graphics with sharp edges or transparency, and modern formats such as WebP where supported — and give files clear, lowercase names without spaces. Always check that the src path is correct relative to your HTML file, because a broken image path is one of the most common beginner errors, and the browser will show a broken-image icon and your alt text in its place.

Images enrich a page enormously, but they should support the content, not replace it. Text that is part of an image cannot be searched, selected, translated, or read aloud, as you learned earlier. Keep important words as real text, use images for what images do best, and describe them well. That combination is what makes a page both beautiful and accessible.

Check: Who benefits from good alt text?

Section 21 — Lists

Lists are one of the most useful structures in HTML, because so much content is naturally a set of items: ingredients, steps, features, navigation links, or questions. HTML provides two main list types. An unordered list, <ul>, is a bulleted list, used when the order of the items does not matter. An ordered list, <ol>, is a numbered list, used when the order does matter, such as steps in a set of instructions. In both cases, each item goes inside an <li> element, short for list item. The structure is always the same: a ul or ol element containing li elements, one per item.

The choice between ul and ol is about meaning, not appearance. If you are listing the features of a product, the order is arbitrary, so use ul; the bullets signal that no item outranks another. If you are listing the steps to assemble something, the order is essential, so use ol; the numbers signal that step two follows step one, and the browser numbers the items automatically. That automatic numbering is a practical benefit: if you insert a new step in the middle, the browser renumbers everything for you, whereas a hand-typed list of numbers would need manual correction and would quickly become wrong. You can also change the numbering style with CSS or with attributes, but the underlying meaning — this is an ordered sequence — stays in the HTML.

Lists can be nested. A list item can itself contain another list, which is how you represent sub-items, such as a category with examples beneath it. When nesting, keep the structure clean: the inner list goes inside an li of the outer list, not directly inside the outer ul or ol. Browsers are forgiving of sloppy nesting, but assistive technology is less so, and a screen reader user navigating a nested list relies on the structure being correct to understand which items belong together.

Lists are also the correct markup for navigation menus, even though a menu may not look like a list when styled. A set of navigation links is genuinely a set of items, so marking it up as a ul inside a nav element gives it a structure that screen readers can announce as a list with a certain number of items, and that CSS can then style horizontally, without bullets, or however the design requires. This is a good example of the principle that runs through this chapter: choose HTML for meaning, then use CSS for appearance. A navigation menu that is a styled list is accessible and flexible; a navigation menu built from divs and line breaks is neither.

Finally, use a list whenever the content is genuinely a set of items, and do not use one when it is not. A paragraph is not a list just because it mentions several things, and a list is not a substitute for paragraphs of prose. But when you catch yourself writing items separated by commas, dashes, or line breaks, stop and ask whether a list would express the content more clearly. Usually, it will, and your readers — human and machine alike — will thank you for it.

Check: Which list type numbers its items automatically?

Section 22 — Your first CSS rule

A CSS rule has two parts: a selector and a declaration block. A simple example is h1 { color: blue; }. The selector, here h1, picks out the elements the rule applies to — in this case, every level-one heading on the page. The declaration block, inside the curly braces, contains one or more declarations, each made of a property and a value separated by a colon and ending with a semicolon. Here, the property is color, which names what changes, and the value is blue, which says how it changes. Read the rule aloud as: "For every h1, set the colour to blue." That sentence is the whole idea of CSS in miniature.

Selectors can be much more specific than an element name. A class selector, written with a dot, such as .note, targets every element with that class. An ID selector, written with a hash, such as #main-title, targets the single element with that id. You can also combine selectors, target elements inside other elements, or target elements in a particular state, such as a link being hovered over. You will learn these in later chapters; for now, understand that the selector is the addressing system of CSS, and choosing the right selector is often the hardest part of writing a rule. A rule that targets too broadly will style things you did not intend, while a rule that targets too narrowly will need constant repetition.

Declarations follow a strict but simple syntax, and small errors in it are a common source of frustration. Every declaration needs a property name, a colon, a value, and a semicolon. Forgetting the semicolon between two declarations will cause the second to be ignored, and misspelling a property name — for example, writing colour instead of the CSS spelling color — will cause that declaration to be ignored silently. Browsers do not show error messages for invalid CSS in the way they do for JavaScript; they simply skip what they do not understand. That is why the developer tools' Styles panel is so valuable: it shows you which rules applied and which were ignored or overridden.

To write your first rule, add a style element to the head of your page, like this:

<style>
  h1 { color: blue; }
</style>

Save, refresh, and watch your heading turn blue. Then experiment: change the value to another colour, add a second declaration such as text-align: center;, and change the selector to target paragraphs instead. Each small experiment teaches you something about how rules work, and because CSS is forgiving, a mistake will not break your page — it will simply not apply, which is a safe way to learn.

One rule is a small thing, but it contains the entire model: select something, declare how it should look, and let the browser apply it. Every stylesheet, however large, is a collection of rules built on this pattern. Master the pattern, and the rest of CSS is a matter of learning more selectors and more properties.

Check: In h1 { color: blue; }, what is the selector?

Section 23 — Three ways to add CSS

CSS can reach a page in three ways, and choosing between them is one of the first architectural decisions you will make. The best method for real projects is an external stylesheet: a separate .css file linked from the page. A second method is an embedded stylesheet: a style block in the head of the page. A third method is inline styles: a style attribute written directly on an element. All three work, and all three are valid, but they are not equal, and understanding their trade-offs will save you from projects that become unmaintainable.

An external stylesheet is linked with a link element in the head, like this: <link rel="stylesheet" href="styles.css">. The browser fetches that file and applies its rules to the page. The great advantage is sharing: a single stylesheet can be linked from every page on a site, so changing one file changes the look of the whole site. External stylesheets are also cached by the browser, meaning that after the first page, later pages can reuse the downloaded file without fetching it again, which makes the site faster. They keep your HTML clean, because presentation lives in its own file, and they let several people work on content and styling without stepping on each other. For any project with more than one page, or any project you expect to maintain, this is the right choice.

An embedded stylesheet lives inside a style element in the head of a single page. Its rules apply only to that page. This is useful for quick experiments, for single-page projects, and for styles that genuinely belong to one page only. It is also how this book's early examples are often written, because it keeps everything in one file while you are learning. Its disadvantage is duplication: if you copy the same style block into ten pages and later want to change a colour, you must edit ten files, and you will inevitably miss one. Embedded styles are a stepping stone, not a destination, for multi-page sites.

Inline styles are written in a style attribute on an individual element, such as <p style="color: red;">. They apply to that element alone, and they override most other styles, which makes them tempting when you want a quick fix. Resist that temptation except in rare cases. Inline styles cannot be reused, cannot be cached separately, mix presentation into your HTML, and are difficult to override later precisely because they are so specific. They also make your HTML harder to read. A legitimate use is when a style is genuinely unique to one element and generated dynamically by JavaScript, but for ordinary styling, a class in an external stylesheet is almost always better.

In practice, you will use external stylesheets for real work, embedded styles for learning and for page-specific exceptions, and inline styles rarely and deliberately. That hierarchy — external first, embedded sometimes, inline almost never — is a habit that scales from your first page to a large professional site.

Check: Why is a separate CSS file better than repeating styles on every page?

Section 24 — Colours in CSS

CSS offers several ways to specify a colour, and you will meet all of them in real code. The simplest is a named colour, such as red, blue, or darkgreen. CSS defines a set of named colours — 148 in the standard set — which are convenient for quick experiments and prototypes. Their limitation is range: you can only use the names that exist, and you cannot fine-tune a named colour to be slightly darker or slightly warmer. For precise design work, you will need a more flexible system.

The most common system in real projects is hexadecimal, or hex, notation. A hex colour is written as a hash followed by six digits, such as #ff0000 for pure red. The six digits are three pairs, representing the red, green, and blue components of the colour, each from 00 to ff in hexadecimal, which corresponds to 0 to 255 in decimal. So #ff0000 means full red, no green, no blue. Hex can also be shortened to three digits when each pair repeats: #f00 is the same as #ff0000. Hex values are compact, precise, and universally supported, which is why design tools and style guides usually express colours in hex, and why you should become comfortable reading them.

A third system is rgb notation, written as rgb(255, 0, 0), which states the same red, green, and blue values in decimal. Its close relative, rgba, adds a fourth value for opacity, from 0 for fully transparent to 1 for fully opaque, allowing colours to blend with whatever sits behind them. Modern CSS also supports hsl notation, which describes a colour by hue, saturation, and lightness, a system many designers find more intuitive when adjusting a colour's brightness. You do not need to master every system at once, but you should recognise each when you see it, and know that they are different spellings of the same underlying idea: a colour is a mixture of red, green, and blue light.

Whichever notation you use, the most important practical rule is contrast. Text must stand out clearly against its background, or it becomes unreadable, especially for people with low vision or for anyone reading in bright sunlight. Light grey text on a white background, or dark blue text on a black background, may look subtle and elegant in a design tool, but it fails real readers. Aim for strong contrast for body text, test your combinations, and remember that contrast checkers exist online to verify your choices objectively. Colour is also not the only way to convey meaning: never use colour alone to signal something important, such as an error, because colour-blind users may not perceive the difference. Pair colour with text, an icon, or another cue.

Finally, be consistent. Pick a small palette — a few colours used deliberately — rather than a different colour for every element. A limited palette looks more professional, is easier to maintain, and helps users learn what each colour means on your site. Define your palette early, write it down, and reuse it through variables or a shared stylesheet as your projects grow.

Check: Write the hex code for pure red.

Section 25 — The box model

Every element on a web page is a box. That is one of the most important ideas in CSS, and understanding it explains a large share of layout behaviour that otherwise seems mysterious. Each box is made of four layers, from the inside out: the content, where the text or image actually sits; the padding, the space inside the border, around the content; the border itself, a line drawn around the padding; and the margin, the space outside the border, separating the box from its neighbours. When you set a width on an element, you are setting the width of its content area by default, and the padding, border, and margin are added around it. Most layout confusion is box-model confusion, because developers expect an element to occupy one size and discover it occupies another.

Padding is worth understanding on its own, because it behaves in a way that surprises beginners. Padding is inside the border, so it extends the element's background. If an element has a background colour and you add padding, the coloured area grows. Padding also increases the total space the element occupies, unless you change the sizing model. Margin, by contrast, is outside the border, so it is transparent: the element's background does not extend into its margin. Margin pushes neighbouring elements away, creating breathing room between boxes, but it does not change the element's own background area.

The border sits between padding and margin. It can have a width, a style such as solid or dashed, and a colour. Borders are often used for emphasis — outlining a card, separating sections, or drawing attention to a button — and they are also a useful debugging tool: giving elements a temporary outline or border lets you see exactly where each box begins and ends, which often reveals why a layout is not behaving as expected. Many developers keep a debugging rule in their toolkit for exactly this purpose, removing it before the site is finished.

There is one subtlety that changes the arithmetic, and you should know it exists even if you do not master it yet. By default, CSS uses the content-box model, in which a width of 200 pixels plus 20 pixels of padding on each side plus a border gives a total wider than 200 pixels. An alternative, border-box, includes padding and border inside the stated width, so that 200 pixels means 200 pixels in total. Many professional stylesheets set border-box for all elements, because it makes sizing more intuitive. You will meet this in detail in later chapters; for now, remember that when an element looks wider than you specified, the box model is the first place to look.

To build intuition, practise with a single box: give a paragraph a background colour, add padding, add a border, add a margin, and watch how each layer changes the result in the browser. That experiment, repeated a few times, will teach you more about layout than any diagram, because you will see the layers rather than just reading about them.

Check: What sits between an element's content and its border?

Section 26 — Margin versus padding

Margin and padding are the two kinds of space in the box model, and confusing them is one of the most common beginner errors in CSS. The distinction is simple once stated clearly: padding is space inside an element's border, while margin is space outside an element's border. Padding grows the element itself, including its background area. Margin pushes other elements away without changing the element's own background. If you remember "padding is personal space inside the box, margin is distance from the neighbours," you will rarely mix them up again.

Consider a button. Suppose you have a button with text and a coloured background, and you want the button to look larger and more comfortable to click. Adding padding increases the space between the text and the button's edge, so the coloured area grows and the button feels bigger, while the text stays centred within it. That is the right tool. Adding margin instead would not enlarge the button at all; it would simply push neighbouring buttons further away, leaving your button the same size with more empty space around it. The visual difference is immediate in the browser, and experimenting with both on the same button is the fastest way to internalise the distinction.

The reverse case is equally instructive. Suppose you have two buttons side by side and you want them further apart. Adding margin to one or both buttons pushes them apart, because margin is outside space. Adding padding would make each button larger without necessarily increasing the gap between them in the way you intended, and it would change the buttons' appearance as a side effect. So the rule of thumb is: to change how big an element looks, use padding; to change how far it sits from other elements, use margin. When you are unsure which one you need, ask yourself whether you want the element's own background to grow. If yes, padding. If no, margin.

There are a few extra behaviours worth knowing. Margins can collapse: when two vertical margins meet, for example between two paragraphs, the browser does not add them together but uses the larger of the two. This is intentional and usually produces pleasing spacing, but it surprises developers who expect margins to add up. Padding never collapses. Margins can also be set to auto, which is a useful technique for centring a block horizontally when it has a fixed width. And negative margins exist, though they are an advanced technique best avoided until you understand the normal behaviour well.

In practice, you will use both constantly. Padding creates comfortable, clickable, readable elements; margin creates rhythm and separation between them. A page with generous, consistent padding inside its cards and consistent margins between its sections feels calm and organised. A page that confuses the two feels cramped in some places and scattered in others. Learning to reach for the right one, deliberately, is a small skill with a large payoff.

Check: Which one pushes neighbouring elements away?

Section 27 — Text styling

CSS gives you detailed control over how text looks, and text styling is where a page's readability is won or lost. The core properties are font family, font size, font weight, and line height, and a typical rule for body text looks like this: p { font-family: Arial, sans-serif; font-size: 16px; line-height: 1.5; }. Each property does a distinct job, and understanding them individually lets you combine them deliberately rather than copying values you do not understand.

Font family names the typeface. The value Arial, sans-serif is a list, not a single font: the browser tries Arial first, and if it is not available, falls back to the system's default sans-serif font. That fallback pattern is essential, because you cannot guarantee which fonts a visitor's device has installed. Always end a font stack with a generic family — serif, sans-serif, or monospace — so that there is always a sensible fallback. Later, you will learn to load web fonts, which give you more control, but the fallback principle remains: never assume a specific font will be present.

Font size is usually set in pixels for learning, such as 16px, which is the browser default for body text and a good starting point. Larger sizes suit headings; smaller sizes suit captions and footnotes, but be cautious about going too small for body text, because readability suffers quickly below about 15 or 16 pixels on most screens. Font weight controls boldness: normal is 400, bold is 700, and intermediate values exist for fonts that support them. Use weight sparingly for emphasis — a page where everything is bold emphasises nothing.

Line height, also called leading, is the space between lines of text, and it has an outsized effect on readability. A line height of about 1.5 for body text — meaning the line height is one and a half times the font size — is a good starting point, because it gives each line breathing room without making the paragraph feel disconnected. Tight line height makes long passages feel dense and tiring; excessive line height makes them feel scattered. You can write line height as a unitless number, as shown, which scales sensibly if the font size changes, and that is the recommended form.

Beyond these core properties, CSS offers letter spacing, word spacing, text alignment, text decoration for underlines, and text transformation for uppercase or capitalised text. Use them with restraint. Centred paragraphs are harder to read than left-aligned ones for long text, fully uppercase text is harder to read than normal case, and underlines should generally be reserved for links, so that users do not mistake ordinary text for a link. The goal of text styling is not decoration for its own sake, but text that invites reading and does not tire the reader.

Check: What line-height value is a good starting point for body text?

Section 28 — Classes and IDs

Classes and IDs are the two ways to target specific elements with CSS and JavaScript, and choosing between them correctly is a fundamental habit. A class is written with a dot in CSS, such as .note, and it can be reused on as many elements as you like. An ID is written with a hash, such as #main-title, and it must be unique on a page: only one element may carry a given id. That single rule — classes repeat, IDs do not — drives almost every decision about which to use.

Reach for classes first, in nearly every situation. Most styling is about patterns that repeat: warning messages, cards, buttons, section headings, and navigation items all appear many times, and a class lets you define the style once and apply it wherever it is needed. If you later change the style, every element with that class changes together, which is exactly the maintainability that CSS is designed to provide. Classes can also be combined: an element can carry several classes, such as class="card featured", allowing you to layer a general style with a specific variation without duplicating rules.

IDs have specific, narrower uses. Because an id is unique, it identifies one particular element unambiguously, which makes it useful as a target for a link fragment — for example, a link to #contact scrolls to the element with id="contact" — and as a hook for JavaScript that needs to find one specific element. IDs also have higher specificity in the cascade, meaning an ID rule will override a class rule for the same property, which can make stylesheets harder to manage if IDs are used for ordinary styling. That is a practical reason, beyond the uniqueness rule, to reserve IDs for identification rather than decoration.

A common beginner mistake is to give every element an id and style by id, treating ids as if they were labels for styling. That approach collapses as soon as you need the same style twice, because you cannot reuse the id, and you end up duplicating rules or inventing new ids for identical elements. The reverse mistake — using a class where uniqueness matters, such as for a fragment target that should point to exactly one place — is less common but equally confusing. Ask yourself: will this appear more than once, or might it in future? If the answer is yes, or even possibly, use a class.

Naming matters too. Choose class names that describe purpose, not appearance: .warning is better than .red-text, because if you later change warnings from red to amber, the name .red-text becomes a lie, while .warning remains true. Keep names lowercase, use hyphens between words, and be consistent. Good naming is a small discipline that makes large stylesheets readable, and it starts with the very first classes you write.

Check: Can two elements on one page share the same ID?

Section 29 — The cascade

The word "cascading" in Cascading Style Sheets describes how the browser resolves conflicts when more than one rule targets the same element and sets the same property. Because styles can come from multiple sources and multiple rules, conflicts are normal, not exceptional. The cascade is the set of rules the browser follows to decide which declaration wins, and understanding it turns CSS from a guessing game into a predictable system. When you write a rule and nothing seems to change, the cascade is almost always the explanation: another rule, somewhere, won.

The cascade considers several factors in order. First, origin and importance: browser default styles are weakest, then author styles — yours — then, in rare cases, user styles, and declarations marked !important override normal ones, though !important should be used very sparingly because it makes stylesheets hard to maintain. Second, specificity: a more specific selector beats a less specific one. An ID selector is more specific than a class selector, which is more specific than an element selector. So a rule targeting #main-title will beat a rule targeting .title, which will beat a rule targeting h1, for the same property on the same element. Third, source order: when two rules have equal specificity, the one that appears later in the stylesheet wins. That is why the order of your rules matters, and why placing general rules first and specific overrides later is a sensible organisation.

Inheritance is related to the cascade but distinct from it, and confusing the two is common. Inheritance means that some properties, such as font family and colour, pass from a parent element to its children unless a more specific rule intervenes. If you set a font on the body, paragraphs inside it inherit that font. Other properties, such as margin and padding, are not inherited, because it would rarely make sense for every nested element to copy its parent's spacing. The cascade resolves conflicts between rules that directly target an element; inheritance fills in values when no rule targets the element at all. Both mechanisms work together to produce the final computed style.

A practical way to think about the cascade is as a scoring system. Imagine each rule earning points for its selector's specificity, with later rules breaking ties. Developer tools make this visible: the Styles panel shows rules in order, with overridden declarations struck through, so you can see exactly which rule won and which lost. When a style does not apply, open that panel before changing your code at random. You will usually find either a more specific rule winning, a later rule winning, or a typo that prevented your rule from being recognised at all.

The lesson for writing CSS is to keep specificity low and order deliberate. Prefer classes, which have moderate specificity and are easy to override, over IDs and deeply nested selectors, which are hard to override and lead to specificity wars in which each fix requires an even more specific rule. Write general rules first, specific ones later, and you will find that the cascade works for you rather than against you.

Check: If two rules set the same property on the same element, which one wins in general?

Section 30 — Your first JavaScript

Your first JavaScript can be a single line that changes a page after it loads. Place a script element in your page, and inside it write code that finds an element and changes it, like this:

<script>
  document.querySelector("h1").textContent = "Hello, world!";
</script>

When the browser reaches this script, it runs the code: document refers to the page, querySelector("h1") finds the first heading element, and setting its textContent replaces the heading's text with "Hello, world!" Save the page, refresh it, and watch the heading change. That small moment — code changing a page you can see — is the core experience of JavaScript development, and everything more complex is built from the same pattern: find something, do something to it, and respond to something happening.

JavaScript talks to the page through the Document Object Model, or DOM, which you will study in the next section. For now, it is enough to know that document is your entry point to the page, and that methods such as querySelector let you select elements in much the same way CSS selectors do. In fact, the selector syntax is shared: "h1" selects a heading, ".note" selects an element with the class note, and "#main-title" selects the element with that id. That overlap is deliberate and helpful: the selectors you learn for CSS transfer directly to JavaScript.

Where you place the script matters. A script in the head runs before the body has been parsed, so if it tries to find a heading that does not exist yet, it will fail. That is why beginner examples often place the script at the end of the body, after all the content it needs to work with, so that the elements exist by the time the code runs. Later, you will learn other techniques, such as waiting for the DOM to be ready or using the defer attribute on external scripts, which solve the same problem more elegantly. For now, the end-of-body placement is a reliable rule that avoids a common and confusing error.

JavaScript errors are visible in the Console tab of developer tools, and you should check there whenever a script does not behave as expected. A misspelled method name, a missing quote, or a selector that matches nothing will often produce an error message that points directly at the problem. Learning to read those messages calmly, rather than guessing, is one of the most valuable skills you will develop. The Console also lets you type JavaScript directly and see the result immediately, which makes it an excellent place to experiment before committing code to a file.

Your first script is intentionally tiny, but do not underestimate it. It demonstrates selection, property assignment, and the relationship between code and the live page. Change the selector, change the text, change the property to style, and observe each result. That cycle of small, deliberate experiments is how JavaScript is learned, and it is far more effective than reading about the language without running any of it.

Check: What does DOM stand for?

Section 31 — What the DOM is

The DOM, the Document Object Model, is the browser's live, tree-shaped model of your page. When the browser loads an HTML file, it does not simply display the text of that file. It parses the HTML — reads it, checks its structure, and builds an internal representation in memory, organised as a tree of nodes. The html element is the root of the tree, the head and body are its branches, and every element, piece of text, and attribute becomes a node in that tree. That tree is the DOM, and it is what the browser actually renders, what CSS styles, and what JavaScript reads and changes.

It is important to understand that the DOM is not the same thing as your HTML file. HTML is source text, written by you and stored in a file. The DOM is the structured version the browser builds from that text, living in memory while the page is open. The distinction becomes visible as soon as JavaScript runs: if a script changes a heading's text, the DOM changes, but the HTML file on the server does not. Reload the page, and the browser rebuilds the DOM from the original HTML, discarding the change. That is why the View Source and Inspect views differ, a topic you will meet later in this chapter: View Source shows the original text, Inspect shows the live tree.

The tree shape of the DOM matters because it defines relationships. Every node has a parent, except the root, and may have children and siblings. A paragraph inside a section is a child of that section; two paragraphs in the same section are siblings. CSS selectors exploit these relationships — for example, selecting elements inside a particular container — and JavaScript methods let you move through the tree, finding parents, children, and siblings, and adding, removing, or rearranging nodes. Thinking in terms of trees, rather than flat text, is a shift that makes both CSS and JavaScript much clearer.

The DOM is also live. When JavaScript changes a node, the browser updates the display, usually immediately, without reloading the page. When a user types into a form field, the DOM reflects the new value. When a script adds a new element, it appears on screen. This liveness is what makes interactive applications possible: the page is not a fixed snapshot but a structure that code and users can modify continuously. It is also why timing matters: code that runs before the DOM has been built cannot find the elements it needs, because they do not exist in the tree yet.

Finally, the DOM is a standard interface, defined so that different browsers build compatible trees from the same HTML, and so that JavaScript written for one browser generally works in others. You do not need to know its full specification to use it well. Start with the essentials: document is the entry point, querySelector finds elements, and properties such as textContent let you read and change what an element contains. With those tools, you can already make pages respond, and every later DOM skill is an extension of this same model.

Check: Is the DOM the same thing as your HTML file? Why or why not?

Section 32 — Events

An event is something that happens on a page: a click, a key press, a form being submitted, a page finishing loading, a mouse moving over an element, or a window being resized. JavaScript's power comes largely from its ability to listen for events and run code in response to them. Without events, a script would run once when the page loads and then stop. With events, a page can wait, watch, and react, which is how buttons do things, menus open, forms validate, and games respond to input. Events are the bridge between what a user does and what your code does.

The pattern for handling an event has three parts: select an element, name the event, and provide a function to run when it occurs. For example, to respond to a button click, you might write:

<script>
  const button = document.querySelector("button");
  button.addEventListener("click", function () {
    alert("Button clicked!");
  });
</script>

The addEventListener method attaches a listener to the button. The first argument, "click", names the event. The second argument is a function, often called a handler, that runs each time the event occurs. Notice that the handler is not called immediately; it is registered, and the browser calls it later, when the user actually clicks. That idea — registering code to run in the future — is central to JavaScript, and it takes a little getting used to, but it is what makes interactive pages possible.

There are many event types, and you will learn the most useful ones gradually. Click and dblclick respond to mouse clicks. Keydown and keyup respond to keyboard input. Submit fires when a form is submitted, and input fires as a user types into a field, which makes it useful for live feedback such as character counts. Mouseover and mouseout track the pointer entering and leaving an element. Load fires when a page or resource has finished loading, and resize fires when the window changes size. You do not need to memorise the full list; you need to know that events exist for the interactions you care about, and where to look them up.

A few practical points will help you avoid common mistakes. First, make sure the element exists before you attach a listener to it, or your code will fail — the end-of-body script placement from the previous sections helps here. Second, remember that a listener stays attached until removed, so a button will respond to every click, not just the first. Third, some events, such as form submission, have a default action — in that case, sending the form and reloading the page — and you can prevent that default with a method on the event object when you want to handle the submission with JavaScript instead. You will practise that technique in later chapters.

Events turn a static document into a conversation. The user acts, the browser reports the action as an event, your handler responds, and the page changes, which may prompt the user to act again. That loop is the heartbeat of front-end interactivity, and every interactive feature you build, from a simple button to a complex application, is composed of events and handlers.

Check: Name three events a page can listen for.

Section 33 — Variables

A variable is a named box for a value. When you write let name = "Ada";, you are creating a variable called name, and storing the text "Ada" in it, so that you can use that value later by referring to its name instead of repeating the text. Variables are what allow programs to work with data that changes: a user's input, a running score, a list of items, or a calculation's result. Without variables, every value would have to be written out literally each time it was needed, and programs could not remember anything from one moment to the next.

JavaScript provides two main ways to declare a variable in modern code: let and const. The difference is about reassignment. A variable declared with let can be assigned a new value later: let score = 0; followed by score = 10; is perfectly valid, and the variable now holds 10. A variable declared with const cannot be reassigned: const name = "Ada"; followed by name = "Grace"; will produce an error. That does not mean a const value can never change in any sense — if a const holds an object or an array, the contents of that object can still be modified — but the variable itself cannot be pointed at a different value. That distinction is subtle and worth learning carefully, but the practical rule is simple.

Prefer const unless you know the value must change. This is the standard advice in modern JavaScript, and it exists for a good reason: when you read code and see const, you know that variable will always refer to the same value within its scope, which makes the code easier to reason about. When you see let, you know to watch for reassignment. Using const by default also catches mistakes: if you accidentally try to reassign something that should not change, the error tells you immediately, rather than allowing a silent bug. Reserve let for genuinely changing values, such as counters, accumulators, and values that are assigned conditionally.

Variable names matter. Choose names that describe what the value is: userName is better than x, and totalPrice is better than t. Use camelCase, in which multi-word names start lowercase and each subsequent word starts uppercase, which is the JavaScript convention. Names must start with a letter, underscore, or dollar sign, and cannot contain spaces or be reserved words such as function or return. Good names are a form of documentation: a reader should be able to guess what a variable holds without hunting through the code to find where it was set.

Finally, understand scope in outline: a variable declared inside a function or a block is generally only visible within that function or block, while a variable declared at the top level is visible more widely. Keeping variables as local as possible — declaring them where they are needed and not making everything global — prevents accidental interference between different parts of a program. You will study scope in depth later; for now, the habit to build is declaring with const or let, naming clearly, and using variables to store anything you will need more than once.

Check: When should you use const instead of let?

Section 34 — Functions

A function is a reusable block of code with a name. Instead of writing the same instructions every time you need a particular job done, you define the function once, give it a name, and then call it whenever you need that job. A simple example is: function greet(name) { return "Hello, " + name; }. This defines a function called greet, which takes one parameter, name, and returns a greeting string built from it. Calling greet("Ada") runs the function with "Ada" as the argument, and produces "Hello, Ada". Calling greet("Grace") produces "Hello, Grace", with no extra code written.

Parameters and return values are what make functions flexible. Parameters are the inputs a function accepts, listed in parentheses when it is defined. Arguments are the actual values passed when it is called. A function can take zero, one, or several parameters, and it can return a value with the return keyword, which also ends the function's execution. Not every function returns a value: some functions perform an action, such as updating the page or showing a message, and return nothing meaningful. Distinguishing between functions that calculate and return, and functions that act, helps you design code that is easy to understand and test.

The main benefit of functions is avoiding repetition. Suppose you need to greet a user in three places in your program. Without a function, you would write the greeting code three times, and if the greeting ever changed — for example, from "Hello" to "Welcome" — you would have to find and change all three copies, risking missing one. With a function, you change one definition and every call benefits. This principle, often called "don't repeat yourself," is one of the most valuable habits in programming, because duplicated code is where inconsistencies and bugs breed.

Functions also help you organise your thinking. A well-named function reads almost like a sentence in your program: calculateTotal(), showMessage(), validateForm(). Breaking a large task into smaller functions, each doing one job well, makes the program easier to write, because you can focus on one job at a time, and easier to debug, because you can test each function separately. If something goes wrong, you can narrow it down to the function responsible, rather than searching through a long, undifferentiated block of code.

There are several ways to write functions in JavaScript, including function declarations, function expressions, and arrow functions, which you will meet as you progress. For now, the declaration form shown above is clear and sufficient. Practise by identifying repeated code in your own scripts and extracting it into a function with a good name and clear parameters. That single exercise will improve your code more than almost any other beginner habit, and it is the foundation for everything from event handlers to large applications.

Check: Why write a function instead of repeating the same code three times?

Section 35 — If statements

Programs need to make choices. An if statement lets code take different paths based on whether a condition is true or false. A simple example is: if (age >= 18) { /* adult */ } else { /* under 18 */ }. The condition inside the parentheses, age >= 18, is evaluated first. If it is true, the code in the first block runs. If it is false, the code in the else block runs instead. The braces mark the boundaries of each block, and the else part is optional: you can write an if without an else when nothing special needs to happen in the false case.

Conditions are built from comparisons and logical operators. Common comparisons include === for strict equality, !== for inequality, > and < for greater and less than, and >= and <= for greater-or-equal and less-or-equal. Note the triple equals: JavaScript also has a double equals, ==, which performs type conversion before comparing and can produce surprising results, so modern code prefers ===, which compares without conversion. Logical operators combine conditions: && means and, both must be true; || means or, at least one must be true; ! means not, reversing a condition. Combining these lets you express rules such as "if the user is logged in and has items in the basket, show the checkout button."

You can chain choices with else if, which tests conditions in order until one is true. For example, a grading program might test whether a score is at least 90, else at least 75, else at least 50, else below 50, assigning a different grade at each step. The order matters: once a condition is true, the remaining branches are skipped, so you should test the most specific or highest-priority conditions first. Indentation and clear formatting make these chains readable; a chain that is hard to follow visually is hard to debug logically.

It is useful to see if statements as one of three building blocks that most programs are made from. The three are sequences, choices, and repeats. A sequence is a list of instructions run in order. A choice, made with if, selects between paths. A repeat, made with a loop, runs a block multiple times. Almost every program, however complex, is composed of these three patterns combined and nested. Recognising them helps you read unfamiliar code: you can ask, for each part, whether it is doing things in order, choosing between alternatives, or repeating.

A few cautions will save you trouble. Always use braces around if and else blocks, even for a single line, because adding a second line later without adding braces is a classic source of bugs. Be careful with assignment versus comparison: writing if (x = 5) assigns 5 to x and is almost never what you meant; you meant if (x === 5). And keep conditions readable: if a condition becomes long and tangled, extract it into a well-named variable or function, so that the if statement itself reads like plain language. Choices are the decision-making heart of programming, and writing them clearly is a skill worth practising from the start.

Check: What three building blocks do most programs use?

Section 36 — The browser console

The browser console is part of developer tools, and it is the first place to look when something breaks. To open developer tools, press F12, or right-click on a page and choose Inspect. The tools open as a panel, usually docked to the side or bottom of the browser window, with several tabs. The Console tab is where JavaScript messages appear: errors in red, warnings in yellow, and any output your code deliberately prints. It is also an interactive playground where you can type JavaScript and run it against the current page, seeing the result immediately.

When a script fails, the console usually tells you why, and learning to read those messages is essential. A typical error names the type of problem — for example, that a variable is not defined, or that you tried to read a property of something that does not exist — and gives the file and line number where it occurred. Clicking that location often jumps you to the relevant code in the Sources tab. Beginners sometimes ignore the console and stare at their code hoping the problem will reveal itself; experienced developers check the console first, because it narrows the search from the whole program to a specific line. Make that your habit from the beginning.

The console is also useful for deliberate output. The statement console.log() prints a value to the console without affecting the page, which makes it ideal for checking what your code is actually doing. If a variable does not hold the value you expected, log it. If a function is not being called, log a message inside it. If a condition is taking the wrong branch, log the condition's value. This technique, sometimes called print debugging, is simple but powerful, and it remains useful even for experienced developers. Remove or tidy up debugging logs before a project is finished, so that visitors' consoles stay clean, but do not hesitate to use them while learning.

Beyond errors and logging, the console lets you experiment. You can type an expression, such as 2 + 2 or document.querySelector("h1"), and see its result instantly, without editing a file or refreshing a page. You can test a selector to see whether it matches anything, try a string method, or call a function you have defined on the page. That immediate feedback loop makes the console an excellent learning tool: when you are unsure how something works, try it in the console first, observe the result, and then write it into your file with confidence.

One caution: the console runs code with the privileges of the current page, so never paste code into the console that someone else gave you unless you understand exactly what it does. Malicious instructions sometimes tell users to paste code into the console to "unlock" something, and that code can steal data or perform actions on their behalf. For your own learning, however, the console is safe and invaluable. Open it often, read what it says, and let it teach you how your code actually behaves.

Check: Where do JavaScript errors appear in the browser?

Section 37 — View Source versus Inspect

Browsers offer two different ways to look at a page's code, and confusing them leads to puzzling moments for beginners. View Source shows the HTML file as the server sent it: the original text, unchanged. Inspect, which opens developer tools on the Elements tab, shows the live DOM: the browser's current model of the page, including any changes JavaScript made after loading, and including corrections the browser applied to malformed HTML. Both views are useful, but they answer different questions, and knowing which one you need is part of debugging effectively.

View Source is the right tool when you want to know what the server actually delivered. It shows the raw HTML, exactly as it arrived, before JavaScript ran and before the browser repaired anything. If you suspect that a file was not updated on the server, or that a stylesheet link is missing from the delivered page, View Source will tell you. It is also a simple way to read a page's structure without the extra information developer tools add. To use it, right-click on a page and choose View Page Source, or use the browser's menu. The source opens in a new tab as plain text, with no interactivity.

Inspect is the right tool when you want to know what the page is now. It shows the DOM tree as it currently exists, with elements expanded and collapsible, and it highlights the corresponding part of the visible page when you hover over an element. If JavaScript added an element, changed text, or applied a class after loading, Inspect shows the result, while View Source does not. If the browser corrected a nesting error — for example, by moving an element that was placed illegally — Inspect shows the corrected structure. Inspect also shows the CSS rules applying to each element and lets you edit the DOM and styles live, for experimentation, without changing the underlying files.

A classic beginner confusion illustrates the difference. A student writes JavaScript that changes a heading, refreshes the page, sees the new heading, then opens View Source and finds the old heading still there, and wonders whether the script failed. It did not fail; View Source simply does not reflect live changes. Inspect would show the new heading, because Inspect shows the live DOM. Conversely, a student who edits something in Inspect and refreshes the page is surprised when the edit disappears, because Inspect edits affect only the live DOM in memory, not the files on disk. Both surprises disappear once the distinction is clear: View Source is the delivered file, Inspect is the living page.

As a rule of thumb, use View Source to check what was sent, and Inspect to check what is happening now. For most front-end debugging — why an element looks wrong, which CSS rule is winning, what JavaScript changed — Inspect is the tool you will reach for, because it shows the page as the user actually experiences it. View Source remains valuable for verifying delivery and for reading clean, original markup. Knowing both, and knowing which question each answers, will save you from a whole category of confusion.

Check: Which view shows changes JavaScript made after loading?

Section 38 — Relative versus absolute links

Links can be written in two ways: absolute and relative, and the difference matters when a site moves or grows. An absolute link contains the full address, including the scheme and domain, such as https://example.com/page. It points to one specific location on the web, regardless of where the linking page lives. A relative link, by contrast, is relative to the current page's location, such as about.html or ../images/logo.png. It does not name a domain; it says, in effect, "from where I am, go to this file." The browser resolves a relative link by combining it with the current page's address to produce a full address.

Relative links use a small set of conventions that are worth learning precisely. A plain file name, such as about.html, refers to a file in the same folder as the current page. A path with a folder, such as images/logo.png, refers to a file inside a subfolder of the current folder. The notation ../ means "go up one folder level": from a page in a pages folder, ../index.html refers to the index file in the parent folder, and ../../ would go up two levels. A path beginning with a single slash, such as /about.html, is root-relative: it refers to a file relative to the site's root, regardless of how deeply nested the current page is. Root-relative links are convenient on a live site, but they behave differently when you open files directly from your computer, because there is no server root in that case, so for early local projects, ordinary relative links are usually simpler.

The great advantage of relative links is portability. If you build a site with relative links and then move the whole site to a new domain, every internal link still works, because none of them names the old domain. The folder structure moves as a unit, and the relationships between files stay the same. If you had used absolute links for internal pages, every one of them would still point to the old domain, and you would have to edit them all. That is why the rule is: use relative links for pages and resources within your own site, and absolute links for resources on other sites, where the domain is genuinely part of the destination.

There are pitfalls to watch for. Moving a file without updating the relative links that point to it, or that it contains, will break those links, because their meaning depends on location. Renaming a folder has the same effect. Case sensitivity matters on many servers, so About.html and about.html may be different files. And when you preview a site by opening files directly, rather than through a local server, some link forms — particularly root-relative ones — may not resolve as they would on a real server, which can make a working site look broken locally, or vice versa. Testing through a simple local server, which you will learn to set up later, avoids that class of surprise.

The habit to build is simple: think about where a link points relative to the page that contains it, and choose the shortest correct form. That habit keeps your sites portable, your links robust, and your moves painless.

Check: Which kind of link survives a site moving to a new domain?

Section 39 — File organisation

Keeping a project tidy from day one is one of those habits that seems optional until the day it saves you. A sensible structure for a beginner project is: an index.html at the root of the project folder, a css folder for stylesheets, a js folder for scripts, and an images folder for pictures. That layout is simple, predictable, and scalable: anyone opening your project — including future you, returning after months away — can immediately see where each kind of file lives, without hunting through a flat pile of files or guessing at idiosyncratic names.

The root index.html is the entry point, as you learned earlier: it is the file a server serves when a visitor asks for the site's root address. Keeping it at the root, rather than buried in a subfolder, makes the site's structure intuitive and its links straightforward. The css folder holds your stylesheets, so a link to a stylesheet from the root index file looks like css/styles.css. The js folder holds scripts, referenced as js/script.js. The images folder holds pictures, referenced as images/photo.jpg. Those paths are relative links, and they work precisely because the folder structure is consistent: from the root page, you go into the named folder to find the file.

As projects grow, this structure grows with them. You might add a pages folder for additional HTML files, a fonts folder, or a data folder, but the principle remains: group files by kind or by purpose, name folders clearly and in lowercase, and avoid spaces in file and folder names, because spaces in URLs must be encoded and cause unnecessary trouble. Avoid deeply nested structures for simple projects; three or four folders are plenty for a beginner site, and clarity matters more than elaborate organisation. A structure that needs a map to navigate has failed at its purpose.

Good organisation also helps with version control, which you will meet in a later chapter. Tools that track changes to your work operate on folders, and a tidy folder makes it easy to see what changed, to ignore generated files, and to share the project with others. It also helps with deployment: when you upload a site to a host, you upload the project folder, and the host serves it with the same structure. If your local structure is messy, your deployed site will be messy in exactly the same ways, including broken links caused by files that were referenced from the wrong place.

Finally, organisation is a form of respect for your future self. The few seconds it takes to save a new stylesheet into the css folder, rather than dropping it at the root with a vague name, compound into hours saved over a project's life. Name files descriptively — main.css is better than style1.css, and hero-photo.jpg is better than img001.jpg — and keep a consistent pattern. Future you will be grateful, and so will anyone who ever collaborates with you.

Check: Where should a project's main stylesheet live?

Section 40 — Accessibility from the start

Accessibility means that people with different abilities can use your page. That includes people who are blind or have low vision, people who are deaf or hard of hearing, people with motor difficulties who cannot use a mouse, people with cognitive differences, and people in temporary situations such as a broken arm or a bright, noisy environment. Accessibility is not a niche concern or a finishing touch to be added at the end; it is part of good front-end work, because a page that excludes some users has failed those users, however impressive it looks to others.

Many accessibility habits are simply the good practices you have already learned in this chapter, applied consistently. Use real headings in order, so that screen reader users can navigate by outline. Write good alt text for meaningful images, so that their information is not lost. Label form fields properly, so that every input has a clear, programmatically associated label rather than relying on placeholder text alone, which disappears when a user starts typing and is not reliably announced. Ensure colour contrast is sufficient, so that text remains readable for people with low vision. These are not extra tasks layered on top of development; they are development done correctly.

Keyboard accessibility deserves special attention. Some users navigate entirely by keyboard, using Tab to move between interactive elements and Enter or Space to activate them. Your pages should support that by default: use real buttons for actions and real links for navigation, because those elements are keyboard-focusable and operable by design, whereas a div with a click handler is not, unless you add considerable extra work. Make sure the focus indicator — the outline that shows which element is currently focused — remains visible, and do not remove it with CSS merely because you dislike its appearance; if you restyle it, replace it with something equally clear. Test your pages by keyboard alone occasionally, and you will discover problems that mouse testing never reveals.

Accessibility also benefits everyone, a principle often called the curb-cut effect, after the pavement ramps built for wheelchair users that also help parents with pushchairs, travellers with luggage, and delivery workers. Captions help viewers in noisy rooms as well as deaf viewers. Clear headings help everyone scan a page. High contrast helps everyone reading in sunlight. Large, well-spaced tap targets help everyone on a phone. Building accessibly is not charity; it is building better for all users, and it often improves search engine understanding and overall usability as a side effect.

Finally, accessibility is partly a legal and professional responsibility. Many countries require public and commercial websites to meet accessibility standards, and many organisations include accessibility in their procurement and hiring criteria. The standard most often referenced is the Web Content Accessibility Guidelines, known as WCAG, which defines levels of conformance. You do not need to memorise WCAG now, but you should know it exists, and you should build the habits in this section from the start, because retrofitting accessibility onto a finished site is far harder than building it in from the first line. Start accessible, and stay accessible.

Check: Name three accessibility habits from this section.

Section 41 — Responsive thinking

People visit pages on phones, tablets, laptops, desktop monitors, and televisions, with screen widths ranging from a few hundred pixels to several thousand. Responsive design means the layout adapts to the screen it is viewed on, instead of forcing a desktop layout onto a phone, where it would require constant sideways scrolling and pinching to read. The goal is not to build separate sites for each device, but to build one site whose layout flexes: columns stack on narrow screens and sit side by side on wide ones, text sizes remain readable, images scale to fit, and navigation adapts to the space available.

The mindset shift is more important than any single technique at this stage. Instead of designing for one screen size — usually your own — and hoping it works elsewhere, you should think in terms of ranges and flexibility. Ask: what should this layout do when it gets narrower? What should happen when it gets wider? Which elements are essential, and which can be rearranged, hidden, or restyled without losing the page's purpose? A layout built from flexible units, such as percentages and flexible grids, adapts more gracefully than one built entirely from fixed pixel widths, which break as soon as the screen differs from the size you assumed.

You will learn the tools for responsive design in later chapters: the viewport meta tag, which tells mobile browsers how to scale the page; media queries, which apply different CSS at different screen widths; and flexible layout systems such as Flexbox and Grid, which distribute space intelligently. For now, you should know those tools exist and understand the problem they solve, so that when you meet them, you recognise them as solutions to a problem you already understand, rather than as abstract techniques. You can also start practising the simplest responsive habit immediately: resize your browser window while viewing your pages, and notice what breaks. That observation alone will teach you a great deal.

Responsive thinking also extends beyond screen width. Users may rotate a phone from portrait to landscape, zoom text larger for readability, or view a page in a split-screen window. A robust layout tolerates those changes without breaking. Images should not overflow their containers; long words should not force horizontal scrolling; and interactive elements should remain large enough to tap comfortably on a touch screen, where fingers are far less precise than mouse pointers. Designing for touch is part of responsive thinking too: a button that is easy to click with a mouse may be frustratingly small to tap with a finger.

Finally, responsive design is not only about appearance; it is about priority. On a small screen, space is scarce, so you must decide what matters most and present it first. That discipline improves the design for large screens as well, because it forces clarity about the page's purpose. A page that works beautifully on a phone and scales up gracefully to a desktop is the mark of a thoughtful developer. Start thinking responsively now, even before you have all the tools, and the tools will make sense when they arrive.

Check: What problem does responsive design solve?

Section 42 — What "the page loads" actually means

When people say a page "loads," they usually mean the moment it appears on screen, but loading is actually a sequence of steps, and understanding that sequence helps you diagnose slowness and errors. The steps, in order, are: fetch the HTML, read it top to bottom, fetch the CSS and JavaScript it points to, build the DOM, apply styles, run scripts, and paint the result on screen. Each step depends on the ones before it, and a problem at any step affects everything that follows. A slow page is usually slow at one particular step, and finding that step is the key to fixing it.

The process begins with a request. Your browser asks the server for the HTML file, using the address you typed or clicked. When the response arrives, the browser starts reading the HTML from the top, building the DOM as it goes. As it encounters references to external resources — a stylesheet link in the head, an image in the body, a script — it fetches those too. Stylesheets are particularly important early on, because the browser generally waits to paint the page until it has the CSS, to avoid showing an unstyled page briefly and then restyling it, a flash that users find jarring. That is why stylesheets are linked in the head: the browser discovers them early.

Once the DOM is built and the styles are known, the browser combines them into a render tree, which represents the elements that will actually be displayed, with their computed styles, excluding elements that are hidden. It then works out the layout: where each element sits, and how large it is, taking the box model, the layout system, and the viewport size into account. Only then does it paint: drawing text, colours, images, and borders onto the screen, in layers. JavaScript complicates this sequence, because a traditional script in the body blocks further parsing until it has been fetched and run, which is one reason scripts are often placed at the end of the body or loaded with attributes that defer their execution.

Knowing this sequence turns vague complaints into diagnosable problems. If a page shows nothing for a long time, the HTML or CSS may be slow to arrive. If a page appears unstyled and then jumps into shape, the CSS may be arriving late. If a page appears but buttons do nothing for a while, JavaScript may be slow or blocking. If a page is slow only when images are included, the images are probably too large. Developer tools include a Network tab that shows each resource, its size, and its timing, allowing you to see exactly which step is slow, rather than guessing.

For your own pages, the practical lessons are straightforward: keep files reasonably small, avoid unnecessary resources, place stylesheets in the head and scripts thoughtfully, and test on realistic connections, not only on fast ones. Loading is not magic; it is a pipeline, and every pipeline can be inspected, measured, and improved, step by step.

Check: List the loading steps in order.

Section 43 — Common beginner mistakes

Every developer makes beginner mistakes, and recognising them quickly is a skill in itself. The most common ones in front-end work are: forgetting a closing tag, nesting elements wrongly, using a heading for size alone, and writing CSS that targets the wrong selector. None of these is a sign of inability; they are the normal errors of learning a new language, and experienced developers still make them, but they find and fix them faster because they know where to look. This section names the mistakes so that you can recognise them in your own work without shame or confusion.

A forgotten closing tag is often the easiest to make and sometimes the hardest to spot, because browsers repair it silently. If you open a paragraph and forget to close it, the browser will close it for you at some point, but perhaps not where you intended, and the following content may inherit styles or structure you did not expect. An editor that highlights matching tags, and the habit of writing the closing tag immediately after the opening tag before filling in the content, both help enormously. Similarly, wrong nesting — closing elements in the wrong order, like overlapping boxes instead of nested ones — produces a DOM tree that differs from what you wrote, and Inspect will show you the tree the browser actually built, which often reveals the error at a glance.

Using a heading for size alone, rather than for its place in the outline, is a mistake of meaning rather than syntax, and it is covered in detail earlier in this chapter. It is worth repeating here because it is so tempting: a heading renders at a convenient size, so reaching for it feels efficient, but it corrupts the document's structure for screen readers, search engines, and future maintainers. The fix is always the same: use the correct heading level for the outline, and control size with CSS. If you find yourself choosing elements for their default appearance, pause and ask whether you are choosing for meaning or for looks.

Writing CSS that targets the wrong selector is the styling equivalent of a forgotten closing tag. You write a rule, refresh, and nothing changes, and the temptation is to write a stronger, more specific rule on top of it, which may eventually work but leaves a tangle behind. Instead, check the selector first: is it spelled correctly, does it match the element's class or id exactly, and is another rule with higher specificity overriding it? The Styles panel in developer tools answers all three questions: it shows which rules applied, which were overridden, and whether your rule appears at all. If your rule does not appear, the selector or the stylesheet link is wrong. If it appears struck through, another rule won the cascade.

The underlying skill in all of these cases is not avoiding mistakes — that is impossible — but finding them systematically: check the console for errors, check Inspect for structure, check the Styles panel for CSS, and change one thing at a time. That methodical approach is what separates a developer who is stuck from one who is debugging.

Check: Which tool helps you find a wrongly targeted CSS rule?

Section 44 — How to learn front-end well

Reading about a tag is not the same as using it. You can read a description of a paragraph element and feel that you understand it, and then sit down to build a page and discover that you are unsure where it goes, how it interacts with CSS, or what happens when you nest something inside it. That gap between recognition and ability is normal, and it closes only through practice. The way to learn front-end development well is to build small things constantly, making mistakes, fixing them, and building again. Each small project consolidates several ideas at once in a way that reading alone cannot.

The practical task at the end of every chapter exists for this reason. It is not homework in the sense of a test to pass; it is where the learning sticks. When you build the task, you are forced to make decisions that reading never required: what should the heading say, how should the list be structured, where does the stylesheet live, what happens when you change a value? Those decisions, and the errors you encounter while making them, are the learning. Skipping the task and moving on to the next chapter feels faster, but it leaves the knowledge fragile, and the next chapter, which assumes the previous one, becomes harder than it needs to be. Do the task before moving on, every time, even if your version is simple.

Build beyond the tasks too, in small, frequent doses. A good habit is to rebuild something you have seen — a simple navigation bar, a card layout, a form — from memory, and then compare it with a reference when you get stuck. Another is to keep a folder of experiments: tiny pages, each testing one idea, named clearly, that you can revisit when you need to recall how something worked. Teaching also consolidates learning: explaining a concept to someone else, or writing it in your own words, reveals gaps in your understanding that reading never exposed. If you can explain the box model to a friend, you understand it; if you cannot, you know what to revisit.

Finally, learn to read documentation and error messages as part of learning, not as a last resort. Reference sites, browser documentation, and the console are not crutches for weak developers; they are the working tools of professional developers, who look things up constantly. The goal is not to memorise every property or method, but to know what exists, where to find it, and how to test it. Combine that with steady building, and with patience when things break — because they will, often — and you will progress faster than any shortcut promises. Front-end development rewards builders, not just readers.

Check: Why does this book put a practical task at the end of every chapter?

Section 45 — The front-end developer's toolkit

You do not need expensive software to start front-end development. A starter toolkit has three components: a code editor, a browser with developer tools, and a way to keep versions of your work. With those three, you can learn, build, and share everything in this book. Everything else — frameworks, build tools, design software, and hosting services — can be added later, when a project genuinely needs it, rather than at the start, when it only adds confusion.

A code editor is where you write HTML, CSS, and JavaScript. Unlike a word processor, it saves plain text exactly as you type it, and it adds features that make coding easier: syntax highlighting, which colours different parts of your code so structure is visible; automatic closing of tags and brackets; indentation help; and extensions for checking errors and formatting code. Visual Studio Code is a popular free choice, and it is the editor many tutorials assume, but any plain-text code editor will serve you well at this stage. Choose one, learn its basics — opening folders, saving files, and using its search — and stick with it long enough to become fluent, rather than switching editors every week.

A browser with developer tools is your second tool, and you already have it. Every major browser includes developer tools, with an Elements panel for inspecting the DOM, a Styles panel for CSS, a Console for JavaScript and errors, and a Network panel for loading. You will use these tools in every chapter, not just when something breaks, because they let you experiment live: change a style and see the result instantly, test a selector, or run a line of JavaScript. Learning developer tools is learning front-end development itself, not an optional extra, and the investment pays off from your very first page.

The third tool is version control, and the standard system is Git, which you will learn in a later chapter. In outline, Git keeps a history of your work: you can save snapshots of a project, see what changed between snapshots, revert to an earlier version when an experiment goes wrong, and collaborate with others without overwriting each other's work. Even for solo learning, Git is valuable, because it frees you to experiment boldly: if an experiment breaks everything, you can return to the last working snapshot in seconds. Hosting services built on Git, such as GitHub, also provide a place to store your work and share it with others.

Beyond these three, you will gradually add tools as needed: a local server for testing, a package manager, a framework, or a design tool. Add them one at a time, for a reason you can state, and learn each one properly. A developer with three tools they understand deeply will outperform one with thirty tools they barely know, and the three in this section are the foundation on which everything else rests.

Check: Name the three tools in a starter toolkit.

Section 46 — HTML, CSS and JavaScript work together

A page is not three separate projects stitched together. It is one project in which HTML says what things are, CSS says how they look, and JavaScript says how they behave, and a good developer keeps each job in its own layer instead of mixing them. That separation, which this chapter has returned to repeatedly, is worth stating as a principle in its own right, because it governs decisions you will make in every project, from the smallest page to the largest application.

Separation brings maintainability. When structure lives in HTML, presentation in CSS, and behaviour in JavaScript, each layer can be changed without disturbing the others. A designer can restyle a site by editing the stylesheet, without touching the content. A developer can fix a bug in a script without rewriting markup. A content editor can update text without breaking layout. When the layers are mixed — styles written inline throughout the HTML, behaviour scattered through HTML attributes, content generated inside scripts with no structure — every change risks breaking something unrelated, and the project becomes brittle and frightening to edit.

A concrete example illustrates the cost of mixing. Suppose behaviour is mixed into HTML as inline handlers everywhere, such as onclick attributes on dozens of buttons. At first, that seems convenient: the behaviour sits right next to the element it affects. But when the behaviour needs to change, you must find and edit every attribute, and you will miss some. When the same behaviour needs to apply to a new button, you must remember to copy the attribute correctly. When you want to remove or disable the behaviour temporarily, you must edit the HTML rather than toggling a script. And because the behaviour is embedded in the markup, it cannot be easily tested, reused, or cached separately. The modern alternative — selecting elements in JavaScript and attaching listeners — centralises the behaviour in one place, where it can be maintained, tested, and understood as a whole.

Separation also supports accessibility and resilience. A page whose content is real HTML remains readable and usable even if CSS fails to load or JavaScript is disabled or errors. That layered resilience, sometimes called progressive enhancement, means starting with solid HTML, enhancing it with CSS, and then enhancing it further with JavaScript, so that each layer adds value without the page depending entirely on it. A page built the other way round — where content only exists if JavaScript runs — fails completely for users whose JavaScript fails, for reasons that may be entirely outside their control.

None of this means the layers never touch. CSS selectors refer to HTML structure, and JavaScript reads and changes the DOM. The point is not isolation but responsibility: each layer should do its own job, and no layer should do another's job unnecessarily. Keep that division in mind, and your projects will stay understandable as they grow, which is the difference between code you can return to with confidence and code you dread opening.

Check: What goes wrong when behaviour is mixed into HTML as inline handlers everywhere?

Section 47 — What this book will cover

Across 50 chapters, this book moves from foundations to professional practice, and each chapter builds on the last. You have begun with the foundations in this chapter: what the web is, how browsers and servers work, and how HTML, CSS, and JavaScript fit together. The next chapters deepen each of those foundations in turn, before moving into the larger topics that define a working front-end developer. Knowing the shape of that journey helps you see where each new idea fits, and why the order matters.

After the foundations, the book turns to pages and styles in depth: more HTML elements and document structure, CSS selectors and the cascade in detail, and the box model applied to real layouts. From there it moves into layout itself — Flexbox, Grid, positioning, and responsive design — the skills that turn a page from a vertical stack of elements into a designed interface that adapts to any screen. Forms follow, because almost every real site collects input, and forms bring together HTML structure, CSS styling, JavaScript validation, and accessibility in a way that tests everything you have learned.

The middle of the book is devoted to JavaScript in depth: variables and data in detail, functions and scope, the DOM and events as a complete system, data handling, and fetching data from APIs, which is how modern pages load content dynamically without full reloads. Later chapters introduce frameworks and component-based thinking, the approach most large professional projects use, while keeping the fundamentals visible underneath, so that a framework never becomes magic you cannot explain. Testing, performance, and accessibility are woven through the later chapters as professional disciplines, not afterthoughts, because a developer who can make a page fast, correct, and usable is worth far more than one who can only make it look good.

The final chapters are about shipping a real site: organising a project, using version control, optimising performance, handling deployment, and maintaining a site after launch. The book ends where real work begins: with a complete, published project you can show, explain, and extend. That arc — from a single heading in a first HTML file to a shipped site — is deliberate. No chapter asks you to use a tool before you understand the problem it solves, and no chapter leaves you without a practical task to consolidate what you have learned.

You do not need to read the whole map before starting the journey, but keep it in mind when a chapter feels narrow or slow. Foundations feel slow because they are load-bearing: everything after them rests on them. Trust the order, do the tasks, and by the final chapters you will be surprised at how much you can build, and how clearly you understand what you have built.

Check: What comes after the foundations in this book's plan?

Section 48 — How to use the questions

Every section in this book ends with a check question, and those questions are not decoration. They are a learning tool, and using them well will significantly improve how much you retain. The method is simple: answer each section's check question before reading on, even if only in your head. Do not skip ahead and hope the answer will become clear later; pause, formulate an answer in your own words, and only then continue. That brief pause, and the act of retrieving the answer from memory rather than recognising it on the page, is what turns reading into learning.

Retrieval is powerful because it tests understanding, not familiarity. Reading a section can leave you feeling that you understand it, because the explanation was clear while you were reading it. Trying to answer a question without looking back reveals whether you actually retained the idea, or merely recognised it. If you can answer, you have evidence of learning, and you can move on with confidence. If you cannot, you have discovered a gap while it is still cheap to fix — by re-reading that one section — rather than discovering it chapters later, when the missing idea has become a foundation for something else.

So the rule for a failed check question is straightforward: re-read that section. Do not simply look up the answer and move on, because looking it up without re-engaging with the explanation leaves the same gap in place. Re-read slowly, note the part you missed or misunderstood, and try the question again. If you still cannot answer it, try explaining the section's idea aloud, in your own words, as if to a friend. The point at which your explanation breaks down is the point you need to revisit, and that diagnosis is itself valuable. If a question still resists you after that, mark the section and return to it after the next practical task, when you will have used the idea and may understand it differently.

The chapter questions at the end of each chapter work the same way, at a larger scale. They ask you to combine ideas from several sections, explain differences, and write small pieces of code from memory. They are not exams to fear, but checks to use: if you can answer them without referring back, you have genuinely learned the chapter. If you cannot, the chapter's sections are still there, and revisiting them is not failure but the normal process of learning. Use the questions actively, honestly, and immediately, and they will do their job: telling you what you know, and what you need to revisit, before you move on. Keep a short note of any question you missed, so your next review session starts with exactly the ideas that need strengthening rather than a vague sense that something was unclear.

Check: What should you do if you cannot answer a check question?

Section 49 — A note on copying code

Copying a snippet to learn from is fine; copying a whole project and claiming it as yours is not. That distinction matters, both ethically and practically, and it is worth stating plainly at the start of your learning. Code on the web is widely shared for learning: tutorials, documentation, and examples exist to be read, tried, and adapted. Using a snippet as a starting point, understanding what it does, and modifying it for your own purpose is legitimate learning, and it is how most developers work. Presenting someone else's complete work as your own, whether in an assignment, a portfolio, or a job application, is dishonest, and it will be discovered, because developers recognise copied work and because you will be unable to explain or maintain what you did not build.

There is also a practical reason to type examples yourself rather than only pasting them. Typing is learning; pasting is not. When you type code, you notice its structure: where the braces go, how the tags nest, which parts are names and which are values. You make small typing errors, and fixing them teaches you the language's syntax in a way that reading never does. When you paste, you bypass all of that. The code may work, but you have not learned why, and you will struggle to write similar code from scratch when you need to. That is why this book asks you to type examples when you can: not as busywork, but because the physical act of writing code is part of understanding it.

That does not mean you should never copy. Professional developers copy from documentation and from their own previous work constantly, and they use tools that generate boilerplate code. The skill is knowing the difference between copying as a shortcut to understanding and copying as a substitute for it. A good test is: can you explain, line by line, what the copied code does, and could you modify it to do something slightly different? If yes, you have learned from it, and it is yours to use, with credit where credit is due. If no, you have borrowed a result without the understanding, and you should slow down and work through it.

Respect licences and attribution too. Open-source code is shared under licences that usually permit use, sometimes with conditions such as preserving a copyright notice or sharing your modifications. Read the licence for anything substantial you reuse, and give credit where it is required or appropriate. That habit protects you legally and marks you as a professional. In short: learn from others' code freely, type it yourself when learning, adapt it honestly, credit it properly, and never claim work you did not do as your own.

Check: Why does this book ask you to type examples rather than only paste them?

Section 50 — Chapter 1 in one paragraph

Front-end development is building what people see and touch on the web, using HTML for structure, CSS for look, and JavaScript for behaviour, delivered by servers to browsers that turn code into pages. That one sentence contains the whole chapter, but it is worth unpacking it once more, because each phrase now carries the weight of a section you have studied. "What people see and touch" is not just decoration; it is layout, words, buttons, forms, and feedback, designed for clarity, accessibility, and responsiveness across devices. "HTML for structure" means real, meaningful markup — headings in order, paragraphs, lists, links, and images with alt text — forming a document that machines and assistive technology can understand, not merely a picture of a page.

"CSS for look" means rules with selectors and declarations, applied through external stylesheets where possible, controlling colour, typography, spacing, and layout through the box model, with the cascade resolving conflicts. "JavaScript for behaviour" means a real programming language, working through the DOM, responding to events, storing values in variables, reusing logic in functions, and making choices with if statements, all debugged through the console and developer tools. "Delivered by servers to browsers" means the internet's request-and-response story: URLs naming resources, HTTP and HTTPS carrying them securely, servers storing and serving files, and browsers fetching, parsing, styling, scripting, and painting the result.

You have already seen every piece in miniature: a first HTML file with a doctype, a head and a body, a first CSS rule, and a first script that changed a heading. You have also seen the habits that will carry you through the rest of the book: organising files tidily, choosing elements for meaning, writing accessible markup from the start, thinking responsively, answering check questions before moving on, typing examples yourself, and building a practical task to make the learning stick. None of those habits is glamorous, and all of them compound. Now the book builds each piece properly, chapter by chapter, starting with deeper HTML and CSS, then layout, then JavaScript in full. You are ready for that journey precisely because you understand, in outline, the whole system you are about to explore in depth. Before you move on, test yourself honestly against the chapter rather than against your memory of reading it. Can you explain, without looking, why a heading level is a statement of meaning and not a choice of size, why padding and margin do different jobs, and what happens step by step between typing a URL and seeing a page? If any answer wobbles, that section is worth a second read, because later chapters assume it. This is also the moment to build the habit of keeping your own notes in your own words: a short page where you rewrite each idea as you understood it will teach you more than re-reading the same paragraphs, and it becomes a reference you actually trust when you are stuck at midnight on a later project. Front-end work rewards that kind of steady, practical study far more than speed, and the developers who last are usually the ones who learned to check their understanding early, ask precise questions, and finish small things properly before reaching for bigger ones.

Check: In your own words, summarise what a front-end developer does.


Chapter 1 — Practical task

Build a one-page personal introduction site with: one h1 with your name, two paragraphs about what you want to learn, a list of three things you want to build, one image with good alt text, and one link to a site you admire. Style it with a separate CSS file: a readable font, a background colour, and padding on the page. Then open it in a browser, open Inspect, and change the heading colour in developer tools just to prove to yourself that the live DOM can be edited.

Chapter 1 — Chapter questions

  1. Explain, in plain words, the difference between a server and a browser.
  2. Why is HTTPS better than HTTP?
  3. A page's heading looks wrong. How do you find out whether the problem is in the HTML, the CSS, or JavaScript?
  4. Write the HTML for a link to https://example.com with the text "Example site".
  5. When should you use a class, and when should you use an ID?