Difficulty: Advanced
Centering elements in CSS is one of the most asked interview questions because it tests understanding of multiple layout mechanisms. What was once famously difficult ('how to center a div') now has several clean solutions thanks to Flexbox, Grid, and modern CSS features. Knowing multiple approaches and when each is appropriate demonstrates deep CSS knowledge. The techniques differ in their requirements, flexibility, and browser support.
Flexbox centering is the most commonly used modern approach. Setting display:flex with justify-content:center and align-items:center on a parent centers its children both horizontally and vertically. This works regardless of the child's dimensions, handles dynamic content, and does not require knowing the child's size. For single-axis centering, use only justify-content (horizontal in a row layout) or align-items (vertical in a row layout, horizontal in a column layout). Flexbox centering is the recommended default approach for most centering needs.
CSS Grid offers the most concise centering syntax: display:grid and place-items:center is a two-property solution that centers content in both axes. Under the hood, place-items is shorthand for align-items and justify-items. For a single child, you can alternatively use place-self:center on the child element. Grid centering is ideal when you are already using Grid for layout, or when you need to center content in a fixed-height container like a full-viewport hero section.
The margin:auto technique works differently for horizontal versus vertical centering. For block elements, margin:0 auto centers horizontally by distributing equal margins on the left and right. The element must have a defined width for this to work. For vertical centering with margin:auto, the element must be inside a flex or grid container -- auto margins in flex and grid contexts distribute space on the specified axis, enabling vertical centering without alignment properties.
The position:absolute with transform technique is a classic approach that works without flex or grid. You set the element to position:absolute, then top:50% and left:50% to move its top-left corner to the parent's center, then transform:translate(-50%, -50%) to shift it back by half its own dimensions. This works with any size element and does not require knowing dimensions in advance. The downside is that the element is removed from normal flow, which can complicate layouts. This technique remains useful for overlays, modals, and tooltip positioning.
Text-align:center only centers inline and inline-block children horizontally -- it does not center block elements or provide vertical centering. Line-height equal to container height is an old trick for vertical centering of single-line text. Both are legacy techniques that have been largely replaced by flexbox and grid, but understanding them shows knowledge of CSS fundamentals and may be needed when working with legacy code.
<style>
/* Center both axes */
.flex-center {
display: flex;
justify-content: center; /* horizontal (main axis) */
align-items: center; /* vertical (cross axis) */
height: 300px;
border: 2px solid #333;
}
/* Center horizontal only */
.flex-horizontal {
display: flex;
justify-content: center;
/* Children are centered horizontally, top-aligned vertically */
}
/* Center vertical only */
.flex-vertical {
display: flex;
align-items: center;
height: 200px;
/* Children are centered vertically, left-aligned horizontally */
}
/* Center with margin auto (flexbox context) */
.flex-container {
display: flex;
height: 300px;
border: 2px solid #333;
}
.flex-container .centered-child {
margin: auto;
/* auto margin in flex distributes all available space equally */
/* Centers both horizontally AND vertically */
}
.box {
width: 100px;
height: 100px;
background: #3b82f6;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
</style>
<div class="flex-center">
<div class="box">Centered</div>
</div>
<div class="flex-container">
<div class="box centered-child">margin: auto</div>
</div>
Flexbox centering is the most versatile approach. justify-content centers on the main axis (horizontal for row), align-items centers on the cross axis (vertical for row). margin:auto in a flex context distributes space on all sides, centering both axes with a single property on the child.
<style>
/* Two-property centering */
.grid-center {
display: grid;
place-items: center;
/* Shorthand for: align-items: center; justify-items: center; */
height: 300px;
border: 2px solid #333;
}
/* One-property centering on child */
.grid-container {
display: grid;
height: 300px;
border: 2px solid #333;
}
.grid-container .self-centered {
place-self: center;
/* Shorthand for: align-self: center; justify-self: center; */
}
/* Full viewport centering (hero section) */
.hero {
display: grid;
place-items: center;
min-height: 100vh;
/* Content is perfectly centered in the full viewport */
}
/* Grid + text centering for mixed content */
.card-center {
display: grid;
place-items: center;
text-align: center;
height: 200px;
padding: 24px;
}
.box {
width: 120px;
height: 80px;
background: #ef4444;
color: #fff;
display: grid;
place-items: center;
}
</style>
<div class="grid-center">
<div class="box">Grid Center</div>
</div>
<div class="hero">
<div>
<h1>Hero Title</h1>
<p>Centered in the full viewport</p>
</div>
</div>
Grid centering with display:grid and place-items:center is the shortest centering solution. place-items is shorthand for both alignment axes. place-self on a child centers just that child. This is ideal for hero sections, empty states, and single-child centering.
<style>
.pos-container {
position: relative;
height: 300px;
border: 2px solid #333;
}
/* Center both axes with position + transform */
.pos-center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* top:50% moves top edge to center of parent */
/* left:50% moves left edge to center of parent */
/* translate(-50%,-50%) shifts back by half of own size */
}
/* Center horizontal only */
.pos-horizontal {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
/* Center vertical only */
.pos-vertical {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* Alternative: inset + margin auto (no transform needed) */
.pos-inset {
position: absolute;
inset: 0; /* top:0; right:0; bottom:0; left:0; */
margin: auto;
width: 120px; /* Must have explicit dimensions */
height: 80px;
/* auto margins distribute remaining space equally */
}
.box {
width: 120px;
height: 80px;
background: #8b5cf6;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
</style>
<div class="pos-container">
<div class="box pos-center">translate</div>
</div>
<div class="pos-container">
<div class="box pos-inset">inset + auto</div>
</div>
The position + transform approach moves the element's top-left corner to the parent's center (top:50%, left:50%), then shifts it back by half its own size (translate(-50%,-50%)). The inset:0 + margin:auto alternative works when the element has explicit dimensions. Both require a positioned parent.
<style>
/* text-align: centers inline/inline-block children horizontally */
.text-center {
text-align: center;
border: 2px solid #333;
padding: 16px;
}
.text-center .inline-child {
display: inline-block;
background: #f59e0b;
padding: 8px 16px;
/* Centered because parent has text-align:center */
}
/* margin: 0 auto - centers block elements horizontally */
.block-center {
width: 200px;
margin: 0 auto;
background: #10b981;
padding: 16px;
text-align: center;
color: #fff;
/* Requires explicit width */
}
/* line-height trick - centers single-line text vertically */
.line-height-center {
height: 60px;
line-height: 60px; /* same as height */
text-align: center;
background: #6366f1;
color: #fff;
/* Only works for single-line text! */
overflow: hidden;
}
/* Table cell centering - legacy vertical centering */
.table-center {
display: table;
height: 200px;
width: 100%;
border: 2px solid #333;
}
.table-center .cell {
display: table-cell;
vertical-align: middle;
text-align: center;
/* vertical-align: middle works in table layout */
}
</style>
<div class="text-center">
<div class="inline-child">text-align centered</div>
</div>
<div class="block-center">margin: 0 auto</div>
<div class="line-height-center">line-height trick</div>
<div class="table-center">
<div class="cell">table-cell + vertical-align</div>
</div>
text-align:center works for inline and inline-block children only. margin:0 auto centers a block with a defined width. line-height matching height centers single-line text vertically. display:table-cell with vertical-align:middle was the pre-flexbox vertical centering hack. All are still valid but flexbox/grid are preferred.
Flexbox Centering, Grid Centering, Margin Auto, Position Transform, Text Align, Vertical Centering