
A reader recently asked me to adapt my Horizontal Events Widget for Events Calendar Pro tutorial for his website (or perhaps it was the CSS Grid Layout for Event List Widget tutorial), because he hadn’t been able to implement it successfully. On looking at his site, I discovered that he’d run into two major issues:
- My sample
default-event.php
file is meant for Genesis themes, and he isn’t using Genesis, which would cause anundefined
error. (And anyway, since he didn’t need to adopt any theme styles for single events, there was no reason to create a newdefault-events.php
file.) - My CSS Grid Layout tutorial applies to the standard List Widget in the free version of The Events Calendar, which outputs an unordered list, making it easy to contain the grid within the list. The Advanced List Widget in Events Calendar Pro actually outputs a sequence of divs, with no convenient built-in container. Because of this, the CSS from the Grid tutorial I wrote couldn’t possibly work on the Advanced List widget.
- His home page was built with Visual (De)Composer, so instead of using the actual widget, we had to use the widget shortcode in a text block. It’s possible to add a class to a text block in order to target it with CSS, but this does not work in the predictable fashion it does with Beaver Builder. It requires some trial and error to figure out exactly where you need to apply your CSS.
What This Looked Like
Here is the text block where I entered the widget shortcode:

And here is the HTML output that I needed to style into a responsive grid. Note the addition of the wpb_wrapper
div below the home-events
div.

Defining the Problem
Because of my less-than-positive experiences with updating template files (not just from The Events Calendar but from WooCommerce), I wanted if at all possible to do everything either with CSS or by using hooks. That meant not using the precise solution I have on Kia’s site, where I modified several template files.
Because I never want to write more media queries than I have to, I like using <auto-repeat>
values for grids. This is what I did on the East Bay WP Meetup site. Take the maximum width of the grid container, divide by the number of columns you want in your largest view (or alternatively, the width of the smallest screen), and use grid-template-columns: repeat(auto-fit, <width-in-pixels>)
or grid-template-columns: repeat(auto-fill, <width-in-pixels>)
. The magic of CSS Grid makes your browser calculate the number of columns required to fill the screen, and creates more rows as needed. Presto: a neat grid of events, and the only PHP modification I needed was a function to display the featured image.
But because display: grid
automatically places all items in the container into the grid in order, that final paragraph with the “View More” link ends up as one column in the row beneath the events, instead of filling the entire width of the grid container.
Spanning the Grid
When you know how many columns you have, you can tell any item within your grid to span as many columns as you like with grid-column: span <number-of-columns-to-span>
. Or you can tell it where to start and end using the numbers or names of the grid-lines: grid-column: <starting-line> / <ending-line>
. (If you’ve played Grid Garden, you’ve done this.)
But what do you do when you don’t know how many columns you need to span? I beat my head on this for a while, not knowing quite what to search for. I have by no means mastered all of the ins and outs of CSS Grid Layout, and I hadn’t had to tackle this particular problem with the standard list widget, where each event is a list item and the “View More” paragraph comes after the list. And there was no problem in the Flexbox fallback: I set the paragraph’s flex
property to 0 0 100%
.
My first attempt was inelegant: in addition to the feature query I wrapped the grid in, I added media queries to address the number of columns at different widths: span 1, span 2, span 3
. It was clunky and didn’t always work correctly, because I hadn’t figured out precisely at which point the grid would recalculate.
The Elegant Solution (Thank You, Rachel Andrew)
This morning while going over my email and news feeds, I saw Rachel Andrew‘s article “CSS Grid Gotchas and Stumbling Blocks” in Smashing Magazine. One of the stumbling blocks she addresses is “Spanning to the End of the Grid.” (That article was published this morning, which means that either Rachel Andrew is psychic, or I’m not the first person to wrestle with this problem.)
And here was the answer I needed: as long as you have an explicit grid, the line number for the last line of the grid is -1. I admit I had to check the docs to make sure that a grid created with <auto-repeat>
values still counted as explicit, because I can get confused between grid-auto-columns
and auto-fill
, but then I hastened into my office to try it, and it worked perfectly.
The Final CSS Code
Here’s what I ended up with:
/* For browsers that do support CSS Grid */
@supports ((display: -ms-grid) or (display: grid)) {
.home-events .wpb_wrapper {
display: grid;
grid-template-columns: repeat(auto-fit, 330px);
grid-gap: 10px;
}
.home-events .wpb_wrapper .type-tribe_events {
flex: 0;
}
.home-events .wpb_wrapper .tribe-events-widget-link {
grid-column: 1 / -1;
}
}
What It Looks Like
That gave me the following results for large, medium, and small screens:



Another elegant CSS Grid Layout solution–though I don’t know how long I might have been searching for it if Rachel Andrew hadn’t published that article this morning.
Another amazing tutorial, I love reading your creative ways of working with the events calendar plugin.
I had a quick issue and I thought I might ask you for some advice … I am using the events calendar on my site, and I do like the photo/list view for displaying events.
My problem is that I want to have two different sets of results on the one page … the first list upcoming events, displaying the next 6 events in a 3×2 grid, with Ajax style pagination … followed by a second set of results past events, displaying the last 6 events also in a 3×2 grid with Ajax style pagination … any suggestions?
Thanks again :)
M
I think you’d have to create a completely new template for that. If you wrote two
tribe_get_events()
loops, one witheventDisplay
set to “upcoming” and one witheventDisplay
set to “past”, you could certainly get the two grids. Pagination would be tougher, though, and I’m not sure what to suggest there.