Welcome to our guide on making responsive layouts with the CSS Grid property! Before, making responsive designs meant writing lots of code, especially with media queries. But now, with CSS Grid, you can do it without all that extra coding hassle.
So let's get started.
When creating grid columns, it's recommended to use a value of 1fr, which stands for a fraction. This unit of measurement in CSS helps set grid items according to the screen size of your desktop, making the grid responsive.
For instance, if you set your template columns to 33%, 33%, and 33% with a gap of 20px, you may encounter a horizontal scroll bar. This occurs because each 33% takes up nearly the entire screen width, and with a gap of 20px between each column, it exceeds the available space, causing the scroll bar to appear.
To avoid this, you can use the value 1fr for each column in the grid template columns. This ensures that the grid adjusts appropriately to the desktop screen size, regardless of the gap between columns.
Responsive Grid Layout
<head>
<style>
body {
text-align: center;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, auto));
grid-gap: 20px;
}
.box {
padding: 20px;
height: 100px;
border: 1px solid black;
}
</style>
</head>
<body>
<h1>Responsive Grid Layout</h1>
<div class="container">
<div class=" box box-1">1. Box</div>
<div class=" box box-2">2. Box</div>
<div class=" box box-3">3. Box</div>
<div class=" box box-4">4. Box</div>
<div class=" box box-5">5. Box</div>
<div class=" box box-6">6. Box</div>
<div class=" box box-7">7. Box</div>
<div class=" box box-8">8. Box</div>
<div class=" box box-9">9. Box</div>
<div class=" box box-10">10. Box</div>
</div>
</body>
In this example, we have five columns that you can customize according to your requirements. However, using only the repeat() function may result in a grid layout that looks bad on smaller screens, as it maintains five columns regardless of screen size.
To achieve responsiveness without writing extensive code with media queries, we can use the auto-fit keyword. By combining auto-fit with the minmax() function, we instruct the browser to dynamically adjust the column sizes based on available space. As the device size decreases, the number of columns will also decrease, and vice versa, ensuring a responsive layout with minimal effort.
How does it work exactly?
In this example, we set up 5 columns each with a width of 250px, which totals 1250px. Considering a typical laptop screen width of 1440px, there's 190px of remaining space. As a result, the second column, with its width of 250px, will start on the second row to accommodate the extra space.
As the screen size decreases, the column boxes will evenly expand to fill the available space. This growth continues until there's enough space to accommodate an additional 250px column width, at which point a new column appears. Conversely, as the screen size shrinks further, the layout transitions into a single-column layout.
With just one line of code, you can create a responsive grid layout that adjusts dynamically to different screen sizes.
Creating spans with autoflow: dense
When creating a grid layout with equal-width columns, you may sometimes need to span two or more columns for certain grid items. This can be easily achieved by adding a span to the grid columns that require more space.
For instance, if you want the third column to span across two columns, you can use the following code:
.box-3 {
grid-column: span 2;
}
However, when spanning columns, you may encounter a problem where a wide item cannot fit on a row, resulting in a gap in the grid layout. This occurs because the item is moved to the next row by grid auto-fit to accommodate its width.
If you want to ensure that another cell fills the space left by the spanning item, you can use the grid-auto-flow: dense property. This property instructs the browser to densely pack grid items, filling any gaps that may occur with other items.
How to specify a span?
To specify the span of a grid item, one simple method is to use the grid-column property with the span keyword followed by the number of columns the item should span. For example, if an item should span two columns, you would use grid-column: span 2.
We understand the concept of grid lines to make it easier to understand other methods. These lines define the boundaries of the grid cells to specify where grid items should start and end within the grid. In the image below, the grid line is shown from where the line starts to where it ends.
You can specify grid lines from left to right positive values (1,2..) or right to left negative values (-1,-2... ) using the grid-column property.
.items {
grid-column: (start column line) / (end column line);
}
The span keyword can replace any item's start or end.
- grid-columns: 1 / 5
- grid-column: -2 / -5
- grid-columns: 2 / span 4
- grid-columns: -5 / span 3
- grid-columns: span 2 / -1 and more.
Overflow side-scrolling problems
We created a grid layout that looks great at desktop size.
Desktop full screen size
But when we see it on a small screen, its size is ruined, indicating that the layout is broken.
Desktop small screen size
The grid layout in this image looks messy, with the container shrinking and failing to provide uniform width to all cells. Consequently, the grid breaks on the container's right side, leading to horizontal scrolling.
This problem happens because the browser follows the grid lines exactly as they're set. Despite the width being sufficient for a two-column grid, the grid line numbering system includes a fifth grid line, contradicting the desired layout. To properly display the implicit two-column grid, only row numbers like 1, 2, and 3, as well as -3, -2, and -1, should be utilized.
When grid items reference grid column numbers beyond the grid boundaries, such as lines 4, 5, or 6 (which can also be negative), it confuses the browser. While we've designed flexible columns (where one column equals two), we've also explicitly referenced a grid layout that doesn't match a two-column grid. In cases of conflict between the implicit and explicit column numbers, the grid follows the explicit grid.
To create distinct columns, spans can be employed similarly to grid line numbers. For instance, using grid-column: span 3 forces the grid to occupy at least three columns, aligning with our intentions.
Media queries seem like the only solution to adjust grid-column values for various screen widths. However, after experimentation, we've found limited workarounds that accommodate up to two columns. Therefore, only one media query is necessary for single-column layouts on the narrowest screens.
Solutions
The solution is to specify the span using only the visible grid lines in the smallest displayed grid. In this case, it's a two-column grid. We'll use a media query to handle single-column scenarios for very narrow screens. By dividing the grid into grid lines 1, 2, and 3 (or -3, -2, and -1), we can safely use spans without issues.
.box-1 {
grid-column: span 2;
}
div:nth-child(8) {
grid-column: -3 / -1;
}
Desktop full screen size
Desktop medium Screen size
Desktop small-screen size
In this example, we've demonstrated how the grid can be adapted into a responsive layout. As the screen size decreases, the items remain responsive, adjusting to fit into two columns. However, for mobile responsiveness, where all items should be displayed within a single column, a media query is necessary. This can be implemented in just one line of code.
So, look at the Media Query example.
In the media query, specify the size at which all grid items should be set on one line. Then, with the display set to flex and the flex decoration set to column, all boxes will be set to line.
Suppose you want all the items to be set in a single line as soon as the screen size is 580 px.
@media (max-width: 580px) {
.container {
display: flex;
flex-direction: column;
}
}
Desktop small screen size
How to use :nth-child() to repeat a variable length display?
Many developers use the :nth-child selector to style a grid of up to two dozen lines of code, such as:
.box:nth-child(1),
.box:nth-child(5),
.box:nth-child(8) {
grid-column: 1 / 3;
}
Styling one or two elements individually is manageable, but when dealing with multiple elements, another approach is more efficient.
Using the :nth-child pseudo-selector allows you to target specific child elements without the need for manual selection each time. For example, :nth-child(2n+2) targets every second child element. This method simplifies styling, especially when dealing with many elements.
Let's get a good understanding of how this selector works.
.box:nth-child(5n + 1) {
grid-column: 1 / 3;
}
In this example, the .box:nth-child(5n + 1) selector targets specific child elements within the grid. It selects the 1st, 6th, 11th, and so forth child items. The equation 5n + 1 generates a sequence of child indices based on the value of n. Starting with n=0, the browser computes the indices (5 * 0 + 1 = 1), (5 * 1 + 1 = 6), and so on. Once the browser reaches an index that doesn't correspond to an existing child item, it stops applying the CSS.
.box:nth-child(10n + 2) {
margin: 20px;
}
The CSS selector .box:nth-child(10n + 2) targets specific child elements within the grid layout. It selects items 2, 12, 22, 32, and so forth, following a pattern defined by the equation 10n + 2.
For instance, when n = 0, the computed index is (10 * 0 + 2 = 2), indicating the second child element. Similarly, when n = 1, the computed index becomes (10 * 1 + 2 = 12), representing the twelfth child element.
This pattern continues, selecting every 10th item starting with the second child. The margin property is then applied to these selected items, creating the desired spacing effect.
Thoughts
Through this example, you've learned about creating responsive grids using CSS Grid. CSS Grid offers a straightforward way to build flexible and responsive layouts with minimal code.
However, one challenge with responsive grids is handling the last row. On smaller screens, the last row may not be filled, leaving empty spaces. To address this, we can specify the starting position of grid items using the "auto" keyword, allowing them to align dynamically based on available space.
.box {
grid-column: auto, -1;
}
This will cause the left-hand edge to extend to the end of the row.
Creating a responsive grid using media queries
If you only want to use a media query to create a responsive grid layout, you can also make it with the help of a media query.
<head>
<style>
body {
text-align: center;
}
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 20px;
}
.box {
padding: 20px;
height: 100px;
border: 1px solid black;
background-color: thistle
}
@media (max-width: 1200px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
@media (max-width: 800px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 550px) {
.container {
grid-template-columns: repeat(1, 1fr);
}
}
</style>
</head>
<body>
<h1>Responsive Grid Layout</h1>
<div class="container">
<div class=" box box-1">1. Box</div>
<div class=" box box-2">2. Box</div>
<div class=" box box-3">3. Box</div>
<div class=" box box-4">4. Box</div>
<div class=" box box-5">5. Box</div>
<div class=" box box-6">6. Box</div>
<div class=" box box-7">7. Box</div>
<div class=" box box-8">8. Box</div>
<div class=" box box-9">9. Box</div>
<div class=" box box-10">10. Box</div>
<div class=" box box-11">11. Box</div>
<div class=" box box-12">12. Box</div>
</div>
</body>
As you can see, the grid layout becomes responsive with the help of a media query but would require writing a lot of code.
You can use functions in Grid instead of media queries, which we looked at in this article. If you use the minmax() function to make the grid layout responsive, you will not need to write much code and will get quicker results with less code.
To see this in action, remove the media queries and add the following line to the (.container) selector.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-gap: 20px;
}
When each column falls below 300px in width, it will automatically break. This is a responsive grid layout created with just one line of code.
Conclusion
CSS Grid is handy for quickly making complex layouts and ensuring they look good on different devices with minimal coding. While CSS Flex can also help with layouts, it only works in one direction either horizontally or vertically. But with CSS Grid, you get the best of both worlds: control over layout in both horizontal and vertical directions.
I hope you found this article helpful. Please share it with your friends so that they can also learn something new. If you have any questions about this article or related to web development, you can ask in the question box below given below. And you will get the answer soon.