Stacking cards vertically and by column, help

Hey guys and gals,

I’m stuck and was hoping someone could unstuck me. I’ve nearly finished my React Recipe App, but I need to get rid of this visual bug first.

The situation: Each recipe is represented by a card, showing just its title unless the mouse hovers over it. When hovered over, the card expands showing the user the recipe’s ingredient list and directions.

The cards fill the space horizontally before falling down into a new row, when the user adds enough recipes to trigger that.

The problem: If there are enough boxes to have a second or third row of cards, when one hovers over a card in one of the top rows, all of the cards below move down to make room for the expanding information in that one card, in that one row.

The preferred behavior: I would prefer if only the cards directly below the hovered card move down to make room for the new information.

So, how might I accomplish this? At the moment my cards are just <divs> with the attribute display: inline-block. I suspect I should put them in some kind of table, that way they’re bound by columns. But, I’m not certain that that will fix it and I don’t even know what to call this desired behavior. This feels like a CSS issue to me, so I’d prefer a CSS solution, but if JS is needed I’m game.

TLDR; How do I get divs that expand on mouse hover, to only push the content that is directly below them?
Replicated Codepen example

There are other ways to do this, but simplest is just make each column a div and put your items in it. Example:

note

  • Apply the width you want to the columns, not the cards, the cards will just fill the column width.
  • I’ve used flex instead of inline-block. You will have issues with inline-block; it isn’t designed for layout, and using it to lay out containers means you will have to use hacks to get around the fact it will add whitespace between every element.
  • You really don’t need to use JS for hover effects unless you really need to do something unusual. Just use :hover, using JS just means you’ve added a big performance hit with no benefit.
  • you don’t need the .hide class
1 Like

Dude, great info. Do you think this will work, with an unknown amount of divs? The user will be adding cards, I’m having trouble imagining pushing each new card to the correct column.

That will be your main problem: you need some way to balance out the cards. This is doable with JS - see https://masonry.desandro.com/. It’s probably easier if you have some way to just insert new items in the right column instead - so just make sure that when a new one is added it goes in the column with the I guess the fewest entries, or the first column if all have the same number. It’s a pain, but I think any solution is going to have some complexity - I was just trying to see if I could get CSS grid to do it, but kept coming round to needing things in actual columns in the HTML.

EDIT: Also, while I was playing around - what I’d do is put the title in an html tag (h1 or whatever) and just hide the body of the recipe. Then same thing happens, hover over the card and it unhides the body. But don’t set an explicit height, just let each recipe just be the height of the title automatically. Otherwise you’ll have an issue with longer recipe titles - because you’re setting an explicit height, you’ll get text overflowing or being sliced off.

1 Like

Yeah, I figured and have a buggy version running at the moment. Regarding your edit, having a title above the body of the card is the solution I found as well. Again, thanks a lot.

EDIT: with a bit of mod division I’ve got the cards stacking evenly in the columns. Your suggestion just ended a week’s worth of fiddling. Gotta thank you again <3