webdev.complete
ðŸĶī HTML — The Bones
ðŸ§ąFoundations
Lesson 4 of 117
20 min

Your First Webpage

DOCTYPE, head, body — anatomy of every HTML file.

HTML is the skeleton of every web page. It's also the first language web developers learn, and somehow the one most often written wrong. By the end of this lesson you'll have built a complete, valid HTML page from scratch and you'll understand every line in it.

The smallest valid HTML page

Here's the entire shape of an HTML document. Memorize this skeleton; you'll type it from muscle memory by the end of the chapter.

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>My first page</title>
  </head>
  <body>
    <h1>Hello, web</h1>
    <p>I made this.</p>
  </body>
</html>

Line by line

  • <!doctype html>- tells the browser "this is modern HTML, parse it in standards mode." Without it, browsers fall back to a 1990s mode that breaks layout in subtle ways.
  • <html lang="en"> - the root element. The lang attribute helps screen readers pick a voice and helps search engines translate.
  • <head> - metadata about the page. Nothing inside renders as content; it tells the browser how to display the body.
  • <meta charset="utf-8">- "treat this text as UTF-8." Without it, emoji and accents can render as garbage.
  • <meta name="viewport"...>- tells mobile browsers to use the device's actual width. Without this, your site looks like a zoomed-out desktop on phones.
  • <title> - what shows in the browser tab and in search results.
  • <body> - the actual content that renders.
Two metas you must not skip
charset and viewportbelong in every page you write. Skip them and you'll get bizarre bug reports ("emoji is broken on Android!") that take an hour to diagnose.

Tags, elements, and attributes

These three terms get used interchangeably. They're not.

  • A tag is the bit between angle brackets: <p> or </p>.
  • An element is the whole thing: opening tag, content, closing tag. <p>Hi</p> is one element.
  • An attribute lives inside the opening tag and configures the element: <a href="/about"> has one attribute, href, with the value /about.

Void elements (the ones that don't close)

Most elements have an opening and closing tag. Some don't. These are void elements: they hold no content. The full list is short and worth knowing:

area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr.

In HTML you can write them as <br> or <br />; both work. In JSX (React) you must self-close them: <br />.

Content categories (the rules behind the rules)

HTML has implicit rules about what can nest inside what. The big categories:

  • Flow content - block-level stuff like <div>, <p>, <section>. Lives directly inside <body>.
  • Phrasing content - inline stuff like <span>, <strong>, <a>. Lives inside paragraphs and headings.
  • Metadata content - <meta>, <link>, <title>. Lives in <head>.
  • Interactive content - <a>, <button>, <input>. Don't nest these inside each other.
The rule that catches most beginners
You cannot put a <div> inside a <p>. Paragraphs only accept phrasing content. If you do it anyway, the browser silently closes the <p> for you and your CSS breaks.

Try it: edit a live page

Below is a working HTML page. Edit it. Add a paragraph, change the heading, break it on purpose to see what happens. Live preview updates as you type.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>My first page</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h1>Hello, web</h1>
    <p>This is a paragraph. <strong>Bold</strong> and <em>italic</em> work.</p>

    <h2>A short list</h2>
    <ul>
      <li>Eggs</li>
      <li>Milk</li>
      <li>Coffee</li>
    </ul>

    <img src="https://placecats.com/300/200" alt="A small cat" />
  </body>
</html>

Common beginner traps

  • Forgetting alt on <img>- screen readers can't describe the image without it, and your accessibility audit will complain.
  • Skipping <!doctype html> - triggers quirks mode in older browsers, breaks subtle layout rules.
  • Using <br> for spacing- that's CSS's job. <br> is for hard line breaks inside text (like a poem), not gaps between blocks.
  • Multiple <h1> per page (in the wrong way)- one per page is the safest default; we'll cover when to break this in the semantic HTML lesson.

Quick quiz

Quiz1 / 3

What's the difference between a tag and an element?

Recap

  • Every page starts with <!doctype html>, then <html> with <head> + <body>.
  • Always include charset="utf-8" and the viewport meta.
  • Tag = the bracket syntax. Element = the whole structural unit. Attribute = key/value on a tag.
  • Void elements (img, br, input, meta, ...) don't close.
  • Content categories explain why some nesting works and some doesn't. div inside p? No.
Built with Next.js, Tailwind & Sandpack.
Learn. Build. Ship.