Question

How to Vertically Align Elements in a div with CSS

htmlcssvertical-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 inside the container. One of the images also needs to be absolutely positioned within 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 techniques are unreliable, and how to align text and images cleanly inside a container using modern layout tools like Flexbox. You will also see how absolute positioning affects layout and how to combine it safely with aligned content.

Concept

Vertical alignment in CSS depends on how elements are laid out.

In your example, the main goal is:

  • place items side by side
  • align them vertically within the container
  • allow one item to be absolutely positioned

This matters because CSS has different layout systems, and each handles alignment differently.

The key idea

For modern layouts, Flexbox is the easiest and most reliable way to align items horizontally and vertically.

When you set a container to:

display: flex;
align-items: center;

its child elements line up in a row and are vertically centered by default.

Why this matters

Beginners often try:

  • vertical-align: middle on block elements
  • line-height hacks
  • table-based layouts

Those approaches can work in specific cases, but they are limited or awkward.

Flexbox is better because:

  • it is built for layout
  • it works well with mixed content like images and headings
  • it is supported in all modern common browsers
  • it makes spacing and alignment easier to control

Absolute positioning changes the rules

An absolutely positioned element is removed from the normal document flow. That means Flexbox will not use it when calculating layout for the other items.

So if one image must be position: absolute, a common pattern is:

  • make the parent position: relative
  • absolutely position the image inside it
  • use Flexbox for the remaining visible flow items

This is the core concept behind solving this kind of layout problem.

Mental Model

Think of a Flexbox container like a shelf.

  • The div is the shelf.
  • The images and heading are items placed on the shelf.
  • align-items: center means all items sit centered from top to bottom.

Now imagine one item is pinned to the wall instead of resting on the shelf. That is what position: absolute does.

  • It is still visually inside the same area.
  • But it no longer takes up normal space on the shelf.
  • You must place it manually using top, left, right, or transforms.

So the layout usually becomes:

  • normal items use Flexbox
  • absolute items are manually positioned relative to the parent
Take Quiz

Syntax and Examples

Basic Flexbox alignment

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

This does three things:

  • display: flex puts child elements in a row
  • align-items: center vertically centers them
  • gap adds space between them

Example with two images and a heading

<div id="header">
  <img src="left.png" alt="Left logo">
  <h1>Testing...</h1>
  <img src="right.png" alt="Right logo">
</div>
#header {
  display: flex;
  align-items: center;
  gap: 12px;
}

#header h1 {
  margin: 0;
}

#header img {
  display: block;
  width: 40px;
  height: 40px;
}

Why this works

  • Images and the heading appear in one row.
  • Their vertical centers line up.
  • Removing the default h1 margin avoids uneven spacing.

Example with one absolutely positioned image

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

#header h1 {
  margin: 0;
}

.left-image {
  width: 40px;
  height: 40px;
  display: block;
}

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

Why this works

  • position: relative on #header creates the positioning reference.
  • .right-image is placed relative to #header.
  • top: 50% moves the image halfway down the container.
  • transform: translateY(-50%) shifts it upward by half its own height, creating vertical centering.
  • padding-right prevents the heading from overlapping the absolutely positioned image.

Step by Step Execution

Consider this example:

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

#header h1 {
  margin: 0;
}

.right-image {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}

What happens step by step

  1. The browser creates the #header element.
  2. display: flex makes its children line up in a horizontal row.
  3. align-items: center centers the normal-flow children vertically.
  4. The h1 default margins are removed so the alignment looks clean.
  5. position: relative on #header tells the browser: any absolutely positioned child should use this box as its reference.
  6. .right-image is removed from normal layout because it is position: absolute.
  7. right: 0 places that image against the right edge of the container.
  8. top: 50% moves its top edge to the middle of the container.
  9. transform: translateY(-50%) pulls it upward by half its own height, so it becomes truly centered.
  10. padding-right: 60px leaves room so the h1 and left image do not slide underneath the absolute image.

Result

  • The left image and heading align using Flexbox.
  • The right image is independently positioned but still centered vertically within the same container.

Real World Use Cases

Vertical alignment inside a container is extremely common in real interfaces.

Common examples

  • Website headers: logo, page title, and icon aligned in one row
  • Navigation bars: text links and icons centered neatly
  • Profile cards: avatar next to a username and status badge
  • Notification items: icon, message text, and action button aligned together
  • Search bars: input field with left and right icons
  • Admin dashboards: section titles with control buttons or badges

When absolute positioning is useful

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

  • a close icon in the top-right corner
  • a badge over an image
  • a decorative icon anchored to one side
  • a floating action control inside a header or card

In these cases, Flexbox handles the main layout, while position: absolute handles the special item.

Take Quiz

Real Codebase Usage

In real projects, developers usually combine layout tools rather than relying on a single property.

Common patterns

1. Flexbox for the main row

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

This is the standard approach for horizontal alignment.

2. Relative parent for positioned children

.header {
  position: relative;
}

This keeps absolute children contained inside the component instead of attaching to the page.

3. Reserve space for absolute elements

If an icon is absolutely positioned on the right, developers often add padding:

.header {
  padding-right: 48px;
}

This avoids overlap.

4. Guard against default margins

Headings and paragraphs often come with default margins that can break alignment:

.header h1 {
  margin: 0;
}

5. Use utility classes or component styles

In larger codebases, teams often use reusable classes such as:

  • .row
  • .items-center
  • .justify-between
  • .relative
  • .absolute-right

Even when using CSS frameworks, the underlying idea is the same: normal flow for most items, absolute positioning only when necessary.

6. Prefer simple layouts first

Experienced developers often ask:

  • Can Flexbox solve this alone?
  • Do I really need absolute positioning?

If the answer is no, they avoid absolute positioning because it adds complexity.

Common Mistakes

1. Using vertical-align: middle on block elements

Many beginners try this:

#header h1 {
  vertical-align: middle;
}

This usually does not work as expected because vertical-align mainly affects:

  • inline elements
  • inline-block elements
  • table cells

It does not magically center normal block layout children.

2. Forgetting position: relative on the parent

Broken example:

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

If the parent is not positioned, the image may be placed relative to the page instead of the container.

Fix:

#header {
  position: relative;
}

3. Not reserving space for the absolute element

Broken example:

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

If the right image is absolute, other content can overlap it.

Fix by adding padding:

#header {
  padding-right: 60px;
}

4. Leaving default heading margins

h1 elements have default margins that can make alignment look off.

Fix:

#header h1 {
  margin: 0;
}

5. Writing closing img tags

Broken HTML:

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

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

Correct:

<img src=".." alt="Description">

6. Overusing absolute positioning

If all elements are positioned absolutely, the layout becomes harder to maintain and less responsive.

A better approach is:

  • use Flexbox for normal alignment
  • use absolute positioning only for the special case

Comparisons

ApproachBest forProsCons
display: flex + align-items: centerModern horizontal alignmentSimple, readable, reliableRequires modern browser support
vertical-align: middleInline or table-cell alignmentUseful in narrow casesNot for general block layout
line-height trickSingle-line text in fixed-height containersQuick for text onlyPoor for mixed content like images and headings
display: table-cellOlder layout patternsCan vertically align contentLess flexible and less semantic
Absolute positioning onlyExact manual placementPrecise controlEasy to break layout and responsiveness

Flexbox vs older methods

Flexbox is usually the best choice because it was designed specifically for layout. Older methods were often workarounds before CSS had better layout systems.

When vertical-align is still useful

vertical-align is helpful when dealing with:

  • icons inside text
  • inline images next to words
  • table cells

But for container-based UI layout, Flexbox is usually clearer and more maintainable.

Take Quiz

Cheat Sheet

Quick reference

Vertical align items in one row

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

Make children appear side by side

.container {
  display: flex;
}

Add spacing between items

.container {
  gap: 12px;
}

Absolutely position one child inside the container

.container {
  position: relative;
}

.child {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
}

Prevent overlap with absolute child

.container {
  padding-right: 60px;
}

Reset heading spacing

h1 {
  margin: 0;
}

Rules to remember

  • Use Flexbox for normal alignment.
  • Use position: relative on the parent if a child is absolute.
  • Absolute elements do not take up normal layout space.
  • vertical-align is not the main tool for block layout.
  • img tags should not have closing tags.

Safe pattern

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

FAQ

How do I vertically center text and images in the same div?

Use Flexbox on the parent container:

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

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

Because vertical-align does not generally center normal block-level layout children. It is mainly for inline, inline-block, and table-cell elements.

How do I absolutely position one image but keep everything aligned?

Set the parent to position: relative, then absolutely position that image while using Flexbox for the other elements.

Does absolute positioning remove an element from layout?

Yes. The element is removed from normal flow, so other items behave as if it is not taking up space.

What is the best modern CSS method for vertical alignment?

For most UI layouts, Flexbox is the best and simplest method.

Should I use tables for vertical alignment?

No, not for normal page layout. Tables should be used for tabular data, not general alignment.

Why is my h1 not lining up cleanly with images?

Default heading margins often cause this. Reset them with:

h1 {
  margin: 0;
}
Take Quiz

Mini Project

Description

Build a simple page header that contains a logo on the left, a title in the middle flow, and an action icon pinned to the right. This demonstrates how to combine Flexbox for normal alignment with absolute positioning for a special element.

Goal

Create a horizontally arranged header where the logo and title are vertically centered, and a right-side icon stays vertically centered using absolute positioning.

Requirements

  • Create a container with one left image, one heading, and one right image.
  • Use Flexbox to align the normal content in a row.
  • Absolutely position the right image inside the container.
  • Make sure the heading does not overlap the right image.
  • Remove default heading spacing so alignment looks clean.
Take Quiz

Keep learning

Related questions

View more