I really like CSS Grid. I really like how, with just some strains of code, we are able to obtain absolutely responsive grid layouts, typically with none media queries in any respect. I’m fairly snug wrangling CSS Grid to supply attention-grabbing layouts, whereas holding the HTML markup clear and easy.

However lately, I used to be offered with a singular UI conundrum to unravel. Primarily, any given grid cell may have a button that may open up one other, bigger space that can also be a part of the grid. However this new bigger grid cell wanted to be:

  1. proper under the cell that opened it, and
  2. full width.

Seems there’s a good answer to it, and within the spirit of CSS Grid itself, it solely entails a few strains of code. On this article, I’ll mix three one-line CSS Grid “tips” to unravel this. No JavaScript wanted in any respect.

An evidence of the particular drawback I would like to unravel

Right here’s a minimalist UI instance of what I wanted to do:

That is our precise product card grid, as rendered in our Storybook part library:

A grid of product cards in a three by two layout. Each card has a placeholder gray image, product name, descriptions, price, and small text.

Every product card wanted a brand new “fast view” button added such that, when clicked, it might:

  • dynamically “inject” a brand new full-width card (containing extra detailed product data) instantly under the product card that was clicked,
  • with out disrupting the present card grid (i.e. retain the DOM supply order and the visible order of the rendered playing cards within the browser), and
  • nonetheless be absolutely responsive.

Hmmm… was this even doable with our present CSS Grid implementation?

Certainly I would want to resort to JavaScript to re-calculate the cardboard positions, and transfer them round, particularly on browser resize? Proper?

Google was not my pal. I couldn’t discover something to assist me. Even a search of “fast view” implementations solely resulted in examples that used modals or overlays to render the injected card. In any case, a modal is often the one selection in conditions like this, because it focuses the person on the brand new content material, without having to disrupt the remainder of the web page.

I slept on the issue, and finally got here to a workable answer by combining a few of CSS Grid’s strongest and helpful options.

CSS Grid Trick #1

I used to be already using the primary trick for our default grid system, and the product card grid is a selected occasion of that method. Right here’s some (simplified) code:

.grid {
  show: grid;
  hole: 1rem;
  grid-template-columns: repeat(auto-fit, 20rem);
}

The “secret sauce” on this code is the grid-template-columns: repeat(auto-fit, 20rem); which supplies us a grid with columns (20rem huge on this instance) which can be organized routinely within the out there house, wrapping to the subsequent row when there’s not sufficient room.

Interested by auto-fit vs auto-fill? Sara Soueidan has written a beautiful clarification of how this works. Sara additionally explains how one can incorporate minmax() to allow the column widths to “flex” however, for the needs of this text, I needed to outline mounted column widths for simplicity.

CSS Grid Trick #2

Subsequent, I needed to accommodate a brand new full-width card into the grid:

.fullwidth {
  grid-column: 1 / -1;
}

This code works as a result of grid-template-columns in trick #1 creates an “express” grid, so it’s doable to outline begin and finish columns for the .fullwidth card, the place 1 / -1 means “begin in column 1, and span each column as much as the final one.”

Nice. A full-width card injected into the grid. However… now we have now gaps above the full-width card.

Two rows of four rectangles. All of the rectangles are light gray and numbered, except one that has a wheat-colored background and another box beneath it containing text, and taking up the full container width.

CSS Grid Trick #3

Filling the gaps — I’ve completed this earlier than with a faux-masonry method:

.grid {
  grid-auto-flow: dense;
}

That’s it! Required format achieved.

The grid-auto-flow property controls how the CSS Grid auto-placement algorithm works. On this case, the dense packing algorithm tries to fills in holes earlier within the grid.

  • All our grid columns are the identical width. Dense packing additionally works if the column widths are versatile, for instance, through the use of minmax(20rem, 1f).
  • All our grid “cells” are the identical top in every row. That is the default CSS Grid conduct. The grid container implicitly has align-items: stretch inflicting cells to occupy 100% of the out there row top.

The results of all that is that the holes in our grid are crammed — and the gorgeous half is that the authentic supply order is preserved within the rendered output. That is essential from an accessibility perspective.

See MDN for an entire clarification of how CSS Grid auto-placement works.

The entire answer

These three mixed tips present a easy format answer that requires little or no CSS. No media queries, and no JavaScript wanted.

However… we do nonetheless want JavaScript?

Sure, we do. However not for any format calculations. It’s purely useful for managing the press occasions, focus state, injected card show, and so on.

For demo functions within the prototype, the full-width playing cards have been hard-coded within the HTML of their appropriate places within the DOM, and the JavaScript merely toggles their show properties.

In a manufacturing setting, nonetheless, the injected card would most likely be fetched with JavaScript and positioned within the appropriate location. Grid layouts for one thing like merchandise on an eCommerce website are likely to have very heavy DOMs, and we need to keep away from unnecessarily bloating the web page weight additional with numerous further “hidden” content material.

Fast views must be thought-about as a progressive enhancement, so if JavaScript fails to load, the person is just taken to the suitable product particulars web page.

Accessibility issues

I’m keen about utilizing appropriate semantic HTML markup, including aria- properties when completely mandatory, and guaranteeing the UI works with only a keyboard in addition to in a display reader.

So, right here’s a rundown of the issues that went into making this sample as accessible as doable:

  • The product card grid makes use of a <ul><li> assemble as a result of we’re displaying a listing of merchandise. Assistive applied sciences (e.g. display readers) will subsequently perceive that there’s a relationship between the playing cards, and customers might be knowledgeable what number of objects are within the record.
  • The product playing cards themselves are <article> components, with correct headings, and so on.
  • The HTML supply order is preserved for the playing cards when the .fullwidth card is injected, offering a very good pure tab order into the injected content material, and out once more to the subsequent card.
  • The entire card grid is wrapped in an aria-live area in order that DOM adjustments are introduced to display readers.
  • Focus administration ensures that the injected card receives keyboard focus, and on closing the cardboard, keyboard focus is returned to the button that initially triggered the cardboard’s visibility.

Though it isn’t demonstrated within the prototype, these further enhancements could possibly be added to any manufacturing implementation:

  • Make sure the injected card, when centered, has an applicable label. This could possibly be so simple as having a heading as the primary aspect contained in the content material.
  • Bind the ESC key to shut the injected card.
  • Scroll the browser window in order that the injected card is absolutely seen contained in the viewport.

Wrapping up

So, what do you assume?

This could possibly be a pleasant different to modals for once we need to reveal further content material, however with out hijacking the complete viewport within the course of. This is likely to be attention-grabbing in different conditions as properly — assume picture captions in a picture grid, helper textual content, and so on. It’d even be a substitute for some circumstances the place we’d usually attain for <particulars>/<abstract> (as we all know these are solely greatest utilized in sure contexts).

Anyway, I’m interested by the way you would possibly use this, and even the way you would possibly method it in another way. Let me know within the feedback!

#Expandable #Sections #CSS #Grid

Leave a Reply

Your email address will not be published. Required fields are marked *