Difficulty: Intermediate
Flexbox provides properties for reordering items visually without changing the DOM structure and for adding consistent spacing between items. The order property changes the visual position of flex items, and the gap properties (gap, row-gap, column-gap) add spacing between items without using margins. These properties simplify common layout patterns that were previously difficult to achieve.
The order property assigns a visual sort order to flex items. By default, all items have order: 0 and appear in their DOM order. Items with lower order values appear first, and items with higher values appear later. Items with the same order value maintain their DOM order relative to each other. You can use negative values (order: -1) to move an item before all default-ordered items. This is powerful for responsive layouts where you might want to reposition elements at different breakpoints.
The gap property (also called flex-gap) sets the spacing between flex items. Unlike margins, gap only creates space between items, not at the edges of the container. This means you do not need to worry about removing margins from the first or last items -- a problem that plagued older layout approaches. The gap property is a shorthand for row-gap and column-gap, which control vertical and horizontal spacing independently. You can write gap: 16px for uniform spacing or gap: 16px 24px for 16px between rows and 24px between columns.
Before the gap property was widely supported in Flexbox (it was originally a CSS Grid-only property), developers used margins and negative margins to simulate gaps. A common pattern was margin: 8px on each item and margin: -8px on the container to cancel out the outer edges. The gap property eliminates this hack entirely and is now supported in all modern browsers for both Flexbox and Grid.
One important consideration with the order property is accessibility. Screen readers and keyboard tab order follow the DOM order, not the visual order set by CSS. If you reorder items with the order property, the visual layout and the tab/reading order will differ, which can confuse keyboard users and screen reader users. Use order for minor visual adjustments, but if you need a fundamentally different order for different screen sizes, consider restructuring your HTML or using CSS Grid's placement properties with caution.
.container {
display: flex;
gap: 12px;
}
/* DOM order: A, B, C, D */
/* Visual order: C, A, B, D */
.item-a { order: 1; }
.item-b { order: 2; }
.item-c { order: -1; } /* Moves to front */
.item-d { order: 3; }
/* Responsive reordering */
@media (max-width: 768px) {
.hero-image { order: -1; } /* Image first on mobile */
.hero-text { order: 0; } /* Text second on mobile */
}
Items are sorted by their order value, lowest first. Default is 0. Negative values move items to the front. This is commonly used for responsive layouts where the content order should differ between mobile and desktop.
/* Uniform gap */
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
/* Different row and column gaps */
.dashboard {
display: flex;
flex-wrap: wrap;
row-gap: 32px;
column-gap: 16px;
}
/* Shorthand: gap: <row-gap> <column-gap> */
.layout {
display: flex;
flex-wrap: wrap;
gap: 32px 16px; /* 32px between rows, 16px between columns */
}
gap creates spacing between items only, not at the container edges. row-gap controls vertical spacing between wrapped lines, and column-gap controls horizontal spacing between items in a line. The gap shorthand takes row-gap first, then column-gap.
/* OLD approach: margins + negative margin hack */
.container-old {
display: flex;
flex-wrap: wrap;
margin: -8px; /* Cancel outer margins */
}
.container-old .item {
margin: 8px; /* Creates gaps AND outer space */
}
/* MODERN approach: gap */
.container-new {
display: flex;
flex-wrap: wrap;
gap: 16px; /* Only between items, not at edges */
}
.container-new .item {
/* No margin needed */
}
The old margin approach creates spacing around every item including the outer edges, requiring a negative margin hack on the container to compensate. The gap property cleanly spaces only between items, eliminating the hack.
.nav {
display: flex;
align-items: center;
gap: 16px;
padding: 0 24px;
height: 60px;
}
/* Push everything after this item to the right */
.nav-spacer {
margin-left: auto;
}
/* Common pattern: logo left, links right */
.logo { /* stays left naturally */ }
.nav-links {
margin-left: auto; /* Pushes to the right */
display: flex;
gap: 16px;
}
Auto margins in Flexbox consume all available space in the specified direction. margin-left: auto pushes an item (and everything after it) to the right. This is the standard technique for split navigation bars and is more flexible than justify-content: space-between when you need asymmetric spacing.
order, gap, row-gap, column-gap, Visual Reordering