30. CSS Practical Project: Style a Profile Page

What you will build

A styled, responsive personal profile page: a header with navigation, a card layout, a styled table, a form, and a footer. It uses variables, Flexbox, Grid, transitions, and a media query.

Before you start

  • You can follow along in the Try it Yourself editor below, or save the file on your computer as profile.html and open it in a browser.
  • Build it in steps. After each step, run the code and check the result.

Step 1: Variables and reset

Step 1: CSS

<style>
  :root {
    --primary: #0d6efd;
    --navy: #082b59;
    --light: #eaf5ff;
    --border: #cfe6ff;
    --text: #17345c;
    --radius: 10px;
  }

  *, *::before, *::after { box-sizing: border-box; }

  body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
    line-height: 1.6;
    color: var(--text);
  }
</style>

Step 2: Header and navigation

A dark header with a flexible menu that wraps on small screens.

Step 2: CSS

header {
  background-color: var(--navy);
  color: white;
  padding: 24px 16px;
  text-align: center;
}
header h1 { margin: 0 0 4px; }

nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 16px;
}
nav a {
  color: white;
  text-decoration: none;
  padding: 8px 16px;
  border-radius: 20px;
  transition: background-color 0.2s ease;
}
nav a:hover { background-color: var(--primary); }
nav a:focus-visible { outline: 3px solid white; outline-offset: 2px; }

Step 3: Page layout and cards

Step 3: CSS

main {
  max-width: 960px;
  margin: 0 auto;
  padding: 24px 16px;
  display: grid;
  gap: 20px;
}

section {
  background-color: white;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
}
section h2 { margin-top: 0; color: var(--navy); }

Step 4: Table, list, and form

Step 4: CSS

table { border-collapse: collapse; width: 100%; }
th, td { padding: 10px; text-align: left; border-bottom: 1px solid var(--border); }
th { background-color: var(--light); }
tbody tr:hover { background-color: var(--light); }

.skills { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; padding: 0; }
.skills li { background-color: var(--light); padding: 6px 14px; border-radius: 20px; }

label { display: block; margin-top: 12px; font-weight: 600; }
input, textarea {
  width: 100%;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit;
}
input:focus, textarea:focus { outline: 3px solid var(--primary); outline-offset: 1px; }

button {
  margin-top: 16px;
  padding: 10px 24px;
  color: white;
  background-color: var(--primary);
  border: 0;
  border-radius: 6px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s ease;
}
button:hover { background-color: var(--navy); }

Step 5: Footer and responsive layout

Step 5: CSS

footer {
  text-align: center;
  padding: 20px;
  background-color: var(--light);
  border-top: 1px solid var(--border);
}

@media (min-width: 700px) {
  main { grid-template-columns: 1fr 1fr; }
  .wide { grid-column: span 2; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; }
}

The complete file

Press Try it Yourself to run the finished page, then change colours, text, and layout.

Example: complete page

<style>
  :root {
    --primary: #0d6efd;
    --navy: #082b59;
    --light: #eaf5ff;
    --border: #cfe6ff;
    --text: #17345c;
    --radius: 10px;
  }
  *, *::before, *::after { box-sizing: border-box; }
  body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
    line-height: 1.6;
    color: var(--text);
    padding: 0;
  }

  header { background-color: var(--navy); color: white; padding: 24px 16px; text-align: center; }
  header h1 { margin: 0 0 4px; }
  nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 16px; }
  nav a { color: white; text-decoration: none; padding: 8px 16px; border-radius: 20px; transition: background-color 0.2s ease; }
  nav a:hover { background-color: var(--primary); }
  nav a:focus-visible { outline: 3px solid white; outline-offset: 2px; }

  main { max-width: 960px; margin: 0 auto; padding: 24px 16px; display: grid; gap: 20px; }
  section { background-color: white; border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; }
  section h2 { margin-top: 0; color: var(--navy); }

  table { border-collapse: collapse; width: 100%; }
  th, td { padding: 10px; text-align: left; border-bottom: 1px solid var(--border); }
  th { background-color: var(--light); }
  tbody tr:hover { background-color: var(--light); }

  .skills { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; padding: 0; margin: 0; }
  .skills li { background-color: var(--light); padding: 6px 14px; border-radius: 20px; }

  label { display: block; margin-top: 12px; font-weight: 600; }
  input, textarea { width: 100%; padding: 10px; border: 1px solid var(--border); border-radius: 6px; font: inherit; }
  input:focus, textarea:focus { outline: 3px solid var(--primary); outline-offset: 1px; }
  button { margin-top: 16px; padding: 10px 24px; color: white; background-color: var(--primary); border: 0; border-radius: 6px; font: inherit; font-weight: 600; cursor: pointer; transition: background-color 0.2s ease; }
  button:hover { background-color: var(--navy); }

  footer { text-align: center; padding: 20px; background-color: var(--light); border-top: 1px solid var(--border); }

  @media (min-width: 700px) {
    main { grid-template-columns: 1fr 1fr; }
    .wide { grid-column: span 2; }
  }
  @media (prefers-reduced-motion: reduce) {
    * { transition-duration: 0.01ms !important; }
  }
</style>

<header>
  <h1>Sam Rivera</h1>
  <p>Student and future web developer</p>
  <nav aria-label="Page sections">
    <a href="#about">About</a>
    <a href="#skills">Skills</a>
    <a href="#hobbies">Hobbies</a>
    <a href="#contact">Contact</a>
  </nav>
</header>

<main>
  <section id="about">
    <h2>About me</h2>
    <p>Hello! I am learning HTML and CSS to build my own websites.</p>
  </section>

  <section id="skills">
    <h2>Skills</h2>
    <ul class="skills">
      <li>HTML</li>
      <li>CSS</li>
      <li>Problem solving</li>
    </ul>
  </section>

  <section id="hobbies" class="wide">
    <h2>Hobbies</h2>
    <table>
      <caption>My weekly hobbies</caption>
      <thead><tr><th scope="col">Hobby</th><th scope="col">Hours per week</th></tr></thead>
      <tbody>
        <tr><td>Reading</td><td>5</td></tr>
        <tr><td>Football</td><td>3</td></tr>
      </tbody>
    </table>
  </section>

  <section id="contact" class="wide">
    <h2>Contact me</h2>
    <form action="#" method="post">
      <label for="name">Name</label>
      <input type="text" id="name" name="name">
      <label for="email">Email</label>
      <input type="email" id="email" name="email">
      <label for="message">Message</label>
      <textarea id="message" name="message" rows="4"></textarea>
      <button type="button">Send</button>
    </form>
  </section>
</main>

<footer>
  <p>&copy; 2026 Sam Rivera</p>
</footer>

The Send button uses type="button" so it does nothing inside the sandboxed editor. A real contact form needs server-side code, which you will meet in the PHP course.

Challenges

  • Change the variables to a new colour scheme, such as green or purple.
  • Add a dark mode with @media (prefers-color-scheme: dark) and variables.
  • Make the cards lift slightly on hover with a transition.
  • Add a fourth section using Grid or Flexbox.
  • Check text contrast and keyboard focus on every control.

Common mistakes

  • Skipping the viewport meta tag when you save the page as a file.
  • Forgetting to close a brace, which breaks every rule after it.
  • Typing a variable name differently from where you declared it.
  • Testing only on a wide screen.

Summary

  • You built a responsive page with variables, Flexbox, Grid, transitions, and media queries.
  • You styled tables, lists, links, and forms accessibly.
  • Next, the JavaScript course makes your pages interactive.
Scroll to Top