Chapter 04 — Front-End Fundamentals

Writing HTML

HTML is structure. It’s not style, it’s not behavior. It’s the bones of a document: what things are, how they relate to each other, and what they mean. CSS handles how things look. JavaScript handles how things behave. Keeping those three concerns separate is what makes code readable, maintainable, and accessible to people using assistive technology.

That separation is worth internalizing early.


Create your first HTML file

Your tutorials project is open in VS Code. In the sidebar, right-click the src folder and select New File. Name it index.html.

You can also do this from the integrated terminal (Ctrl+`):

bash~/tutorials/
touch src/index.html

Either way, click the file in the sidebar to open it in the editor.


The basic document

Type this out rather than copying it. Writing boilerplate by hand a few times is what makes it stick.

html~/tutorials/
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Project</title>
  </head>
  <body>

  </body>
</html>

Let’s go through what each line does.

<!DOCTYPE html> tells the browser this is an HTML5 document. Without it, browsers enter “quirks mode,” a compatibility state that causes inconsistent rendering. Always include it, always first.

<html lang="en"> is the root element that wraps everything. The lang attribute tells browsers and screen readers what language the page is in. This matters for accessibility and for search engines. Set it to match the actual language of your content.

A note on lang: "en" is correct when your content is in English. If you’re building a page in French, use lang="fr". Spanish is lang="es". Japanese is lang="ja". The value is an IETF language tag, a standardized code, not a guess. You can also apply lang to individual elements within a page when only a portion of the content is in a different language, which is useful for multilingual sites. A screen reader uses this attribute to switch pronunciation and speech rules, so getting it right has real consequences for users.

<head> contains metadata: information about the document that doesn’t appear on the page itself.

<meta charset="UTF-8"> sets the character encoding. UTF-8 handles virtually every character in every language. Without it, special characters can render as garbage.

<meta name="viewport" ...> controls how the page scales on mobile. Without it, mobile browsers shrink the page to fit a desktop layout. With it, the page respects the actual screen width and responds to your CSS correctly.

<title> sets the text in the browser tab and in search results.

<body> is where your visible content goes.


Preview your page

With the Live Preview extension from Chapter 3 installed, click the preview icon in the top right of the editor, or open the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and search for Live Preview: Start Server. A browser panel opens alongside your editor and updates automatically each time you save.


Elements and attributes

HTML is made of elements. Most elements have an opening tag and a closing tag with content between them:

html~/tutorials/
<p>This is a paragraph.</p>

Some elements are self-closing, meaning they have no content and no closing tag:

html~/tutorials/
<img src="photo.jpg" alt="A description of the photo" />
<meta charset="UTF-8" />

Attributes go inside the opening tag and provide additional information about the element. In <img src="photo.jpg" alt="...">, src and alt are both attributes. src tells the browser where the image file is. alt provides a text description for screen readers and for cases where the image fails to load.

The alt attribute is not optional. If an image is purely decorative, use alt="" to tell screen readers to skip it. If the image carries meaning, describe that meaning. This is where accessibility starts: in the markup, before you’ve written a line of CSS.


Semantic HTML

There are two ways to mark up a page: with semantic elements and with generic containers.

A <div> is a generic container. It means nothing on its own. A <nav> means “this is a navigation block.” A <main> means “this is the primary content of the page.” A <footer> means “this is a footer.” Screen readers, search engines, and other browsers use those meanings to understand your page.

Compare:

html~/tutorials/
<!-- Generic. The browser has no idea what any of this is. -->
<div class="header">
  <div class="nav">
    <div class="nav-item"><a href="/">Home</a></div>
  </div>
</div>

<!-- Semantic. The structure tells the story. -->
<header>
  <nav>
    <ul>
      <li><a href="/">Home</a></li>
    </ul>
  </nav>
</header>

Both render a link in a browser. One communicates structure. Use semantic elements by default and reach for <div> when no semantic element fits the job.

MDN maintains a complete HTML elements reference. It’s worth browsing even before you need it.


Build a simple page

Add this to the <body> of index.html. Try using Emmet: type header>nav>ul>li*2>a and press Tab, then fill in the content.

html~/tutorials/
<body>
  <header>
    <nav>
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about.html">About</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <article>
      <h1>Getting started with front-end development</h1>
      <p>
        This is a project built as part of a tutorial series covering
        the basics of front-end development. By the end, you'll have
        built a working WordPress theme from scratch.
      </p>

      <h2>What you'll need</h2>
      <ul>
        <li>A computer running macOS or Linux</li>
        <li>A text editor</li>
        <li>A terminal</li>
      </ul>

      <h2>A note on process</h2>
      <p>
        Each chapter assumes you've completed the previous one. If
        something here isn't making sense, go back to the chapter
        that introduced it.
      </p>
    </article>
  </main>

  <footer>
    <p>&copy; 2026 Your Name</p>
  </footer>
</body>

Save the file. The Live Preview panel updates immediately. The page is unstyled. That’s correct. HTML is structure. Style comes in the next chapter.


Elements worth knowing

You’ve used several already. Here are the others you’ll reach for regularly.

<h1> through <h6> are headings. <h1> is the most important. Use exactly one <h1> per page. Headings communicate hierarchy, not visual size. Control size with CSS.

<p> is a paragraph.

<a href="..."> is a link. The href attribute sets the destination: another page, another site, a section of the current page via #id, an email address with mailto:, or a phone number with tel:.

<img src="..." alt="..."> embeds an image. Always include alt.

<ul> is an unordered list. <ol> is an ordered list. Both contain <li> elements.

<section> groups related content within a page. <article> is for content that makes sense independently of the surrounding page. <aside> is for content tangentially related to the main content.

<strong> and <em> convey importance and emphasis. They have semantic meaning. <b> and <i> are purely visual. Use <strong> and <em>.


Commit your work

Open the integrated terminal in VS Code with Ctrl+` and run:

bash~/tutorials/
git add .
git commit -m "Add initial HTML structure"

What you now know

You can write a well-structured HTML document with semantic elements, proper metadata, and accessible image markup. In Chapter 5 you’ll create a stylesheet and start making this page look like something.

Reference