skip to Main Content

I’m trying to align a label inline with a text input and have them stay on the same line in a flex container that will change widths. If I make the container smaller, like 200px, it wraps the input. Make the container 400px width, and it doesn’t wrap. I can’t figure out why the input wraps, but if I set its width smaller to say 100px, it stops wrapping. I can’t do that. The reason I need wrapping is for the third element that needs to always wrap to the following row.

I can’t change the HTML structure.

#test {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
}

#test label {
  border-bottom: 1px solid black;
}

#test input {
  background-color: transparent;
  border: 0;
  border-bottom: 1px solid black;
  flex-grow: 1;
  line-height: 18px;
  min-width: 0;
  /* width: 100px; */
}
<div id="test">
  <label>Label text:</label><input type="text" value="Stay inline!" />
  <span>Third element to wrap to next line.</span>
</div>

4

Answers


  1. You can try CSS grid.

    #test {
      width: 200px;
      display: grid;
      grid-template-columns: max-content auto;
      grid-template-areas:
        "label input"
        "text text";
    }
    
    #test label {
      border-bottom: 1px solid black;
      grid-area: label;
    }
    
    #test input {
      background-color: transparent;
      border: 0;
      border-bottom: 1px solid black;
      line-height: 18px;
      grid-area: input;
    }
    
    #test span {
      grid-area: text;
    }
    <div id="test">
      <label>Label text:</label>
      <input type="text" value="Stay inline!" />
      <span>Third element to wrap to next line.</span>
    </div>
    Login or Signup to reply.
  2. You have 3 elements and flex wrap applies to all of them, letting all of them move around. If you want input to stay inline with label you will have to group it.

    In some point label and input will forced by size of size of #test div to stack, to avoid this and force them to overflow #test, you can apply display: flex without allowing wrap. Here is my implementation:

    #test {
      display: flex;
      flex-wrap: wrap;
      width: 200px;
    }
    
    #test label {
      border-bottom: 1px solid black;
    }
    
    #test input {
      background-color: transparent;
      border: 0;
      border-bottom: 1px solid black;
      flex-grow: 1;
      line-height: 18px;
     width: 200px;
    }
    
    .form-field{
      display:flex;
    }
    <div id="test">
     <div class="form-field"> <label>Label text:</label><input type="text" value="Stay inline!" /></div>
      <span>Third element to wrap to next line.</span>
    </div>
    Login or Signup to reply.
  3. Use display: flex as normal, but for the span, you can use flex flex: 1 1 100%;. For the input, give it a width, say width: 100px;, or less with flex-grow: 1;.

    #test {
      display: flex;
      flex-wrap: wrap;
      width: 200px;
    }
    
    #test label {
      border-bottom: 1px solid black;
    }
    
    #test input {
      background-color: transparent;
      border: 0;
      border-bottom: 1px solid black;
      flex-grow: 1;
      line-height: 18px;
      box-sizing : border-box;
      width: 100px;
    }
    #test span{
      flex : 1 1 100%;
    }
    <div id="test">
      <label>Label text:</label><input type="text" value="Stay inline!" />
      <span>Third element to wrap to next line.</span>
    </div>

    The problem with your input was that it has a fixed width by default, so you need to set a smaller width to it.

    Login or Signup to reply.
  4. I found a non-grid solution: You can set width: 0 for input while keeping its flex-grow: 1. To make the third element wrap, set a flex-basis of 100% for it and prevent it from shrinking/growing.

    #test input {
      width: 0;
    }
    
    #test span {
      flex: 0 0 100%;
    }
    

    Do note that this won’t work if #test‘s width is smaller than that of label.

    Try it:

    #test input {
      width: 0;
    }
    
    #test span {
      flex: 0 0 100%;
    }
    
    /* Original styles */
    
    #test {
      display: flex;
      flex-wrap: wrap;
      width: 200px;
    }
    
    #test label {
      border-bottom: 1px solid black;
    }
    
    #test input {
      background-color: transparent;
      border: 0;
      border-bottom: 1px solid black;
      flex-grow: 1;
      line-height: 18px;
    }
    <div id="test">
      <label>Label text:</label>
      <input type="text" value="Stay inline!" />
      <span>Third element to wrap to next line.</span>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search