9

I have two rows within a HTML table. Here is a simplified view of it:

#topTextbox {
  width: 98%;
}

#bottomTextbox {
  width: 693px;
}
<table>
  <tr>
    <td>
      <input type=text id=topTextbox />
    </td>
  </tr>
  <tr>
    <td>
      <select>
        <option value="0"></option>
        <option value="saab">Saab</option>
        <option value="mercedes">Mercedes</option>
      </select>
      <input type=text id=bottomTextbox />
    </td>
  </tr>
</table>

The first row has one long textbox and the second row has a dropdown and a textbox. I am trying to get it so these line up with the same total width. The issue is that as new data comes into the dropdown the width will change so I am trying to figure out the correct css on the bottom textbox so it lines up on the right side with the top textbox.

Here is what it looks like in Firefox: enter image description here

Here is what it looks like in IE: enter image description here

So I have an issue today that they don't line up across browsers as well as the fact that this will get worse as items are added to the dropdown (since the bottom has a fixed width).

What is the correct way to keep these textboxes aligned on the right no matter how big the overall table gets as well as new items are added to the dropdown?

Community
  • 1
  • 1
leora
  • 188,729
  • 360
  • 878
  • 1,366

10 Answers10

13

This the following approach involves CSS3 box-sizing and calc(). It works fine on IE9+ and all modern browsers.

table {
  width: 100%;
}
input,
select {
  box-sizing: border-box;
  display: inline-block;
}
#topTextbox {
  width: 100%;
}
select {
  width: calc(30% - 4px);
  /* why 4px? http://stackoverflow.com/q/5078239/483779 */
}
#bottomTextbox {
  width: 70%;
}
<table>
  <tr>
    <td>
      <input type="text" id="topTextbox" />
    </td>
  </tr>
  <tr>
    <td>
      <select>
        <option value="0"></option>
        <option value="saab">Saab</option>
        <option value="mercedes">Mercedes</option>
      </select>
      <input type="text" id="bottomTextbox" />
    </td>
  </tr>
</table>
Stickers
  • 75,527
  • 23
  • 147
  • 186
2

Try somthing like this

<table>
        <tr>
            <td colspan="2">
                <input type=text id=topTextbox />
            </td>
        </tr>
        <tr>
            <td>
                <select>
                    <option value="0"></option>
                    <option value="saab">Saab</option>
                    <option value="mercedes">Mercedes</option>
                </select>
            </td>
            <td style="width: 100%;">
                <input type=text id=bottomTextbox />
            </td>
         </tr>
      </table>

CSS

table {
    width: 98%;
}

input {
    width: 100%;
}
select{
    width: 150px;/**may be**/
}

SEE DEMO http://jsfiddle.net/JentiDabhi/dq3g5k3j/

Jenti Dabhi
  • 870
  • 5
  • 11
2

The following does the asked behavior, but it is made with flexbox instead of table. I decided to post it since it might be helpful.

It is achievable in flexbox with flex-shrink; check the following snippet:

var j = 3;

document.querySelector("button").addEventListener("click", function () {
    var opt = document.createElement("option"),
    i;
    for (i = 0; i < j; i += 1) {
        opt.innerHTML += "123456789";
    }
    j += 1;
    document.querySelector("select").appendChild(opt);
});
.container {
    width: 98%;
}

.here {
    display: flex;
}
    
.select { flex-shrink: 0; width: auto; }
.input { flex-shrink: 1; width: 100%; }


select, input { width: 100%; }
<div class="container">
    <div>
        <input type="text" id="topTextbox" />
    </div>
    <div class="here">
        <div class='select'>
            <select>
                <option></option>
                <option>123456789</option>
                <option>123456789123456789</option>
            </select>
        </div>
        <div class='input'>
            <input type="text" id="bottomTextbox" />
        </div>
    </div>
</div>

<hr></hr>

<button>Add longer option value</button>
s4nji
  • 449
  • 1
  • 6
  • 17
2

A responsive solution:

By adapting the markup with a div-tag around the text input and a little CSS, it will fill automatically the whole width (unless the select-box fills the table cell).

<table>
<tr>
      <td><input type="text" id="topTextbox" /></td>
</tr>
<tr>
      <td>
          <select>
            <option value="0"></option>
            <option value="saab">Saab</option>
            <option value="mercedes">Mercedes</option>
          </select> 

          <div><input type="text" id="bottomTextbox" /></div>
       </td>
</tr>
</table>

CSS Style:

table{
    width: 100%; /* your custom width */
}
input{
    box-sizing: border-box;
    width: 100%;
    overflow: hidden;
    clear: none;
}
select{
    float: left;
    margin-right: 5px; /* your custom margin */
}
div{
    overflow: hidden;
}

See the JSFiddle.

This will work also when filling up the select-box dynamically.

spaark
  • 701
  • 10
  • 17
2

i think cellspacing and cellpadding properties should be set for the TABLE tag, and then you can use margin or padding css properties that apply to INPUT and SELECT tags.

furthermore, for the cross-browserness, fixed widths work fine.

Example HTML code:

<table cellspacing="0" cellpadding="0">
    <tr>
        <td colspan="2">
            <input type=text id=topTextbox style="width: 600px" />
        </td>
    </tr>
    <tr>
        <td>
            <select style="width: 200px">
                <option value="0"></option>
                <option value="saab">Saab</option>
                <option value="mercedes">Mercedes</option>
            </select>
        </td>
        <td >
            <input type=text id=bottomTextbox style="width:400px" />
        </td>
     </tr>

1

Try use box-sizing like @Pete Suggestion:

#topTextbox,#bottomTextbox{
    width: 100%;
    box-sizing: border-box;
} 
Eko Junaidi Salam
  • 1,663
  • 1
  • 18
  • 26
1

I tested this out in both Chrome and IE. It seems to work properly. Personally, I don't like using values that aren't percentages. However, this comes up well.

http://jsfiddle.net/7sk6p3ex/

<html>
  <head>
    <style>
      .top{width: 300px;}
      .bottom{width: 148px;}/* The space between select & input = 4px */
    </style>
  </head>
<body>
  <table style="width: 100%;">
    <tr>
      <td><input class="top" type="text" id="topTextbox"></td>
    </tr>
    <tr>
      <td>
        <select class="bottom">
        <option value="0"></option>
        <option value="saab">Saab</option>
        <option value="mercedes">Mercedes</option>
        </select>
      <input class="bottom" type="text" id="bottomTextbox">
     </td>
    </tr>
  </table>
</body>
</html>
1

Simulate a nested table, get table-like layout behavior

If you can modify the HTML markup, you can achieve the desired result by simulating a nested table with div and span elements styled with display: table and display: table-cell respectively. (You could use an actual nested table, but that isn't semantically ideal for non-tabular data.)

HTML

<div class="input-combo">
    <span class="select">
        <select>
            <option value="0"></option>
            <option value="saab">ThisIsAReallyLongName</option>
            <option value="mercedes">ThisNameIsMuchLongerThanTheOther</option>
        </select>
    </span>
    <span class="input">
        <input type="text" />
    </span>
</div>

CSS

.input-combo {
    display: table;
    border-collapse: collapse;
    width: 100%;
}

.input-combo .select,
.input-combo .input {
    display: table-cell;
    box-sizing: border-box;    
}

.input-combo .select {
    padding-right: 0.25em;
}

The desired layout behavior you are looking for is native to tables, which is to adjust the width of each cell so that the sum of cell-widths equals the width of the table itself. Browsers handle this logic automatically and rather intelligently.

You can then style each input element to simply have a width of 100%, filling up each cell, and allow the browser to determine the width of the cell based on the width of each cell's contents.

The below example compares two identical tables for which the only difference is the width of the content in the select box. The HTML and CSS is the same.

Example:

table {
    width: 100%;
}

input, select {
    width: 100%;
    box-sizing: border-box;
    padding: 1px 0; /* normalize */
}

.input-combo {
    display: table;
    border-collapse: collapse;
    width: 100%;
}

.input-combo .select,
.input-combo .input {
    display: table-cell;
    box-sizing: border-box;    
}

.input-combo .select {
    padding-right: 0.25em;
}
<table>
    <tr>
        <td><input type="text" /></td>
    </tr>
    <tr>
        <td>
            <div class="input-combo">
                <span class="select">
                    <select>
                        <option value="0"></option>
                        <option value="saab">Saab</option>
                        <option value="mercedes">Mercedes</option>
                    </select>
                </span>
                <span class="input">
                    <input type="text" />
                </span>
            </div>
        </td>
    </tr>
</table>

<table>
    <tr>
        <td><input type="text" /></td>
    </tr>
    <tr>
        <td>
            <div class="input-combo">
                <span class="select">
                    <select>
                        <option value="0"></option>
                        <option value="saab">ThisIsAReallyLongName</option>
                        <option value="mercedes">ThisNameIsMuchLongerThanTheOther</option>
                    </select>
                </span>
                <span class="input">
                    <input type="text" />
                </span>
            </div>
        </td>
    </tr>
</table>
gfullam
  • 11,531
  • 5
  • 50
  • 64
-1

try this. Works fine for me.

CSS:

table {
    width: 98%;
}

input {
    width: 100%;
}

HTML:

<table>
    <tr>
        <td colspan="2">
            <input type=text id=topTextbox />
        </td>
    </tr>
    <tr>
        <td>
            <select>
                <option value="0"></option>
                <option value="saab">Saab</option>
                <option value="mercedes">Mercedes</option>
            </select>
        </td>
        <td style="width: 100%;">
            <input type=text id=bottomTextbox />
        </td>
     </tr>
  </table>
KBeckers
  • 416
  • 4
  • 12
-1

Try this code once

    <tr>
      <td><input type=text id=topTextbox /></td>
</tr>
<tr>
      <td>
          <select>
            <option value="0"></option>
            <option value="saab">Saab</option>
            <option value="mercedes">Mercedes</option>
          </select> 
          <input type=text id=bottomTextbox />
       </td>
</tr>

#topTextbox
{  
 width: 98%;
 }

#bottomTextbox
{  
   width: 80%;
}
chakri
  • 629
  • 3
  • 11
  • 21