Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shrink-to-fit menu items - first item grows

Tags:

html

css

Let's say I have a menu of a pre-specified width.

I want each menu item to shrink-to-fit with its contents, with the exception of ONE, which then fills up the remaining space in the menu.

Like this:


                                                       Fill | item | item | item

So far the closest I've come to achieving this effect is by using display:table-cell in the css code for each menu item. But the problem is unless I define a width for the item's, they all expand to take up the same amount of width in the table.


      Fill      |      item      |      item      |      item      |      item

Is there any way to have the item spaces shrink to fit the item and have the fill item just fill up the rest of the div?

like image 429
Vervious Avatar asked Jan 03 '11 07:01

Vervious


3 Answers

For those who want to do it with a table, you can give the first "td" a class and set it to a ridiculously large width, then it will push and force the other columns to shrink as much as it can. It works because tables can't expand more than the width to which they were set.

For example:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
table td {
    border:solid 1px #000;
}
table td.fill {
    width:9999em;
    text-align:right;
}
table {
    width:300px;
    border-collapse:collapse;
}
</style>
</head>
<body>
    <table>
        <tr><td class="fill">Fill</td><td>item</td><td>item</td><td>item</td></tr>
    </table>
</body>
</html>

In the old example that worked in Firefox and IE only I set the "td" width to 0, then it shrinked the column as much as it could.

You can set all columns to shrink-to-fit by setting the td width to something small, like 1px when you don't set the table width, this works in Chrome, Firefox and IE.

table td {
  width:1px;
}

You might want to set white-space:nowrap; too, otherwise all the words will wrap, or give the td some larger width

like image 50
Timo Huovinen Avatar answered Nov 12 '22 07:11

Timo Huovinen


One way I've dealt with this issue is to apply width: 1px; to every <TH> where I'd like their cells to shrink. Then on each individual cell where I want to shrink to the content, I apply white-space: nowrap;. This prevents the cell from actually shrinking to 1px.

I'm currently using this method on a table of financial figures so I'm not sure if it works with longer paragraphs of text.

like image 7
cjezowicz Avatar answered Nov 12 '22 07:11

cjezowicz


Why not use a float instead? Just reverse the order of your menu items.

#menubar {
  background-color: lime;
  width: 100%;
}
.menuitem {
  float: right;
  padding-right: 10px;
  padding-left: 10px;
}

/* Clear float */
#menubar:after {
  content: ' ';
  display: block;
  clear: right;
}
<div id="menubar">
  <div class="menuitem">item</div>
  <div class="menuitem">item</div>
  <div class="menuitem">item</div>
  <div class="menuitem">item</div>
  <div class="menuitem">fill</div>
</div>

Alternate way to use display: inline-block that fills the width:

#menubar {
  width: 100%;
  text-align: right;
}
.menuitem {
  display: inline-block;
  background-color: aqua;
}
.filled {
  width: 100%;
  background-color: gray;
}
<div id="menubar">
  <div class="menuitem filled">fill
    <div class="menuitem">item</div>
    <div class="menuitem">item</div>
    <div class="menuitem">item</div>
  </div>
</div>

The only downfall with this second method is that the menu item's are actually contained within the first menu item / filled. It does the trick for filling width:100%... If they are drop-down menus you will probably want to do some z-index work and collapse borders / set padding / etc...

like image 3
CarpeNoctumDC Avatar answered Nov 12 '22 06:11

CarpeNoctumDC