There's plenty of Shopify ecommerce stores out there that only have a few products, but those products have many variants. The drawback to this approach is that collection pages can look a little sparse but let's fix that with some simple theme edits. Let's explore some example code for you to review / adapt.
This post won't be a step by step guide so don't expect to come here for some copy and paste action. You'll need to adapt the logic here to you own needs. Since each theme is quite different in approach there's not going to be a one size fits all option. I am going to use the Shopify Timber theme as an example so you might luck out and be able to use this as is.
The first thing to do (for any theme) is to locate the main collection product loop code. At the time of writing that can be found in the product-grid-item.liquid snippet. We are going to replace that with something new.
Some Shopfiy Liquid Code.
I will just be modding the original snippet that so that considers variants. Take a peek at the code blow or just grab it from the link. and compare it to the original to see the process. You can see that I've added a check to detect if the product has variants or not. If it doesn't it will just run as normal. If it does have variants it will loop over them and show on the page.
Two small warnings
Doing this will have a layout side effect that you'll need to consider. If your collection is paginated (meaning that there's multiple pages) this code will likely show a different number of products / variants per page. One page might have 50, another 200. This can be weird to look at. I don't expect anyone with large collections to use this code in any place, but no doubt someone will...
Nathan makes a fine point in the comments below that I am just going to steal and post part of it here verbatim:
An additional "small warning" I'll add is that if your products have many variants, you risk exceeding the memory limit Shopify puts in place to prevent pages from slamming them with requests.
He talks about skipping variants that might be just sizes. This makes a hell of a lot of sense because it would just look odd seeing a collection page with a pair of shoes repeated twenty times, but essentially showing the same thing. I'll jump back in and adjust the gist code so it's a bit smarter, and less bloated. Until then, you're stuck with my memory hog version.
Err, but my theme uses ajax on the collection page.
Yeah, that adds some extra complexity for sure. If that's of some interest to people just leave a comment and I'll make some notes on that as well.