Beginner HTML and CSS lab

Responsive Website Project with HTML and CSS for Beginners

Build a small business landing page with navigation, three service cards and a contact section. The complete example below runs as one HTML file, so you can practice layout without installing packages. It uses a fictional brand and does not send forms or collect enquiries.

This is an original learning exercise for students exploring Web Designing training in Vizag. For the order in which to learn the skills, see the beginner web designing roadmap.

The project brief

Imagine a visitor who wants to understand what a small studio does and find its contact information. The page should communicate the service quickly, work with a keyboard and remain readable on a phone. Harbour Studio is a fictional practice business, not a real client or a student placement claim.

  • Keep the navigation visible at narrow widths by allowing it to wrap.
  • Show cards in one column on smaller screens and three columns when space allows.
  • Make the main call to action reach the service section.
  • Label the contact section as a static example.

Run the complete example

  1. Create a folder named responsive-site.
  2. Create index.html inside it and paste the code below.
  3. Save the file, then open it in your browser.
  4. Resize the window and follow each navigation link.

No account, build tool or JavaScript library is required. If your editor saves a file named index.html.txt, rename it so the extension is .html.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Harbour Studio | Web Design Practice Project</title>
  <style>
    * { box-sizing: border-box; }
    body { margin: 0; font-family: system-ui, sans-serif; color: #172b42; line-height: 1.6; }
    a { color: #174db2; }
    a:focus-visible { outline: 3px solid #bf5800; outline-offset: 4px; }
    .wrap { width: min(100% - 2rem, 68rem); margin-inline: auto; }
    .skip { position: absolute; left: 1rem; top: -8rem; padding: .5rem; background: white; }
    .skip:focus { top: 1rem; z-index: 2; }
    header { background: #f0f5fc; border-bottom: 1px solid #cad8ea; }
    .header-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding-block: 1rem; }
    .brand { color: #172b42; font-weight: 800; text-decoration: none; }
    nav ul { display: flex; flex-wrap: wrap; gap: .5rem 1rem; list-style: none; padding: 0; margin: 0; }
    nav a { display: inline-block; padding-block: .6rem; }
    .hero { padding-block: clamp(2.5rem, 8vw, 5rem); }
    .eyebrow { font-weight: 700; color: #174db2; }
    h1 { max-width: 20ch; font-size: clamp(2rem, 5vw, 3.6rem); line-height: 1.1; }
    h2 { font-size: 1.8rem; line-height: 1.25; }
    h3 { margin-top: 0; }
    p { max-width: 65ch; }
    .button { display: inline-block; padding: .8rem 1.2rem; background: #174db2; color: white; border-radius: .4rem; text-decoration: none; }
    section { padding-block: 2rem; scroll-margin-top: 1rem; }
    .cards { display: grid; grid-template-columns: 1fr; gap: 1rem; }
    .card { min-width: 0; border: 1px solid #cad8ea; border-radius: .6rem; padding: 1.4rem; overflow-wrap: anywhere; }
    .contact { background: #f0f5fc; border-radius: .6rem; padding: 1.5rem; }
    footer { border-top: 1px solid #cad8ea; margin-top: 2rem; padding-block: 1.5rem; }
    @media (min-width: 48rem) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  </style>
</head>
<body>
  <a class="skip" href="#main">Skip to content</a>
  <header>
    <div class="wrap header-row">
      <a class="brand" href="#main">Harbour Studio</a>
      <nav aria-label="Main navigation">
        <ul><li><a href="#services">Services</a></li><li><a href="#work">Our approach</a></li><li><a href="#contact">Contact</a></li></ul>
      </nav>
    </div>
  </header>
  <main id="main" class="wrap">
    <section class="hero" aria-labelledby="intro-title">
      <p class="eyebrow">Fictional business · HTML and CSS practice</p>
      <h1 id="intro-title">Simple websites for local businesses.</h1>
      <p>This student exercise demonstrates a clear introduction, flexible navigation, service cards and a contact section. Harbour Studio is a fictional practice brand.</p>
      <a class="button" href="#services">Explore the sample services</a>
    </section>
    <section id="services" aria-labelledby="services-title">
      <h2 id="services-title">Sample services</h2>
      <div class="cards">
        <article class="card"><h3>Portfolio layout</h3><p>Introduce a person, show project work and make the next step easy to find.</p></article>
        <article class="card"><h3>Business landing page</h3><p>Explain one service with a clear heading, useful details and a contact action.</p></article>
        <article class="card"><h3>Responsive review</h3><p>Check text, navigation and card layouts on narrow and wide screens.</p></article>
      </div>
    </section>
    <section id="work" aria-labelledby="work-title">
      <h2 id="work-title">From brief to browser</h2>
      <ol><li>Sketch the content order.</li><li>Write semantic HTML before styling.</li><li>Add CSS and test at several widths.</li></ol>
    </section>
    <section id="contact" class="contact" aria-labelledby="contact-title">
      <h2 id="contact-title">Contact section</h2>
      <p>This is a static practice page. It does not send enquiries or collect personal details. Replace this section with your own contact information only when you are ready to publish your portfolio.</p>
      <a href="#main">Back to the introduction</a>
    </section>
  </main>
  <footer><div class="wrap">Student exercise · Fictional content · Built with HTML and CSS</div></footer>
</body>
</html>

How the layout works

The .wrap container has side space on small screens and a maximum width on large ones. The header uses Flexbox with wrapping, which keeps its links available instead of depending on a hidden mobile menu. Cards start in one column; a media query switches them to three columns at 48rem.

minmax(0,1fr) lets the columns share available space without forcing a large minimum track width. The cards also allow long text to wrap. The heading uses clamp() to vary its font size between a minimum and maximum. These are small, inspectable choices rather than a complete design framework.

For more background, read MDN’s responsive design explanation. A breakpoint is a layout decision based on content space, not a guarantee that only one named phone or tablet will use that layout.

Test the page before calling it finished

CheckExpected result
375px viewportCards stack, navigation remains visible and the page does not scroll sideways.
768px and 1440px viewportsCards use available width without overlapping; body text remains readable.
Keyboard onlyTab reveals the skip link; links have a visible focus outline; Enter follows the selected link.
Longer contentAdding sentences to a card increases its height without hiding the text.
Navigation linksServices, Our approach and Contact reach the corresponding sections.
Increased text sizeHeadings and navigation wrap instead of covering other content.

Also check intermediate widths and, if available, a real phone. This is a starter test list, not a complete accessibility audit. Record the actual checks you perform in your README rather than claiming that the site works on every device.

Common problems and where to look

  • The browser displays code: check the file extension and that the HTML was pasted without surrounding Markdown fences.
  • A link does not move: its href="#services" must match an existing id="services".
  • A card spills out: inspect fixed widths, long unbroken text and any new margins before hiding overflow.
  • Your changes do not appear: save the correct file, refresh and confirm the browser is opening that file.
  • An image breaks the layout: check its path and give it responsive dimensions when you add it.

Extensions that make the work your own

First change the content and typography. Then add an about page with consistent navigation. Add an image you are allowed to use, descriptive alternative text where appropriate and a flexible width. Try a four-card layout and explain when it should use one, two or four columns.

A contact form is a separate extension. HTML labels, input types and required fields can improve the interface, but they do not deliver an email on their own. A real submission flow needs a suitable endpoint or form service, server-side validation and a clear success or error response. MDN’s forms and buttons guide is a useful starting point.

What to include in your project portfolio

Save the source, a screenshot at a narrow width and one at a wide width. Add a README with the fictional brief, features, setup steps, checks performed and limitations. Describe one bug you found and the rule you changed to fix it. Keep the contact section’s static behavior explicit.

For guided practice across HTML, CSS, Bootstrap, responsive layouts and portfolio preparation, review Softenant’s Web Designing course in Visakhapatnam. Use this exercise to identify which parts you can explain and which you want help understanding in a demo class.

Leave a Comment

Your email address will not be published. Required fields are marked *