October 25, 2022

CMS Item-Specific Layouts in a CSS Grid

Recently in the Webflow forums, a question was asked regarding whether it's possible to have specific CMS items take up a larger amount of space in a CSS grid layout. For example- if I have a Collection list of blog posts, laid out in a 3 column CSS grid.. how can I make featured items stand out by spanning multiple columns or rows?

Now personally, I don't think I'd approach a layout this way, but I do like interesting problems, and this was an interesting problem to solve.

And here's the solution

Yes, this can be done, and no script is required. CSS grids are CSS-based, so it’s not hard to adjust and target your item layouts. Here’s a demo I whipped up, and the project read-only link.

I randomized the list order for kicks, but you can sort it however you like.

The basic approach is this-

  • Create your collection with something easily identifiable as a “featured” flag. I used a boolean switch named Featured?.
  • Create & bind your collection list. Select the center Collection List part ( between the Collection List Wrapper and the Collection Item) and set it to a CSS Grid. Configure your grid however you like.
  • Add an HTML Embed inside of your list item. Type this in;
image
  • Now add another HTML Embed element at the very top or bottom of your page, outside of any collection lists, which will contain your CSS;
<style>
div.w-dyn-item:has(data[featured='true']) {
    -ms-grid-column: span 2;
    grid-column-start: span 2;
    -ms-grid-column-span: 2;
    grid-column-end: span 2;
    -ms-grid-row: span 1;
    grid-row-start: span 1;
    -ms-grid-row-span: 1;
    grid-row-end: span 1;
}

If you’ve done it right, you’ll immediately see your new layout behavior, even while working in the designer.

WAIT, WHAT MAGIC IS THIS?

This solution was fun because it leverages a very simple but powerful technique, a workaround I use a lot in Webflow.

When you have a piece of CSS that you want to target specifically to certain elements, you can target elements with specific attributes, using CSS’s attribute selectors. That means if you can put a custom attribute of featured="true" on your list item, you can target your CSS to it.

Unfortunately, Webflow does not yet give us a way to dynamically set custom attributes on Collection List Items, but it does allow us to put HTML Embeds inside of our Collection List Items. With those HTML Embeds, we can create an arbitrary hidden element which does have our CMS-sourced custom attribute.

Then to target our collection list item, we use another piece of CSS selector magic, the :has() pseudoselector. This allows us to match elements whose contents match another rule.

I’m using these 3 things together to achieve whatever dynamically-targeted CSS magic I want to achieve. And yes, you can use a similar approach to target jQuery.

HOW THESE WORK TOGETHER

Here’s how I’ve applied these principles here;

I’m using an HTML embed to “attach” our Featured? flag data to our collection list item by creating a identifiable element, with our data as an attribute, e.g.;

<data featured="true"></data>

DATA elements work great, because they’re distinctive, and invisible without contents. But now we have something our CSS selector can match.

This CSS selector matches it with

div.w-dyn-item:has(data[featured='true'])

Which says…

  • Find any Webflow Collection Items [ div.w-dyn-item ]
  • Which contain [ :has() ] a <data> element
  • With an attribute of featured='true'

And then it applies the CSS styling I want, in this case, make my grid item span 2 columns, and 1 row.

I hope me CSS-targeting technique helps you as much as it has helped me.

Want to support our team?
Passion drives our long hours and late nights supporting the Webflow community. Click the button to show your love.
Buy us a beer