Appearance
CSS Centering
When to use
Use this skill when centering elements — horizontally, vertically, or both. The right centering method depends on the layout context, not habit. One-element demos make every method look identical; they diverge the moment a container has multiple children, an element overflows, or the layout changes under stress.
The top: 50%; left: 50%; transform: translate(-50%, -50%) pattern still works but is legacy — anchor-based and inset-based approaches are simpler and more maintainable today.
Decision guide
| Scenario | Method |
|---|---|
| Block container, single or multiple items | align-content: center on the container |
| Grid container | place-content: center |
| Flex container, responsive wrap | flex-wrap: wrap + place-content: center |
| Absolute or fixed positioned element | inset: 0 + place-self: center |
| Anchor-positioned element | position-area or anchor-center |
| Text within its line box | text-box: cap alphabetic |
| Overflow must stay visible | place-content: safe center |
Block container (single or multiple items)
align-content: center works on block-level containers in modern browsers — no display change required. justify-items: center centers inline content horizontally but is Chrome-only as of 2026.
css
.container {
display: block;
align-content: center; /* centers children vertically in block containers */
justify-items: center; /* Chrome-only: centers inline children horizontally */
}Use align-content: center when you want the simplest vertical centering without changing the display mode. Skip justify-items on block containers until cross-browser support improves.
Grid
place-content is the shorthand for both align-content and justify-content. On a grid container with a single item, it centers the item both axes in one declaration.
css
.container {
display: grid;
place-content: center;
}Flexbox (responsive wrap)
Adding flex-wrap: wrap before place-content: center makes centering work correctly when multiple children wrap. Without flex-wrap, align-content has no effect on single-line flex containers.
css
.container {
display: flex;
flex-wrap: wrap;
place-content: center;
}Prefer this over the bare display: flex; justify-content: center; align-items: center pattern — it handles multiple wrapped children correctly and is more concise.
Absolute / fixed positioning
Instead of the legacy top: 50%; left: 50%; transform: translate(-50%, -50%) hack, use inset: 0 with place-self: center. This is simpler, readable, and handles any size.
css
/* Legacy pattern — avoid */
.overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Modern replacement */
.overlay {
position: absolute;
inset: 0;
place-self: center;
}inset: 0 expands the element's position constraints to all four edges of its containing block, and place-self: center centers it within that space.
Anchor positioning
CSS anchor positioning offers two centering mechanisms depending on what you're centering relative to:
Area-relative centering — position-area places the anchored element in a region relative to the anchor. Use center for centering on both axes:
css
.anchored {
position: absolute;
position-anchor: --my-anchor;
position-area: center;
}Anchor-relative centering — anchor-center on justify-self or align-self centers the element on the corresponding axis of the anchor element itself, not a grid area:
css
.tooltip {
position: absolute;
position-anchor: --trigger;
bottom: anchor(top);
justify-self: anchor-center; /* horizontally centered on the anchor */
}Note the difference: position-area: center centers within the layout area; anchor-center aligns the element's center to the anchor's center on one axis.
Text centering with text-box
The default line box includes font metric whitespace (ascenders, descenders, leading) above capital letters and below baselines, making text appear vertically off-center in containers. text-box removes this whitespace.
css
/* For uppercase or mixed-case text */
.heading {
text-box: cap alphabetic;
}
/* For lowercase text without ascenders or descenders */
.label {
text-box: ex alphabetic;
}captrims the space above the cap height (top of uppercase letters).extrims to the x-height (top of lowercase letters without ascenders).alphabetictrims below the baseline (removes descender whitespace).
Use text-box when centering text in buttons, badges, or icon + text pairs where pixel-precise vertical alignment matters. Without it, the text will visually appear above center even when mathematically centered.
Safe vs. unsafe alignment
By default, centering is unsafe — the center wins even if content overflows and is clipped. Add safe to preserve content visibility when overflow occurs.
css
/* Content can clip on overflow — default behavior */
.container {
display: grid;
place-content: center;
}
/* Content stays visible — overflows start edge instead of clipping */
.container {
display: grid;
place-content: safe center;
}The unsafe keyword is occasionally needed explicitly in anchor positioning when a containing block (e.g., a sticky header) would otherwise constrain an anchored element like a tooltip:
css
.tooltip {
justify-self: unsafe anchor-center;
}Use safe center as the default for scrollable or dynamic-content containers. Use unsafe only when the design requires the anchor-relative position to win over viewport or containing-block constraints.
Trade-offs
- Block
align-contentvs. flex/grid: Blockalign-contentis the lowest-friction change but has the least cross-browser history — test early. Flex and grid centering are well-supported everywhere. justify-itemson block containers: Chrome-only as of 2026. Don't rely on it in production until Firefox and Safari ship it.text-boxsupport: Broadly available in modern browsers as of 2025, but verify for your target audience before using in production.- Anchor positioning: Good support in Chrome/Edge; Firefox and Safari added support in 2024–2025. Check browser support for
position-areaandanchor-centerspecifically, as these shipped later than the core spec. inset: 0+place-selfvs.translatehack: The modern approach requires the element to beposition: absolute/fixedinside a positioned parent, same as the legacy approach. The advantage is readability and avoiding a transform that can interfere with other transforms.
Source
Temani Afif, The State of CSS Centering in 2026, CSS-Tricks, May 2026.