
I stopped using Jetpack on this site a while ago. It’s not so much that I think Jetpack is evil, though there are many things that annoy me about it. I was experimenting with PHP 7.1 and for some reason it was giving me problems. It’s possible those have all been taken care of, but since I’ve moved on, I was never motivated to go back.
One thing that Jetpack actually does pretty well is show related posts at the end of each blog entry. Unlike some related posts plugins, it doesn’t use up server resources indexing the posts to decide what’s related, and it displays them in a nice compact row.

You can choose to show featured images or not, and you can customize the placement of the related posts using a bit of code. It’s fairly flexible and generally works well.
Better than Jetpack: Related Posts for WordPress
Without Jetpack, obviously, I had to find another way to show related posts. Back in I’d heard an interview with Barry Kooij (that’s pronounced, roughly, “coy”) on Office Hours FM and learned that among other useful activities, he had created a related posts plugin that was so performant even WP Engine doesn’t ban it. (Yes, “performant” is a horrible jargon term. If you search for it in Google, the first thing you’ll see is an attempt to translate it from French. In this case, it means that it’s fast and doesn’t suck up your CPU or other resources.)
There’s a commercial version of the plugin that you’ll need if you want to include pages and custom post types in your related items, or if you want drag-and-drop design or custom weighting. But if all you want is to change the default layout, it’s easy to do that with the free version.
Related Posts for WordPress Default Display
When you install the free version of Related Posts for WordPress, there are only a few things to configure:
- Enable automatic linking (otherwise you can choose your related posts manually)
- Choose the number of related items to show at the end of each post
- Select your heading text
- Choose your excerpt length (set to 0 if you don’t want to show excerpts)
- Check the “display image” box if you want to show featured images.
That produces a related posts list with featured images floated to the right of the title and excerpt, like this:

This isn’t awful, but it doesn’t work very well for my site, because my featured images are 960 x 330, which is almost a 3:1 image ratio, and a 1:1 thumbnail won’t show them to advantage. And anyway, I was used to Jetpack’s display.
Modifying the Featured Image for Related Posts for WordPress
Fortunately, the plugin documentation explains quite clearly how to modify the thumbnail size.
function rp4wp_example_my_thumbnail_size( $thumb_size ) {
return 'my-thumbnail-size';
}
add_filter( 'rp4wp_thumbnail_size', 'rp4wp_example_my_thumbnail_size' );
Note that you don’t have to worry too much about the image size you choose, as long as it’s defined in your theme. As long as there is another image in the same ratio, the responsive images function in WordPress will choose the correct size for the display—whether that’s larger or smaller. In my case, I ended up with
//* Modify related posts image size
function srg_rp4wp_thumbnail_size( $thumb_size ) {
return 'featured-small';
}
add_filter( 'rp4wp_thumbnail_size', 'srg_rp4wp_thumbnail_size' );
This by itself improved the appearance of my related events considerably, because the images became meaningful.

Because I couldn’t find an easy way to make the plugin show my actual custom excerpts, I decided to set the excerpt length to “0.” I was going to be fitting them into a very small space anyway.
Displaying a Post Grid Instead of a Post List
Now we get to the magic part: applying CSS Grid. It’s true that, since I’m only displaying a single row of items, I could just as easily use Flexbox here, but Grid has some advantages even for a single-row layout, so that’s what I decided to use. I didn’t put in a fallback: if you look at this site on an older browser, you’ll see the list above.
The easiest place to add this code is in the plugin settings “Display” tab. In addition to the checkbox for displaying the featured image, there’s a CSS box that contains the default CSS for the related posts display. Once you’ve adjusted your column size to match your own content area, just paste the new CSS into that box. (Pro tip: copy the old CSS and save it somewhere, just in case you need to retrieve it.)

I’ve refined my automatic responsive grid a bit since I read Rachel Andrew’s The New CSS Layout and learned how to combine auto-fit
with minmax()
. It’s still very simple. Here is the code to set up the grid on the list container. (There are some additional modifications for things like image display that I’ll include at the end of this post.)
.rp4wp-related-posts ul {
width:100%;
padding:0;
margin:0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
}
.rp4wp-related-post-image {
width:100%;
padding:0;
float:none;
margin-bottom: 10px;
}
Here’s what that grid looks like.

Using auto-fit
means we will get as many columns of the specified width as will fit in the container, expanded to fill the container. Using minmax()
with 1fr
as the maximum means a column can expand to fill the entire row. The minimum of 200 px means that in my 671 px content area on desktop, I can fit three columns across.
If my content area magically grew (say I changed themes), I’d end up with three columns of 200+ pixels until there was room for four columns of 200px plus the 10px gap. (Which would be 830px, because gaps run between items, not outside of them.)
Restricting the Grid to Larger Screens
The code above looks great at both large and small sizes, but a little odd at medium sizes. On narrow screens, where you can’t fit more than one 200-pixel-wide column across, you just get a list. But on screens where the content area is less than 620px and more than 410px wide, our three related posts show in two columns.

I could get around this problem by showing six related posts instead of three, since six is evenly divisible by both two and three, but it seems to me that so many related posts would just confuse people rather than encouraging them to click. Hard as I try to avoid media queries, it’s worth adding one here.
@media screen and (min-width:1140px) {
.rp4wp-related-posts ul {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
}
}
That gives us the same view on medium screens as on small ones:

Related Posts for WordPress with CSS Grid Layout: the Final Code
Now that we’ve worked that out, here is all the code you need to duplicate my efforts. It will take you far less time to apply it than it took me to write about it, so let me know if it works for you.
.rp4wp-related-posts ul {
width:100%;
padding:0;
margin:0;
}
.rp4wp-related-posts ul>li {
list-style:none;
padding:0;
margin:0;
padding-bottom:20px;
clear:both;
}
.rp4wp-related-posts ul>li>p {
margin:0;
padding:0;
}
.rp4wp-related-post-image {
width:100%;
padding:0;
float:none;
margin-bottom: 10px;
}
@media screen and (min-width:1140px) {
.rp4wp-related-posts ul {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
}
}
Heh! Thanks for the tips I was looking to do this at one moment and had no clue on how I can do it!
Thanks…I did not know but got acquainted with it.
So very generous of you! My mission for this extended holiday weekend = replace JetPack with this specific plugin. Since I’m paranoid, I just grabbed the Under Construction plugin so I can toil without (overwhelming) fear. Wish me luck! (Although I *will* confine this effort to wee hours LoL).
Two suggestions: 1) Backups. 2) Staging environment. (Some hosts let you do this very easily.) The staging environment is especially useful because you don’t have to take your live site offline while you’re making adjustments.
Can you please explain the css to style the post title?
If you mean the titles in Related Posts for WP, they just use my theme’s default styling for links. (They’re not headings.) Right-click and choose “Inspect Element” to get the details.
Thanks, Sallie. Your tutorial was very helpful and I appreciate the time you took to write and post it.
Great post! thank you it was exactly what I was looking for…
Hmm, well I added all the css code but did not get the desired result with the images. I ended up with square thumbnails. I am sure I need to do something with the images. I’ll plow on tomorrow. Glad to not have to use Jetpack.
If you only have square image sizes defined, you’ll only get square images. Define a landscape image size in your `functions.php` file, then regenerate your thumbnails so that image size is available, then use the filter to choose that image size for the related posts.
Hey Sallie
Great work. I’m in the proces of doing this same thing and I like your code. I also free’ed myself of Jetpack. No offence to them, but I find it obstructs other plugins doing what JP insists doing. I don’t like invasive SW and prefer to decide myself :)
Anyways I am not sure what image size you defined in the above example. Could you let us know.
300x100px or other?
My `feature-small` image size is 330 x 110, 1/3 the size of my regular featured images. If you use images in the same ratio as your regular featured images, they have the advantage of being there to be served as responsive images.
I play’ed with your code a bit and did the following:
First: PHP
I don’t really have image sizes in my theme suited for related posts, so I added a snippet in PHP that has two function:
1) Add custom images to Gutenberg blocks, so that these new are also accessible when adding post, pages etc.
2) Creates the custom size images that needs to be added.
// Add Custom Images to Gutenberg
add_filter( ‘image_size_names_choose’,’wpmudev_custom_image_sizes’ );
function wpmudev_custom_image_sizes( $sizes ) {
return array_merge( $sizes, array(
// Add your custom sizes here
‘rise-home-project’ => __( ‘400x400px croped’ ),
‘rise-home-blog’ => __( ‘400x250px croped’ ),
‘related-posts-thumb’ => __( ‘400x100px croped’ ),
‘woocommerce_thumbnail’ => __( ‘500x500px croped’ ),
‘slides-front’ => __( ‘1200x750px croped’ ),
) );
}
// Define Custom Images
// Slides format
add_image_size( ‘slides-front’, 1200, 750, array( ‘center’, ‘center’ )); // Hard crop X: left,center,right Y: top,center,bottom
// Related Posts
add_image_size( ‘related-posts-thumb’, 400, 150, array( ‘center’, ‘center’ )); // Hard crop X: left,center,right Y: top,center,bottom
Second: PHP
Added your code as snippet that replaces related post image to the new size I created above
//* Modify related posts image size
function rp4wp_example_my_thumbnail_size( $thumb_size ) {
return ‘related-posts-thumb’;
}
add_filter( ‘rp4wp_thumbnail_size’, ‘rp4wp_example_my_thumbnail_size’ );
Third: CSS
I altered your CSS in order to
– have opacity over the image unless hover as Jetpack does with ease-in effect
– have a 3 step media screen size adjustment. (full width < 500px < 2 column < 700px li {
list-style:none;
padding:0;
margin:0;
padding-bottom:20px;
clear:both;
}
.rp4wp-related-posts ul>li>p {
margin:0;
padding:0;
}
.rp4wp-related-post-image {
width:100%;
padding:0;
float:none;
margin-bottom: 10px;
opacity: 0.3 !important;
}
.rp4wp-related-post-image:hover {
transition: .8s ease;
opacity: 1 !important;
}
.rp4wp-related-posts ul {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
grid-gap: 10px;
}
@media only screen and (max-width: 700px){
.rp4wp-related-posts ul {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(49,9999%, 49,9999%));
grid-gap: 10px;
}
}
@media only screen and (max-width: 500px){
.rp4wp-related-posts ul {
width: 100%;
}
}
Thanks for sharing. This was on my to do list for some time :)
Henrik
I do not upload featured images. But in my post content, it has images from external sources.
Eg:
I want to show first images from Post Content as thumbnail.
How to do it ?
Some themes have built-in code to use the first image as the featured image, but that code (whether in a theme or a plugin) usually checks for images in the WordPress media library. There are plugins that let you add external images to your media library. You could probably write a function to search for the first
<img>
tag and show that image, but my sense is that it would be harder than using thewp_get_attachment_image
function.