Reputation: 2107
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
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;
}
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;
}
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;
}
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;
}
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
Reputation: 13360
Change these two lines to look like this:
.email { width: 99%; float: right; }
.last-name { width: 65%; float: right;}
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
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% }
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; }
Firefox Screenshot.
Upvotes: 0