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>