Horizontal margin collapse on inline elements?!?!?

Recently, I was experimenting with a way to layout form controls WITHOUT floats or display:inline blocks. I have encountered a real challenge when attempting to create layout “columns”.

For example:

							Name: |_______INPUT________|       Lastname: |_______INPUT________|

From this EXACT CODE:

	<DIV><label>Name: </label><input><label>Last Name: </label></DIV>

It didn’t seem like it would be tough. Tho inline elements do not have explicit dimensions, inputs do. So I figured I would use a left margin on the INPUT element to clear a “column” space for the LABEL, and then use a negative right margin on the LABEL into that space and simulate the right-justify. The idea being that no matter what there would be a fixed amount of space to the left of the INPUT, as created by its left margin.
Despite that the spec specifically states that horizontal margins don’t collapse, input{width: 15em; margin-left:11em;} label{margin-right:-11em;} acts seems to acts ALMSOT as if canceling out both margins. Maybe am entirely off the mark here and this is just not possible to do suing only the margin + padding on inline elements, but maybe my web math is off. suggestions or thoughts on the matter would be greatly appreciated.

  1. I assume you left out the second input by accident :smiley:

  2. Not sure what you’re finding so difficult – though I think what you are missing is display:inline-block. (or is that what you mean by display:inline blocks?1?) – kinda hard following what you mean…

  3. You don’t need a div when you should have a perfectly good FIELDSET.


<label>First Name:</label><input type="text" />
<label>Last Name:</label><input type="text" />
<br />


label {
  display:inline-block; /* so we can set a width */
  width:14em; /* or whatever */
  text-align:right;
}

Simple… and why I laugh at the messes some people come up with for forms in terms of markup. Lists for no reason, tables for no reason, extra block level containers at every line for no reason… all doing the job of the existing semantic tags and a simple line-break.

No fancy margin tricks needed… at most you might want a margin-right to space them apart, and really the width on LABEL should be sufficient to handle that.

Ooops the omission was a typo, sorry. However my OP stated:

Recently, I was experimenting with a way to layout form controls WITHOUT floats or display:inline blocks. I have encountered a real challenge when attempting to create layout “columns”.

Any ideas?
( and yeahI would use a fieldset eventually… like I said am just trying to discover something new… file this under one of my philosophical posts) :slight_smile:

Despite that the spec specifically states that horizontal margins don’t collapse, input{width: 15em; margin-left:11em;} label{margin-right:-11em;} acts seems to acts ALMSOT as if canceling out both margins.

Hi d_p,

You can still drag elements on top of each other with negative margins though, which is what I am seeing with that css.

Any ideas?

I know your handy with adjacent sibling selectors, see if this is what your after

input{
    width: 15em;
    margin-left: 1em;
}
input+label {
    margin-left: 5em;
}


<div>
    <label>First Name:</label><input type="text">
    <label>Last Name:</label><input type="text">
</div>

You could also use word-spacing

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test Page</title>

<style type="text/css">
div  {
    word-spacing:5em;
}
div * {
    word-spacing:normal;
}
input {
    width: 15em;
    margin-left:1em;
}
</style>

</head>
<body>

<div>
    <label>First Name:</label><input type="text">
    <label>Last Name:</label><input type="text">
</div>

</body>
</html>

Rayzur,

thanks for looking. I had something like:


input{width: 15em; margin-left:11em;} 
label{margin-right:-11em;}

because in the markup the label will always be followed by an input the adjacent selector seems redundant.

The challenge really stems from the fact that inline elements cant have widths, but floats, APs, and inline-blocks aren’t inline elements. :confused: I thought I could use a neg. margin on the label to position it WITHIN the space crated by the left margin of the input ( assuming of course that the label text is short enough to fit). This what I meant by “columns” So, for example, assuming all inputs have a witdh of 10em, and a left margin of 15em. Then it would be like having columns of 15ems( for the label) and 10 ems ( for inputs).

Wasn’t sure if you meant display:inline or inline-block – the omission of the hyphen is why I replied “just use inline-block”

I guess my question would be WHY?!? and how… if you can’t set a width how are you going to get consistent columns? No margin tricks in the world are going to create a reliable fixed (or dynamic) width, so the minute you have more than one row of them (what columns are for) you’re not going to get them to line up.

Unless you did something strange like display:table and table-cell… Just playing with margins… what would that even accomplish? Much less facing margins with the different collapse behaviors cross browser – oh, I see… you’re trying to use the negative width collapse trick; problem with that is if you can’t set the width on the label, it won’t behave right… and the only way to set the width on the label is…

inline-block, block or float.

The reason that’s a problem? Excessively large negative margins should continue right past the element’s content. Again, if you can’t fix the width, negative margins larger than the element width are going to be unpredictable… and if you can fix the width, you don’t need them.

But… hmm… crazy idea. How about instead of playing games left/right… yeah, that could work…


fieldset {
  line-height:1.5em;
}

label {
  display:block;
  margin-bottom:-1.5em;
}

input {
  margin-left:15em;
}

Instead of trying to use facing margins, use margin-bottom to basically negate the label’s flow… means using display:block, but at least on that axis you have a predictable size… the display:block would also mean you’d not have to worry about extra white-space should you break the label and input into separate lines.

Really though I’d stick with inline-block or float BECAUSE it lets you specify a width, so should the font size change the label can wrap instead of ending up behind the input if the text becomes too big.

I’m not seeing why (apart from the theoretical) why that’s even an issue… and inline-block IS an display:inline type element… hence the word ‘inline’ in it’s name.

… and you do know that the display state has nothing to do with the elements LEVEL, right? It just sounds like you’re mixing up display:inline and inline-level, which while that may be the default appearance, it’s not what it means.

Lol, looks like we all replied again at 20:27
I mentioned using word-spacing in my last post

Because… I’ve been toying with this technique:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<title></title>
		<style type="text/css">
form {
	padding: 5px ;
	border: 3px #ccc double;
}
fieldset {
		text-align: right;
		width: 10em;/*space for label*/
		padding:.5em 15.5em .5em .5em; /*padding right= space for the input columns*/
}
input + label:before, fieldset:after {
	content: '\\D\\A';
	white-space: pre;
}
input {
	width: 15em;
	margin-right:-15em;	
}
label{ margin-right:.25em;		line-height:2;
}
input, label {font-size: 100%}
		</style>
	</head>
	<body>
<form>
	<fieldset><legend>legend txt</legend>
		<label>First field label:</label> <input>
		<label>Second field:</label> <input>
		<label>3rd field:</label> <input>
	</fieldset>
</form>
	</body>
</html>


Of course the limitation is that the padding to “houses” the INPUT. This limits the technique to one column. So I want quite satisfied with it. This is why I thought tah’t if I used a left margin on the input I could have the “appearance” of columns for the labels.

All that would do is push them apart – I think you missed what D_P is trying to do here… the negative margin on his label is to cancel out it’s width in flow, so that the margin declared on the INPUT would be flush against the left edge as if the label wasn’t even there, creating a fixed width column. Your code with the word-spacing would just push them apart and does nothing to make the ‘label’ look like it’s fixed width or allow multiple lines of different width labels to have the inputs all line up in a nice neat row. Hence the word ‘columns’.

… though at that point… how about position:absolute; and don’t set left/top/bottom/right to anything… that would pull the label from flow without moving it’s position.


label {
  position:absolute;
}

input {
  margin-left:15em;
}

Though pulling it from flow opens all sorts of nasty nasty issues…

rule of thumb I use is that if something looks too complex for it’s own good, it probably is… and if you have to resort to :before and :after just to do what a simple inline-block can do, there’s probably something wrong with the code in question… This just seems really fragile – for something that could just as easily be done with floats and clears, or inline-block.

Especially given how SIMPLE inline-block is to use.

Though another monkey-wrench thrown in the works is width on a INPUT – since all four browser engines will result in a different width element… as width:15em is NOT consistent on input across browsers AT ALL, what with IE and FF’s DIFFERENT paddings over which you have no control and oddball behavior of borders, Opera’s treating inputs EXACTLY as if they were just inline-block, and of course don’t even get me STARTED about webkit and form elements…

I mean, just try this in all four engines…

<div style=“width:15em; height:2em; background:#F00;”></div>
<input type=“text” style= style=“width:15em; height:2em;” />

… and compare how they render. Just love that CSS specification which doesn’t say EXACTLY how values should be applied to elements. People want to blame the HTML spec for that when really, that’s not HTML’s job :smiley:

Yes, I did miss the point.

And I agree, I would be using inline-block before I got involved with any unpredictable trickery

OKies. Had to give it a shot just to see if I had found something new that was worth exploring. Thanks guys for all the ‘inputs’ …:smiley: