Florian Shena
Florian Shena

Reputation: 1434

Calculate elements dimensions in order to fit inside container

I have an ul with fixed width 235px and height 200px. This ul is populated by n numbers of li depending on a query results. How can I calculate the dimensions of the li in order for them to fill all the available space inside the ul.

I have tried calculating the container's perimeter and comparing it with the total of each element's perimeter but that doesn't work.

Upvotes: 1

Views: 2828

Answers (4)

Matt Sach
Matt Sach

Reputation: 1170

OK, here's my attempt at code that will work out a fairly high coverage of the ul (not sure if it's actually maximal), given the constraints that the lis need not be square, but must all be the same size for any given number of items.

The first part gives a function getSquare(n) which will memoize the generation of squares, so that if you need to use it multiple times on a page it won't keep recalculating things.

The second part is the function that does the calculation. Pass it the number of items, and the width and height of your container, and it will return an object with width and height properties for the items. It doesn't ensure integer results.

The line with the throw is just there for testing purposes really, could be removed.

var getSquare = (function()
{
    var squares = [];
    return function(n)
    {
        if (!squares[n])
        {
            squares[n] = Math.pow(n, 2);
        }
        return squares[n];
    };
})();


function calcItemDimensions(itemCount, areaWidth, areaHeight)
{
    var x, y, slots,
        n = 0,
        sq = 0;

    while (itemCount > sq)
    {
        n += 1;
        sq = getSquare(n);
    }

    x = y = n;
    slots = sq;

    while (slots - itemCount >= x)
    {
        if (x === y) { y -= 1; }
        else { x = y; }
        slots = x * y;
        if (slots < itemCount) { throw new Error('slots < itemCount: ' + slots + ' < ' + itemCount); }
    }

    return { width: areaWidth / x, height: areaHeight / y };
}

Upvotes: 0

Wouter
Wouter

Reputation: 41

You might do this with jQuery if you want to.

something like:

$(document).ready(function(){
   var liCount = parseInt($('ul li').length());
   var height = parseInt($('ul').height();
   var liHeight = height / liCount;
   $('ul li').css('height', liHeight);
});

An ofcourse, Don't forget to give the ul and ID and pass this into jQuery instead of 'ul li', otherwise all li object in your page will be affected

Upvotes: 0

Sowmya
Sowmya

Reputation: 26969

Do not mention width for li at all

HTML

<div class="wrap">
    <ul>
        <li><a href="#">link1</a></li>
        <li><a href="#">link2</a></li>
            <li><a href="#">link3</a></li>
    </ul>
</div>

CSS

.wrap{
    width:235px;
    height:200px;
    background:grey
}
ul{background:red; margin:0; padding:0; width:100%;}
li{
    display:inline-block;  
    margin-right:2px;
    background:red;
    border-right:solid black green; 
}

DEMO


CASE 2

Add height:100% to li (it force li to cove the entire available height) and give the same bg color for both ul & li so that it looks like it has occupied the available width

html,body{height:100%}
ul{
   background:red; 
   margin:0; padding:0; 
   width:235px;
   height:200px;
}
li{
    display:inline-block;   height:100%;
    margin-right:2px;
    background:green;
    border-right:solid black green; 
}

DEMO 2

Upvotes: 0

Amar
Amar

Reputation: 363

Make ul height dynamic according to number of li and apply css display:inline-block and overflow: hidden to ul

Upvotes: 1

Related Questions