0

I have read all the stackoverflow posts about this problem but all have a fixed amount of columns or divs in the width (unless I missed it).

I am designing an online store. Each product is presented on a product tile. Each product tile floats (left). At the browser window's widest, there are three product tiles on each line. When sizing the browser down to 680px, there are only two product tiles on each line and at 400px only one on each line.

If one tile contains a product name that takes up two lines, it increases the height of the product tile. Therefor, the tiles beneath it won't float. They'll get stuck at the right bottom corner of the higher product tile above it.

I wrote some javascript/jquery to check for the highest tile and then set all the tiles to the same height. This works well on load (eventlistener), but for some reason not on resize.

Can someone explain why this function does not work on resize? And if someone knows a way to only set all product tiles in a row to the same height as the highest product tile in that row, versus setting all product tiles to the highest product tile, that would really make my day. (don't forget the amount of tiles in a row depends on the window width)

This is the html for a product tile.

<div class="productTile"> <!-- stuff goes here --> </div> 

This is the CSS for a product tile.

.productTile { background:grey; width:33%; float:left; } @media only screen and (max-width:680px) { .productTile { width:50%; } } @media only screen and (max-width:400px) { .productTile { width:100%; } } 

This is the jQuery

function setProdTiles() { var prodTileH = 0; // set variable to catch largest height $(".productTile").each(function(){ H = $(this).outerHeight(); // height current productTile if (H > prodTileH) // get highest { prodTileH = H; } }); $(".productTile").outerHeight(prodTileH); } window.addEventListener("load", setProdTiles); window.addEventListener("resize", setProdTiles); 

Thank you in advance.

10
  • I would use a table in HTML. All rows are the same height, automatically resizing to the maximum height of the content in each cell. No javascript! Significantly less overhead in comparison to what you're trying to do. Commented Sep 2, 2017 at 18:06
  • 1
    The amount of <td> is not determined for every <tr>. Commented Sep 2, 2017 at 18:07
  • You mean you don't know how many products you'll have returned, but you want it to be 3 elements in length? Commented Sep 2, 2017 at 18:10
  • 1
    You should probably start using flexbox to avoid such problems. Also you may check this Commented Sep 2, 2017 at 18:19
  • 1
    @Kobbe Take a look at this fiddle using the CSS grid system and tell me if it doesn't work. You can resize the result using the center column to simulate smaller screens. I'll post an answer if it does work for you. Commented Sep 2, 2017 at 18:24

2 Answers 2

6

The crux of your issue lies with the fact that you are attempting to recompute the outer height of your elements after setting an explicit height on them before hand. This means that the first time your setProdTiles() method is executed, the height of the elements will be fixed and cannot be altered, since all subsequent firing of the same method will simply read the set height.

What you want is to allow the browser to recompute the height of each product tiles, by setting height: auto, before attempting to retrieve the new browser computed outerHeight:

function setProdTiles() { var prodTileH = 0; $(".productTile") .css('height', 'auto') // set height to auto, allow browser to relayout .each(function() { // iterate through all tiles H = $(this).outerHeight(); // height current productTile if (H > prodTileH) // get highest { prodTileH = H; } }); $(".productTile").outerHeight(prodTileH); } 
Sign up to request clarification or add additional context in comments.

1 Comment

Spot on Terry. Thank you so much. I did not explore this, although I thought about it, because I did not see why it could be different, triggering the function with load or resize.
1

I'd recommend using the CSS grid system with media queries to change the layout as you scale.

.container { max-width: 800px; margin: 0 auto; display: grid; grid-auto-rows: 1fr; grid-column-gap: 30px; grid-row-gap: 30px; grid-template-rows: auto; } @media (max-width:400px) { .container { grid-template-columns: repeat(1, 1fr); } } @media (max-width:680px) and (min-width:401px) { .container { grid-template-columns: repeat(2, 1fr); } } @media (min-width:681px) { .container { grid-template-columns: repeat(3, 1fr); } } 

And in HTML:

<div class="container"> <div class="col"> Sample Content </div> <div class="col"> Sample content<br>two lines </div> <!-- As many other divs as you need--> </div> 

The grid will automatically resize each row to the same height as its tallest box, and the columns will also resize automatically. Check this fiddle to see an interactive demo.

1 Comment

Thank you forrestmid. You did make my day because you have a solution that only sizes each div in one row to the highest div in that row only, versus setting all divs to the same height of the highest div. I've learned a lot from your answer and also from Terry's answer. Thanks a bunch!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.