Web site Developer I Advertising and marketing I Social Media Advertising and marketing I Content material Creators I Branding Creators I Administration I System SolutionExpandable Sections Inside a CSS Grid

Web site Developer I Advertising and marketing I Social Media Advertising and marketing I Content material Creators I Branding Creators I Administration I System SolutionExpandable Sections Inside a CSS Grid

Web site Developer I Advertising and marketing I Social Media Advertising and marketing I Content material Creators I Branding Creators I Administration I System Resolution

I like CSS Grid. I like how, with just some strains of code, we are able to obtain absolutely responsive grid layouts, usually with none media queries in any respect. I’m fairly comfy wrangling CSS Grid to provide fascinating layouts, whereas preserving the HTML markup clear and easy.

However lately, I used to be offered with a singular UI conundrum to resolve. Primarily, any given grid cell might have a button that might 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 resolution 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 “methods” to resolve this. No JavaScript wanted in any respect.

A proof of the particular downside I want to resolve

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 wish to resort to JavaScript to re-calculate the cardboard positions, and transfer them round, particularly on browser resize? Proper?

Google was not my good friend. 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 spite of everything, 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 in the end got here to a workable resolution 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 particular occasion of that strategy. 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 provides us a grid with columns (20rem vast on this instance) which can be organized robotically within the accessible house, wrapping to the following row when there’s not sufficient room.

Inquisitive about auto-fit vs auto-fill? Sara Soueidan has written a beautiful rationalization 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 fastened 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 now have 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 strategy:

.grid {
  grid-auto-flow: dense;

That’s it! Required structure 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, by utilizing minmax(20rem, 1f).
  • All our grid “cells” are the identical top in every row. That is the default CSS Grid habits. The grid container implicitly has align-items: stretch inflicting cells to occupy 100% of the accessible row top.

The results of all that is that the holes in our grid are stuffed — and the attractive 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 rationalization of how CSS Grid auto-placement works.

The whole resolution

These three mixed methods present a easy structure resolution 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 structure calculations. It’s purely useful for managing the press occasions, focus state, injected card show, and many others.

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 surroundings, nevertheless, 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 inclined to have very heavy DOMs, and we need to keep away from unnecessarily bloating the web page weight additional with plenty of extra “hidden” content material.

Fast views ought to be thought of as a progressive enhancement, so if JavaScript fails to load, the person is solely taken to the suitable product particulars web page.

Accessibility concerns

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

So, right here’s a rundown of the concerns 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 screen readers) will subsequently perceive that there’s a relationship between the playing cards, and customers might be knowledgeable what number of gadgets are within the record.
  • The product playing cards themselves are <article> components, with correct headings, and many others.
  • 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 following card.
  • The entire card grid is wrapped in an aria-live area in order that DOM modifications are introduced to display screen 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 extra enhancements might be added to any manufacturing implementation:

  • Make sure the injected card, when targeted, has an applicable label. This might be so simple as having a heading as the primary factor 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 suppose?

This might be a pleasant various to modals for after we need to reveal extra content material, however with out hijacking your complete viewport within the course of. This is likely to be fascinating in different conditions as properly — suppose photograph captions in a picture grid, helper textual content, and many others. It’d even be an alternative choice to some instances the place we’d usually attain for <particulars>/<abstract> (as we all know these are solely finest utilized in sure contexts).

Anyway, I’m desirous about the way you may use this, and even the way you may strategy it in a different way. Let me know within the feedback!

Supply hyperlink

Leave a Reply