Corey
Corey

Reputation: 2563

Making a form input 100% width of what's left after the label

Basically I'm trying to create this:

enter image description here

This is what I have so far: jsFiddle.

Basically I have tried setting the label and inputs to display:block; and making the inputs have width:100%;. But that of course makes the inputs break to a new line. Then I tried adding white-space:nowrap; to the p tags and that almost gets the effect that I need, but the inputs then go outside of the container bounds.

Any idea how to do something like this?

Upvotes: 0

Views: 2998

Answers (2)

Danield
Danield

Reputation: 125473

Here are two solutions using CSS alone

Solution #1: Flexbox

FIDDLE

Set flex:1 on the input to fill the remaining width

.container {
  width: 500px;
  padding: 40px;
  border: 1px solid black;
}
label {
  display: inline-block;
  padding: 8px 10px 0 0;
}
p {
  display: flex;
}
input {
  -webkit-box-shadow: -2px 2px 10px 0px rgba(50, 50, 50, 0.22);
  -moz-box-shadow: -2px 2px 10px 0px rgba(50, 50, 50, 0.22);
  box-shadow: -2px 2px 10px 0px rgba(50, 50, 50, 0.22);
  border: 0;
  padding: 10px;
  flex: 1;
}
<div class="container">
  <form>
    <p>
      <label>*First Name</label>
      <input type="text" />
    </p>
    <p>
      <label>*Last Name</label>
      <input type="text" />
    </p>
    <p>
      <label>*Street Address</label>
      <input type="text" />
    </p>
    <p>
      <label>Address Line 2</label>
      <input type="text" />
    </p>
  </form>
</div>

Solution #2: Intrinsic Sizing

Use Intrinsic Sizing by setting the value for width of the label with min-content:

label {
    display: table-cell;
    width: -webkit-min-content;
    width: -moz-min-content;
    width: min-content;
}

FIDDLE

Browser support for Intrinsic Sizing is actually quite good - except for IE - which currently doesn't support these values yet.

(Edit: This particular example seems to only work on Firefox and not on chrome, I'm not sure why though.)

Upvotes: 6

Weafs.py
Weafs.py

Reputation: 22992

Well, I would use JavaScript to do this, since CSS can't do the math and this is how it would look like without changing your HTML or CSS.

(Note: This will work even if you change the width of your .container)

Demo on Fiddle

HTML:

<div class="container">
  <form>
    <p>
      <label>*First Name</label>
      <input type="text" />
    </p>
    <p>
      <label>*Last Name</label>
      <input type="text" />
    </p>
    <p>
      <label>*Street Address</label>
      <input type="text" />
    </p>
    <p>
      <label>Address Line 2</label>
      <input type="text" />
    </p>
  </form>
</div>

JavaScript:

var fWidth = window.getComputedStyle(document.getElementsByClassName('container')[0]).width.slice(0, -2);
var labels = document.getElementsByTagName('label');
var inputs = document.getElementsByTagName('input');

for (i = 0; i < labels.length; i++) {
  var labelWidth = window.getComputedStyle(labels[i]).width.slice(0, -2);
  var inputWidth = fWidth - labelWidth;
  inputs[i].style.width = inputWidth + 'px';
}

CSS:

.container {
    width: 500px;
    padding: 40px;
    border: 1px solid black;
}
label {
    display: inline-block;
}
p {
    white-space: nowrap;
}
input {
    -webkit-box-shadow: -2px 2px 10px 0px rgba(50, 50, 50, 0.22);
    -moz-box-shadow: -2px 2px 10px 0px rgba(50, 50, 50, 0.22);
    box-shadow: -2px 2px 10px 0px rgba(50, 50, 50, 0.22);
    border: 0;
    padding: 10px;
    display: inline-block;
}

Upvotes: 0

Related Questions