search
HomeWeb Front-endCSS TutorialResponsive Grid Magazine Layout in Just 20 Lines of CSS

Responsive Grid Magazine Layout in Just 20 Lines of CSS

Recently I'm trying to redesign a blog list. The idea is to provide readers with the latest posts from these blogs, with a magazine-style layout instead of just listing our favorite blogs in the sidebar.

The easy part is getting a list of articles with summary from our favorite RSS feed. To do this, we used the WordPress plugin Feedzy lite, which aggregates multiple feeds into a list sorted by time – perfect for presenting their latest content. The hard part is making it look great.

The default list UI for this plugin is pretty bland, so I wanted to style it to resemble a newspaper or magazine website, mixing smaller and larger "featured content" panels.

This seems to be an ideal use case for CSS Grid! Create a grid layout for different layouts, for example, a five-column layout and a three-column layout, and then use media queries to switch between different breakpoints. Right? But when we can create a smooth responsive grid for us automatically using the grid's auto-adaptation option, do we really need these media queries—and all the hassles of identifying breakpoints?

This approach sounds attractive, but when I started introducing cross-column elements, I had problems with the grid overflowing on a narrow screen. Media queries seem to be the only solution. That is, until I find a solution!

After looking at several tutorials on CSS Grid, I found that they are mainly divided into two categories:

  1. Tutorials showing you how to create interesting layouts using span elements, but the number of columns is fixed.
  2. Tutorial explaining how to make a responsive grid that is automatically resized, but all grid items have the same width (i.e., no span columns).

I want the grid to do both at the same time: create a fully responsive fluid layout that also includes multiple column elements that responsively resize.

The beauty is that once you understand the limitations of responsive grids and why and when column spans destroy grid responsiveness, you can define responsive magazine/news style layouts with just a dozen lines of code plus a simple media query (or if you are willing to limit the span option, or even without media query).

This is a visual that shows the out-of-the-box RSS plugin and how we look after we style it.

This magazine-style grid layout is fully responsive, and the color feature panels will be dynamically adjusted as the number of columns changes. The page shows about 50 articles, but the layout code has nothing to do with the number of items displayed. Upgrade the plugin to display 100 projects, and the layout remains interesting all the time.

All this is implemented using CSS only, and there is only one media query to handle single column displays on the narrowest screen (i.e. less than 460 pixels).

Incredibly, this layout uses only 21 lines of CSS code (excluding global content styles). But to achieve this flexibility with so few lines of code, I had to dig deep into some of the more obscure parts of the CSS Grid and learn how to solve some of its inherent limitations.

The basic elements of the code that produces this layout are very short, demonstrating the power of CSS Grid:

 <code>.archive { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); grid-gap: 32px; grid-auto-flow: dense; } /* 特宽网格文章*/ .article:nth-child(31n 1) { grid-column: 1 / -1; } .article:nth-child(16n 2) { grid-column: -3 / -1; } .article:nth-child(16n 10) { grid-column: 1 / -2; } /* 手机单列显示*/ @media (max-width: 459px) { .archive { display: flex; flex-direction: column; } }</code>

The techniques in this article can also be well used to set up any dynamically generated content, such as the output of the latest article widget, archive page, or search results.

Create a responsive mesh

I set up seventeen projects to display various mock contents—titles, images, and excerpts—all included in a wrapper

<code><div>
  </div></code>

The code to convert these items into responsive grids is very compact:

 <code>.archive { /* 将元素定义为网格容器*/ display: grid; /* 自动适应尽可能多的项目在一行上,而不会低于180像素*/ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); /* 文章之间的一点间距*/ grid-gap: 1em; }</code>

Note that the row height is automatically adjusted to suit the highest content in the row. If you change the width of the Pen, you will see the items grow and shrink smoothly, with the number of columns changing from one column to five columns respectively.

The CSS Grid magic used here is the auto-fit keyword, which is used in conjunction with the minmax() function applied to grid-template-columns .

How it works

We can implement a five-column layout using only the following methods:

 <code>.archive { display: grid; grid-template-columns: repeat(5, 1fr); }</code>

However, this creates five columns that grow and shrink with different screen widths, but always keeps five columns, causing them to become very narrow on small screens. The first idea might be to create a bunch of media queries and redefine the grid with different numbers of columns. This works fine, but with the auto-fit keyword, all of this is done automatically.

In order for auto-fit to work the way we want, we need to use the minmax() function. This tells the browser how small the columns can be compressed, and then the maximum width they can expand to. Smaller, it will automatically reduce the number of columns. Larger, the number of columns increases.

 <code>.archive { grid-template-columns: repeat (auto-fit, minmax(180px, 1fr)); }</code>

In this example, the browser will accommodate as many columns as possible 180 pixels wide. If space is left, the column will grow averagely by sharing the remaining space between them—this is what the 1fr value says: make the column an ​​equal fraction of the available width.

Drag the window, and as the available space increases, all columns grow evenly to use any extra space. The column will continue to grow until the available space allows an additional column of 180 pixels, and a whole column will appear. Reduce the screen width and the process will reverse, perfectly adjusting the grid to a single column layout. magic!

And you can get all this responsiveness with just one line of code. How cool is this?

Create spans with "autoflow: density"

So far we have a responsive grid, but all items have the same width. For news or magazine layouts, we need some content to be highlighted by spanning two or more columns or even possibly all columns.

To create multi-column spans, we can add the column-span function to the grid project we want to take up more space. For example, if we want the third item in the list to be two columns wide, we can add:

 <code>.article:nth-child(3) { grid-column: span 2; }</code>

However, once we start adding spans, many problems arise. First, gaps may appear in the grid, because wide items may not fit the rows, so the grid automatically adapts to push it to the next row, leaving the gap where it was supposed to be:

The simple workaround is to add grid-auto-flow: dense to the grid element, which tells the browser to fill any gaps with other items, effectively making narrower content flow around wider items, as shown below:

Note that the project is now out of order, with the fourth project appearing before the third project with double width. As far as I know, this is not possible to avoid, and it is one of the limitations of the CSS Grid you have to accept.

Check out Geoff Graham's "Auto-flow capability for grid-intensive keywords" for an introduction grid-auto-flow: dense and an example of how it works.

Several ways to specify a span

There are several ways to indicate how many columns the item should span. The easiest way is to apply grid-columns: span [n] to one of the items, where n is the number of columns the element will span. The third item in our layout has grid-column: span 2 , which explains why it is twice as wide as other items that span just one column.

Other methods require you to explicitly define grid lines. The numbering system of grid lines is as follows:

You can specify grid lines from left to right using a positive value (e.g. 1, 2, 3) or a negative value (e.g. -1, -2, -3) to perform right to left. These can be used to place items on the grid using grid-column property, as shown below:

 <code>.grid-item { grid-column: (起始轨道) / (结束轨道); }</code>

So this gives us other ways to specify a span of projects. This is especially flexible, as both the start value or the end value can be replaced with the span keyword. For example, the three-column blue box in the example above can be created by adding any of the following to the eighth grid item:

  • grid-column: 3 / 6
  • grid-column: -4 / -1
  • grid-column: 3 / span 3
  • grid-column: -4 / span 3
  • grid-column: span 3 / -1
  • etc.

On a non-responsive (i.e. fixed column) grid, all of these produce the same effect (as in the blue box in the picture above), but if the grid is responsive and the number of columns changes, their differences begin to appear. Some column spans can destroy layouts with automatic flow grids, making the two technologies appear incompatible. Fortunately, there are some solutions that allow us to successfully combine the two.

But first, we need to understand the problem.

Overflow side scrolling problem

Here are some featured areas created using the above symbols:

Everything looks good at full width (five columns), but when resized to the point that it should be two columns, the layout breaks like this:

As you can see, our grid is out of responsiveness and although the container has been reduced, the grid tries to keep all five columns. To do this, it abandons trying to keep the columns of the same width, and the grid overflows from the right side of its container, causing horizontal scrolling.

why is that? The problem is that the browser tries to obey the explicit grid lines we named. At this width, the automatic adaptation grid should implicitly show two columns, but our grid line numbering system contradicts it by explicitly referencing the fifth grid line. This contradiction leads to chaos. To correctly display our implicit two-column grid, the only allowed row numbers are 1, 2 and 3 and -3, -2, -1 as shown below:

However, if any of our grid items contain grid-column references that are outside this range, such as grid line numbers 4, 5, or 6 (or -4, -5, or -6), the browser receives a mixed message. On the one hand, we require it to automatically create flexible columns (this should implicitly give us two columns under this screen width), but we also explicitly reference grid lines that are not present in the two-column grid. When there is a conflict between the implicit (automatic) column and the number of explicit columns, the grid always tends toward an explicit grid ; therefore, unwanted columns and horizontal overflows occur (which is also appropriately referred to as CSS data loss). Just like using grid line numbers, spans can also create explicit columns. Therefore, grid-column: span 3 (the eighth grid item in the demo) forces the grid to explicitly adopt at least three columns, while we want it to implicitly show two columns.

At this point, it seems that the only way forward is to use media queries to change grid-column value at the width of our layout breaks - but not too fast! This is exactly what I assumed at the beginning. However, after thinking more carefully and trying various options, I found that there are some limited workarounds that work all the way down to two columns, leaving only one media query to handle the single column layout on the narrowest screen.

Solution

I realized that the trick is to specify the span using only grid lines that appear in the narrowest grid you intend to display. In this case, it is a two-column grid. (We will use media queries to handle single-column scenes on the narrowest screen.) This means we can safely use grid lines 1, 2, and 3 (or -3, -2, and -1) without breaking the grid.

I initially thought this meant limiting myself to spans of up to two columns, using the following combination:

  • grid column: span 2
  • grid-column: 1 /3
  • grid-column: -3 / -1

This remains perfectly responsive throughout the ranges up to both columns:

While this works, it's rather limited from a design standpoint and not particularly exciting. I want to be able to create spans that are three, four, or even five columns wide on a large screen. But what? My first thought was that I had to turn to media queries (good, old habits are hard to change!), but I was trying to get rid of this approach and think about responsive design in a different way.

Looking again at what we can do with just 1 to 3 and -3 to -1, I gradually realized that I could mix positive and negative numbers of the start and end values ​​of the grid column, such as 1/-3 and 2/-2. At first glance, this doesn't seem very interesting. Things change when you realize the position of these lines when resizing the grid: these spanning elements change width as the screen size changes. This opens up a new set of possibilities for responsive column spans: As the screen widens, items of different columns will be spanned without media queries.

The first example I found is grid-column: 1/-1 . This makes the item span from the first column to the last column under all column counts like a full width banner. It even works for a column width!

By using grid-column: 1/-2 , you can create a left-aligned almost full-width span, which always leaves a column of items to its right. When narrowing down to two columns, it responsively shrinks to one column. Surprisingly, it even works when narrowed down to a single column layout. (The reason seems to be that the grid doesn't compress the item to zero width, so it keeps a column wide, as does grid-column: 1/1 .) I'm assuming grid-column: 2/-1 works similarly, but aligns with the right edge, and it does in most cases, except that it causes overflow when displayed in a single column.

Next I tried 1/-3 and it works fine on a wider screen, showing at least three columns and one column on a smaller screen. I think it will do something weird on two column grids, because the first grid line is the same as the grid line of -3. To my surprise, it still displays normally as a single column item.

After a lot of attempts, I found eleven possible grid column values, using grid line numbers from the two grids. Surprisingly, three of them work properly until the single column layout. The other seven can work all the way down to two columns, only one media query is required to handle single column display.

Here is the full list:

As you can see, while this is a finite subset of all possible responsive spans, there are actually many possibilities.

  • 2/-2 is fun because it creates a centered span that works fine until a column!
  • 3/-1 is the most useless because it can cause overflow even in two columns.
  • 3/-3 is a surprise.

By using the various grid-column values ​​in this list, you can create interesting and fully responsive layouts. For the narrowest single column display, using a single media query, we can use ten different grid column span patterns.

Single-column media queries are usually simple, too. One on this final demo restores flexbox on a smaller screen:

 <code>@media (max-width: 680px) { .archive { display: flex; flex-direction: column; } .article { margin-bottom: 2em; } }</code>

This is the final grid, which, as you can see, is completely responsive from one column to five columns:

Repeat variable length display with:nth-child()

The last trick I used to reduce the code to more than twenty lines is :nth-child(n) selector, which I use to style multiple items in the grid. I want my span style to be applied to multiple items in my feed so that the featured post box appears regularly in the page. First, I used a comma-separated list of selectors as follows:

 <code>.article:nth-child(2), .article:nth-child(18), .article:nth-child(34), .article:nth-child(50) { background-color: rgba(128,0,64,0.8); grid-column: -3 / -1; }</code>

But I quickly found this to be a hassle, especially when I had to repeat this list for every child element I wanted to style it in each post - like title, link, etc. During prototyping, if I want to play around with the position of spanning elements, I have to manually change the numbers in these lists, which is both laborious and error-prone.

At that time I realized that I could use the powerful feature :nth-child pseudo-selector instead of a simple integer like I used in the list above. :nth-child(n) can also take the equation, such as :nth-child(2n 2) , which will locate each second child element.

Here's how to create blue full-width panels in my grid using :nth-child([公式]) that appear at the top of the page and repeat below the page:

 <code>.article:nth-child(31n 1) { grid-column: 1 / -1; background: rgba(11, 111, 222, 0.5); }</code>

Bits (31n 1) in brackets ensure that the first, 32nd, 63rd and other subitems are selected. The browser runs a loop, starting with n=0 (in this case, 31 0 1 = 1), then n=1 (31 1 1 = 32), then n=2 (31 * 2 1 = 63). In the last case, the browser realizes that there is no 63rd child, so it ignores that, stops the loop, and applies the CSS to the 1st and 32nd child.

I did something similar to the purple box that appears alternately from right to left:

 <code>.article:nth-child(16n 2) { grid-column: -3 / -1; background: rgba(128, 0, 64, 0.8); } .article:nth-child(16n 10) { grid-column: 1 / -2; background: rgba(128, 0, 64, 0.8); }</code>

The first selector is used for the purple box on the right. 16n 2 Make sure the style is applied to each 16th grid project, starting with the second project.

The second selector locates the box to the right. It uses the same spacing (16n), but the offset is different (10). As a result, these boxes will appear regularly to the right of grid items such as 10, 26, and 42.

When it comes to visual styles of these mesh items and their content, I use another trick to reduce duplication. For styles shared by both boxes (for example, background-color ), you can use a single selector to locate both:

 <code>.article:nth-child(8n 2) { background: rgba(128, 0, 64, 0.8); /* 其他共享样式*/ }</code>

This will locate items 2, 10, 18, 26, 34, 42, 50, and so on. In other words, it selects two feature boxes on the left and right.

It works because 8n is exactly half of 16n and because the offsets used in two separate selectors differ by 8 (i.e. the difference between 10 and 2 is 8)

The final thought

Currently, CSS Grid can be used to create flexible responsive grids with minimal code, but this does have some important limitations on locating elements without using the backward steps of media queries.

It would be great to be able to specify spans that do not force overflow on smaller screens. Currently, we are actually telling the browser, "Please create a responsive grid", which is very beautifully done. But when we continue, “Oh, and make this grid item span four columns”, it gets tantrums on the narrow screen, prioritizing four column span requests over responsive grids. It would be great to be able to tell the grid to prioritize responsiveness over our span requests. Similar to this:

 <code>.article { grid-column: span 3, autofit; }</code>

Another problem with responsive grid is the last line. As the screen width changes, the last line is often not filled. I've spent a long time looking for a way to make the last grid item span (and thus fill) the remaining columns, but it seems you can't do that in Grid at the moment. It would be great if we could use keywords like auto to specify the starting position of the project, which means "please put the left edge anywhere it falls". Similar to this:

 <code>.article { grid-column: auto, -1; }</code>

...This will cause the left edge to span to the end of the line.

The above is the detailed content of Responsive Grid Magazine Layout in Just 20 Lines of CSS. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Iterating a React Design with Styled ComponentsIterating a React Design with Styled ComponentsApr 21, 2025 am 11:29 AM

In a perfect world, our projects would have unlimited resources and time. Our teams would begin coding with well thought out and highly refined UX designs.

Oh, the Many Ways to Make Triangular Breadcrumb Ribbons!Oh, the Many Ways to Make Triangular Breadcrumb Ribbons!Apr 21, 2025 am 11:26 AM

Oh, the Many Ways to Make Triangular Breadcrumb Ribbons

SVG Properties in CSS GuideSVG Properties in CSS GuideApr 21, 2025 am 11:21 AM

SVG has its own set of elements, attributes and properties to the extent that inline SVG code can get long and complex. By leveraging CSS and some of the forthcoming features of the SVG 2 specification, we can reduce that code for cleaner markup.

A Few Functional Uses for Intersection Observer to Know When an Element is in ViewA Few Functional Uses for Intersection Observer to Know When an Element is in ViewApr 21, 2025 am 11:19 AM

You might not know this, but JavaScript has stealthily accumulated quite a number of observers in recent times, and Intersection Observer is a part of that

Revisting prefers-reduced-motionRevisting prefers-reduced-motionApr 21, 2025 am 11:18 AM

We may not need to throw out all CSS animations. Remember, it’s prefers-reduced-motion, not prefers-no-motion.

How to Get a Progressive Web App into the Google Play StoreHow to Get a Progressive Web App into the Google Play StoreApr 21, 2025 am 11:10 AM

PWA (Progressive Web Apps) have been with us for some time now. Yet, each time I try explaining it to clients, the same question pops up: "Will my users be

The Simplest Ways to Handle HTML IncludesThe Simplest Ways to Handle HTML IncludesApr 21, 2025 am 11:09 AM

It's extremely surprising to me that HTML has never had any way to include other HTML files within it. Nor does there seem to be anything on the horizon that

Change Color of SVG on HoverChange Color of SVG on HoverApr 21, 2025 am 11:04 AM

There are a lot of different ways to use SVG. Depending on which way, the tactic for recoloring that SVG in different states or conditions — :hover,

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools