How to make text input box to occupy all the remaining width within parent block?
Asked Answered
O

6

42

How do achieve the following:

┌────────────────────parent────────────────────┐
│ label [text-box                   ] [button] │
│ paragraph                                    │
└──────────────────────────────────────────────┘
  • label is aligned to the left
  • button is aligned to the right
  • text-box occupies all remaining width within parent
  • paragraph is aligned to the left, must be left-aligned with label too

Both label and button should obey font properties defined elsewhere as maximum as possible. parent is center-aligned within window, and, naturally, can have arbitrary width.

Please advise.

Outcast answered 28/4, 2011 at 22:42 Comment(0)
A
53

Updated [Oct 2016]: Flexbox version...

form {
  display: flex;
}
form input[type="text"] {
  flex: 1;
}
<form>
  <label>Name</label>
  <input type="text" />
  <button>Submit</button>
</form>
<p>Lorem ipsum...</p>

Original answer [Apr 2011]: Table-less CSS version (of table behavior)...

<div id="parent">
    <div id="inner">
        <label>Name</label>
        <span><input id="text" type="text" /></span>
        <input id="submit" type="button" value="Submit" />
    </div>
    <p>some paragraph text</p>
</div>

CSS...

#inner {
    display: table;
    width: 100%;
}
label {
    display: table-cell;
}
span {
    display: table-cell;
    width: 100%;
    padding: 0px 10px;
}
#text {
    width: 100%;
}
#submit {
    display: table-cell;
}

Demo: http://jsfiddle.net/wdm954/626B2/4/

Amatruda answered 28/4, 2011 at 22:56 Comment(4)
It looks nice until parent block has given an extreme widths. Stretch it and there will be a large hole between label text and text input box. Compress it and text withing label and button nodes will collapse. This is an essence of the problem i'm struggling with.Outcast
Cool, thanks, now it works completely independent of parent's widthOutcast
yea, it is cool but it won't work in IE7, because it doesn't support display: table-cell;Radman
here is the solution to work in IE7: https://mcmap.net/q/54744/-how-to-make-an-element-width-100-minus-paddingRadman
U
13

I don't like first answer with the "table-less" version that actually uses table-cell. Nor the second answer that uses actual tables. Nor third answer that uses hardcoded widths. Here is solution using flex. It is by far simplest:

#parent {
  display: flex;
}
input {
  flex: 1;
}
<div id="parent">
  <label>Name</label>
  <input type="text" />
  <button>Button</button>
</div>
<div>paragraph</div>
Unsettled answered 7/7, 2015 at 13:22 Comment(1)
Note that flex doesn't work in Android 4.2 browsers thus not allowing building cross-platform Cordova applications. Flex simplifies things so much and I love it a lot, but for compatibility one or two more years we have to use floats instead.Sucre
C
10

Use tables. :D I know people tend to hate tables, but they will work in this situation...

<div id="parent">
    <table style="width:100%">
        <tr>
            <td>label</td>
            <td style="width:100%">
                <input type="text" style="width:100%">
            </td>
            <td>
                <button>clickme</button>
            </td>
        </tr>
    </table>
</div>
Crossbench answered 28/4, 2011 at 23:3 Comment(4)
Now i'm curious how it works, because it does (w/o predefined widths, even percentage)Outcast
because the definition of a table cell is to keep going until it hits the next cell or the end of the row or table. You don't have to specify it.Crossbench
make everything as simple as possible but not simpler, said Einstein. That's an argument for your table solution. Occam would agree, too, and razor away chatty div solution. Some believe in the virgin birth, others in not using tables. Gotta have faith. Just gotta.Weldon
It works without tables when you put the button before the input box and assign float: right to it and wrap the input box inside span with display: block and overflow: hidden. No magic involved: <div style="width:100%"><button style="float:right">clickme 2</button><button style="float:right">clickme 1</button><label style="float:left">label</label><span style="display:block;overflow:hidden"><input type="text" style="width:100%"/></span></div>. The basic idea that all right side buttons are specified in the reverse order.Sucre
L
2

The only way I know how to achieve this or similar, is to have the "text-box" as a block element that would automatically fill the entire width of the parent, then apply padding to the left and right equal to the total width of the containers on the left and right. Then make the "label" and "button" elements have their position set as relative and float them to where they need to be (float: left, float: right).

Something like,

HTML:

<div id="parent">
    <div id="label">label</div>
    <div id="button">button</div>
    <div id="text-box">
        text<br />
        text<br />
        text<br />
        text<br />
        text
    </div>
</div>

CSS:

div#label
{
    position: relative;
    float: left;
    width: 200px;
    background: #F00;
}

div#button
{
    position: relative;
    float: right;
    width: 120px;
    background: #0F0;
}

div#text-box
{
    padding-left: 200px;
    padding-right: 120px;
    background: #00F;
}

If the button and label elements don't need to have a set width, all elements could just have their width as a percentage value (all adding up to 100%).

Longterm answered 28/4, 2011 at 22:56 Comment(4)
Unfortunately button block floats above text-box block, overlappling its content (try: opacity:0.75). Also, please check out my comment to wdm's answer on percentage width fragility.Outcast
You can avoid the collapsing of the left and right elements by giving the body a minimum width - I'm not sure what you mean by the hole between label text and text input - my solution makes sure that the content of text-box is always snapped to the right-hand-side of the input element.Longterm
Both the label and button elements are overlapping the text-box area. But the content within this area won't ever be behind or underneath because of the padding applied..Longterm
It works without tables when you put the button before the input box and assign float: right to it and wrap the input box inside span with display: block and overflow: hidden. No magic involved: <div style="width:100%"><button style="float:right">clickme 2</button><button style="float:right">clickme 1</button><label style="float:left">label</label><span style="display:block;overflow:hidden"><input type="text" style="width:100%"/></span></div>. The basic idea that all right side buttons are specified in the reverse order.Sucre
C
2

Don't forget, you can use calc(). Let's assume total of width used by label and button is 100px (including margin), then the width is:

.text-box {    
  width: calc(100% - 100px);
}

If you think it doesn't support a lot of browser, well you are wrong indeed. It supports a lot now. Time has changed

Catechize answered 2/7, 2016 at 13:51 Comment(1)
Wow! It looks like this is supported pretty far back, even to IE9. I'm suprised I don't see it more.Dissert
S
0

It works without flex and tables if assign float: right and put the button (or several buttons in reverse order) before the input box.

Then place the label with float: left, give the input box 100% width and wrap it inside a span with display: block and overflow: hidden.

No magic involved:

<div style="width:100%">
  <button style="float:right">clickme 2</button>
  <button style="float:right">clickme 1</button>
  <label style="float:left">label</label>
  <span style="display:block;overflow:hidden">
    <input type="text" style="width:100%"/>
  </span>
</div>

The basic idea that all right side buttons are specified before the input box in the reverse order.

Sucre answered 1/3, 2017 at 21:3 Comment(1)
For those who needs the label to pass clicks and taps to the input box and wrap it, padding-right: 100% and margin-right: -100% is the only solution in this case. But it'll be discovered that it draws the buttons unclickable. I love the advice https://mcmap.net/q/391672/-why-does-adding-float-left-to-my-css-make-my-link-unclickable . Complete solution is here: codepen.io/avesus/pen/VpaPWKSucre

© 2022 - 2024 — McMap. All rights reserved.