Auto Min-Width

Summary

An experiment to "stretch out" a list of floated items so it wouldn't collapse or stack when the window is shrunk. A continuation of the previous experiment, which rounded up the width values of list items to the next unit of measurement. Made for Flash Experiments portal, where I made the list items look like frames on a timeline in Flash.

The entire thing is accessible so that if JavaScript is turned off, the preset CSS widths will be displayed. Otherwise the JavaScript will replace them if JS is turned on.

Things learned:

  1. element.style.width only sets the width and can't return the value; element.offsetWidth does that.
  2. Remember to add px when setting a style measurement via JS; it works just like in CSS.
  3. When running through an array, the typical end value in the for loop should be "less than" (<) and not "less than or equal to" (<=). It caused me grief when my Firebug kept saying the item has no properties. That's because I made the loop run past the number of arrays, resulting in a request for nothing.

Example

Click on the button above to see the script re-run as the longest row hides and appears. Adjust your window size to see where the bottom scrollbar appears. Turn off JavaScript and see how the list items would behave if the script is not active. (The items would stack if necessary.) (JavaScript is turned off.)

Row 1:

Row 2:

Row 3:

Date Created

25 Feb 2008.

Help

  1. w3schools.com
  2. http://www.thescripts.com/forum/thread460556.html for where I discovered the JavaScript properties offsetWidth, among other offsetWhatever properties, which returns (as opposed to "setting") the current value of the element property.
  3. http://www.litfuel.net/plush/?postid=101 for reminding me the pickiness of programming accuracy. Make sure you include "px" when defining style measurements via JS.
  4. http://www.jslint.com/ for fun. It's a tool to help write JS the most accurate way possible. Not sure how valid and necessary the rules are. But fun to be accurate and problem-free sometimes.
  5. http://www.javascriptkit.com/javatutors/arraysort.shtml for teaching me stuff about sort() that w3schools.com seriously lacked.

Process

Relatively simple addition, sorting, and styles applying.

  1. Use code from the preceding experiment and create multiple lists.
  2. Make input boxes to display the widths of all the list items (Experiment Only).
  3. Create variables for with adding function
  4. Loop through the row arrays to define the row item arrays
  5. Add the widths of each list item and keep count. Store the sums in an array.
  6. Sort the sums
  7. Take the largest sum add that to the min-width formula. Apply the min-width value.

The Code

Here’s the code. Please link back here if you’re using it.

Place this CSS in the head tag.

body{
/*set your own minimum width in case JS is turned off.
ALSO: min-width won't work in IE unless you have a hack*/

min-width:800px;
}

ul.allLists{
list-style-position:outside;
clear:left;
}

ul.allLists li.row{
list-style-type:none;
float:left;
}

ul.allLists li.row{
margin-bottom:1em;
clear:left;
}

ul.allLists li.row ul li{
padding:0 16px 0 8px;
width:200px;
border-left:1px solid #000;
border-top:1px solid #000;
}

Place this JavaScript in the head tag.

//Redefine the width so Opera won't be confused later when width="auto" renders to 100%
//This also makes all the browsers with JS enabled to read it as auto

document.write("<style type='text/css' >ul#allLists li.row ul li.listItem{width:auto;}</style>");

Place this HTML in the body tag.

<ul id='allLists' >
<li class='row' id='row1' >
<ul id='list1' >
<li class='listItem' >Put list item content here. Repeat <li class="listItem">'s and <li class="row">'s as needed.</li>
</ul>
</li>
<li class='row' id='row2' >
<ul id='list2' >
<li class='listItem' >Put list item content here.</li>
</ul>
</li>
</ul>

Place this JavaScript at the end of the body tag.

//THIS PAGE ONLY - to show whether JS is turned on/off

    document.getElementById("JSswitch").innerHTML="on";

/*global document, onload */
function doIt() {

    var listItem=getElementsByClassName(document,"li","frameItem");
        
    for (var i = 0;i < listItem.length;i += 1) {
        listItem[i].style.width = 8-((listItem[i].offsetWidth-1)%8) + listItem[i].offsetWidth -26 + "px";
    }
    
    minWidth();

}

function minWidth(){
    
    var row = getElementsByClassName(document, "ul", "row");
    var rowItem=new Array();
    var countAiner=new Array();
    var count=0;
    var k=0;
    var l=0;

    for (k=0;k<row.length;k+=1){
        rowItem=getElementsByClassName(row[k],"li","frameItem");
        count=0;
        
        for (l=0;l<rowItem.length;l+=1){
            count+=rowItem[l].offsetWidth;
            countAiner[k]=count;
            }
        
        }

    countAiner.sort(function(a,b){return b-a});

    var minWidth=countAiner[0]+32;
    document.body.style.minWidth=minWidth+"px";
}

onload = doIt;

var onOff=true; //true means on
var button=document.getElementById("switch2ndRow");
button.onclick=function(){
    if (onOff==true){
        document.getElementById("list2").style.display="none";
        onOff=false;
        } else if(onOff==false){
        document.getElementById("list2").style.display="block";
        onOff=true;
        }
        
    doIt();    
    }

Return to top