In a previous tutorial, I described how to create a simple fluid card grid with CSS Grid. In this tutorial, we’ll take it a step further and create promotional spaces that morph in interesting ways.
Using Grid, we’ll gain the following advantages:
- Semantic, un-nested HTML
- Images as actual accessible content and not background images
- Mobile-first design with simple breakpoint changes
- Different design patterns that match the advantages of the device used
To do this, we’ll use:
- Well-formed HTML
- Grid’s ease of overlap
- Named Grid Lines and Named Grid Areas
We’ll be setting up three different designs for our promo space.
On mobile, we’ll have an image with a darkened overlay in the background and the text and button in the foreground.
On larger screens – tablets and landscape mobile phones – we’ll use the same promo design but have them two across.
On devices bigger than tablets, we’ll have a full row for each promo with the image beside the text and no overlay.
Sweet and simple. One parent container for the promos and one child container per promo. Inside that, we’ve got our content. A
a and an
img. That’s right, we’re using an
<img> tag for a background image.
If you consider your image to be part of your content and not there for ambiance, then using an
<img> tag is the proper, semantic way to write it. We’ll see in the next section how we make it appear to be a background image.
Crafting our initial grid
Here’s where the power starts. We’re going to define our grid with one column and five rows.
The five rows allow for us to vertically center our content. The first and last rows will be blank, but have an equal height set. Each of the middle three rows is sized by its content with the
Finally, we tell the browser where to put our content by assigning a grid area name in
grid-template-areas. We then assign
button keywords to the classes of content that match.
In this declaration, each row is represented by one string with columns separated by spaces. In this case, there’s only one column and five rows. The first and last rows are represented by one or more periods. This allows for these grid cells to be blank.
One quick note: By assigning
align-self: end to our headline, we create a stronger tie between headline and text.
Converting the image to a background
At this point, you may have noticed we haven’t styled our
To make the image span the full height and width our container, we need to tell it to fill all the rows. We could use
grid-row: 1 / 6 but then we’d need to redefine this at various breakpoints.
The current specification of Grid doesn’t account for overlap in grid-template-areas. So, we’ll create “named lines” instead by redefining our grid-template-columns and -rows.
Three big things are happening here:
- A string inside of brackets
[image-start]creates a named line.
- Two named lines containing
-endwill create a named area.
- Two named lines in rows and two named lines in columns create a two-dimensional grid area.
By defining these four lines, we can now call
grid-area: image on our image and it will fill the entire promo.
You’ll note two other properties:
Align-self will allow the image to fill the entire grid cell. By allowing the image to stretch, it fills the space. Object-fit and the keyword
cover allow an
<img> tag to have the same functionality as
Add the overlay with mix-blend-modes
Normally, I’d advocate for an ::after element in CSS to handle the darkened overlay. In this instance, because our main background is an
<img> tag, an
::after element won’t work.
To address this, we can add a
background-color to the entire promo area and use
mix-blend-mode on the image to blend the two.
To avoid blending all the elements, we can add a z-index to affect our stacking context. By giving our image a z-index of 0 and our text elements a z-index of 1 (or more), only the image and background color will be blended.
Add a breakpoint for tablets and large phones
This is the easy part. For larger phones and tablets, let’s set a breakpoint to put our promos side-by-side.
In this example, we have two promos, so we’ll set our grid to two columns. If you have dynamic content, you could explore creating a fluid card grid.
Now for the fun: desktop reconfiguration
Tablets were easy: Add an extra column. Done. For desktop, let’s create a row for each promo and let them breathe a bit.
To build our new grid template, all we need to do is add a column and adjust our grid-template-areas.
Since we named our grid areas, they’ll automatically flow into their new homes.
With our grid now in place, let’s make a few stylistic choices to solidify this design.
Let’s add a little white space on either side of our promos by setting a width and auto margins.
We’ll also reset our font color and background color for the promos to values that make sense for the space the promos take up and align the text left instead of center.
Alternate image and text location on promos
If you’re anything like me, it bothers you to see those images repeating down the right side of the screen. We can fix this with the addition of a class and one more grid-template-area reset.
With that, we have an interesting set of design patterns that best match the device on which they’re viewed. As always, you can play with the code on CodePen.
What are some other design patterns that would work well together with the power of Grid?