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.htmland 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>© 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.