tags:

views:

3020

answers:

3

For example I have a 200px div containing three buttons, the text is only minimal so the buttons don't fill the horizontal space available. Is it possible to..

1) Make the last button stretch to occupy all the remaining space?

2) The First button to stretch to fill the remaining space pushing the last two buttons along?

3) The middle button to stretch to fill the remaining space pushing the last button along?

Regards,

Chris

A: 

Can't you just set the widths like so...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd"&gt;

<html>
<head>
<title>test css button stretch</title>
<style>

#btn_container 
{
   width: 200px;
}
#btn_container button
{
   width: 20%;
}
#btn_container button.stretch
{
   width: 58%;
}
</style>
</head>
<body>

<div id="btn_container">
<p>last button stretch...</p>
<button type="button">eat</button>
<button type="button">drink</button>
<button class="stretch" type="button">sleep</button>
<br>
<p>first button stretch...</p>
<button class="stretch" type="button">eat</button>
<button type="button">drink</button>
<button type="button">sleep</button>
<br>
<p>middle button stretch...</p>
<button type="button">eat</button>
<button class="stretch" type="button">drink</button>
<button type="button">sleep</button>
</div>
</body>
</html>

This seems to get the desired effect, is fluid (if the div button container's width is changed or set to a %), and works in IE, Firefox and Opera.

edit: removed the redundant btn class; bumped up the width % for the stretch class; added the doctype. Left the types on, could technically haved removed for just an example, but meh.

@rpflo: the types are in there because my buttons in this example are not submit buttons. If these were part of a form and were submitting, I'd have left them off since the default is type=submit. (W3C HTML BUTTON)

Robert
What's with all the classes and types?
rpflo
You're right what was I thinking. I'll edit to clean it up.
Robert
A: 

Similar to Roberts:

HTML

<div id="container">
    <button id="one">One</button><button id="two">Two</button><button id="three">Three</button>
</div>

CSS

div#container {
    border: solid 1px;
    width: 200px;
}

div#container button {
    width: 33%;
}

div#container button:last-child {
    width: 34%;
}

That doesn't allow for a fluid layout: #container width must be known, then you do the math.

To allow for a fluid layout you need to hop into the world of absolute positioning:

div#container {
    border: solid 1px;
    width: 50%; /* resize your browser window to see results */

    position: relative;
}

div#container button {
    position: absolute;
    width: 50px;
}

button#one {
    top: 0;
    left: 0;
}

button#two {
    top: 0;
    left: 55px;
}

button#three {
    width: auto !important; /* get rid of the 50px width defined earlier */
    top: 0;
    left: 110px;
    right: 0px;
}

Watch out for the height of #container. It's gone since all it's children in this example are absolutely positioned--you can see that from the border.

rpflo
This example doesn't seem to work for me in Firefox, haven't tried any other browsers.
ChrisInCambo
That's right, firefox gets a little odd w/ absolutely positioned input elements. No time right now, but I know I've fixed this in the past.
rpflo
+1  A: 

I've realised that the real issue is buttons won't stretch until you give them an explicit width (ie, width:100%). You still need the table-cells though to constrain that 100% to a 'what will fit' model. You could just set 33% on each button but that won't work if your buttons are being added dynamically (unless you calculate the percentages on the server).

METHOD 1 (doesn't work): Buttons don't expand to fit the row (ie, display:table-cell appears to be ignored).

<div style="display:table;width:200px">
    <div style="display:table-row">
        <button style="display:table-cell">1</button>
        <button style="display:table-cell">2</button>
        <button style="display:table-cell">3</button>
    </div>
</div>

For IE prior to IE8 you'll need to feed a real table or a compatibility script like IE8-js. The basic concept is easy enough though:

<!--[if ie lt 8]>
<script><!--pseudo-code, not real js-->
for (el in getElementsByTagName('button')) {
    if el.style.find('display:table-cell') {
        el.innerHTML = '<td><button>'+el.innerHTML+'</button></td>'
    }
}
</script>
<![endif]-->

METHOD 2 (works): Hmmm.. Well for whatever reason the display:table-cell style does not work on button elements. I was able to do it with some extra markup though.

<div style="display:table;width:500px;">
    <div style="display:table-row">
        <div style="display:table-cell"> <button style="width:100%">1938274</button> </div>
        <div style="display:table-cell"> <button style="width:100%">2</button> </div>
        <div style="display:table-cell"> <button style="width:100%">3</button> </div>
    </div>
</div>

I admit it ain't pretty but it will ensure all of the horizontal space is filled. It can be cleaned up a bit by using classes like in this demo I put together. Still, when combined with IE's shortcomings this is probably a case where I'd say ignore the purists and just use a table:

<style>table button {width:100%}</style>

<table style="width:500px;">
    <tr> <td><button>1938274</button> <td> <button>2</button> <td> <button>3</button> </tr>
</table>
SpliFF
Hi SpilFF, thanks for the answer this is definitely the type of solution I was looking for although unfortunately it's not working for me, the buttons aren't stretching (tried in Firefox). I also noticed that the table-row div wasn't closed to also closed that, but no joy.
ChrisInCambo