Filtering with JavaScript

Because of the limitations of the CSS solution, in this case I'd recommend using JavaScript.

You can do all of this in your main.js file, but for clarity, and because we only need it on one page, I'm going to create a mushroom-filter.js file.

If you also create a new file, don't forget to add the <script> linking to it on your page!

First steps

First, we need to get our different elements:

const cards = document.querySelectorAll(".mushroom-guide .card");
const seasonalFilter = document.querySelector("#season");
const edibleFilter = document.querySelector("#edible");

We also want an easy way to keep track of our filters, so we can create a currentFilters object for that, and set both to all as a default.

const currentFilters = {
  season: "all",
  edible: "all",
};

We need to be able to update the current filters when we select a new one from our menu.

For example, for our seasonal filter:

seasonalFilter.addEventListener("change", (e) => {
  currentFilters.season = e.target.value;
});

If we do it this way, we then need to repeat everything for the edible filter though, so I think making a reusable function makes more sense:

function updateFilter(e) {
  const filterType = e.target.name;
  currentFilters[filterType] = e.target.value;
}

Because the property name is being stored as a variable, we have to use the bracket notation, rather than the dot notation.

And then we could use for filtering both of them:

seasonalFilter.addEventListener("change", updateFilter);
edibleFilter.addEventListener("change", updateFilter);

Updating the cards based on the filter

First, create a filterCards() function, where we loop over the cards and find the tag values.

function filterCards() {
  cards.forEach((card) => {
    const season = card.querySelector("[data-season]").dataset.season;
    const edible = card.querySelector("[data-edible]").dataset.edible;
  });
}

Next, for every card, we can check if they match the current filters:

// inside the forEach loop
const matchesSeason = currentFilters.season === season;

const matchesEdible = currentFilters.edible === edible;

And then we could show/hide elements based on whether or not these are true.

// still inside the forEach

if (matchesSeason && matchesEdible) {
  card.hidden = false;
} else {
  card.hidden = true;
}

Right now, this won't work because, while the hidden attribute has a user agent style with display: none, we're currently overwriting that with our display: flex on .card.

So, in our utilities layer, we can add:

[hidden] {
  display: none;
}

And finally, we also need to ensure that we don't hide it if the filter is set to "all"!

We can do that by updating our if statement:

if (
  (currentFilters.season === "all" || currentFilters.season === season) &&
  (currentFilters.edible === "all" || currentFilters.edible === edible)
) {
  card.hidden = false;
} else {
  card.hidden = true;
}