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.
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 defaultalign-items: center;vertically centers them within the containerposition: relative;makes the container the positioning reference for any absolutely positioned childgap: 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 containertransform: 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
- The browser reads
#header. display: flexmakes its children layout in a row.align-items: centervertically centers the flex items inside the100pxtall container.position: relativetells the browser that absolutely positioned children should use#headeras their reference box.- The
.leftimage stays in normal flow and appears at the start of the row. - The
h1also stays in normal flow and is placed next to the left image. - The
.rightimage hasposition: absolute, so it is removed from the row layout. right: 10pxplaces it near the right edge of the container.top: 50%places its top at the vertical middle of the container.transform: translateY(-50%)shifts it upward by half of its own height, creating true vertical centering.padding-right: 60pxreserves enough room so theh1does 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
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
| Approach | Good for | Pros | Cons |
|---|---|---|---|
| Flexbox | Aligning items in a row or column | Simple, modern, readable | Needs a modern browser environment |
vertical-align | Inline or table-cell elements | Works for text-like alignment cases | Confusing for full layout |
display: table-cell | Older vertical centering tricks | Can work without Flexbox | Less intuitive, less flexible |
| Absolute positioning | Precise manual placement | Great for overlays and badges | Removed from normal flow, can overlap content |
Flexbox vs vertical-align
- Use Flexbox when aligning multiple UI elements in a container.
- Use
vertical-alignmainly 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.
Cheat Sheet
/* Best modern default */
.container {
display: flex;
align-items: center;
position: relative;
}
Vertical alignment rules
align-items: centervertically centers flex itemsposition: relativeon the parent creates the reference point for absolute childrenposition: absoluteremoves the child from normal flowtop: 50%+transform: translateY(-50%)centers an absolute element vertically- headings like
h1often needmargin: 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-aligndoes not solve most block layout problems- absolute elements can overlap content
imgshould 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">
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.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.