CSS Alignment – Center, Horizontal, and Vertical Alignment
Lesson 27: CSS Alignment — Center, Horizontal, and Vertical Alignment
Lesson Introduction
One of the most common questions in web development — even among experienced developers — is: “How do I centre this thing?”
Aligning content perfectly is one of the most important skills in CSS. Whether you are building a personal portfolio, a business landing page, a navigation bar, or a login form, you will constantly need to position elements exactly where you want them — centred on the page, pushed to the right, sitting perfectly in the middle of a box, or lined up neatly side by side.
CSS gives you many tools to control alignment. Some tools are for horizontal alignment (left, right, or centre across the page). Others are for vertical alignment (top, middle, or bottom within a container). And some powerful tools — like Flexbox — can handle both at once.
In this lesson you will learn all the major techniques for aligning elements in CSS, understand exactly when to use each one, and practice through exercises and a complete mini-project.
By the end of this lesson you will confidently be able to:
- Centre a block element horizontally using
margin: auto - Align text left, right, or centre using
text-align - Position elements using
floatandclear - Centre elements perfectly using Flexbox
- Vertically centre content using multiple techniques
- Know which technique to choose for any alignment situation
Prerequisite Concepts
Before we begin, let us make sure you understand a few building-block ideas.
Block vs Inline Elements
HTML elements fall into two main categories:
Block elements take up the full width available and always start on a new line. Examples: <div>, <p>, <h1>, <section>. You can set a width on them.
Inline elements only take up as much space as their content needs and do not start a new line. Examples: <span>, <a>, <strong>, <img>. Setting width and height on them has no effect (unless you change their display value).
This distinction matters greatly for alignment — many techniques only work on block elements.
What is a Container?
A container is simply the parent element that wraps around the element you want to align. When you centre a <div> inside a <section>, the <section> is the container.
Most alignment techniques work by applying CSS to the container (to align all its children), or to the element itself (to position it within its container).
The Box Model Reminder
Every HTML element is a rectangular box with content, padding, border, and margin. Understanding this helps when using margin: auto for centring — it is the margin (the outside space) that does the magic.
Part 1: Centring a Block Element Horizontally — margin: auto
What is margin: auto?
The most classic way to centre a block element horizontally inside its parent is to set its left and right margins to auto.
When you set margin: auto on the left and right sides, the browser divides the available horizontal space equally between the two sides — effectively pushing the element to the exact centre.
Syntax:
.element {
width: 300px; /* REQUIRED — must have a width set */
margin: 0 auto; /* 0 = top/bottom margin, auto = left/right margin */
}
Important Rule:
margin: autofor horizontal centring only works if the element has a definedwidth. Without a width, a block element stretches to fill 100% of its parent, so there is no leftover space to divide — andautohas nothing to work with.
Simple Example
<!DOCTYPE html>
<html>
<head>
<style>
.container {
background-color: lightgrey;
padding: 20px;
}
.box {
width: 300px; /* width is required */
background-color: steelblue;
color: white;
padding: 20px;
margin: 0 auto; /* centres the box horizontally */
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<div class="box">I am centred!</div>
</div>
</body>
</html>
Expected Output:
- A grey container stretching full width.
- A blue box that is 300px wide, sitting perfectly in the horizontal centre of the grey container.
Thinking Prompt: What happens if you remove
width: 300pxfrom.box? (The box stretches full width andmargin: autohas no effect — there is nothing to centre.)
Centring with max-width
Using max-width instead of a fixed width is better for responsive design because the element can shrink on smaller screens but will not grow beyond the max-width on larger screens.
.content-wrapper {
max-width: 960px; /* never wider than 960px */
margin: 0 auto; /* centred on large screens, full-width on small ones */
padding: 0 20px; /* a little breathing room on the sides */
}
Expected Output:
- On a large monitor: the content wrapper is 960px wide and centred.
- On a phone: the content wrapper fills the screen (since the phone is narrower than 960px).
This pattern is used on almost every professional website for the main content area.
Part 2: Aligning Text — text-align
What is text-align?
text-align controls how inline content (text, inline elements, inline-block elements) is positioned horizontally within a block container.
p {
text-align: left; /* default — text lines up on the left */
text-align: right; /* text lines up on the right */
text-align: center; /* text is centred */
text-align: justify; /* text is spread to fill the full width (like a newspaper) */
}
Important:
text-alignis applied to the container, and it affects all the inline content inside that container. It does NOT centre a block element — it only aligns text and inline items.
Example — All Four Values
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 400px;
background-color: #f0f0f0;
padding: 15px;
margin: 10px auto;
border: 1px solid #ccc;
}
.left { text-align: left; }
.right { text-align: right; }
.centre { text-align: center; }
.justify { text-align: justify; }
</style>
</head>
<body>
<div class="box left">
Left aligned text. This is the default. Text starts at the left edge.
</div>
<div class="box right">
Right aligned text. Text starts at the right edge.
</div>
<div class="box centre">
Centre aligned text. Text is centred between the two edges.
</div>
<div class="box justify">
Justified text. Each line is stretched so it touches both the left and right edges. Like a newspaper column. This works best with longer paragraphs.
</div>
</body>
</html>
Expected Output: Four boxes, each demonstrating a different text alignment.
text-align also works on inline-block elements
<style>
.nav {
text-align: center; /* centres the inline-block items inside */
background-color: #333;
padding: 10px;
}
.nav a {
display: inline-block;
color: white;
padding: 8px 16px;
text-decoration: none;
}
</style>
<nav class="nav">
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Contact</a>
</nav>
Expected Output: A dark navigation bar with three links horizontally centred inside it.
Part 3: Horizontal Alignment with float
What is float?
The float property was originally designed to allow text to wrap around images (like in a magazine or newspaper). It moves an element to the left or right side of its container, and the content that follows flows around it.
img {
float: left; /* image moves to the left, text wraps on the right */
float: right; /* image moves to the right, text wraps on the left */
float: none; /* default — no floating */
}
Simple Float Example
<!DOCTYPE html>
<html>
<head>
<style>
.container {
background-color: #f5f5f5;
padding: 15px;
overflow: auto; /* fixes the collapsing parent problem — explained later */
}
.left-box {
float: left;
width: 200px;
background-color: steelblue;
color: white;
padding: 15px;
margin-right: 15px;
}
p {
font-size: 16px;
line-height: 1.6;
}
</style>
</head>
<body>
<div class="container">
<div class="left-box">I am floated left</div>
<p>This text wraps around the floated box. In a magazine, you often see images on the left with text flowing to the right of them. This is exactly what float was designed for — allowing content to wrap around another element.</p>
</div>
</body>
</html>
Expected Output:
- A blue box on the left.
- The paragraph text flows alongside it on the right.
Using float to push an element to the right
<style>
.header {
background-color: #333;
color: white;
padding: 15px 20px;
overflow: auto;
}
.logo {
float: left;
font-size: 22px;
font-weight: bold;
}
.login-btn {
float: right;
background-color: steelblue;
color: white;
padding: 8px 16px;
border-radius: 4px;
text-decoration: none;
}
</style>
<header class="header">
<span class="logo">MyWebsite</span>
<a class="login-btn" href="#">Login</a>
</header>
Expected Output:
- A dark header bar.
- “MyWebsite” logo floated to the left.
- “Login” button floated to the right.
- This is a very common header layout pattern.
The clear Property — Stopping Float Effects
Once an element is floated, everything after it tries to wrap around it. To stop this and force an element to appear below all floated elements, use clear.
.footer {
clear: both; /* do not allow anything floated on either side */
}
| Value | What it does |
|---|---|
clear: left |
The element moves below any left-floated elements |
clear: right |
The element moves below any right-floated elements |
clear: both |
The element moves below ALL floated elements on both sides |
clear: none |
Default. No clearing happens |
<style>
.float-left { float: left; width: 45%; background-color: coral; padding: 15px; }
.float-right { float: right; width: 45%; background-color: steelblue; padding: 15px; color: white; }
.footer { clear: both; background-color: #333; color: white; padding: 15px; }
</style>
<div class="float-left">Left column</div>
<div class="float-right">Right column</div>
<footer class="footer">Footer — appears below both columns because of clear: both</footer>
Expected Output:
- Two columns side by side (coral on the left, blue on the right).
- A dark footer appearing below both columns (thanks to
clear: both).
When to use float today: Float is largely replaced by Flexbox and Grid for layout purposes. But it is still useful for making text wrap around images, and you will encounter it frequently in older codebases.
Part 4: The Modern Way — Horizontal Alignment with Flexbox
What is Flexbox?
Flexbox (Flexible Box Layout) is a modern CSS layout system designed specifically for aligning and distributing elements inside a container. It makes alignment — both horizontal and vertical — extremely simple and powerful.
To activate Flexbox on a container:
.container {
display: flex;
}
This one line turns .container into a flex container, and all its direct children become flex items that can be aligned and distributed easily.
Horizontal Alignment with justify-content
The justify-content property controls how flex items are distributed along the main axis (by default, horizontally left to right).
.container {
display: flex;
justify-content: flex-start; /* items packed to the left (default) */
justify-content: flex-end; /* items packed to the right */
justify-content: center; /* items packed to the centre */
justify-content: space-between; /* first item at left, last at right, equal space between */
justify-content: space-around; /* equal space around each item */
justify-content: space-evenly; /* equal space between items AND at the edges */
}
Example — All justify-content Values
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
display: flex;
background-color: #f0f0f0;
padding: 10px;
margin: 8px 0;
}
.flex-container span {
background-color: steelblue;
color: white;
padding: 10px 20px;
border-radius: 4px;
font-size: 14px;
}
.start { justify-content: flex-start; }
.end { justify-content: flex-end; }
.centre { justify-content: center; }
.between { justify-content: space-between;}
.around { justify-content: space-around; }
.evenly { justify-content: space-evenly; }
label { display: block; font-family: monospace; margin-top: 10px; }
</style>
</head>
<body>
<label>justify-content: flex-start</label>
<div class="flex-container start">
<span>A</span><span>B</span><span>C</span>
</div>
<label>justify-content: flex-end</label>
<div class="flex-container end">
<span>A</span><span>B</span><span>C</span>
</div>
<label>justify-content: center</label>
<div class="flex-container centre">
<span>A</span><span>B</span><span>C</span>
</div>
<label>justify-content: space-between</label>
<div class="flex-container between">
<span>A</span><span>B</span><span>C</span>
</div>
<label>justify-content: space-around</label>
<div class="flex-container around">
<span>A</span><span>B</span><span>C</span>
</div>
<label>justify-content: space-evenly</label>
<div class="flex-container evenly">
<span>A</span><span>B</span><span>C</span>
</div>
</body>
</html>
Expected Output: Six rows of three blue boxes, each showing a different spacing pattern.
Thinking Prompt: Which value would you use to build a navigation bar with the logo on the far left and the login button on the far right? (
space-between!)
Part 5: Vertical Alignment — The Techniques
Vertical alignment is historically much harder than horizontal alignment in CSS. Over the years, developers have used many clever workarounds. Today, Flexbox has made it easy. Let us go through all the important techniques.
Technique 1: padding — Simple and Reliable
The simplest way to centre content vertically is to add equal padding to the top and bottom of its container.
.card {
padding: 50px 20px; /* 50px top/bottom creates equal vertical space */
background-color: lightblue;
text-align: center;
}
Expected Output: Text centred visually in the middle of the box (because equal space above and below pushes it to the visual centre).
When to use it: When you just need a comfortable amount of vertical breathing room and do not need pixel-perfect centring. Great for buttons, cards, and banners.
Technique 2: line-height — For Single-Line Text
When you have a container with a fixed height and a single line of text, you can make the line-height equal to the container’s height. This pushes the text to the vertical middle.
<style>
.btn {
height: 50px; /* fixed height */
line-height: 50px; /* same as height — centres single-line text */
background-color: steelblue;
color: white;
text-align: center;
width: 200px;
border-radius: 6px;
margin: 0 auto;
}
</style>
<div class="btn">Click Me</div>
Expected Output: A 50px-tall blue button with the text perfectly vertically centred inside it.
When to use it: Only works reliably for single-line text. If the text wraps to a second line, it breaks completely.
Technique 3: position: absolute with transform — Precise Centring
For absolute positioning, you can push an element 50% down from the top of its parent, then shift it back up by half its own height using transform: translateY(-50%). This works regardless of the element’s height.
<style>
.container {
position: relative; /* REQUIRED — makes this the anchor for absolute child */
height: 300px;
background-color: #f0f0f0;
}
.centred {
position: absolute;
top: 50%; /* move 50% down from the top of the container */
left: 50%; /* move 50% right from the left of the container */
transform: translate(-50%, -50%); /* shift back by 50% of own width and height */
background-color: steelblue;
color: white;
padding: 20px 30px;
border-radius: 8px;
}
</style>
<div class="container">
<div class="centred">I am perfectly centred!</div>
</div>
Expected Output: The blue box sitting perfectly in both the horizontal AND vertical centre of the grey container, regardless of the box’s size.
How it works step by step:
top: 50%— the element’s top-left corner is placed at the 50% vertical point of the parent.left: 50%— the element’s top-left corner is placed at the 50% horizontal point of the parent.- At this point, the element is slightly off-centre because its top-left corner (not its centre) is at 50%.
transform: translate(-50%, -50%)shifts the element LEFT by 50% of its own width and UP by 50% of its own height.- Now the element’s true centre aligns with the parent’s centre. Perfect!
Technique 4: Flexbox — The Modern Best Practice
Flexbox makes vertical AND horizontal centring trivially easy with just three lines:
.container {
display: flex;
justify-content: center; /* horizontal centring */
align-items: center; /* vertical centring */
}
That is it! The container now perfectly centres all its children both ways.
<style>
.container {
display: flex;
justify-content: center; /* centres children horizontally */
align-items: center; /* centres children vertically */
height: 300px;
background-color: #1a1a2e;
}
.card {
background-color: white;
padding: 30px 40px;
border-radius: 10px;
text-align: center;
}
</style>
<div class="container">
<div class="card">
<h2>Perfectly Centred</h2>
<p>Both horizontally and vertically!</p>
</div>
</div>
Expected Output: A white card sitting perfectly in the dead centre of a dark blue container.
Vertical Alignment with align-items
align-items controls how flex items are aligned along the cross axis (by default, vertically top to bottom).
.flex-container {
display: flex;
height: 200px; /* needs a height to see vertical alignment */
align-items: stretch; /* default — items stretch to fill the container height */
align-items: flex-start; /* items align to the top */
align-items: flex-end; /* items align to the bottom */
align-items: center; /* items align to the middle */
align-items: baseline; /* items align by their text baseline */
}
Example — All align-items Values
<!DOCTYPE html>
<html>
<head>
<style>
.flex-container {
display: flex;
height: 120px;
background-color: #f0f0f0;
margin: 8px 0;
gap: 10px;
padding: 5px;
}
.flex-container span {
background-color: steelblue;
color: white;
padding: 10px 15px;
border-radius: 4px;
}
.start { align-items: flex-start; }
.end { align-items: flex-end; }
.centre { align-items: center; }
.stretch { align-items: stretch; }
.baseline { align-items: baseline; }
.big-font { font-size: 28px; }
label { display: block; font-family: monospace; margin-top: 10px; }
</style>
</head>
<body>
<label>align-items: flex-start</label>
<div class="flex-container start">
<span>A</span><span class="big-font">B</span><span>C</span>
</div>
<label>align-items: flex-end</label>
<div class="flex-container end">
<span>A</span><span class="big-font">B</span><span>C</span>
</div>
<label>align-items: center</label>
<div class="flex-container centre">
<span>A</span><span class="big-font">B</span><span>C</span>
</div>
<label>align-items: stretch (default)</label>
<div class="flex-container stretch">
<span>A</span><span class="big-font">B</span><span>C</span>
</div>
<label>align-items: baseline</label>
<div class="flex-container baseline">
<span>A</span><span class="big-font">B</span><span>C</span>
</div>
</body>
</html>
Expected Output: Five rows showing the same three items (where B is larger) aligned differently — at the top, bottom, middle, stretched full height, and by their text baseline.
Part 6: Aligning a Single Flex Item — align-self
If you want most flex children to have one alignment but a specific child to behave differently, use align-self on that individual child.
.container {
display: flex;
align-items: flex-start; /* all children align to the top by default */
height: 200px;
}
.special-child {
align-self: flex-end; /* THIS child aligns to the bottom */
}
/* Other values: align-self: center, stretch, baseline, auto */
Example:
<style>
.nav {
display: flex;
align-items: flex-start;
height: 80px;
background-color: #333;
padding: 0 20px;
gap: 15px;
}
.nav a {
color: white;
text-decoration: none;
padding: 5px 10px;
align-self: center; /* vertically centres the links in the tall nav bar */
}
.nav .logo {
font-size: 24px;
font-weight: bold;
color: gold;
align-self: center;
}
</style>
<nav class="nav">
<span class="logo">Brand</span>
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Contact</a>
</nav>
Expected Output: A dark nav bar with the logo and links all vertically centred regardless of the bar’s height.
Part 7: Centring with CSS Grid
CSS Grid also makes centring extremely straightforward:
.container {
display: grid;
place-items: center; /* shorthand for align-items + justify-items: center */
height: 300px;
}
place-items: center is a shorthand that sets both align-items and justify-items to center in one line.
<style>
.grid-centre {
display: grid;
place-items: center;
height: 300px;
background-color: #1a1a2e;
}
.box {
background-color: gold;
padding: 25px 40px;
border-radius: 10px;
font-size: 20px;
font-weight: bold;
}
</style>
<div class="grid-centre">
<div class="box">Grid-centred!</div>
</div>
Expected Output: A gold box sitting perfectly in the centre of the dark container.
Part 8: Horizontal Alignment Quick Reference
Here is a summary of all techniques and when to use each:
| Goal | Technique | When to Use |
|---|---|---|
| Centre a block element horizontally | margin: 0 auto + width |
Centring containers, cards, wrappers |
| Align text left / right / centre | text-align |
Text, headings, inline content |
| Push element to far left or right | float: left / float: right |
Text wrapping around images; old-school layouts |
| Distribute children horizontally | Flexbox justify-content |
Navigation bars, button groups, card rows |
| Centre element using position | position: absolute + left: 50% + transform |
Overlays, modals, tooltips |
Part 9: Vertical Alignment Quick Reference
| Goal | Technique | When to Use |
|---|---|---|
| Simple vertical space | Equal padding top and bottom |
Buttons, cards, banners |
| Centre single-line text | line-height = height |
Single-line buttons, list items |
| Centre child in positioned parent | top: 50% + transform: translateY(-50%) |
Overlays, popups |
| Centre children in any container | Flexbox align-items: center |
Most modern layouts |
| Centre in both directions at once | Flexbox justify-content: center + align-items: center |
Hero sections, splash screens, modals |
| Quick centre with Grid | display: grid; place-items: center |
Simple centring needs |
Part 10: Guided Practice Exercises
Exercise 1 — Centre a Card (Warm-Up)
Objective: Centre a product card horizontally on the page.
Scenario: You are building a single product page. There is one card in the middle of the screen.
Starter Code:
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-color: #f0f4f8;
font-family: Arial, sans-serif;
}
.product-card {
/* Add styles here to centre this card */
background-color: white;
border-radius: 10px;
padding: 30px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<div class="product-card">
<h2>Wireless Headphones</h2>
<p>Premium sound quality. Up to 30 hours battery life.</p>
<p><strong>₦45,000</strong></p>
</div>
</body>
</html>
Your Task:
- Give
.product-carda fixedwidthof400px. - Add
margin: 40px autoto centre it horizontally and add vertical spacing.
Expected Output: A white card 400px wide, centred on the grey background.
Solution:
.product-card {
width: 400px;
margin: 40px auto;
background-color: white;
border-radius: 10px;
padding: 30px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
Self-Check Questions:
- What would happen if you removed
width: 400px? (The card would stretch full width andmargin: autowould have no effect.) - Why did we use
margin: 40px autoinstead ofmargin: 0 auto? (The40pxadds a comfortable gap above and below the card.autohandles the left and right centring.)
Exercise 2 — Navigation Bar with Float
Objective: Build a header bar with a logo on the left and navigation links on the right.
Starter Code:
<!DOCTYPE html>
<html>
<head>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
.header {
background-color: #2d2d2d;
padding: 15px 30px;
overflow: auto; /* clearfix for floated children */
}
.logo {
/* Float this to the left */
color: gold;
font-size: 22px;
font-weight: bold;
}
.nav-links {
/* Float this to the right */
list-style: none;
}
.nav-links li {
display: inline-block;
margin-left: 20px;
}
.nav-links a {
color: white;
text-decoration: none;
font-size: 15px;
}
</style>
</head>
<body>
<header class="header">
<div class="logo">TechBrand</div>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Contact</a></li>
</ul>
</header>
</body>
</html>
Your Task:
- Add
float: leftto.logo. - Add
float: rightto.nav-links.
Expected Output: A dark header bar with “TechBrand” on the far left in gold, and the three navigation links on the far right in white.
What-if Experiment: What happens if you remove overflow: auto from .header? (The header collapses to zero height because its children are floated and taken out of normal flow. This is called the “collapsing parent” problem.)
Exercise 3 — Flexbox Centred Hero Section
Objective: Build a full-screen hero section with text and a button perfectly centred both horizontally and vertically.
<!DOCTYPE html>
<html>
<head>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Arial', sans-serif;
}
.hero {
/* Make this a flex container that centres its children both ways */
background: linear-gradient(135deg, #1a1a2e, #16213e, #0f3460);
height: 100vh; /* full screen height */
/* ADD: display, justify-content, align-items */
}
.hero-content {
text-align: center;
color: white;
}
.hero-content h1 {
font-size: 48px;
margin-bottom: 20px;
}
.hero-content p {
font-size: 20px;
margin-bottom: 30px;
opacity: 0.8;
}
.hero-btn {
display: inline-block;
background-color: #e94560;
color: white;
padding: 14px 32px;
border-radius: 30px;
text-decoration: none;
font-size: 16px;
font-weight: bold;
transition: background-color 0.3s;
}
.hero-btn:hover {
background-color: #c73652;
}
</style>
</head>
<body>
<section class="hero">
<div class="hero-content">
<h1>Welcome to Our Platform</h1>
<p>Build something amazing today.</p>
<a class="hero-btn" href="#">Get Started</a>
</div>
</section>
</body>
</html>
Your Task: Add three CSS properties to .hero:
display: flexjustify-content: centeralign-items: center
Expected Output: A full-screen deep blue gradient background with the heading, paragraph, and pink button all perfectly centred in the middle of the screen.
Exercise 4 — Mixed Alignment Card Row
Objective: Create a row of three cards where the heading is left-aligned, the price is right-aligned, and a “Buy” button is centred.
<!DOCTYPE html>
<html>
<head>
<style>
.card-row {
display: flex;
gap: 20px;
padding: 30px;
background-color: #f0f4f8;
justify-content: center;
}
.card {
background-color: white;
border-radius: 10px;
padding: 20px;
width: 220px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.card h3 {
text-align: left; /* heading on the left */
font-size: 16px;
margin-bottom: 8px;
}
.card .price {
text-align: right; /* price on the right */
font-size: 20px;
font-weight: bold;
color: #e94560;
margin-bottom: 15px;
}
.card .btn {
display: block;
text-align: center; /* button text centred */
background-color: steelblue;
color: white;
padding: 10px;
border-radius: 6px;
text-decoration: none;
font-size: 14px;
}
</style>
</head>
<body>
<div class="card-row">
<div class="card">
<h3>Laptop Stand</h3>
<p class="price">₦12,500</p>
<a class="btn" href="#">Buy Now</a>
</div>
<div class="card">
<h3>Wireless Mouse</h3>
<p class="price">₦8,000</p>
<a class="btn" href="#">Buy Now</a>
</div>
<div class="card">
<h3>USB-C Hub</h3>
<p class="price">₦22,000</p>
<a class="btn" href="#">Buy Now</a>
</div>
</div>
</body>
</html>
Expected Output:
- Three white product cards side by side in a grey row.
- Each card has its heading left-aligned, its price right-aligned, and a blue “Buy Now” button with centred text.
Self-Check Questions:
- Why do we use
text-align: centeron the.btninstead ofmargin: 0 auto?
(Because the button isdisplay: blockinside the card, but we want the text inside the button centred —text-aligncontrols inline content within the block.margin: 0 autowould centre the button block itself if it had a fixed width less than the card, but here the button fills the card width, sotext-aligncentres the text inside it.) - What
justify-contentvalue on.card-rowcentres the three cards horizontally in the row? (center)
Part 11: Mini Project — Centred Profile Card
In this mini-project you will build a polished profile card that uses every alignment technique from this lesson: margin: auto for page centring, text-align for text, Flexbox for internal layout, and position + transform for a decorative element.
Stage 1: Page Setup and Outer Centring
Create profile.html and profile.css.
profile.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Profile Card</title>
<link rel="stylesheet" href="profile.css">
</head>
<body>
<main class="page">
<div class="profile-card">
<div class="avatar-wrapper">
<div class="avatar">JD</div>
</div>
<div class="card-body">
<h1 class="name">Jane Doe</h1>
<p class="role">Senior Web Developer</p>
<p class="location">📍 Lagos, Nigeria</p>
</div>
<div class="stats">
<div class="stat">
<span class="stat-number">128</span>
<span class="stat-label">Projects</span>
</div>
<div class="stat">
<span class="stat-number">4.9</span>
<span class="stat-label">Rating</span>
</div>
<div class="stat">
<span class="stat-number">3k</span>
<span class="stat-label">Followers</span>
</div>
</div>
<div class="card-footer">
<a class="btn btn-primary" href="#">Hire Me</a>
<a class="btn btn-secondary" href="#">Portfolio</a>
</div>
</div>
</main>
</body>
</html>
Milestone Output (before CSS): Plain unstyled text and links stacked vertically.
Stage 2: Core CSS — Centring the Card on the Page
profile.css:
/* --- Reset --- */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* --- Page: uses Flexbox to centre the card both ways --- */
.page {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e, #16213e, #0f3460);
font-family: 'Arial', sans-serif;
}
/* --- The Card itself: centred on page via the flex parent --- */
.profile-card {
background-color: white;
border-radius: 20px;
width: 340px;
overflow: hidden;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
text-align: center; /* text-align centres all inline content in the card */
}
Milestone Output: A white card centred perfectly on a dark blue gradient background.
Stage 3: Avatar — Absolute Positioning and Transform Centring
/* --- Avatar wrapper: provides a surface for the avatar to overlap --- */
.avatar-wrapper {
background: linear-gradient(135deg, #e94560, #c73652);
height: 100px;
position: relative; /* anchor for the absolute avatar circle */
}
/* --- Avatar circle: positioned to overlap the wrapper bottom edge --- */
.avatar {
position: absolute;
width: 90px;
height: 90px;
border-radius: 50%;
background-color: #0f3460;
color: white;
font-size: 32px;
font-weight: bold;
border: 4px solid white;
/* Centre the avatar circle on the wrapper's bottom edge */
bottom: -45px; /* pull half of it below the wrapper */
left: 50%; /* start at horizontal centre */
transform: translateX(-50%); /* shift left by half its own width */
/* Centre the initials text inside the circle */
display: flex;
justify-content: center;
align-items: center;
}
Milestone Output: A coral/pink header band with a circular avatar overlapping its bottom edge, perfectly centred. The initials “JD” are centred inside the circle.
Stage 4: Card Body Text and Stats
/* --- Card body text --- */
.card-body {
padding: 60px 30px 20px; /* 60px top to clear the avatar overlap */
}
.name {
font-size: 24px;
color: #1a1a2e;
margin-bottom: 6px;
text-align: center;
}
.role {
color: #555;
font-size: 15px;
margin-bottom: 6px;
text-align: center;
}
.location {
color: #888;
font-size: 13px;
text-align: center;
}
/* --- Stats row: Flexbox distributes the three stats evenly --- */
.stats {
display: flex;
justify-content: space-around; /* equal space between stats */
align-items: center;
padding: 20px 30px;
border-top: 1px solid #f0f0f0;
border-bottom: 1px solid #f0f0f0;
margin: 15px 0;
}
.stat {
display: flex;
flex-direction: column; /* stack number above label */
align-items: center; /* centre number and label horizontally */
}
.stat-number {
font-size: 22px;
font-weight: bold;
color: #1a1a2e;
}
.stat-label {
font-size: 12px;
color: #888;
margin-top: 3px;
}
Milestone Output: Name, role, and location text centred. Three stats (Projects, Rating, Followers) evenly spaced in a row below the text.
Stage 5: Buttons — Flex Row, Centred
/* --- Footer buttons --- */
.card-footer {
display: flex;
justify-content: center; /* centre the button group */
gap: 12px;
padding: 20px 30px 30px;
}
.btn {
padding: 10px 24px;
border-radius: 25px;
font-size: 14px;
font-weight: bold;
text-decoration: none;
text-align: center;
cursor: pointer;
transition: opacity 0.2s;
}
.btn:hover {
opacity: 0.85;
}
.btn-primary {
background-color: #e94560;
color: white;
}
.btn-secondary {
background-color: transparent;
color: #e94560;
border: 2px solid #e94560;
}
Final Output: A polished profile card perfectly centred on a deep blue gradient background, containing:
- A coral header band
- A circular avatar overlapping the header bottom edge, centred using
absolute+left: 50%+transform: translateX(-50%) - “JD” initials centred inside the avatar using Flexbox
- Name, role, and location text centred with
text-align: center - Three stats distributed evenly using Flexbox
justify-content: space-around - Two buttons centred using Flexbox
justify-content: center
Reflection Questions for the Mini-Project
-
The page uses Flexbox with
justify-content: centerandalign-items: center. What would happen if you removedmin-height: 100vhfrom.page? (The page would have no height, so the card would not appear vertically centred — there would be no space to centre it within.) -
The avatar uses
left: 50%+transform: translateX(-50%). Why not just usemargin: 0 auto? (Because the avatar isposition: absolute—margin: autodoes not work on absolutely positioned elements the same way. Thetransformtechnique is the reliable method for absolutely positioned elements.) -
The stats use
justify-content: space-around. How would the layout change withspace-between? (The stats would be pushed to the extreme edges of the container — the first stat would touch the left edge, the last the right edge.space-aroundkeeps them more balanced with some space at the edges too.) -
The card has
text-align: centerset on.profile-card. Which child elements benefit from this? Which do NOT? (Text content like.name,.role,.locationbenefits. The flex children in.statsand.card-footerare not affected because they use Flexbox alignment instead.)
Part 12: Common Beginner Mistakes
Mistake 1 — margin: auto without a width
Wrong:
.box {
margin: 0 auto; /* won't work — no width defined */
}
Correct:
.box {
width: 500px; /* or max-width: 500px */
margin: 0 auto;
}
Mistake 2 — Using text-align: center to centre a block element
text-align only affects inline content. It does NOT centre a block element.
Wrong (for centring a block):
.parent {
text-align: center; /* this centres the TEXT inside .child, not .child itself */
}
.child {
width: 200px;
background: blue;
}
Correct:
.child {
width: 200px;
margin: 0 auto; /* THIS centres the block element */
}
Mistake 3 — Forgetting height when vertical centring
/* This won't appear vertically centred — the container has no height! */
.container {
display: flex;
align-items: center;
/* missing: height or min-height */
}
Correct:
.container {
display: flex;
align-items: center;
min-height: 300px; /* container needs a height to centre within */
}
Mistake 4 — Collapsing float parent
<!-- The container collapses because its only children are floated -->
<div class="container">
<div style="float: left;">Left</div>
<div style="float: right;">Right</div>
<!-- Container height = 0! Nothing to hold it open. -->
</div>
Fix — Add overflow: auto to the container:
.container {
overflow: auto; /* forces the container to expand and wrap its floated children */
}
Mistake 5 — Using line-height for multi-line text centring
/* Only works for exactly one line of text */
.btn {
height: 50px;
line-height: 50px; /* breaks if text wraps to 2 lines */
}
Better for modern layouts:
.btn {
height: 50px;
display: flex;
align-items: center; /* works perfectly even if text wraps */
justify-content: center;
}
Mistake 6 — margin: auto on a flex item’s parent
/* Trying to use margin: auto on a flex item itself */
.flex-container {
display: flex;
}
.child {
margin: auto; /* this actually DOES work in Flexbox — it absorbs free space */
}
Interesting Note:
margin: autoon a flex item actually works inside a flex container! It absorbs all available free space in the specified direction, effectively centring the item. This is a legitimate and useful technique for pushing items to opposite ends.
Reflection Questions
-
You want to centre a
<div>that contains a paragraph of text both horizontally and vertically on the screen. What is the minimal CSS needed? (Make the body or a wrapper a flex container withjustify-content: center,align-items: center, andmin-height: 100vh. Give the<div>awidth.) -
A student sets
text-align: centeron a<p>but nothing happens. What could be the reason? (The parent container might be very narrow, or the<p>might be inside an element that has overriding alignment. More likely: there is nothing wrong —text-align: centeron a<p>should always work. Check ifwidth: 0ordisplay: noneis accidentally applied.) -
You are using
float: leftandfloat: rightto create a two-column layout. The footer is overlapping the columns instead of sitting below them. What is the fix? (clear: bothon the footer.) -
When would you choose
position: absolute+transform: translate(-50%, -50%)over Flexbox for centring? (When you need to centre something inside an element that already hasposition: relativeand cannot be changed to a flex container — for example, a label over an image, or a badge on a card corner.) -
What is
place-items: centerand which layout model uses it? (It is a shorthand foralign-items: center+justify-items: center, used in CSS Grid.)
Completion Checklist
- I can centre a block element horizontally using
margin: 0 autoand a defined width - I understand why
margin: autorequires awidthto work - I can align text using
text-align: left,right,center, andjustify - I understand the difference between aligning text and aligning a block element
- I can use
float: leftandfloat: rightto push elements to the sides - I can use
clear: bothto stop elements from wrapping around floated elements - I can fix the “collapsing parent” problem caused by floated children
- I can create a horizontal flex container and distribute items using
justify-content - I can vertically align flex children using
align-items - I can override vertical alignment for a single item using
align-self - I can centre an element using
position: absolute+top: 50%+transform: translateY(-50%) - I can centre content in both directions at once using Flexbox
- I can use CSS Grid
place-items: centerfor quick centring - I completed all four guided exercises
- I built the full profile card mini-project
- I can identify which technique is best for a given alignment scenario
Lesson Summary
CSS alignment is one of the most essential skills in web development. This lesson covered all the major techniques from classic to modern.
Horizontal alignment can be achieved by applying margin: 0 auto with a width on block elements, using text-align for inline content and text, using float: left or float: right to push elements to the sides (with clear: both to fix the footer), or using Flexbox justify-content to distribute flex children across the horizontal axis.
Vertical alignment can be achieved using equal padding for simple visual centring, line-height equal to height for single-line text, position: absolute with top: 50% and transform: translateY(-50%) for precisely positioned elements, or Flexbox align-items: center for the cleanest, most modern approach.
Centring in both directions simultaneously is best done with Flexbox (display: flex + justify-content: center + align-items: center) or CSS Grid (display: grid + place-items: center).
Real World Uses:
margin: 0 autoon the main content wrapper of almost every websitetext-align: centerfor hero headings, call-to-action buttons, and cardsfloatfor magazine-style text wrapping around images- Flexbox for navigation bars, card grids, button groups, and form layouts
position + transformcentring for modal dialogs, tooltips, and image overlays- Flexbox hero sections with perfectly centred content at full viewport height
The ability to control alignment precisely — knowing exactly why something is where it is — is what separates a developer who struggles with CSS from one who builds layouts confidently and quickly.