align-self & order
align-self allows individual flex items to override the container's align-items alignment, positioning themselves differently on the cross axis. The order property lets you reorder flex items visually without changing the HTML, useful for responsive design. These two properties enable fine-grained control over flex layouts.
align-self: override container alignment
Value | Alignment |
|---|---|
| Use container's align-items (default) |
| Align to start of cross axis |
| Align to end of cross axis |
| Center on cross axis |
| Stretch to fill cross axis |
| Align to baseline |
<!-- All items aligned to center by default -->
<div class="container">
<div class="item">Item 1</div>
<div class="item special">Item 2</div>
<div class="item">Item 3</div>
</div>
.container {
display: flex;
height: 200px;
align-items: center; /* all items centered vertically */
}
.item {
/* Centers with container's align-items */
}
.special {
align-self: flex-start; /* this item aligns to top */
}
<!-- Result -->
Item 1 Item 2 Item 3
(centered) (top) (centered)
<!-- Another example -->
.sticky-bottom {
align-self: flex-end; /* aligns to bottom */
}
.stretch-full {
align-self: stretch; /* stretches full height */
}Practical align-self patterns
<!-- Card with header, content, and footer -->
<div class="card">
<div class="card-header">Header</div>
<div class="card-content">Content goes here...</div>
<div class="card-footer">Footer</div>
</div>
.card {
display: flex;
flex-direction: column;
height: 300px;
}
.card-header {
flex: 0 0 auto; /* fixed height */
}
.card-content {
flex: 1; /* grows to fill space */
overflow-y: auto;
}
.card-footer {
flex: 0 0 auto; /* fixed height */
align-self: flex-end; /* sticks to bottom even if content is short */
}
<!-- Navbar with misaligned item -->
<nav class="navbar">
<div class="logo">Logo</div>
<div class="nav-links">Links</div>
<div class="search-box">Search</div>
</nav>
.navbar {
display: flex;
align-items: center;
height: 60px;
}
.search-box {
align-self: stretch; /* stretch to fill navbar height */
padding: 10px;
}order: reordering without HTML changes
The order property controls the visual order of flex items without requiring HTML changes. Useful for responsive designs where you want different column orders on different screen sizes.
<!-- Three items in HTML order: 1, 2, 3 -->
<div class="container">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</div>
.item {
order: 0; /* default order value */
}
<!-- Items display in HTML order: [1] [2] [3] -->
<!-- Change visual order with order property -->
.item:nth-child(1) {
order: 2; /* move to position 2 */
}
.item:nth-child(2) {
order: 3; /* move to position 3 */
}
.item:nth-child(3) {
order: 1; /* move to position 1 */
}
<!-- Result: [3] [1] [2] -->
<!-- HTML order unchanged, visual order changed -->Responsive reordering
<!-- Three-column layout on desktop -->
<div class="layout">
<aside class="sidebar">Sidebar</aside>
<main class="main">Main</main>
<aside class="secondary">Secondary</aside>
</div>
/* Desktop: sidebar | main | secondary */
.sidebar {
order: 1;
flex: 0 0 200px;
}
.main {
order: 2;
flex: 1;
}
.secondary {
order: 3;
flex: 0 0 150px;
}
.layout {
display: flex;
gap: 20px;
}
<!-- Desktop: [Sidebar] [Main] [Secondary] -->
/* Mobile: reorder to main first */
@media (max-width: 768px) {
.sidebar {
order: 2; /* move to second */
flex: 0 0 100%; /* full width */
}
.main {
order: 1; /* move to first */
flex: 1;
}
.secondary {
display: none; /* hide on mobile */
}
.layout {
flex-direction: column;
}
}
<!-- Mobile: [Main]
[Sidebar] -->
/* Or different mobile order */
@media (max-width: 600px) {
.sidebar { order: 1; }
.main { order: 2; }
.secondary { order: 3; }
.layout { flex-direction: column; }
}
<!-- Mobile: [Sidebar]
[Main]
[Secondary] -->Order values
/* Order is a number (can be negative) */
.item {
order: 0; /* default */
order: 1; /* moves after default items */
order: -1; /* moves before default items */
order: 100; /* very high number = moves to end */
}
<!-- Items with no order specified have order: 0 -->
<!-- Items with negative order appear first -->
<!-- Items sort by order value, then by HTML order -->
.priority {
order: -1; /* always appears first */
}
.normal {
order: 0; /* appears in HTML order */
}
.last {
order: 1; /* appears last -->
}Accessibility consideration with order
Reordering with order changes visual layout but not source order. For keyboard navigation and screen readers, content follows HTML order. Use order only for visual layout; ensure content makes sense in HTML order.
<!-- GOOD: order used for visual layout, content still makes sense in HTML -->
<div class="card">
<div class="card-header">Title</div>
<div class="card-body">Content</div>
<div class="card-footer">Action button</div>
</div>
.card {
display: flex;
flex-direction: column;
}
.card-footer {
order: -1; /* visually appears first */
}
<!-- Keyboard users follow HTML order: Header → Body → Footer -->
<!-- Visual order: Footer → Header → Body (just different on screen) -->
<!-- BAD: order changes logical flow -->
<div class="form">
<label>Username</label>
<input type="text">
<label>Password</label>
<input type="password">
<button>Submit</button>
</div>
.input-password {
order: -1; /* moves visually to top -->
}
<!-- Keyboard navigation is confusing (wrong order) -->
<!-- Avoid this pattern! -->