stretching text field with button to fill parent div

Problem

I have a div <div id="ab"> which contain a text field <input type="text" class="a" /> and a submit button <input type="submit" value="Test" class="b" />. The div has fixed height and have length 100%. Text field have specific height. Submit button have specific height only. I want Text field to stretch the entire div (in width) leaving space for the submit button to dock. Setting width in percentage is not working;

styling;

#ab{
    background-color: #CCCCCC;
    width: 100%;
    height: 36px;
    border: solid 1px #999999;
}
#ab .a{
    display: block;
    float: left;
    border: none;
    height: 34px;
}
#ab .b{
    display: block;
    float: left;
    border: none;
    width: 100px;
    height: 36px;
}

html;

<div id="ab">
  <input type="text" class="a" />
  <input type="submit" value="Test" class="b" />
</div>

I am getting this;

enter image description here

and I want this;

enter image description here

Here is the fiddle.

How can I do this using css?

Problem courtesy of: blasteralfred Ψ

Solution

The cleanest way to achiev this is giving #ab a fixed width. Then it's pure math.

Or you do this:

#ab .a{
    width:100%; /* << */
    display: block;
    float: left;
    border: none;
    height: 34px;
}
#ab .b{
    margin: 0 0 0 -100px; /* << */
    display: block;
    float: left;
    border: none;
    width: 100px;
    height: 36px;
}

Additionally also apply box-sizing: border-box; to .a if you want its width to include optional paddings.

.a { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }
Solution courtesy of: dom

Discussion

If you have to have the button at 100px and not variable (with percents) then there isn't a way to do it with pure CSS. You can't say width: (100%-100px), so I would suggest setting it with Jquery:

Here is the Fiddle: http://jsfiddle.net/jesseclark/rXKqv/

Discussion courtesy of: Jesse Clark

You can realize that with a table

html

<div id="ab">
  <table>
     <tr>
         <td><input type="text" class="a" /></td>
         <td class="right"><input type="submit" value="Test" class="b" /></td>
     </tr>        
  </table> 
</div>

css

#ab{
background-color: #CCCCCC;
height: 36px;
border: solid 1px #999999;
width: 100%;
}
table{
    width:100%;      
}
.right{
    width:100px;
}
#ab .a{
    display: block;
    border: none;
    height: 34px;
    width:100%;
}
#ab .b{
    display: block;
    border: none;
    width: 100%;
    height: 36px;
}
Discussion courtesy of: Sven Bieder

This recipe can be found in it's original form on Stack Over Flow.