align-items and align-self in CSS Flexbox

What You Learn From This Page

  • How align-items establishes cross-axis alignment for every item in a flex line.
  • How align-self overrides that default for one individual flex item.
  • Why the cross axis changes when flex-direction or writing mode changes.
  • How stretch, start, end, center, and baseline alignment are resolved.
  • Why explicit cross sizes, auto margins, wrapping, and intrinsic content change the result.
  • How to apply alignment in navigation, forms, cards, notifications, and pricing components.
  • How these properties differ from justify-content, align-content, text-align, and vertical-align.
  • How to debug cross-axis alignment without relying on trial and error.

Introduction

CSS Flexbox separates layout into two directions: a main axis and a cross axis. The main axis follows flex-direction, while the cross axis runs perpendicular to it. The align-items and align-self properties control how flex items are aligned within their flex line along that cross axis.

The difference is one of scope. align-items belongs to the flex container and supplies the default alignment for all of its flex items. align-self belongs to one flex item and can replace that default for the selected item. A row can therefore center every item while keeping one notification icon at cross-start, or a column can stretch every field while allowing one button to remain content-sized.

These properties are often described as vertical-alignment tools, but that shortcut is unreliable. They appear vertical in the common case of a horizontal row because the row's cross axis is vertical. In a column, the cross axis is horizontal. Writing modes can change the physical direction again. The durable rule is simple: align-items sets the cross-axis default for the group, and align-self overrides it for one item.

The Core Difference

Set align-items on the element that establishes the flex formatting context. Every eligible in-flow direct child receives that alignment unless another rule, an auto margin, or its own align-self changes the outcome.

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

Set align-self on an individual flex item. It does not align the item's own children. It changes that item's cross-axis alignment within the flex line created by its parent.

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

.special-item {
  align-self: flex-end;
}

In this example, ordinary items remain centered and only .special-item moves toward cross-end. This container-versus-item distinction is the most important concept on the page.

Quick Comparison

PropertyApplied ToAxisScope
align-itemsFlex containerCross axisDefault for all items
align-selfIndividual flex itemCross axisOne item override
justify-contentFlex containerMain axisContent group in each line
align-contentMulti-line flex containerCross axisDistribution of flex lines

Identify the Cross Axis First

With flex-direction: row or row-reverse, the main axis follows the inline direction and the cross axis follows the block direction. In common horizontal English text, that makes the main axis horizontal and the cross axis vertical. Align-items therefore appears to move items up and down or stretch them vertically.

.row {
  display: flex;
  flex-direction: row;
  min-block-size: 12rem;
  align-items: center;
}

With flex-direction: column or column-reverse, the main axis follows the block direction and the cross axis follows the inline direction. In the same writing mode, align-items now appears to move items left and right or stretch them horizontally.

.column {
  display: flex;
  flex-direction: column;
  align-items: center;
}

Do not memorize that align-items means vertical centering. Ask which direction is perpendicular to the main axis. That question remains correct for reversed directions, right-to-left documents, and vertical writing modes.

Common align-items Values

The values most often used in Flexbox are stretch, flex-start, flex-end, center, and baseline. The Box Alignment specification also provides logical start and end, self-position values, baseline variants, and optional safe or unsafe overflow alignment in applicable combinations.

.container {
  align-items: stretch;
  align-items: flex-start;
  align-items: flex-end;
  align-items: center;
  align-items: baseline;
}

Only one declaration wins in actual CSS; the sequence above is a compact list of alternatives. Choose a value according to the relationship among the items rather than according to a single screenshot.

align-items: stretch

stretch is the normal default effect for flex items in many practical Flexbox layouts. It makes an item with an automatic cross size fill the available cross size of its flex line, subject to minimum and maximum constraints. In a row, this commonly makes items share the line's height. In a column, it commonly makes them fill the available width.

.cards {
  display: flex;
  align-items: stretch;
  gap: 1rem;
}

.card {
  flex: 1 1 0;
}

This pattern can create equal-height cards when their content lengths differ. Stretch does not mean that Flexbox assigns an arbitrary fixed height. It resolves each auto cross size against the line's cross size, and the final result still respects padding, borders, box sizing, minimums, maximums, and content constraints.

When Stretch Does Not Work

Stretch depends on the item's cross-axis size being automatic. In a row, an explicit height or block size usually prevents the normal stretch behavior. In a column, an explicit width or inline size usually does the same. The item already has a specified cross size, so alignment positions that box rather than replacing its size with a stretched one.

.row {
  min-block-size: 12rem;
  display: flex;
  align-items: stretch;
}

.fixed-height {
  block-size: 5rem;
}

The fixed-height item will not fill the entire row merely because the container declares stretch. Also inspect cross-axis margins. An auto cross-axis margin can absorb available space and suppress the ordinary align-self effect for that axis. If stretch appears inactive, check the item's computed cross size, min/max constraints, margins, and the flex line's actual size.

align-items: flex-start

flex-start packs each item's margin box toward the cross-start side of its flex line. In a common row this looks like top alignment. In a common column it looks like alignment toward the inline-start side, which is usually left in an LTR horizontal writing mode.

.notification {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

Start alignment works well when a small icon sits beside a multi-line message. Centering the icon against the full paragraph may make it float awkwardly halfway down the text, while cross-start keeps it associated with the first line. The right choice depends on the component's reading relationship, not a universal preference.

align-items: flex-end

flex-end packs items toward cross-end. For a row in a common writing mode, items appear near the bottom of the flex line. It can align badges, controls, or metadata against the lower edge of a deliberately sized row.

.comparison-row {
  min-block-size: 10rem;
  display: flex;
  align-items: flex-end;
  gap: 1rem;
}

Use flex-end only when the lower-edge relationship communicates something useful. If content heights change substantially, baseline or start alignment may create a stronger reading flow. Test the layout with wrapping labels and larger text rather than evaluating only short sample content.

align-items: center

center positions every item at the center of the flex line's cross axis. It is common in navigation bars, toolbars, compact profile rows, and controls where icons and labels of different natural heights should share a visual center.

.navbar {
  display: flex;
  align-items: center;
  gap: 1rem;
}

Centering requires cross-axis room in which movement can be seen. If the flex line is exactly as tall or wide as the largest item, center may appear to do nothing because there is no remaining cross-axis space. Give a demonstration container an intentional minimum cross size, but avoid fixed production heights that clip translated text or enlarged user fonts.

align-items: baseline

baseline aligns items according to a shared typographic baseline rather than their outer centers or edges. This produces natural reading alignment when adjacent items use different font sizes, such as a large price followed by a smaller billing period.

<div class="price-row">
  <span class="price">$99</span>
  <span class="period">/ month</span>
</div>

.price-row {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
}

.price { font-size: 3rem; }
.period { font-size: 1rem; }

Center alignment would align the geometric centers of the two text boxes, often leaving the smaller text visually too high or low. Baseline alignment lets the characters sit on a common reading line. If an item cannot provide the required baseline, the browser synthesizes one according to the alignment rules, so complex components can produce results that differ from plain text spans.

First and Last Baseline Alignment

Box Alignment includes first baseline and last baseline concepts. First-baseline alignment aligns the first relevant baselines of the items, while last-baseline alignment uses the last relevant baselines. These distinctions become useful when components contain multiple lines of text and the design needs either their first lines or final lines to align.

.product-row {
  display: flex;
  align-items: first baseline;
}

Baseline behavior can be more difficult to predict than edge or center alignment because font metrics, line boxes, nested layout contexts, and writing modes matter. Inspect actual rendered content and keep a fallback design in mind when supporting older or unusual browser environments.

Logical start and end

The values start and end come from the broader Box Alignment model. They express alignment relative to the relevant logical axis rather than relying solely on Flexbox-specific start terminology. This can make intent clearer in components designed for multiple writing modes.

.message-row {
  display: flex;
  align-items: start;
}

flex-start and flex-end remain common and well understood in Flexbox. Whichever vocabulary you choose, test RTL content and supported writing modes. Logical intent is most valuable when the rest of the component also avoids hard-coded physical assumptions.

Safe and Unsafe Alignment

Some positional alignment syntax can include an overflow-position keyword such as safe or unsafe. Safe alignment falls back toward start when the requested alignment would place content where it becomes inaccessible through overflow. Unsafe alignment preserves the requested position even when data loss may occur.

.dialog-actions {
  display: flex;
  align-items: safe center;
}

Support and exact applicability should be tested for the browsers in a project's support matrix. More importantly, do not treat safe alignment as a substitute for responsive sizing, wrapping, scrolling, and content testing. A component should remain usable at narrow widths and high zoom before overflow alignment becomes its last line of defense.

How align-self Overrides the Container

The align-self property accepts values comparable to align-items for an individual item. Its initial value is auto. For a flex item, auto generally defers to the parent's align-items value, while an explicit self-alignment value replaces that default for the item.

.container {
  min-block-size: 12rem;
  display: flex;
  align-items: center;
}

.first  { align-self: auto; }
.second { align-self: flex-start; }
.third  { align-self: flex-end; }

The first item follows center, the second moves to cross-start, and the third moves to cross-end. This is a local exception, not a reconfiguration of the line for the other items.

align-self: auto

auto preserves the container-driven model. If a reusable item should ordinarily follow whatever alignment its parent establishes, leaving align-self at auto is preferable to repeating a value on every child.

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

.toolbar-item {
  align-self: auto;
}

The item remains centered because its parent supplies center. If the same component later appears in a start-aligned parent, it can follow that new context without an override fighting the container.

align-self: flex-start and flex-end

Use start or end overrides when a particular item has a genuine edge relationship different from its siblings. A status marker might stay at the first line of a tall content block, or an action might align to the lower edge of a fixed comparison panel.

.profile-row {
  min-block-size: 9rem;
  display: flex;
  align-items: center;
}

.status-badge {
  align-self: flex-start;
}

Frequent per-item overrides can indicate that the items do not belong in one alignment group. If several subsets need different alignment rules, nested flex containers often express the design more clearly than many align-self declarations.

align-self: center

An individual item can center itself while siblings stretch or remain at an edge. This is useful in a column card where full-width fields are followed by a content-sized button.

.form-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1rem;
}

.secondary-action {
  align-self: center;
}

Because the column's cross axis is horizontal in a common writing mode, the button becomes horizontally centered. Its own text alignment is unchanged; align-self positions the button box, not the text inside it.

align-self: stretch

One item can stretch while its siblings use another cross-axis alignment, provided the selected item's cross size remains automatic and its constraints permit stretching.

.summary-row {
  min-block-size: 10rem;
  display: flex;
  align-items: center;
}

.details-panel {
  align-self: stretch;
}

The details panel can fill the flex line's height while nearby controls remain centered. If the panel declares a fixed height, stretch no longer replaces that dimension. Also remember that stretching the outer item does not automatically distribute or center its children; establish a nested layout context when the inside content needs alignment.

Cross Size and Available Space

Alignment can move an item only when the flex line has cross-axis space beyond the item's used cross size. In a row, that usually means the line is taller than the item. In a column, it usually means the line is wider. Without that difference, start, center, and end can render at essentially the same location.

.demo-row {
  min-block-size: 12rem;
  display: flex;
  align-items: center;
}

Production components should gain cross size from legitimate content, padding, minimum sizing, aspect ratios, or layout constraints. Adding a fixed height only to make center visible can create clipping and overflow when real content changes.

Alignment Within Each Flex Line

When wrapping creates multiple flex lines, align-items applies to the items within each line. Each line has its own cross size, commonly based on the largest item in that line. An item is centered, stretched, or baseline-aligned inside its own line rather than across the entire container.

.tag-board {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

To distribute the lines themselves within extra cross-axis space, use align-content. This two-level model explains why changing align-items does not move an entire wrapped group toward the center of a tall container.

align-items vs align-content

Align-items controls the cross-axis placement of items inside each flex line. Align-content controls the distribution of multiple flex lines within the container. Align-content normally has no meaningful distribution work when only one line exists.

.gallery {
  block-size: 30rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: space-between;
}

Here, items are centered within their respective lines, while the lines are distributed through the container's cross-axis space. Confusing these levels is one of the most common Flexbox alignment errors.

align-items vs justify-content

justify-content operates along the main axis; align-items operates along the cross axis. Used together, they can center a group in both directions when the container has available space on both axes.

.empty-state {
  min-block-size: 20rem;
  display: flex;
  justify-content: center;
  align-items: center;
}

Changing flex-direction swaps which physical direction is main and which is cross. The properties do not permanently mean horizontal and vertical. If an alignment rule seems to move content in the wrong direction, inspect flex-direction before changing values.

align-items vs text-align and vertical-align

text-align controls inline content inside a box. It does not position the flex item box within its parent. vertical-align applies to inline-level and table-cell alignment contexts and does not align ordinary flex items.

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

.item {
  text-align: center;
}

The first declaration positions each item on the parent's cross axis. The second centers inline text inside each item. Both may be useful, but they solve different layers of the layout.

Cross-Axis Auto Margins

Auto margins have special behavior in Flexbox. If an item has an auto margin on the cross axis and positive space is available, that margin can absorb the space. Ordinary align-self alignment then does not control that axis in the usual way.

.column-card {
  block-size: 20rem;
  display: flex;
  flex-direction: column;
}

.footer-action {
  margin-block-start: auto;
}

In this column, the block direction is the main axis, so the margin shown separates the footer along the main axis rather than the cross axis. The example also demonstrates why axis identification matters before diagnosing alignment. Inspect each logical margin according to the current flex direction and writing mode.

Nested Flex Containers

A flex item can also be a flex container. Its align-self value controls how the outer box participates in the parent, while its own align-items value controls its direct children. The same element can therefore have both properties without contradiction.

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

.account-menu {
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

Read nested components from the outside inward. First ask how account-menu aligns as an item of header. Then ask how its avatar and label align inside account-menu. This prevents applying a correct property to the wrong relationship.

Absolutely Positioned Children

An absolutely positioned child is removed from normal flex layout and does not participate as an ordinary flex item. Align-items does not reserve a normal item slot for it. Static-position rules can involve alignment concepts, but authors should not depend on that complexity for primary component structure.

Use absolute positioning for genuine overlays, badges, and decorative layers. Keep content and interactive controls in normal flow whenever possible so sizing, wrapping, alignment, reading order, and keyboard navigation remain predictable.

Real-World Navigation Bar

A horizontal navigation bar often contains a logo, text links, an icon button, and a profile image with different intrinsic heights. Center alignment creates a stable shared visual center without assigning fixed heights to every child.

.navbar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-block: 0.75rem;
}

Let padding establish comfortable bar height. Avoid clipping the bar with a rigid block size, especially when navigation labels can wrap or user text settings increase. If one group must move to the far edge, use a logical auto margin or a nested group rather than changing cross-axis alignment.

Real-World Toolbar

Toolbars frequently combine selects, text inputs, labels, and icon buttons. Center alignment is a useful starting point, but controls should also share compatible sizing, line-height, and accessible target dimensions.

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

Wrapping keeps controls available on narrow screens. Remember that each wrapped line aligns its own items. If rows need shared column tracks or exact label alignment, CSS Grid may represent the relationship better.

Real-World Notification Row

For an icon beside a potentially long message, cross-start alignment often gives a more natural relationship than center. The icon stays near the first line while the message can grow vertically.

.notification {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.notification-icon {
  flex: 0 0 auto;
}

Do not use alignment to compensate for a decorative icon that should be hidden from assistive technology or for an unlabeled icon button. Semantic labeling and accessible names remain separate responsibilities.

Real-World Form Card

A column form commonly stretches fields across the available inline size. A submit button may remain content-sized by overriding that default.

.form {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1rem;
}

.submit-button {
  align-self: flex-start;
}

Because the column cross axis is inline, stretch fills the form width and flex-start keeps the button near inline-start. At small widths, a full-width submit button may be easier to operate; use a media or container query to change align-self and inline size when the component requires it.

Real-World Card Row

Stretch can create cards with a shared row height, but the inner card layout still needs its own rules if actions should line up at the bottom.

.card-row {
  display: flex;
  align-items: stretch;
  gap: 1rem;
}

.card {
  flex: 1 1 16rem;
  display: flex;
  flex-direction: column;
}

.card-actions {
  margin-block-start: auto;
}

The outer container equalizes the item heights. The inner column and auto margin then place each action area after flexible content. Separating those responsibilities makes the layout easier to understand and maintain.

Grid Behavior

Align-items and align-self also participate in CSS Grid, where they align grid items within their grid areas along the block axis. The vocabulary is shared through Box Alignment, but the layout model differs. A grid item aligns inside an assigned area, while a flex item aligns within a flex line.

.dashboard {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: start;
}

.featured-widget {
  align-self: stretch;
}

Do not assume that a Flexbox result and a Grid result are interchangeable merely because the property names match. Inspect the containing block, track sizes, and item area in Grid; inspect the line cross size and flex axes in Flexbox.

Writing Modes and International Layouts

Logical axes allow one component to adapt to different languages and writing systems. A row's cross axis follows the block axis, which is not always physically vertical. A column's cross axis follows the inline axis, which is not always physically horizontal.

Prefer logical sizing and spacing properties such as inline-size, block-size, and logical margins when building writing-mode-aware components. Test actual translated content and RTL direction. Cross-axis reasoning remains correct even when a familiar top, bottom, left, or right shortcut does not.

Responsive Design Considerations

An alignment that looks balanced with short desktop content may fail when labels wrap on a small screen. Centered icons can drift away from the first line, stretched controls can become excessively wide, and fixed-height containers can clip enlarged text. Test realistic content rather than placeholder words.

Use wrapping, fluid sizes, min/max constraints, container queries, and nested groups to preserve relationships. Change alignment at a breakpoint only when the component's structure genuinely changes. Avoid setting many one-off align-self values merely to imitate one viewport.

Accessibility Considerations

Align-items and align-self change visual geometry without reordering the DOM. That is generally safer than visual reordering, but alignment can still affect usability when it clips text, reduces touch targets, hides overflow, or separates a control from its label. A visually polished row is not accessible if keyboard focus or enlarged content falls outside the visible area.

Test at 200 and 400 percent zoom, with larger text, keyboard navigation, screen magnification, long labels, and localized content. Preserve meaningful source order and semantic relationships. Do not use fixed heights solely to produce perfect centering when the content needs room to grow.

Common Mistake: Putting align-items on the Child

A developer may place align-items on a flex item while expecting that item to move inside its parent. Align-items instead controls the direct children of the element when it establishes a compatible layout context.

/* Does not move .item within its parent. */
.item { align-items: center; }

/* Moves this item on the parent's cross axis. */
.item { align-self: center; }

If the item is also a flex container, its align-items declaration can still be valid, but it affects a different, nested relationship.

Common Mistake: Putting align-self on the Container

Align-self on a container affects that element only if the container is itself a flex or grid item of another layout. It does not align the container's children.

/* Aligns children of .container. */
.container {
  display: flex;
  align-items: center;
}

Always identify the parent-child boundary involved in the movement. The parent establishes the default, and the participating child may override it.

Common Mistake: Assuming Alignment Is Always Vertical

This assumption works only for the common row in a horizontal writing mode. When flex-direction becomes column, align-items acts across the column and usually appears horizontal. Reversed directions and alternate writing modes add more reasons to use axis terminology.

In DevTools, inspect the flex-direction and enable the Flexbox overlay. Most modern browser tools draw the main and cross directions, making an incorrect axis assumption immediately visible.

Common Mistake: No Visible Difference

If center, start, and end look identical, the flex line may have no spare cross-axis room. The item may already fill that dimension, the container may shrink-wrap its content, or a single line may derive its cross size directly from the largest item.

Inspect used sizes rather than adding random declarations. Confirm the container's cross size, the line's cross size, each item's cross size, margins, and min/max constraints. In a controlled demonstration, add a minimum cross size to reveal the alignment behavior.

Common Mistake: Stretch Blocked by a Fixed Size

An explicit height in a row or explicit width in a column commonly prevents stretching because the cross size is no longer auto. Removing that size may restore stretch, but do not remove legitimate constraints blindly.

Determine whether the design truly needs equal cross sizes. If it does, let the container and automatic sizing establish them. If each item requires a specific size, use start, center, or end alignment and accept that stretch is not the correct mechanism.

Common Mistake: Using align-content for One Line

Align-content distributes multiple flex lines. A one-line navbar does not gain cross-axis item centering from align-content: center. Use align-items for the items in that line.

If a wrapping container has multiple lines, both properties may be needed: align-items for each line's items and align-content for the collection of lines. Keeping those two levels separate prevents many debugging detours.

Common Mistake: Baseline on Non-Text Components

Baseline alignment is most intuitive when items expose meaningful text baselines. Image-heavy cards, replaced elements, and nested controls can use synthesized baselines that do not match the visual edge a designer expected.

Inspect the actual baseline behavior and choose start or center when the relationship is primarily geometric. Do not add arbitrary transforms or offsets to force a fragile baseline result.

A Systematic Debugging Workflow

First confirm that the parent establishes Flexbox and that the target element is an in-flow direct child. Inspect flex-direction, writing mode, and direction to identify the cross axis. Then inspect the container, flex line, and item's used cross sizes.

Check whether align-self overrides align-items, whether the item has an explicit cross size, and whether minimums or maximums constrain it. Inspect cross-axis margins for auto values, confirm that wrapping has not created a different line, and determine whether the child is absolutely positioned. Finally, use the browser's Flexbox overlay and computed styles to verify which declaration wins.

1. Confirm the flex container and direct item
2. Identify the cross axis
3. Inspect line and item cross sizes
4. Check align-self and auto margins
5. Check explicit and min/max cross sizes
6. Inspect wrapping and positioned children
7. Verify the winning computed declaration

Complete Example

The following component centers all items by default, then places one item at cross-start and another at cross-end. A deliberate minimum block size provides room for the differences to appear.

<div class="alignment-demo">
  <div class="item item-one">One</div>
  <div class="item item-two">Two</div>
  <div class="item item-three">Three</div>
</div>

.alignment-demo {
  min-block-size: 12rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem;
}

.item-two {
  align-self: flex-start;
}

.item-three {
  align-self: flex-end;
}

Item one follows the container and remains centered. Item two overrides the default toward cross-start. Item three overrides it toward cross-end. If the container changes to column, those positions shift to the new horizontal cross axis under a common writing mode.

Common Interview Questions

What does align-items do? It sets the default cross-axis alignment for the flex items in each flex line.

What does align-self do? It overrides the container's cross-axis alignment for one individual flex item.

Does align-items always align vertically? No. It follows the cross axis, whose physical direction depends on flex-direction and writing mode.

What is the common default behavior? Flex items commonly behave as though align-items is stretch, provided their cross size is auto and constraints permit stretching.

Why might stretch not work? The item may have an explicit cross size, a limiting min/max size, an auto cross-axis margin, or no additional line space to fill.

What does baseline alignment do? It aligns compatible item baselines so differently sized text can share a natural reading line.

How does align-items differ from align-content? Align-items positions items within each line; align-content distributes multiple lines inside the container.

Can align-self be used on the flex container? It affects that container only if the container is itself an item of an outer flex or grid layout. It does not align its own children.

What can override normal cross-axis alignment? An explicit align-self value and cross-axis auto margins are important factors, along with sizing constraints and positioned layout.

Practical Review Checklist

  • Set align-items on the flex container.
  • Set align-self only on the item that needs an exception.
  • Identify the cross axis from flex-direction and writing mode.
  • Use stretch when automatic cross sizes should fill the flex line.
  • Check explicit height in rows and explicit width in columns when stretch fails.
  • Use center for compact controls that need a shared visual center.
  • Use start for icons beside long, multi-line content when appropriate.
  • Use baseline for related text with different font sizes.
  • Use align-content only when multiple flex lines need distribution.
  • Remember that text-align and vertical-align solve different problems.
  • Inspect auto margins before assuming align-self is broken.
  • Use nested containers when subsets require different alignment systems.
  • Test narrow screens, zoom, RTL, translations, and enlarged text.
  • Use DevTools to inspect axes, flex lines, computed sizes, and winning rules.

Key Takeaway

align-items defines the cross-axis alignment default for all flex items in a line, while align-self lets one item override that default. Their physical effect follows the cross axis, so a row commonly produces vertical alignment and a column commonly produces horizontal alignment in a standard horizontal writing mode.

Predictable results require more than choosing center or stretch. Check the line's available cross space, each item's automatic or explicit cross size, minimum and maximum constraints, auto margins, wrapping, and nested layout roles. Use baseline for typographic relationships, start alignment for first-line relationships, center for compact visual groups, and stretch for items that should fill an automatic cross size. With that mental model, cross-axis alignment becomes a deliberate layout decision rather than a sequence of guesses.