Don Tomato
Don Tomato

Reputation: 3539

CSS way to align form's input elements, based on the widest label

Suppose I have a form:

<form action="#">
  <p>
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />
  </p>

  <p>
    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />
  </p>

  <p>
    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />
  </p> 
</form> 

With the following CSS:

form {
  width: 400px;
}

p {
  display: flex;
}

label {
  margin-right: 10px;
}

input {
  flex-grow: 1;
}

It looks the following way:

enter image description here

I need to align the right side of inputs, based on the widest label. That's what I want:

enter image description here

I don't know label's width beforehand, so bootstrap-like solutions with columns are not good here. Is there pure HTML/CSS way to achieve it, without using JS?

PS!!: And I don't want to use table

Upvotes: 1

Views: 101

Answers (5)

Temani Afif
Temani Afif

Reputation: 274384

Remove the p and use CSS grid:

form {
  width: 400px;
  display:grid;
  grid-template-columns:auto 1fr;
  grid-gap:5px;
  margin:10px;
}

input {
  width:100%;
}
<form action="#">
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />

    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />

    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />

</form> 


<form action="#" style="width:600px;">
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />

    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />

    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />

</form> 

Or use display:contents with the p

form {
  width: 400px;
  display:grid;
  grid-template-columns:auto 1fr;
  grid-gap:5px;
  margin:10px;
}

input {
  width:100%;
}

p {
 display:contents;
}
<form action="#">
<p>
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />
</p>
<p>
    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />
</p>
<p>
    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />
</p>
</form> 


<form action="#" style="width:600px;">
<p>
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />
</p>
<p>
    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />
</p>
<p>
    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />
</p>
</form>

Upvotes: 2

dashingdove
dashingdove

Reputation: 435

You could simply organise it into a table. This will give you the formatting that you want.

Edit: Since you have specified that you don't want to use a table (and it would be better to avoid having to reorganise your html), how about styling your elements as if they were a table? I've changed my answer to keep your original html intact.

form {
  display:table;
}

p {
  display:table-row;
}

label, input {
  display: table-cell;
}
<form action="#">
  <p>
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />
  </p>

  <p>
    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />
  </p>

  <p>
    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />
  </p> 
</form> 

Upvotes: 1

Yogendra Chauhan
Yogendra Chauhan

Reputation: 825

Here is the working example:

form {
  width: 400px;
}

.form-group {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.form-group label {
  margin-right: 10px;
  flex: 1;
}

.form-group input {
  min-width: 180px;
}
<form action="#">
  <div class="form-group">
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />
  </div>

  <div class="form-group">
    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />
  </div>

  <div class="form-group">
    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />
  </div> 
</form>

Upvotes: 0

KeiZ
KeiZ

Reputation: 31

You should put the flex-grow on the label :) :

form {
  width: 400px;
}

p {
  display: flex;
}

label {
  flex: 1;
  margin-right: 10px;
  white-space: nowrap;
}
<form action="#">
  <p>
    <label for="name">Name:</label>
    <input type="text" placeholder="John Smith" />
  </p>

  <p>
    <label for="name">What do you think about him?:</label>
    <input type="text" placeholder="Your opinion" />
  </p>

  <p>
    <label for="name">Another Text Input:</label>
    <input type="text" placeholder="John Smith" />
  </p> 
</form> 

Upvotes: 1

Super Hornet
Super Hornet

Reputation: 2907

The best way to do so is, creating a table with two columns.

<table>
<tr>
<td>label</td>
<td>input</td>
</tr>
<tr>
<td>label</td>
<td>input</td>
</tr>
</table>

Upvotes: 0

Related Questions