Ten years ago, I started learning CSS with the goal of modifying the style of my blog. Soon, I was able to write cool code with more mathematical, easier to understand features like transform. However, other areas of CSS, such as layout, have been my pain point.
This article is about a problem I encountered ten years ago and only recently found a clever solution. Specifically, it's about how I used modern CSS Grid technology to solve a long-standing problem and in the process, I got more cooler results than I originally thought.
It should be noted that this is not a tutorial on how to best use CSS Grid, but more like a record of my personal learning process.
question
One of the earliest posts on my blog was random photos in the city, so I had the idea of creating a fixed-size thumbnail grid. For aesthetics, I want this grid to be vertically centered relative to the upper and lower paragraphs, but at the same time, I want the last row of thumbnails to be left-aligned relative to the grid. Meanwhile, the width of the article (and the width of the mesh in which) will depend on the viewport.
The HTML code looks like this:
<p></p> <div class="grid--thumbs"> <a href="https://www.php.cn/link/19e321d9f307ccfc1c37106191cbbc74"> <img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174381745622040.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="Cool Little CSS Grid Tricks for Your Blog"> </a> </div> <p></p>
It seems simple, but it becomes one of the toughest CSS issues I have ever encountered.
Unsatisfactory solution
These are the methods I've tried or seen in years and have not really solved the problem.
Limitations of floating schemes
The floating scheme turns out to be a dead end, as I can't figure out how to get the grid to center vertically in this way.
.grid--thumbs { overflow: hidden; } .grid--thumbs a { float: left; }
The following demonstration shows the attempts of floating schemes. Resize embeds and see how they perform at different viewport widths.
Insufficient in inline-block
At first, this seemed like a better idea:
.grid--thumbs { text-align: center } .grid--thumbs a { display: inline-block }
But that's not the case:
The last line is not left-aligned in this case.
At some point, due to unexpected CSS autocomplete on CodePen, I found a property called text-align-last
which determines how the last row of the block is aligned.
Unfortunately, setting text-align-last: left
on the grid is not the solution I want either:
At this point, I actually consider giving up the idea of vertical centering grids. Can the combination of text-align: justified
and text-align-last: left
produce better results on the grid?
This is not the case. Unless the last row has only one thumbnail and the gap between the columns is not too large. Resize the embed below and see what I mean.
This is almost the situation I was in two years ago, and after nine years of trial and failure, I still can't find a solution to this problem.
Messy Flexbox Tips
A Flexbox solution that looks feasible at first is to add a ::after
pseudo-element to the grid and set flex: 1
on the thumbnail and this pseudo-element:
.grid--thumbs { display: flex; flex-wrap: wrap; a, &::after { flex: 1; } img { margin: auto; } &:after { content: 'AFTER'; } }
The following demonstration shows how this approach works. I've added purple borders to the thumbnails and ::after
pseudo-elements to make it easier to see what's going on.
This is not what I want because the thumbnail grid is not vertically centered. That is, as long as the last row has one image less than the other rows, it looks good... Once there is a change, if more projects are missing or no projects are missing, the layout will break.
This is a bad idea. Another approach is to not use pseudo-elements, but add as many empty divs after the thumbnail as we expect to have.
We should be able to approximate the number of expected columns because the size of the thumbnail is fixed and we may want to set the maximum width of the article, as text spanning the entire screen width can visually strain your eyes. Dividing the maximum width by a fixed thumbnail width should give the maximum number of columns in this case.
The first empty element will occupy the rows that are not fully filled with the thumbnail, and the rest will overflow to the other rows. But because they are zero in height, they are visually irrelevant.
This approach does work, but again, it's clumsy and still doesn't produce the exact result I want, as it sometimes leaves a large and ugly gap between the columns.
Grid Solution?
Given its name, grid layouts have always sounded like the answer. The problem is that all the examples I saw at the time used a predefined number of columns, which doesn't work for this particular pattern, where the number of columns is determined by the viewport width.
Last year, while writing a series of single-element pure CSS background patterns, I thought of generating a bunch of media queries that would modify a CSS variable --n
, which corresponds to the number of columns used to set grid-template-columns
.
$w: 13em; $h: 19em; $f: $h/$w; $n: 7; $g: 1em; --h: #{$f*$w}; display: grid; grid-template-columns: repeat(var(--n, #{$n}), var(--w, #{$w})); grid-gap: $g; place-content: center; @for $i from 1 to $n { @media (max-width: ($n - $i 1)*$w ($n - $i 2)*$g) { --n: #{$n - $i} } }
I was very proud of this idea at the time, although I feel embarrassed when I look back now. One media query per possible column count is not ideal, let alone it is not very useful when the grid width does not equal viewport width but is still a bit flexible and also depends on the width of its sibling element.
Magical solution
I ended up finding a better solution when using CSS Grid and failing to understand why the repeat()
function doesn't work in a specific case. It was so frustrating that prompted me to go to the MDN website to check it out, and I happened to notice the auto-fit
keyword, and while I don't understand the explanation, I had a hunch that it could help with this other problem, so I gave up everything else and tried it out.
This is what I got:
.grid--thumbs { display: grid; justify-content: center; grid-gap: .25em; grid-template-columns: repeat(auto-fit, 8em); }
I also found the minmax()
function which replaces fixed size on grid items. I still can't fully understand how minmax()
works - the more I play, the less I understand it - but in this case it looks like creating a grid and then stretching its columns equally until they fill all the available space:
grid-template-columns: repeat(auto-fit, minmax(8em, 1fr));
Another cool thing we can do here is to prevent the image from spilling when it is wider than the grid element. We can do this by replacing the minimum 8em with min(8em, 100%)
. This basically ensures that the image never exceeds 100%, but never below 8em. Thanks Chris for the advice!
Remember that the min()
function does not work in Edge before Chromium!
Remember that this can only produce good results when all images have the same aspect ratio (like the square images I use here). This is not a problem for my blog, as all the photos were taken with my Sony Ericsson W800i phone and they all have the same aspect ratio. However, if we remove images with different aspect ratios, the grid looks less good:
Of course, we can set the image height to a fixed value, but this distorts the image...unless we set object-fit
to cover
, which solves our problem!
Another idea is to turn the first thumbnail into a kind of banner that spans all grid columns. The only problem is that we don't know the number of columns, because it depends on the viewport. However, there is a solution - we can set grid-column-end
to -1!
.grid--thumbs { /* same styles as before */ a:first-child { grid-column: 1/ -1; img { height: 13em } } }
The height of the first picture is larger than that of the other pictures.
Of course, if we want the image to span all columns except the last column, we will set it to -2 and so on... Negative column indexing is OK!
auto-fill
is another grid attribute keyword I noticed on MDN. The explanations of these two keywords are long-lasting and have no visual effects, so I found them useless. Worse, replacing auto-fit
with auto-fill
in any grid demonstration above will not make any difference. Even after looking at the article or trying the examples, how they really work and how they differ remains a mystery.
However, trying different approaches and looking at the results in various scenarios eventually led me to the conclusion: if we use minmax()
column width instead of fixed column width (e.g. 8em), it is better to use auto-fill
instead of auto-fit
because if we only have a few images, the results will look better, as shown in the interactive demonstration below:
I think my personal favorite is the idea of the initial thumbnail grid, which is vertically centered and has an almost fixed column width (but still uses min(100%, 15em)
instead of just 15em). Ultimately, it's a matter of personal preference, and what you can see in the demo below happens to look better for me:
I'm using auto-fit
here because it produces the same result as auto-fill
and has fewer characters. However, what I didn't understand when making this is that these two keywords produce the same result because there are more items in the gallery than we need to fill a line.
But once there is a change, auto-fit
and auto-fill
will produce different results, as shown below. You can change justify-content
value and the number of items placed on the grid:
I'm not sure which one is the better option. I think it depends on personal preference. Combined with justify-content: center
, auto-fill
seems to be a more logical choice, but at the same time, auto-fit
will produce better visual effects.
The above is the detailed content of Cool Little CSS Grid Tricks for Your Blog. For more information, please follow other related articles on the PHP Chinese website!

If you've ever had to display an interactive animation during a live talk or a class, then you may know that it's not always easy to interact with your slides

With Astro, we can generate most of our site during our build, but have a small bit of server-side code that can handle search functionality using something like Fuse.js. In this demo, we’ll use Fuse to search through a set of personal “bookmarks” th

I wanted to implement a notification message in one of my projects, similar to what you’d see in Google Docs while a document is saving. In other words, a

Some months ago I was on Hacker News (as one does) and I ran across a (now deleted) article about not using if statements. If you’re new to this idea (like I

Since the early days of science fiction, we have fantasized about machines that talk to us. Today it is commonplace. Even so, the technology for making

I remember when Gutenberg was released into core, because I was at WordCamp US that day. A number of months have gone by now, so I imagine more and more of us

The idea behind most of web applications is to fetch data from the database and present it to the user in the best possible way. When we deal with data there

Let's do a little step-by-step of a situation where you can't quite do what seems to make sense, but you can still get it done with CSS trickery. In this


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Atom editor mac version download
The most popular open source editor

EditPlus Chinese cracked version
Small size, syntax highlighting, does not support code prompt function

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.