Auto-fill phantom grid columns happen when CSS Grid reserves empty tracks, gaps, and column space even when there are not enough real items to fill the row.
CSS Grid Auto-Fill Fix
Why does auto-fill create phantom grid columns?
auto-fill creates phantom grid columns when the browser keeps empty tracks in the grid even though there are no real items inside them. That can leave visible gaps, make cards look squeezed, and create a strange sense that the layout is reserving space for invisible content.
This is not a browser bug. It is the main difference between auto-fill and auto-fit. auto-fill fills the row with as many tracks as can fit, including empty ones. auto-fit collapses empty tracks and lets the remaining items stretch. If you choose the wrong one, your grid can look like it has ghost columns.
- CSS Grid
- auto-fill
- phantom columns
- empty tracks
Compare auto-fill and auto-fit with only two cards
The fastest test is simple: keep the same grid, leave only two items, then switch auto-fill to auto-fit. If the phantom space disappears, the empty tracks were being preserved by auto-fill.
Related: Try this in the FrontFixer Live Inspector.
Open Live Inspector→What the bug looks like
A responsive card grid appears to reserve columns for missing items or leaves strange empty areas.
Why it happens
auto-fill keeps empty grid tracks instead of collapsing them like auto-fit.
What usually fixes it
Switch to auto-fit, cap track width, or use auto-fill only for intentional slot systems.
Why auto-fill can make invisible columns feel real
auto-fill tells CSS Grid to create as many tracks as can fit in the container. If the container can fit four tracks but you only have two real cards, the grid can still reserve the shape of those extra tracks. That is why the layout can look like it is saving room for cards that do not exist.
This behavior is useful in some designs. For example, a calendar, dashboard slot system, skeleton loading state, or reserved product shelf may need empty columns to remain part of the layout. In those cases, the “phantom” columns are not a bug. They are a feature.
But for normal article cards, product cards, feature cards, and related-post grids, phantom columns often look accidental. The reader sees a strange gap, not a clever grid algorithm. When the design should be content-driven, auto-fit is often the better default.
auto-fill preserves tracksEmpty columns can still affect the layout rhythm.auto-fit collapses tracksExisting cards can expand after empty tracks disappear.Empty tracks stay reserved with only a few cards
The most common mistake is using auto-fill for a normal card grid where the existing cards should use the available space. With only a few cards, empty tracks stay reserved and the row looks like it contains invisible items.
Broken code
Empty tracks remain.cards {
display: grid;
grid-template-columns:
repeat(auto-fill, minmax(220px, 1fr));
gap: 16px;
}
Broken visual result
The row keeps room for columns with no real cards.
Correct code
Empty tracks collapse.cards {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(min(100%, 220px), 1fr));
gap: 16px;
}
Fixed visual result
The empty tracks collapse and the two cards own the row.
auto-fit when existing cards should expand into unused space.Phantom gaps make the row look misaligned
Phantom columns do not only reserve width. They can also preserve the visual rhythm of gaps. That is why a grid can look slightly shifted, squeezed, or oddly spaced even when the cards themselves are not overflowing.
Broken code
Gap belongs to phantom tracks.product-grid {
display: grid;
grid-template-columns:
repeat(auto-fill, minmax(180px, 1fr));
gap: 24px;
}
Broken visual result
Large gaps make the empty column feel visible.
Correct code
Gap and behavior aligned.product-grid {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(min(100%, 180px), 1fr));
gap: clamp(12px, 3vw, 24px);
}
Fixed visual result
The grid uses available space without exposing ghost gaps.
Cards refuse to stretch because phantom tracks take space
A layout may look like the cards are too small even though the container has plenty of room. The missing detail is that the empty tracks still participate in the grid. The real cards are sharing space with phantom columns.
Broken code
Real cards share with ghosts.cards {
display: grid;
grid-template-columns:
repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
}
Broken visual result
The real cards do not get all the available row width.
Correct code
Only real cards share.cards {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(min(100%, 240px), 1fr));
gap: 16px;
}
.cards > * {
min-width: 0;
}
Fixed visual result
The existing cards now share the available space.
Using auto-fit when the design actually needs reserved slots
The opposite mistake can happen too. Some interfaces really do need empty slots to remain visible. If the design is a scheduler, seat map, dashboard placeholder, or loading skeleton, auto-fill may be the correct behavior.
Broken code
Slots collapse accidentally.slot-grid {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(160px, 1fr));
gap: 16px;
}
Broken visual result
The design expected empty slots to stay visible.
Correct code
Reserved slots intentional.slot-grid {
display: grid;
grid-template-columns:
repeat(auto-fill, minmax(160px, 1fr));
gap: 16px;
}
.slot.is-empty {
opacity: .45;
}
Fixed visual result
Empty slots are visible because the design needs them.
auto-fill when the empty tracks communicate real future slots.A production-minded auto-fill pattern
A premium grid does not treat auto-fill as a random replacement for auto-fit. It uses auto-fill only when empty tracks are part of the interface. For content-driven card grids, it usually uses auto-fit instead.
Premium code
Choose by intent/* Content-driven cards */
.card-grid {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(min(100%, 240px), 1fr));
gap: clamp(14px, 2vw, 24px);
}
/* Slot-based UI */
.slot-grid {
display: grid;
grid-template-columns:
repeat(auto-fill, minmax(160px, 1fr));
gap: 16px;
}
Premium visual result
The card grid collapses empties. The slot grid preserves them.
Fast practical rule
If auto-fill creates phantom grid columns, ask whether the empty tracks are useful. If the grid is a normal card list, switch to auto-fit. If the grid is a slot-based interface, keep auto-fill and make the empty slots visually intentional.
Debug checklist
- Check whether the grid uses
repeat(auto-fill, minmax(...)). - Test the grid with only one or two items.
- Look for empty tracks that still preserve width or gaps.
- Switch temporarily from
auto-filltoauto-fitand compare the result. - Decide whether empty columns should communicate real reserved slots.
- Use
auto-fitfor normal content-driven card grids. - Use
auto-fillfor calendars, placeholders, skeletons, or slot systems. - Make reserved empty states visually intentional when they are part of the UI.
auto-fill with auto-fit and test the same item count.When phantom columns are actually useful
Phantom columns are not always a mistake. A booking calendar, empty dashboard panel, skeleton loading layout, or seat map may need those empty tracks to remain visible. In that context, the empty space is not “dead.” It communicates that the interface has reserved positions.
The problem is using that same behavior for regular content cards. A related-post grid, feature section, or product list usually should not look like it is missing invisible cards. Those layouts usually want the existing cards to control the space.
The authority move is to name the intent before choosing the keyword: content-driven grids usually want auto-fit; slot-driven grids can justify auto-fill.
Why this bug survives desktop review
This bug often hides during development because the demo content has the perfect number of cards. Six cards in a three-column layout look clean. Eight cards in a wide grid might also look fine. The phantom-column problem usually appears when filters, search results, or dynamic content leave only one or two items.
A strong review checks content states, not just breakpoints. Test one item, two items, many items, and empty loading states. That is the only way to know whether auto-fill is helping the interface or quietly creating ghosts.
The simplest mental model
Think of auto-fill as a grid that draws possible seats first, then places cards into some of those seats. Think of auto-fit as a grid that removes the empty seats and lets the occupied seats use the remaining space. Once you see that difference, the phantom column bug becomes much easier to diagnose.
Final takeaway
auto-fill creates phantom grid columns because it preserves empty tracks. That is useful when your interface needs reserved slots, but it can look broken when a normal card grid appears to be saving space for invisible items.
Use auto-fit when existing content should expand into available space. Use auto-fill when empty tracks are meaningful. The fix is not memorizing one keyword. The fix is matching the keyword to the layout’s real intent.