Skip to content

Fix: CSS Flexbox Not Working (display: flex Has No Effect)

FixDevs · (Updated: )

Part of:  React & Frontend Errors

Quick Answer

How to fix CSS Flexbox not working — why display flex has no effect, flex children not aligning, flex-grow not stretching, and how to debug common Flexbox layout issues.

The Error

You add display: flex to a container but nothing changes. Items still stack vertically, justify-content has no effect, or flex-grow does not stretch the children. There is no error message — the layout just does not behave as expected.

Common symptoms:

  • Items are not in a row even though flex-direction: row is set (the default).
  • justify-content: center does nothing.
  • align-items: stretch is not stretching children to the container height.
  • flex: 1 on a child does not make it fill the available space.
  • A flex item is overflowing or not shrinking when expected.
  • Flexbox works on desktop but breaks on mobile.

Why This Happens

Flexbox works by applying rules to two things: the flex container (the element with display: flex) and flex items (its direct children). Most problems fall into one of these categories:

  • The flex rule is applied to the wrong element (e.g., a grandchild instead of a direct child).
  • A different CSS rule is overriding the flex behavior.
  • The flex container has no height, so vertical alignment has nothing to work with.
  • Properties are applied to the container that belong on items, or vice versa.
  • The flex item is absolutely positioned, which takes it out of the flex flow.
  • A browser bug or missing vendor prefix (rare in modern browsers).

Platform and Environment Differences

Flexbox is part of every modern browser, but small differences between engines and form factors cause real bugs that look like missing rules.

Safari and WebKit quirks. Safari shipped flexbox earlier than other engines and still carries the longest history of legacy -webkit- prefixes. The gap property on flex containers landed in Safari 14.1 (April 2021); before that, Safari accepted gap only inside CSS Grid containers. iOS Safari versions trail desktop Safari by a few weeks per release, and users on older iPads often run a Safari WebView that does not match the latest spec. If a layout works in Chrome and breaks on a specific iPhone, check the Safari version with navigator.userAgent and confirm gap support against the actual build.

Firefox vs Chromium nested behavior. Firefox and Chromium both implement the modern Flexbox spec, but their interaction with auto-sized images and the intrinsic-size algorithm differs. A flex item containing an unsized <img> may report a min-content width of the image’s natural width in Chromium and 0 in Firefox under some flex-basis: auto settings. The cross-browser fix is min-width: 0 on the flex item plus an explicit width or max-width on the image.

iOS Safari and the legacy -webkit- prefix. Older iOS (12 and below) still uses the 2009 flexbox syntax (display: -webkit-box) for some properties. You generally do not need to write -webkit-flex in 2026, but if you support enterprise kiosks or in-app WebViews on legacy Android, autoprefixer with a realistic browserslist is safer than writing prefixes by hand.

Android WebView and in-app browsers. Apps using the system WebView pin against the device’s Chrome version. On older Android tablets, the WebView can be several major versions behind. The gap property on flex containers was not supported in WebView until the underlying Chrome reached 84. If a hybrid app shows a broken layout but the same URL works in standalone Chrome, the WebView version is almost always the cause.

Mobile vs desktop viewport units. A flex container sized with height: 100vh behaves differently on iOS Safari, where 100vh includes the area behind the dynamic URL bar. The container becomes taller than the visible viewport, and centered content drifts below the fold. The modern fix is the small-viewport-height unit 100svh (supported in Safari 15.4+ and Chromium 108+) or, with broader support, height: 100dvh for the dynamic viewport.

IE11 and enterprise still asks. IE11 reached end of life on most platforms in 2022, but enterprise SKUs and embedded industrial software still target it. IE11’s Flexbox implementation is the older 2012 syntax with multiple known bugs: flex-shrink does not respect flex-basis: auto, percentages on flex-basis are unreliable, and min-height on a column flex container is ignored. If you must support IE11, set explicit flex-basis in pixels and avoid nested flex containers.

CSS Grid subgrid and Flexbox interplay. Subgrid is a Grid feature, not Flex, but you may be debugging the wrong layout. Firefox shipped subgrid in 71 (December 2019); Chromium shipped it in 115 (July 2023); Safari in 16. If a parent uses Grid and children are flex containers, subgrid availability changes how the children’s intrinsic sizes feed back into the grid track sizes.

Fix 1: Make Sure display: flex Is on the Container, Not the Child

display: flex makes an element a flex container. Its direct children become flex items. Properties like justify-content and align-items go on the container; properties like flex-grow, align-self, and order go on the children.

Broken — flex applied to the wrong element:

/* You want the nav links in a row */
nav {
  /* display: flex is missing here */
}

nav a {
  display: flex; /* This makes each link a flex container, not what you want */
}

Fixed:

nav {
  display: flex;
  gap: 1rem;
}

nav a {
  /* No display: flex needed here */
}

Verify with DevTools: Right-click the container element, inspect it, and look for the flex badge next to the element in the Elements panel. If it is not there, display: flex is not applied or is being overridden.

Fix 2: Give the Flex Container a Height for Vertical Alignment

align-items controls alignment along the cross axis (vertical, by default). If the container has no explicit height, it shrinks to fit its content — and there is no extra space to align in.

Broken — container has no height:

.container {
  display: flex;
  align-items: center; /* Does nothing — container is only as tall as its content */
}

Fixed — set an explicit height:

.container {
  display: flex;
  align-items: center;
  height: 100vh;     /* Full viewport height */
  /* or */
  min-height: 200px; /* Minimum height */
}

Why this matters: align-items: center centers children within the container’s height. If the container is exactly as tall as its content, there is zero free space and nothing to center. Always check the container has sufficient height when vertical centering does not work.

Fix 3: Fix flex: 1 Not Expanding

flex: 1 on a child makes it grow to fill available space in the container. It does not work if:

  • The container has no defined width (for flex-direction: row).
  • The container has no defined height (for flex-direction: column).
  • Another property like width or max-width overrides the flex growth.

Broken — column flex container with no height:

.sidebar {
  display: flex;
  flex-direction: column;
}

.sidebar .menu {
  flex: 1; /* Does not expand — .sidebar has no height */
}

Fixed:

.sidebar {
  display: flex;
  flex-direction: column;
  height: 100vh; /* Now .menu can fill the remaining space */
}

.sidebar .menu {
  flex: 1;
}

Broken — explicit width overrides flex-grow:

.item {
  flex: 1;
  width: 200px; /* This overrides flex-basis, flex-grow cannot expand beyond it */
}

Fixed — use min-width instead:

.item {
  flex: 1;
  min-width: 200px; /* Item can still grow beyond this */
}

flex: 1 is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0. An explicit width sets flex-basis effectively, limiting growth.

Fix 4: Fix justify-content Not Working

justify-content aligns items along the main axis (horizontal by default). It has no visible effect when:

  • There is only one item and it fills the container.
  • The items are wider than the container (no free space to distribute).
  • You are using it on a flex item instead of the container.

Verify the container has free space:

.container {
  display: flex;
  justify-content: space-between; /* Only works if items don't fill 100% of width */
  width: 100%;
}

.item {
  /* If flex: 1 is set here, items fill all space — space-between has no effect */
  flex: 1; /* Remove this if you want space-between to work */
}

justify-content on wrong element:

/* Wrong — on the item */
.item {
  justify-content: center;
}

/* Right — on the container */
.container {
  justify-content: center;
}

Common Mistake: justify-content and align-items go on the container. align-self, justify-self, flex-grow, flex-shrink, flex-basis, and order go on the items. Mixing these up is the most common Flexbox mistake.

Fix 5: Fix Flex Items Wrapping When They Should Not (or Vice Versa)

By default, flex items do not wrap (flex-wrap: nowrap). If items are overflowing, they are being forced into a single line. If they are wrapping when you do not want them to, check for flex-wrap: wrap being set.

Prevent overflow by allowing wrapping:

.container {
  display: flex;
  flex-wrap: wrap; /* Items wrap to the next line when they run out of space */
  gap: 1rem;
}

Force items to stay in one row and shrink:

.container {
  display: flex;
  flex-wrap: nowrap; /* Default — items shrink to fit */
}

.item {
  min-width: 0; /* Important: allows items to shrink below their content size */
}

min-width: 0 is important. By default, a flex item’s minimum width is its content width (min-width: auto). This means it will not shrink smaller than its content even if flex-shrink is set. Adding min-width: 0 allows the item to shrink further.

Fix 6: Fix Absolutely Positioned Flex Items

Absolutely positioned elements are removed from the flex flow. They do not participate in flex layout:

.container {
  display: flex;
  justify-content: space-between;
}

.item {
  position: absolute; /* This item is now out of the flex flow */
  /* justify-content and align-items won't affect it */
}

If you need a child to be positioned absolutely within a flex container, that is valid — but it will not be laid out by Flexbox. Other items in the container will behave as if this item does not exist.

Fix 7: Fix Text Overflow Inside Flex Items

Long text or content inside a flex item can cause the item to overflow the container:

Broken:

.container {
  display: flex;
}

.item {
  /* Item expands to fit the long text, overflowing the container */
}

Fixed:

.item {
  min-width: 0;       /* Allow shrinking */
  overflow: hidden;   /* Hide overflow */
  text-overflow: ellipsis;
  white-space: nowrap;
}

Or for wrapping text:

.item {
  min-width: 0;
  word-break: break-word;
}

Fix 8: Fix Flexbox in Specific Contexts

Flexbox inside a table cell. Table cells (td, th) have a default display: table-cell. You can override this with display: flex, but it may conflict with table layout. Use a wrapper div inside the cell instead.

Flexbox on <button> or <input>. Some browsers have quirks with flex on form elements. Add display: flex explicitly and check computed styles. For <button>, also set width: 100% if you want it to fill its container.

Flexbox and SVG. SVG elements do not respond to Flexbox the same way HTML elements do. Wrap SVGs in a <div> flex item if you need to position them with Flexbox.

Tailwind CSS: If you are using Tailwind and flex classes are not applying, see Fix: Tailwind CSS classes not applying. For z-index stacking issues that can affect overlapping flex children, see Fix: CSS z-index not working. For Grid-specific track sizing problems that often get blamed on Flexbox, see Fix: CSS Grid not working.

Debugging Flexbox

Use browser DevTools. In Chrome/Firefox DevTools, click the flex badge next to the container element to open the Flexbox inspector. It shows you the flex lines, item sizes, and free space distribution visually — far faster than guessing.

Temporarily add a background color. Add distinct background colors to the container and each flex item to see their actual boundaries:

.container { background: rgba(255, 0, 0, 0.1); }
.item { background: rgba(0, 0, 255, 0.1); }

Check the computed styles. In DevTools, the Computed panel shows the final value of every CSS property after all cascading and inheritance is resolved. If display: flex shows as block in computed styles, something is overriding it.

Simplify first. Create a minimal reproduction with just the container and one or two items, no other styles. Add styles back one at a time until the layout breaks.

Still Not Working?

Check for !important overrides. Another stylesheet may be overriding your flex rules with !important. In DevTools, overridden rules appear with a strikethrough.

Check inheritance. Flex properties are not inherited. display: flex on a container does not make grandchildren flex items — only direct children are flex items. To apply flex to nested elements, you need display: flex on each level.

Check for display: none. A hidden container cannot be inspected visually. If the parent is display: none, none of its flex behavior is visible.

Browser support. Flexbox is supported in all modern browsers. If you are targeting older browsers (IE 11), some properties like gap are not supported and you need margin instead. Check MDN for browser compatibility tables.

gap vs margin. The gap property (previously grid-gap) works in Flexbox since Chrome 84, Firefox 63, Safari 14.1. If gap is not working, you may need to use margin on flex items as a fallback, or check the browser version.

Check the parent’s writing mode. Flexbox respects writing-mode and direction. A flex-direction: row container with writing-mode: vertical-rl lays items top to bottom, not left to right. If your layout looks rotated, check the closest ancestor with a non-default writing-mode — common with multi-language sites that flip directions per locale.

Check contain and modern containment. A container with contain: layout or contain: size constrains layout calculations to itself. Inside such a container, percentage heights and flex-basis: auto can resolve differently than expected because the parent no longer participates in the inner sizing pass. Remove contain temporarily to see if it is masking the issue.

Check user style sheets and browser extensions. Reader-mode extensions, dark-mode shims, and accessibility tools like Stylus inject CSS into the page. Flex rules may be overridden by * { display: block !important; } or similar nuclear declarations from an extension. Test in a clean incognito window with extensions disabled before going further.

Check for Tailwind v4 layer ordering. If you migrated to Tailwind v4 and your custom flex utilities stopped winning, the @layer ordering changed in the new CSS cascade. See Fix: Tailwind v4 not working for the layer-priority rules and migration checklist.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles