Question

How to Vertically Align Elements in a Div with CSS

csshtmlvertical-alignment

Question

I have a div containing two images and an h1, and I want all of them to appear next to each other while being vertically aligned within the container. One of the images also needs to be absolutely positioned inside the div.

What CSS should I use to make this work reliably across common browsers?

<div id="header">
  <img src=".." alt="Left image">
  <h1>testing...</h1>
  <img src="..." alt="Right image">
</div>

Short Answer

By the end of this page, you will understand how vertical alignment works in CSS, why some older approaches are unreliable, and how to use modern layout tools like Flexbox to align text and images cleanly inside a div. You will also learn how absolute positioning affects layout and how to combine it safely with normal document flow.

Concept

Vertical alignment in CSS can mean different things depending on the layout context.

For elements like text, images, and inline items, alignment behaves differently than it does for block-level layout. In your example, you want:

  • multiple elements on the same horizontal row
  • their vertical centers aligned
  • one element positioned absolutely inside the container

This matters because CSS layout rules depend on how elements participate in layout:

  • Normal flow: elements take up space naturally
  • Inline/inline-block layout: items sit on a line, affected by text baselines
  • Flexbox layout: items are aligned along horizontal and vertical axes intentionally
  • Absolute positioning: the element is removed from normal flow and positioned relative to an ancestor

Historically, vertical alignment was tricky in CSS. Developers used hacks such as line-height, display: table-cell, or manual margins. Today, Flexbox is the standard and most reliable way to align items vertically and horizontally in a row.

A key detail: if one image is position: absolute, it no longer affects the layout of the other elements. That means the remaining image and the h1 can be aligned with Flexbox, while the absolutely positioned image can be placed independently inside the same container.

Mental Model

Think of the div as a shelf.

  • With Flexbox, the shelf neatly lines up all items in a row and lets you center them vertically.
  • With absolute positioning, one item is taken off the shelf and pinned to a specific spot on the wall behind it.

So you have two layout systems working together:

  • the shelf handles the normal items
  • the pinned item is placed manually

This explains why absolutely positioned elements do not push other elements away unless you add spacing for them yourself.

Take Quiz

Syntax and Examples

The most common modern solution is to make the container a flex container.

#header {
  display: flex;
  align-items: center;
  position: relative;
  gap: 12px;
}

What this does

  • display: flex; puts the children in a row by default
  • align-items: center; vertically centers them within the container
  • position: relative; makes the container the positioning reference for any absolutely positioned child
  • gap: 12px; adds space between normal-flow items

Basic example

<div id="header">
  <img class="logo" src="left.png" alt="Logo">
  <h1>Testing...</h1>
  <img class="badge" src="right.png" alt="Badge">
</div>
#header {
  display: flex;
  align-items: center;
  position: relative;
  min-height: 80px;
  gap: 12px;
}

.logo {
  width: 40px;
  height: 40px;
}

#header h1 {
  margin: 0;
}

.badge {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
}

Why top: 50% and transform: translateY(-50%)?

That is a common technique for vertically centering an absolutely positioned element:

  • top: 50% moves its top edge to the middle of the container
  • transform: translateY(-50%) pulls it up by half of its own height

If you need space for the absolute image

Because .badge is removed from normal flow, it may overlap the heading. Add padding to the container:

#header {
  display: flex;
  align-items: center;
  position: relative;
  min-height: 80px;
  padding-right: 48px;
}

Step by Step Execution

Consider this example:

<div id="header">
  <img class="left" src="left.png" alt="Left">
  <h1>Hello</h1>
  <img class="right" src="right.png" alt="Right">
</div>
#header {
  display: flex;
  align-items: center;
  position: relative;
  height: 100px;
  padding-right: 60px;
}

.left {
  width: 40px;
  height: 40px;
}

h1 {
  margin: 0 0 0 10px;
}

.right {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: 30px;
}

Step by step

  1. The browser reads #header.
  2. display: flex makes its children layout in a row.
  3. align-items: center vertically centers the flex items inside the 100px tall container.
  4. position: relative tells the browser that absolutely positioned children should use #header as their reference box.
  5. The .left image stays in normal flow and appears at the start of the row.
  6. The h1 also stays in normal flow and is placed next to the left image.
  7. The .right image has position: absolute, so it is removed from the row layout.
  8. right: 10px places it near the right edge of the container.
  9. top: 50% places its top at the vertical middle of the container.
  10. transform: translateY(-50%) shifts it upward by half of its own height, creating true vertical centering.
  11. padding-right: 60px reserves enough room so the h1 does not collide with the right image.

Real World Use Cases

Vertical alignment inside a container appears everywhere in real interfaces.

Common examples

  • Website headers: logo, page title, notification icon
  • Navigation bars: icon + label + user avatar
  • Cards: thumbnail, title, and action button aligned in one row
  • Chat apps: profile image, username, and status icon
  • Admin dashboards: section title with badges or action buttons
  • Media players: album image, track title, and play controls

When absolute positioning is useful

Absolute positioning is often used for elements that should sit in a fixed visual spot, such as:

  • a badge in the top-right corner
  • an overlay icon on an image
  • a menu button aligned to the far edge
  • a close icon inside a header or modal
Take Quiz

Real Codebase Usage

In real projects, developers usually solve this with Flexbox first, then use absolute positioning only when an item should not affect the main layout.

Common patterns

1. Flex container for row alignment

.header {
  display: flex;
  align-items: center;
}

This is the standard pattern for headers, toolbars, and list items.

2. Relative parent + absolute child

.header {
  position: relative;
}

.header__icon {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
}

This is used for badges, overlays, and pinned controls.

3. Guarding against overlap

Developers often add padding where the absolute element lives.

.header {
  padding-right: 48px;
}

4. Resetting default heading margins

Headings often have top and bottom margins by default, which can make alignment look wrong.

.header h1 {
  margin: 0;
}

5. Utility classes in component systems

In larger codebases, teams often use utility classes or design systems:

.row-center {
  display: flex;
  align-items: center;
}

.relative {
  position: relative;
}

This avoids repeating layout rules across many components.

Common Mistakes

1. Using vertical-align: middle on block elements

Beginners often try this:

#header h1 {
  vertical-align: middle;
}

This usually does not work as expected because vertical-align applies mainly to inline, inline-block, and table-cell elements.

2. Forgetting position: relative on the parent

Broken example:

.right {
  position: absolute;
  right: 0;
  top: 50%;
}

If the parent is not position: relative, the image may position itself relative to the page or another ancestor.

Fix:

#header {
  position: relative;
}

3. Not accounting for absolute elements overlapping content

Broken example:

#header {
  display: flex;
  align-items: center;
}

If the right image is absolute, the heading may run underneath it.

Fix by reserving space:

#header {
  padding-right: 50px;
}

4. Leaving default h1 margins in place

Broken example:

h1 {
  font-size: 24px;
}

Default browser margins can make vertical spacing seem uneven.

Fix:

h1 {
  margin: 0;
}

5. Using invalid HTML for img

An img element is a void element and should not have a closing tag.

Prefer:

<img src="left.png" alt="Left image">

Not:

<img src="left.png"></img>

Comparisons

ApproachGood forProsCons
FlexboxAligning items in a row or columnSimple, modern, readableNeeds a modern browser environment
vertical-alignInline or table-cell elementsWorks for text-like alignment casesConfusing for full layout
display: table-cellOlder vertical centering tricksCan work without FlexboxLess intuitive, less flexible
Absolute positioningPrecise manual placementGreat for overlays and badgesRemoved from normal flow, can overlap content

Flexbox vs vertical-align

  • Use Flexbox when aligning multiple UI elements in a container.
  • Use vertical-align mainly for inline content like text and icons.

Flexbox vs absolute positioning

  • Use Flexbox for structured layout.
  • Use absolute positioning for decorative or pinned elements that should not affect layout.

Old approach: inline-block + vertical-align

This older technique can work:

#header > * {
  display: inline-block;
  vertical-align: middle;
}

But Flexbox is usually cleaner and easier to maintain.

Take Quiz

Cheat Sheet

/* Best modern default */
.container {
  display: flex;
  align-items: center;
  position: relative;
}

Vertical alignment rules

  • align-items: center vertically centers flex items
  • position: relative on the parent creates the reference point for absolute children
  • position: absolute removes the child from normal flow
  • top: 50% + transform: translateY(-50%) centers an absolute element vertically
  • headings like h1 often need margin: 0

Useful pattern

.header {
  display: flex;
  align-items: center;
  position: relative;
  padding-right: 50px;
}

.header h1 {
  margin: 0;
}

.header .icon {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}

Watch out for

  • vertical-align does not solve most block layout problems
  • absolute elements can overlap content
  • img should not use a closing tag
  • default margins can make alignment appear broken

FAQ

How do I vertically center text and images inside a div?

Use Flexbox on the container:

.container {
  display: flex;
  align-items: center;
}

Why does vertical-align: middle not work on my div elements?

Because vertical-align is mainly for inline, inline-block, and table-cell elements, not general block layout.

How do I vertically center an absolutely positioned image?

Use:

position: absolute;
top: 50%;
transform: translateY(-50%);

Why is my absolute image overlapping the heading?

Because absolute elements do not take up layout space. Add padding or margin to reserve room.

Should I use Flexbox or absolute positioning for alignment?

Use Flexbox for the main layout. Use absolute positioning only for items that need fixed placement within the container.

Do I need browser prefixes for Flexbox?

In most modern projects, no. Flexbox is widely supported in common browsers.

Is <img></img> valid HTML?

No. img is a void element and should be written without a closing tag:

<img src="image.png" alt="Description">
Take Quiz

Mini Project

Description

Build a simple site header containing a logo on the left, a page title in the middle, and a status icon pinned to the right. This demonstrates how to combine Flexbox for normal alignment with absolute positioning for a fixed-position element inside the same container.

Goal

Create a header where the visible items are vertically centered and the right-side icon stays pinned inside the container without breaking the layout.

Requirements

  • Create a container with one left image, one heading, and one right image.
  • Use Flexbox to align the normal-flow items vertically.
  • Absolutely position the right image inside the container.
  • Prevent the heading from overlapping the right image.
  • Remove default heading spacing that affects alignment.
Take Quiz

Keep learning

Related questions

View more