user291701
user291701

Reputation: 39721

Make buttons the same width without specifying the exact size

I have five buttons. I want them to take up the available width of their parent div, each being equally sized:

<div style="width: 100%; background-color: red;">
    <button type="button" style="width: 20%;">A</button>
    <button type="button" style="width: 20%;">B</button>
    <button type="button" style="width: 20%;">C</button>
    <button type="button" style="width: 20%;">D</button>
    <button type="button" style="width: 20%;">E</button>
</div>

Is there a way I can do this without having the manually figure out that they each require 20% width? I want to remove a button at runtime, and that means I have to go and update each remaining button again to width=25%.

I am just checking if there's a more automated way of doing it.

Upvotes: 20

Views: 128288

Answers (8)

AndyS
AndyS

Reputation: 836

If you have variable width text then the table approach still works, or you can still use flex if you use box-sizing: border-box; and add an extra div around your buttons, e.g. see the snippet below (sorry it is so long).

N.B. Note how flex-grow can be used to weight the different buttons - so the left button is ~half the size of the other buttons (within about 0.5 pixel?)

body {
  font-family: arial, sans-serif;
  background-color: black;
  margin: 0;
}

.quando_button {
  color: ffffff;
  font-weight: normal;
  transition: opacity 1.0s linear;
  background-color: rgb(224, 119, 0);
}

.quando_button_parent {
  /* overridable weight */
  flex-grow: 1;
  flex-basis: 0;
  margin: 0;
  border: 0;
  padding: 0;
}

.quando_button {
  /* make flex allow for border and padding */
  box-sizing: border-box;
  border: 5px solid black;
  padding: 10px;
  /* force centre middle */
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  width: 100%;
}

#quando_buttons {
  position: absolute;
  z-index: 100;
  bottom: 5%;
  width: 90%;
  height: 70%;
  left: 5%;
  display: flex;
  flex-direction: row;
}
<div id="quando_buttons">
  <div class="quando_button_parent" style="flex-grow: 0.5;">
    <div class="quando_button">Left</div>
  </div>
  <div class="quando_button_parent" style="flex-grow: 1;">
    <div class="quando_button">Middle</div>
  </div>
  <div class="quando_button_parent" style="flex-grow: 1;">
    <div class="quando_button">Big Right Button that should wrap itself</div>
  </div>
</div>

Upvotes: 0

Bart
Bart

Reputation: 6814

If you can define a min-width and a max-width, here is a pretty simple solution (which does not use flex or tables).

div {
  display: inline-block;
  min-width: 100px; /** The min-width for each button **/
  max-width: 200px; /** The max-width for each button **/
  white-space: nowrap; 
}
button { 
  width: 100%;
  white-space: initial; 
}
<div>
    <button type="button">Short</button>
    <button type="button">Short</button>
</div>

<hr />

<div>
    <button type="button">This is a long button</button>
    <button type="button">Short button</button>
</div>

<hr />

<div>
    <button type="button">Short</button>
    <button type="button">This is a really really long button</button>
</div>

Upvotes: 0

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201828

The simplest way, and the most robust way, is to use a table:

<style>
.buttons { 
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  background-color: red; 
}
.buttons button { 
  width: 100%;
}
</style>
<table class=buttons>
 <tr>
    <td><button type="button">A</button>
    <td><button type="button">B</button>
    <td><button type="button">C</button>
    <td><button type="button">D</button>
    <td><button type="button">E</button>
</table>

(This won’t improve your reputation among colleagues these days if they see your code, though it actually solves the problem probably better than any alternative. So you might consider doing the next best thing: use div markup and display: table etc. Fails on old browsers that don’t support such CSS features.)

Upvotes: 26

openHBP
openHBP

Reputation: 691

With bootstrap it is as simple as

<div class="btn-group-vertical">

</div>

Upvotes: 2

Fasmir
Fasmir

Reputation: 169

This is my favorite method (Flexbox)! -

<div style="width: 100%; background-color: red;">
    <button type="button">A</button>
    <button type="button">B</button>
    <button type="button">C</button>
    <button type="button">D</button>
    <button type="button">E</button>
</div>

div {
  display: flex;
  justify-content: space-around;
}
button {
  width: 100%;
  margin: 5px; /* or whatever you like */
}

No matter how many buttons you have, it will resize the button width automatically and fill the div.

Working pen: http://codepen.io/anon/pen/YpPdLZ

Upvotes: 16

kelly johnson
kelly johnson

Reputation: 1636

I think, with jQuery, you could do something more dynamic.

The process for the algorithm would be:

  1. get the width of the div, put into a variable.

  2. divide the width by the number of buttons and put that answer into a variable.

  3. run a function that creates a button at that width by however many times required.

Upvotes: -1

crowjonah
crowjonah

Reputation: 2878

This is how I'd tackle a situation like this, taking a queue from front-end grid systems. Use classes! When you remove the button, change the class. Here's a fiddle.

Your HTML markup could change to this:

<div>
    <button type="button" class="fiveup">A</button>
    <button type="button" class="fiveup">B</button>
    <button type="button" class="fiveup">C</button>
    <button type="button" class="fiveup">D</button>
    <button type="button" class="fiveup" id="remove_this">E</button>
</div>
<button id="remove_one">Remove One</button>​

CSS like so:

.fiveup {width: 18%;margin:1%;float: left;}
.fourup {width: 23%;margin:1%;float: left;}

and jQuery like so, though you'll probably want to use this script as part of whatever process removes the button:

$('#remove_one').click(function(){
    $('#remove_this').remove();
    $('button').each(function(){
        $(this).removeClass('fiveup').addClass('fourup');
    });
});​

Upvotes: 3

Matey Yanakiev
Matey Yanakiev

Reputation: 167

If we take that their parents are equally sized, you have two solutions to your problem:

CSS:

button { /* You may want to limit the selector */
     width: 100%; /* Or any other percent */
}

JavaScript (jQuery):

$("button").width("100%");

Please note, however, that to be sure you also get the exact value, you may want to stick to pixels. If you are willing to use JavaScript, you can also use computed width.


Edit

If you want to use JavaScript without jQuery, try:

var buttons = document.getElementsByTagName("button"),
    i = 0;
for (; i < buttons.length; i++) {
     buttons[i].width = "100%"; //Or any other value
}

Note, however, that .getElementsByTagName() will have to be replaced if you want a more complex query.

Upvotes: 0

Related Questions