Build a Semantic Landing Page with Vanilla JS Form Validation

Computer Science

Build a Semantic Landing Page with Vanilla JS Form Validation

HTML5CSS3Vanilla JavaScript (ES6)

Build a Semantic Landing Page with Vanilla JS Form Validation

From your solid HTML/CSS foundation, you’ll create a compact, accessible landing page and add a client‑side contact form that validates inputs and shows inline messages – all without any backend.

3 modules9 lessonsComputer ScienceHTML5CSS3Vanilla JavaScript (ES6)Live Server (VS Code extension) for local preview

What you learn by building this

  • Create a fully semantic HTML structure for a landing page
  • Apply modern CSS selectors and layout techniques to achieve a compact design
  • Write vanilla JavaScript to capture form input, validate fields, and display inline feedback
  • Ensure the form is accessible and usable on all devices without server‑side code

Learning Journey

1

Semantic Markup Foundations

2 lessons

Lay the structural groundwork for the landing page using only semantic HTML elements.

2

Styling the Landing Page

3 lessons

Use modern CSS selectors and layout modules to turn the markup into a compact, responsive design.

3

Vanilla JavaScript Form Validation

4 lessons

Add client‑side logic that validates input, shows inline feedback, and clears the form on success.

Public lesson

Map the page layout with semantic elements

Lesson 3.1 — Give your page a semantic map

Your HTML project already demonstrated that you can build a document structure. This time, make the structure describe the page’s purpose clearly—not just how it happens to look. Keep your existing class names where possible so your CSS selectors continue to work.

Tasks

1. Map the page before changing it

Open your current index.html. On paper or in a note, match each visible area to one of these roles:

  • Header — site name or logo and the main navigation
  • Hero — the page’s main introduction and primary action
  • Features — the repeated benefits or capabilities
  • Contact — the heading, supporting text, and message form
  • Footer — copyright or secondary information

Tasks

Now inspect your current markup. For each area, write down:

  1. Which element contains it now?
  2. Which semantic element should contain it?
  3. Which existing class or id must remain for your CSS?

For example:

Page areaSemantic elementExisting selector to preserve
Site navigation<header> and <nav>your current navigation class
Main introduction<section> inside <main>your hero class
Repeated feature<article>your feature-card class

You already know CSS selectors, so this is a chance to practice changing the HTML structure without accidentally disconnecting the styles.

Tasks

2. Build the document skeleton

In index.html, create a semantic structure like this. The comments show decisions you still need to make; do not leave them as the final page content.

<!-- tangeble:starter -->
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title><!-- write the page title --></title>
  <link rel="stylesheet" href="<!-- keep your stylesheet path -->">
</head>
<body>
  <header>
    <!-- site name or logo -->

    <nav aria-label="Primary navigation">
      <!-- add links to the page sections -->
    </nav>
  </header>

  <main>
    <section id="hero" aria-labelledby="hero-title">
      <h1 id="hero-title"><!-- write the page's main heading --></h1>
      <!-- add the hero description and primary action -->
    </section>

    <section id="features" aria-labelledby="features-title">
      <h2 id="features-title"><!-- write the features heading --></h2>
      <!-- create one article for each repeated feature -->
    </section>

    <section id="contact" aria-labelledby="contact-title">
      <h2 id="contact-title"><!-- write the contact heading --></h2>
      <!-- add supporting contact text -->

      <form action="#" method="post">
        <!-- add a labeled name field -->
        <!-- add a labeled email field -->
        <!-- add a labeled message field -->
        <!-- add a submit button -->
      </form>
    </section>
  </main>

  <footer>
    <!-- add the footer content -->
  </footer>
</body>
</html>

Use your project’s real content rather than inventing a new page. A semantic element should describe the purpose of its content:

  • Use <header> for introductory or navigational content.
  • Use one <main> for the page’s central content.
  • Use <section> for each major, named area.
  • Use <article> for each feature that could make sense as a separate item.
  • Use <footer> for closing information.
  • Use <nav> around navigation links.
  • Use <form> around controls that collect information.

Tasks

Check in the browser

Save the file and refresh the page.

The page may look different if your old CSS depended on a wrapper such as <div>. That is useful evidence, not a failure. Use the browser inspector to check:

  • Is there exactly one <main>?
  • Are the hero, features, and contact areas inside <main>?
  • Does each section have a heading?
  • Are the feature items grouped consistently?
  • Is the page’s content still visible?

If a style disappeared, compare the old and new class names. Restore the class on the new semantic element instead of adding unnecessary wrapper elements.

Tasks

3. Turn the features into repeated articles

Inside the features section, create an <article> for every feature card. Each article should have its own heading.

A feature section should have this shape, adapted to your project’s content and class names:

<section class="your-features-class" id="features" aria-labelledby="features-title">
  <h2 id="features-title">Your features heading</h2>

  <article class="your-card-class">
    <h3>First feature</h3>
    <p>Description of the first feature.</p>
  </article>

  <!-- add the remaining feature articles -->
</section>

Do not copy the example’s class names unless they match your project. The important relationship is:

section heading → repeated article → article heading and content

Tasks

Refresh the page and confirm that every feature still appears. In the inspector, expand the features section and count the <article> elements.

Tasks

4. Give every form control a real label

A form is more usable when someone can identify each control even without relying on placeholder text. For each control:

  1. Give the <label> a for value.
  2. Give the matching input or textarea the same id.
  3. Add a useful name value.
  4. Add required where the field must be completed.

Tasks

Create your fields using this pattern, changing the names and wording to fit your project:

<label for="your-field-id">Your field label</label>
<input id="your-field-id" name="your-field-name" type="text" required>

For the email field, use type="email". For a longer message, use <textarea> rather than a single-line <input>.

Tasks

Your form should contain:

  • a name field
  • an email field
  • a message field
  • a submit button

The form does not need a working backend yet. Its job in this lesson is to have clear, valid structure.

Tasks

Check the labels

Click each label in the browser. The corresponding input should receive focus. If it does not, the label’s for value and control’s id do not match exactly.

Tasks

5. Connect the navigation

Give each navigation link an href that points to one of your section IDs:

<a href="#your-section-id">Your link text</a>

Make sure the destination ID exists exactly once. Test every link by clicking it. The browser should move to the matching section.

Tasks

6. Run the semantic validation check

Use the Nu HTML Checker at validator.w3.org/nu. Upload your index.html or validate its local source.

Tasks

Fix errors one at a time. In particular, look for:

  • missing closing tags
  • duplicate id values
  • headings placed outside the intended section
  • labels whose for value does not match an input id
  • incorrectly nested elements
  • missing alt text on images, if your page has images

Warnings are worth reading, but first get the document to zero errors.

Finished when

Your index.html meets all of these checks:

  • It has one <header>, one <main>, and one <footer>.
  • The hero, features, and contact areas are named <section> elements.
  • Each section has an appropriate heading.
  • Repeated features use <article>.
  • Navigation links point to real section IDs.
  • Every form control has a matching label.
  • The browser still displays your page and its styles.
  • The semantic validator reports no errors.

Course Outline

3 modules · 9 lessons

Semantic Markup Foundations

Styling the Landing Page

Vanilla JavaScript Form Validation

Learn by building your own version.

Remix this public project to open the workspace, follow the guided build, and let the AI mentor teach you through the work instead of doing it for you.