How to create offset card rows?
Hello! Please explain how to create a structure with two rows of cards where the rows are offset relative to each other - one row shifted left and the other shifted right, with both rows extending beyond the viewport. I’m interested in implementation for both desktop and mobile versions.
Creating Offset Card Rows with CSS Grid
To create offset card rows, use CSS Grid with different positioning for each row, applying media queries for responsiveness. On desktop, create two rows with different offsets, and on mobile devices, transform the layout into a vertical column for better readability.
Table of Contents
- Main Principle of Creating Offset Rows
- HTML Structure for Cards
- CSS Grid for Offset Layout
- Mobile Responsiveness
- Animations and UX Improvements
- Examples and Best Practices
Main Principle of Creating Offset Rows
Offset card rows are created using CSS Grid, where each row has a different horizontal offset. This approach allows you to create a visually interesting layout with a “staircase” effect, which is particularly effective for portfolios, galleries, or product cards.
Important: Offset rows not only improve visual appeal but also help better organize content, creating natural visual paths for the user’s eye movement.
To implement this approach, we need to:
- Create a container with
display: grid - Define the number of columns and rows
- Apply different
grid-columnormarginvalues for different rows - Add media queries for mobile adaptation
HTML Structure for Cards
<div class="offset-cards-container">
<!-- First row (left) -->
<div class="card-row row-left">
<div class="card">Card 1</div>
<div class="card">Card 2</div>
<div class="card">Card 3</div>
<div class="card">Card 4</div>
</div>
<!-- Second row (right) -->
<div class="card-row row-right">
<div class="card">Card 5</div>
<div class="card">Card 6</div>
<div class="card">Card 7</div>
<div class="card">Card 8</div>
</div>
</div>
More advanced structure using CSS Grid directly:
<div class="offset-cards-grid">
<div class="card card-left">Card 1</div>
<div class="card card-left">Card 2</div>
<div class="card card-left">Card 3</div>
<div class="card card-right">Card 4</div>
<div class="card card-right">Card 5</div>
<div class="card card-right">Card 6</div>
</div>
CSS Grid for Offset Layout
Basic Desktop Implementation
.offset-cards-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
max-width: 1200px;
margin: 0 auto;
padding: 40px 20px;
}
/* Left row cards */
.card-left {
grid-column: 1 / 2;
grid-row: auto;
margin-right: auto;
}
/* Right row cards */
.card-right {
grid-column: 2 / 4;
grid-row: auto;
margin-left: auto;
}
Alternative Approach Using Margin
.card-row {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.row-left {
margin-left: 0;
justify-content: flex-start;
}
.row-right {
margin-right: 0;
justify-content: flex-end;
}
Creating Overflow Beyond Viewport Effect
To make rows extend beyond the viewport, use negative margins:
.offset-cards-container {
overflow-x: hidden;
position: relative;
padding: 0 20px;
}
.card-row {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.row-left {
margin-left: -100px; /* Extends beyond left edge */
justify-content: flex-start;
}
.row-right {
margin-right: -100px; /* Extends beyond right edge */
justify-content: flex-end;
}
Mobile Responsiveness
Media Queries for Mobile Version
@media (max-width: 768px) {
.offset-cards-grid {
grid-template-columns: repeat(2, 1fr);
gap: 15px;
padding: 20px;
}
.card-left,
.card-right {
grid-column: 1 / -1;
margin: 0;
}
}
@media (max-width: 480px) {
.offset-cards-grid {
grid-template-columns: 1fr;
gap: 10px;
padding: 15px;
}
.card-row {
flex-direction: column;
margin: 0;
}
.row-left,
.row-right {
margin: 0;
}
}
Complete Example with Adaptation
.offset-cards-container {
display: flex;
flex-direction: column;
gap: 20px;
padding: 40px 20px;
overflow-x: hidden;
}
.card-row {
display: flex;
gap: 20px;
transition: all 0.3s ease;
}
/* Desktop version */
@media (min-width: 769px) {
.row-left {
margin-left: -100px;
justify-content: flex-start;
}
.row-right {
margin-right: -100px;
justify-content: flex-end;
}
}
/* Mobile version */
@media (max-width: 768px) {
.offset-cards-container {
padding: 20px;
}
.card-row {
justify-content: center;
margin: 0;
}
.row-left,
.row-right {
margin: 0;
}
}
Animations and UX Improvements
Adding Smooth Transitions
.card {
background: white;
border-radius: 12px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);
}
Card Appearance Animation
.card {
opacity: 0;
transform: translateY(20px);
animation: fadeInUp 0.6s ease forwards;
}
.card:nth-child(1) { animation-delay: 0.1s; }
.card:nth-child(2) { animation-delay: 0.2s; }
.card:nth-child(3) { animation-delay: 0.3s; }
.card:nth-child(4) { animation-delay: 0.4s; }
/* and so on */
@keyframes fadeInUp {
to {
opacity: 1;
transform: translateY(0);
}
}
Examples and Best Practices
Example 1: 3-Column System
.offset-cards-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 25px;
padding: 50px 30px;
}
/* First row - offset to the left */
.card-left {
grid-column: 1 / 2;
grid-row: auto;
}
/* Second row - offset to the right */
.card-right {
grid-column: 2 / 4;
grid-row: auto;
}
/* Adaptation */
@media (max-width: 768px) {
.offset-cards-grid {
grid-template-columns: repeat(2, 1fr);
gap: 20px;
padding: 30px 20px;
}
.card-left,
.card-right {
grid-column: 1 / -1;
}
}
Example 2: Combining Flexbox and Grid
.flex-grid-container {
display: flex;
flex-direction: column;
gap: 30px;
padding: 60px 40px;
}
.flex-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 25px;
}
.flex-row.offset-left {
margin-left: -50px;
}
.flex-row.offset-right {
margin-right: -50px;
justify-content: flex-end;
}
/* Mobile adaptation */
@media (max-width: 768px) {
.flex-grid-container {
padding: 30px 20px;
}
.flex-row.offset-left,
.flex-row.offset-right {
margin: 0;
justify-content: center;
}
}
Best Practices
- Use relative units - rem, em, % for better scalability
- Add responsive breakpoints - typically 768px and 480px for tablets and mobile
- Optimize performance - use
will-change: transformfor animated cards - Ensure accessibility - add aria-labels and semantic HTML markup
- Test on real devices - different browsers and screens may display the layout differently
Conclusion
Creating offset card rows is an effective way to add visual interest to your design. Key points:
- Use CSS Grid as the primary tool for creating complex layouts
- Apply negative margins for the overflow beyond viewport effect
- Always add media queries for mobile adaptation
- Experiment with different offset patterns to achieve the desired visual effect
- Don’t forget about performance and accessibility when adding animations
This approach is perfect for portfolios, product galleries, news feeds, and many other web applications where visual hierarchy and interface appeal are important.
Sources
- Responsive Card Layout with CSS Grid: A Step-by-Step Guide - DEV Community
- Designing Responsive Card Layouts with CSS Grid and Flexbox | ArtOfCode.org
- Building a Card Layout Using CSS Subgrid - DZone
- How should a responsive grid of cards look and work? - Reddit
- Creating Stacked Cards Using Only HTML & CSS - Medium
- 7 Amazing CSS Flexbox Tricks Every Beginner Should Know - InfoWebStar
- How To Combine Flexbox and CSS Grids for Efficient Layouts - WP Engine