3

I got a html with a lot of label + input

<label>Application</label>
<input id="ApplicationName" />
...
<label>Foo</label>
<input id="Foo" />
...
<label>Junk</label>
<input id="Junk" />

I force a width to add some consistency

label {
    display: inline-block;
    width: 10em;
}
input {
    width: 10em;
}

With this style it's a bit better but the flow still breaks "anywhere" depending on the width of container. How can I make the label + input to be a block ? (Without enclosing both of them in a container)

Another acceptable solution would be to
add a virtual carriage return after each input or
before each label.
I didn't succeed to put it after because the input tag doesn't support after.
Neither can I put it before because

label::before {
    content: "\A";
    white-space: pre;
}

doesn't mix well with label{display:inline-block}

label {
    display:inline-block;
    width:10em;
}

input {
    width:10em;
}
<div>
    <label>namespace</label>
    <input id="namespace" />
            
    <label>Application</label>
    <input id="application" />
            
    <label>Description</label>
    <input id="Description" />
            
    <label>Author</label>
    <input id="Author" />
</div>
resize the window to exhibit unwanted behaviour
julianstark999
  • 3,450
  • 1
  • 27
  • 41
frenchone
  • 1,547
  • 4
  • 19
  • 34

2 Answers2

2

You can use a mixture of floating and clearing, a bit old school but seems to work for the structure:

label {
  display: block;
  width: 10em;
  float: left; /* makes the element act like inline block */
  clear: left; /* clears any left floats so before so this should start on new line */
}

input {
  width: 10em;
  float: left;
}
<div>
  <label>namespace</label>
  <input id="namespace" />

  <label>Application</label>
  <input id="application" />

  <label>Description</label>
  <input id="Description" />

  <label>Author</label>
  <input id="Author" />
</div>

Or you could just give a width to your parent container to force the content onto the next line:

div {
  width: 21em;
}

label {
  display: inline-block;
  width: 10em;
}

input {
  width: 10em;
}
<div>
  <label>namespace</label>
  <input id="namespace" />

  <label>Application</label>
  <input id="application" />

  <label>Description</label>
  <input id="Description" />

  <label>Author</label>
  <input id="Author" />
</div>
Pete
  • 57,112
  • 28
  • 117
  • 166
0

Option #1, CSS-only

If you really can't edit the HTML, then you can apply white-space: pre; and content: "\a"; to the label:before. See this updated JSFiddle.

label:before {
  content: "\a";
  white-space: pre;
}
<label>Application</label>
<input id="ApplicationName" />

<label>Foo</label>
<input id="Foo" />

<label>Junk</label>
<input id="Junk" />

Option #2, HTML-only

A better solution could be to just wrap the <input>s in the <label>s (another benefit of this, is that you don't need to use the for attribute to link each label the the corresponding input!). Here's a working JSFiddle with your code snippet :)

input{
  width: 10em;
}

label{
  float: left; 
  clear: left;
}
<label>Application: <input id="ApplicationName" /></label>
        
<label>Foo: <input id="Foo" /></label>

<label>Junk: <input id="Junk" /></label>
        
Alicia Sykes
  • 5,997
  • 7
  • 36
  • 64
  • I don't think it will help : I want label to be on the left and input on the right. With this I'll get : label
    input label
    input label
    ... and I want label input
    label input
    label input
    – frenchone Nov 27 '17 at 14:27
  • Yeah. It would probably better to do it that way but I got little or no way to alter the html. – frenchone Nov 27 '17 at 15:14
  • Ah, sorry - I misunderstood you- I've updated the answer to also provide a method without changing the HTML :) Does that help? – Alicia Sykes Nov 27 '17 at 15:41
  • thank you for your jsfiddle but this doesn't adress the problem of fixed width for label. I used Pete's solution – frenchone Nov 27 '17 at 17:22