tribalvibes
tribalvibes

Reputation: 2107

How to justify form input fields with css?

I have a simple signup input form (haml for brevity here:)

%form#signup
  %fieldset
    %input.email{type:'text'}
    %br
    .name
      %input.first-name{type:'text'}
      %input.last-name{type:'text'}

and css:

#signup { width: 350px; }
fieldset { width: 100%; }
.name { width: 100%; }
.first-name { width: 30%; }
.last-name { /* occupy remainder of 'name' line */ }

How to style this so that the .email field is the full width of the fieldset and the .last-name and/or .first-name fields expand to also fill the entire width of the fieldset and with the right edge aligned with the .email field?

Yes it might be easier to use a table here but is there a simple way with css? It need only work for css3 compliant browsers and degrade reasonably for IE8 and 9.

fiddle link: http://jsfiddle.net/3UP9H/1

Upvotes: 2

Views: 6427

Answers (3)

David Thomas
David Thomas

Reputation: 253416

Original answer appears below the hr; the answer to the question, for clarity, appears to be a combination of box-sizing (and its vendor-previxed variants), in order to include the border-width and padding in the defined width of the elements(s) (rather than their width being defined-width + border-width + padding) and font-size: 0 for the parent element, which removes the errant space between the two input elements (although the space is, technically, still there; it just doesn't have any size to influence the position of the surrounding elements).

So, the CSS is that from the second example below:

fieldset input[type=text] {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    width: 350px;
}

fieldset div input[type=text] {
    width: 105px;
    margin: 0;
}

fieldset div input[type=text] + input[type=text] {
    float: right;
    width: 245px;
}

div.name {
    font-size: 0;
}​

JS Fiddle demo.


Original answer follows:

One way seems to be:

form {
    width: 350px;
}

fieldset {
    width: 100%;
}

​fieldset input[type=text] {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    display: inline-block;
    width: 350px;
}​​

fieldset div input[type=text] {
    width: 105px;
    margin: 0;
}

fieldset div input[type=text] + input[type=text] {
    float: right;
    width: 241px;
}​

JS Fiddle demo.

The use of box-sizing (and the vendor-prefixed variants) is to simply include the border of the element, and any assigned padding within the defined width of the element.

I've used self-closing input tags in the linked demo, since input elements, so far as I know, don't have closing tags </input>.

I've amended the above, slightly, to remove the issue of the errant space (between the sibling input elements in the .name element from requiring arbitrary corrections to allow them both on the same line (hence the strange width: 241px in the above CSS):

form {
    width: 350px;
}

fieldset {
    width: 100%;
}

fieldset input[type=text] {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    display: inline-block;
    width: 350px;
}

fieldset div input[type=text] {
    width: 105px;
    margin: 0;
}

fieldset div input[type=text] + input[type=text] {
    float: right;
    width: 245px;
}

div.name {
    font-size: 0;
}​

JS Fiddle demo.


Edited to remove the fixed-width measurements, and replaced with relative, percentage, based units (as in the original question):

form {
    width: 350px;
}

fieldset {
    width: 100%;
}

fieldset input[type=text] {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
    display: inline-block;
    width: 100%;
}

fieldset div input[type=text] {
    width: 30%;
    margin: 0;
}

fieldset div input[type=text] + input[type=text] {
    float: right;
    width: 70%;
}

div.name {
    font-size: 0;
}​

JS Fiddle demo.

Unfortunately there's no way to set the width of the input elements to 100% by default, while still allowing sibling input elements to have differing widths. Or, there is, but it's substantially more awkward and requires you to explicitly identify both siblings as, although it's possible to select the second, or later, sibling with the + or ~ combinators it's not possible to select the first sibling based on its having subsequent siblings (without JavaScript, or other scripting language, whether client-, or server-, side).

Upvotes: 3

saluce
saluce

Reputation: 13360

Change these two lines to look like this:

.email { width: 99%; float: right; }
.last-name { width: 65%; float: right;}​

Fiddle Link

EDIT The odd thing is that about width in Chrome and IE is that there is an extra 4px width that isn't there in Firefox. The problem is that Chrome and IE add the border to the width of the box, while Firefox compensates the width of the internal textfield to make it fit the border within the bounds specified. See this version of the fiddle for a demonstration.

EDIT2 Check this updated fiddle.

Upvotes: 0

The Alpha
The Alpha

Reputation: 146219

#signup { width: 350px; }
fieldset { width: 100%; border: 1px solid grey; padding:2px;}
.email { width: 99%;margin-bottom:2px; }
.name { width: 100%; }
.first-name { width: 30%; }
.last-name { width : 67% }

DEMO

Update

#signup { width: 350px; }
fieldset { width: 100%; border: 1px solid grey; padding:2px;}
.email { width: 99%;margin-bottom:2px; }
.name { width: 100%; }
.first-name { width: 30%; }
.last-name { width : 67%; float:right; }

DEMO

Firefox Screenshot.

enter image description here

Upvotes: 0

Related Questions