In short
In this beginner CSS project, you will style a profile card step by step using colors, fonts, the box model, border-radius and box-shadow. The full final code is at the end. What you will build You'll build a profile card: the kind of small box you see on team pages, social apps and portfolios.
In this beginner CSS project, you will style a profile card step by step using colors, fonts, the box model, border-radius and box-shadow. The full final code is at the end.
What you will build
You'll build a profile card: the kind of small box you see on team pages, social apps and portfolios. It has a round photo, a name, a job title, a short bio, a few skill tags and a "Contact me" button. It's a perfect project because it uses almost everything from this level.
Create a folder called profile-card with two files: index.html and styles.css. Put any square photo in the same folder and name it avatar.jpg.
Step 1: Write the HTML
Start with clean HTML that describes the content. No styling yet.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profile Card</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<article class="card">
<img class="card-photo" src="avatar.jpg" alt="Portrait of Maya Chen">
<h1 class="card-name">Maya Chen</h1>
<p class="card-role">Front-End Developer</p>
<p class="card-bio">I build friendly, fast websites for small businesses. When I'm not coding, I'm baking bread or hiking.</p>
<p class="card-tags">
<span class="tag">HTML</span>
<span class="tag">CSS</span>
<span class="tag">Design</span>
</p>
<a class="card-button" href="mailto:maya@example.com">Contact me</a>
</article>
</body>
</html>
Open it in the browser. You'll see a plain page, maybe with a very large photo. That's fine. Every element has a class, so styling will be easy.
Step 2: Reset, page background and font
Start styles.css with the box-sizing reset, then style the whole page.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
padding: 2rem 1rem;
font-family: "Poppins", system-ui, sans-serif;
color: #2d3748;
background-image: linear-gradient(135deg, #e0f2f1, #e8eaf6);
}
The page now has a soft teal-to-lavender gradient that fills the screen, and all text uses Poppins with a system font as backup.
Step 3: Shape the card with the box model
Now turn the <article> into a white, centered card.
.card {
max-width: 340px;
margin: 0 auto;
padding: 2rem 1.5rem;
background-color: #ffffff;
border-radius: 16px;
box-shadow: 0 10px 30px rgb(0 0 0 / 0.1);
text-align: center;
}
Two new properties appear here:
border-radiusrounds the corners. Bigger values mean rounder corners.box-shadowadds a shadow around the box. The values are: horizontal offset (0), vertical offset (10px), blur (30px) and color. A soft, transparent shadow makes the card look like it floats above the page.
Step 4: The round photo
.card-photo {
display: block;
width: 120px;
height: 120px;
margin: 0 auto 1rem;
border-radius: 50%;
border: 4px solid #4db6ac;
object-fit: cover;
}
The image is now a block, so margin: 0 auto can center it. border-radius: 50% on a square makes a perfect circle. object-fit: cover makes sure the photo fills the circle without stretching, even if it isn't perfectly square.
Tip: If your photo looks squashed, check that
widthandheightare equal and thatobject-fit: coveris there.
Step 5: Text styles
.card-name {
margin: 0;
font-size: 1.5rem;
font-weight: 600;
}
.card-role {
margin: 0.25rem 0 1rem;
font-size: 0.85rem;
color: #00897b;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.card-bio {
margin: 0 0 1rem;
line-height: 1.6;
color: #4a5568;
}
The name is big and bold, the job title is a small teal uppercase label with extra letter spacing, and the bio has comfortable line height. Setting the margins ourselves, instead of using the browser defaults, gives us control over the spacing.
Step 6: Skill tags and the button
.tag {
display: inline-block;
margin: 0.2rem;
padding: 0.25rem 0.75rem;
font-size: 0.8rem;
background-color: #e0f2f1;
color: #00695c;
border-radius: 999px;
}
.card-button {
display: inline-block;
margin-top: 1rem;
padding: 0.75rem 1.75rem;
background-color: #00897b;
color: #ffffff;
text-decoration: none;
font-weight: 600;
border-radius: 8px;
}
.card-button:hover {
background-color: #00695c;
}
The tags become small pill shapes thanks to inline-block, padding and a very large border-radius. The link looks like a solid teal button that gets darker when you hover over it.
Common mistake: Forgetting
display: inline-blockon the tags and button. As inline elements, their top and bottom padding would overlap nearby lines and the spacing would look broken.
Final code: the complete profile card CSS
Here is the full styles.css. Use it with the HTML from Step 1.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
padding: 2rem 1rem;
font-family: "Poppins", system-ui, sans-serif;
color: #2d3748;
background-image: linear-gradient(135deg, #e0f2f1, #e8eaf6);
}
.card {
max-width: 340px;
margin: 0 auto;
padding: 2rem 1.5rem;
background-color: #ffffff;
border-radius: 16px;
box-shadow: 0 10px 30px rgb(0 0 0 / 0.1);
text-align: center;
}
.card-photo {
display: block;
width: 120px;
height: 120px;
margin: 0 auto 1rem;
border-radius: 50%;
border: 4px solid #4db6ac;
object-fit: cover;
}
.card-name {
margin: 0;
font-size: 1.5rem;
font-weight: 600;
}
.card-role {
margin: 0.25rem 0 1rem;
font-size: 0.85rem;
color: #00897b;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.card-bio {
margin: 0 0 1rem;
line-height: 1.6;
color: #4a5568;
}
.tag {
display: inline-block;
margin: 0.2rem;
padding: 0.25rem 0.75rem;
font-size: 0.8rem;
background-color: #e0f2f1;
color: #00695c;
border-radius: 999px;
}
.card-button {
display: inline-block;
margin-top: 1rem;
padding: 0.75rem 1.75rem;
background-color: #00897b;
color: #ffffff;
text-decoration: none;
font-weight: 600;
border-radius: 8px;
}
.card-button:hover {
background-color: #00695c;
}
Refresh the page. You now have a polished profile card: a white rounded box floating on a soft gradient, with a circular photo, clear text hierarchy, colorful skill tags and a button. It also works on phones, because the card uses max-width and the body has side padding.
Practice exercise
Make the card your own. Change the main teal color to your favorite color everywhere it appears, add a fourth skill tag, and give the card a colored top border with border-top: 6px solid plus your color. For a challenge, make a second card for a friend and place both on the page.
Hint: use your browser's DevTools to try new colors live, then copy the ones you like into styles.css. If you want the two cards side by side, try display: inline-block with vertical-align: top on each card, or wait for the Flexbox module.
Key takeaways
- Start with clean, meaningful HTML and give each part a clear class name.
- The box-sizing reset,
max-widthandmargin: 0 autocreate a centered, responsive card. border-radiusrounds corners;50%on a square makes a circle.- A soft
box-shadowwith a transparent color adds depth. - Small text details like uppercase labels and
line-heightmake a design look professional.