The mushroom guide

For this section of the page, grid's auto-fit will be perfect!

The syntax looks something like this:

.grid-auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
}

In the above example, the smallest a column is allowed to be is 300px wide. If there is room for two columns, each being 300px, then the browser will give us two columns, or three, or four, etc.

When the minimum size is too big

One issue with using auto-fit is the potential for the minimum size to introduce overflow.

In the code I shared above, for example, if the viewport is narrower than 450px wide, you will have overflow.

To prevent this from happening, we can use a min() function:

.grid-auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(450px, 100%), 1fr));
}

Making it more readable

It is kind of hard to read, or even understand what's going on at first glance.

We can fix that, and make it more adaptable as well, by once again using a locally scoped custom property:

.grid-auto-fit {
  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(var(--grid-auto-fit-min-column-size, 450px), 100%), 1fr)
  );
}

The cards

As for the cards inside of the grid, we can reuse the .card class we already created.

<div class="grid-auto-fit">
  <div class="card">...</div>
  <!-- 12 of these -->
</div>

I do think the tags make sense to be a part of a list, and we improve it with an aria-label as well.

<div class="card">
  <h3 class="card__title">...</h3>
  <ul class="tag-list" role="list" aria-label="Mushroom characteristics">
    <li>...</li>
    <li>...</li>
  </ul>
</div>

Alternatively, we could create an h4 with an id and a class of visually-hidden, and use aria-labeledby on the list. Generally speaking, aria-label should be considered a last resort, but I do think in this situation, it makes sense to use it.

We are going to be filtering these cards, and so I'm going to suggest that we use data attributes on the list items, which will make sorting them easy:

<li data-edible="edible">...</li>
<li data-season="fall">...</li>

Visually, it's obvious what the list items are, but if you were to have this page read to you, the words "edible" and "summer" aren't as obvious.

We can improve this as well, with our .visually-hidden class.

<li data-season="summer">
  <span class="visually-hidden"> You can harvest this mushroom in the </span>
  summer
</li>

And finally, the last paragraph is something that I could potentially see repeated in other places if ever this site were to grow in size, so a generic class here could be useful:

<div class="card">
  <!-- other content -->

  <p>...</p>
  <p class="card__note">...</p>
</div>

The selects

We can add a couple of <select> elements for our filtering.

They do have limited styling (more on that in the next lesson), but they'll work well for us here.

One thing that's important though, is selects are required to have a name, whether that's through a label or aria-label.

We already have a .visually-hidden class, so we can use that:

<div>
   <label class='visually-hidden' for='season'>Filter mushrooms by season</label>
   <select name='season' id='season'>
     <option value="all" selected>Season: all</option>
     <option value="spring" >Spring</option>
     <option value="summer" >Summer</option>
     <option value="fall" >Fall</option>
</div>