HTML Tutorial

HTML Project: Restaurant Menu

A cafe menu grouped by section: starters, mains, and drinks, with prices in a readable table.

What you will build

A cafe menu for North Pine Kitchen. The page names the cafe, then three sections: starters, mains, and drinks. Each section is a table of item names and prices, not a decorative layout grid.

Prices are data. That is why they sit in <table>. Headings name the groups. A caption on each table tells a screen reader what the numbers mean.

Use Try it in HTML under an example to open /html/try. That is the HTML preview, not a Python window.

Tags you will use

TagJob on this page
headerCafe name and a one-line promise
sectionOne group: starters, mains, or drinks
h1 / h2Page title, then each group title
table, caption, th, tdItem and price rows
thead and tbodyHeader row versus data rows

Do not fake columns with spaces in a paragraph. A table keeps the price aligned when the dish name is long.

Build in slices

First write the banner. A cafe needs a name people can say out loud.

Example

<header>
  <h1>North Pine Kitchen</h1>
  <p>Daytime plates, poured drinks, and a quiet window table.</p>
</header>

Then add one section as a table. Caption first. Header cells for Dish and Price. Two data rows are enough to test alignment.

Example

<section>
  <h2>Starters</h2>
  <table>
    <caption>Starters and prices in euros</caption>
    <thead>
      <tr>
        <th scope="col">Dish</th>
        <th scope="col">Price</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Pickled beet and rye</td>
        <td>6.50</td>
      </tr>
      <tr>
        <td>Leek soup</td>
        <td>5.00</td>
      </tr>
    </tbody>
  </table>
</section>

Preview the slice at /html/try before you add mains and drinks. If the table looks like a blob, your CSS is missing, not the HTML.

Complete document

Three sections, three tables, one stylesheet. Borders stay light so the type does the work. Prices sit on the right of each row.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>North Pine Kitchen menu</title>
  <style>
    body {
      margin: 0;
      background: #f4efe6;
      color: #2a2118;
      font-family: Georgia, serif;
    }
    header, main {
      max-width: 36rem;
      margin: 0 auto;
      padding: 1.5rem 1.2rem 0;
    }
    header p { color: #5a4c3c; }
    h1 { margin-bottom: 0.3rem; }
    h2 {
      margin: 1.6rem 0 0.5rem;
      font-size: 1.15rem;
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }
    table {
      width: 100%;
      border-collapse: collapse;
      margin-bottom: 0.4rem;
    }
    caption {
      caption-side: bottom;
      text-align: left;
      font-size: 0.8rem;
      color: #6b5c4b;
      padding-top: 0.35rem;
    }
    th, td {
      border-bottom: 1px solid #d7cbb8;
      padding: 0.45rem 0;
    }
    th { text-align: left; }
    td:last-child, th:last-child {
      text-align: right;
      font-variant-numeric: tabular-nums;
    }
    footer {
      max-width: 36rem;
      margin: 1.5rem auto 2rem;
      padding: 0 1.2rem;
      font-size: 0.9rem;
      color: #5a4c3c;
    }
  </style>
</head>
<body>
  <header>
    <h1>North Pine Kitchen</h1>
    <p>Daytime plates, poured drinks, and a quiet window table.</p>
  </header>
  <main>
    <section>
      <h2>Starters</h2>
      <table>
        <caption>Starters and prices in euros</caption>
        <thead>
          <tr><th scope="col">Dish</th><th scope="col">Price</th></tr>
        </thead>
        <tbody>
          <tr><td>Pickled beet and rye</td><td>6.50</td></tr>
          <tr><td>Leek soup</td><td>5.00</td></tr>
          <tr><td>Warm olives</td><td>4.00</td></tr>
        </tbody>
      </table>
    </section>
    <section>
      <h2>Mains</h2>
      <table>
        <caption>Mains and prices in euros</caption>
        <thead>
          <tr><th scope="col">Dish</th><th scope="col">Price</th></tr>
        </thead>
        <tbody>
          <tr><td>Mushroom barley bowl</td><td>13.00</td></tr>
          <tr><td>Trout on greens</td><td>16.50</td></tr>
          <tr><td>Herb omelette</td><td>11.00</td></tr>
        </tbody>
      </table>
    </section>
    <section>
      <h2>Drinks</h2>
      <table>
        <caption>Drinks and prices in euros</caption>
        <thead>
          <tr><th scope="col">Drink</th><th scope="col">Price</th></tr>
        </thead>
        <tbody>
          <tr><td>Filter coffee</td><td>2.80</td></tr>
          <tr><td>Pot of mint tea</td><td>3.20</td></tr>
          <tr><td>Sparkling water</td><td>2.00</td></tr>
        </tbody>
      </table>
    </section>
  </main>
  <footer>
    <p>Kitchen closes at 15:00. Ask the counter about allergens.</p>
  </footer>
</body>
</html>

Evening board, same structure

A second complete menu proves the pattern. New cafe, new dishes, same three sections and tables.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Lamp Room evening board</title>
  <style>
    body {
      margin: 0;
      background: #1c1917;
      color: #f5f0e8;
      font-family: "Segoe UI", sans-serif;
    }
    header, main, footer { max-width: 34rem; margin: 0 auto; padding: 1.2rem; }
    table { width: 100%; border-collapse: collapse; }
    th, td { border-bottom: 1px solid #44403c; padding: 0.4rem 0; }
    th { text-align: left; color: #d6d3d1; }
    td:last-child, th:last-child { text-align: right; }
    caption { caption-side: bottom; text-align: left; color: #a8a29e; font-size: 0.8rem; }
    h2 { color: #fbbf24; font-size: 0.95rem; letter-spacing: 0.12em; text-transform: uppercase; }
  </style>
</head>
<body>
  <header>
    <h1>Lamp Room</h1>
    <p>Evening board. Small plates first.</p>
  </header>
  <main>
    <section>
      <h2>Starters</h2>
      <table>
        <caption>Starter prices in euros</caption>
        <thead><tr><th scope="col">Dish</th><th scope="col">Price</th></tr></thead>
        <tbody>
          <tr><td>Bread and cultured butter</td><td>4.50</td></tr>
          <tr><td>Cured trout</td><td>9.00</td></tr>
        </tbody>
      </table>
    </section>
    <section>
      <h2>Mains</h2>
      <table>
        <caption>Main prices in euros</caption>
        <thead><tr><th scope="col">Dish</th><th scope="col">Price</th></tr></thead>
        <tbody>
          <tr><td>Lamb shoulder, beans</td><td>22.00</td></tr>
          <tr><td>Roast squash, hazelnut</td><td>16.00</td></tr>
        </tbody>
      </table>
    </section>
    <section>
      <h2>Drinks</h2>
      <table>
        <caption>Drink prices in euros</caption>
        <thead><tr><th scope="col">Drink</th><th scope="col">Price</th></tr></thead>
        <tbody>
          <tr><td>House red, glass</td><td>6.00</td></tr>
          <tr><td>Still water</td><td>0.00</td></tr>
        </tbody>
      </table>
    </section>
  </main>
  <footer><p>Last seating 21:00.</p></footer>
</body>
</html>

Common mistakes

  • Using one giant table for the whole menu. Split by section so headings stay meaningful.
  • Skipping th and putting Dish and Price in a td. Headers are not data.
  • Leaving out scope="col". It costs nothing and helps the table make sense aloud.
  • Hiding prices in CSS generated content. If CSS fails, the price must still be in the cell.
  • Laying out the page with a table of empty cells. Tables are for the dishes, not the chrome.

Practice tasks

  1. Add a fourth starter to North Pine Kitchen. Keep Dish and Price in separate cells.
  2. Rename the cafe and rewrite every dish. Keep starters, mains, and drinks as three sections.
  3. Add a tfoot note under drinks that says service is included. Preview it at /html/try.

FAQ: HTML Project: Restaurant Menu

Common questions about this page.

What is the StudyGrid HTML tutorial?

The StudyGrid HTML tutorial is a full beginner track: tags, headings, links, images, tables, layout, forms, and media. Each chapter has copy-and-run examples.

Should I run html menu project examples locally for better learning?

Yes. Use the browser editor on StudyGrid for a quick check, then Download the example and run it on your computer. Local runs show real errors and the real toolchain, which is one of the fastest ways to learn html menu project in this HTML HTML lesson (HTML Project: Restaurant Menu).

Is the HTML editor the same as Try Python?

No. Try HTML is a live page preview at /html/try. Try Python stays at /try and runs Python. HTML lessons never open the Python editor.

Do I need to install anything to learn HTML?

No. Open a chapter, click Try it in HTML, and the page preview updates in the browser. You can also download a .html file and open it locally.

Where should I start the HTML tutorial?

Start at HTML Intro, then Basic, Elements, and Attributes. After the first document, continue to headings, links, and forms. Use Next at the bottom of each chapter.

Is the HTML tutorial free?

Yes. The HTML studio on StudyGrid (studygrid.in) is free: dashboard, chapters, and the live preview editor.