skip to Main Content

We currently have an input that we want to align baseline to the content around it. The label wrappers the input and for the most part everything aligns correctly. However we have been wanting to pull the input outside the label, but this seems to be throwing the layout off.

This snippet demonstrates the issue and possible solutions. However, I want to know is there a better option? Or a way to get the label to be ignored by the baseline layout?

<h1>Original <span style="font-size: 14px;">(input within label)</span></h1>
<div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
  <div>Test value</div>
  <div>
    <label for="myInput" style="display: inline-block;">
      <div>My label</div>
      <input id="myInput" placeholder="test" />
    </label>
  </div>
  <button>My Button</button>
</div>

<h1>Problem <span style="font-size: 14px;">(splitting label and input breaks layout)</span></h1>
<div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
  <div>Test value</div>
  <div>
    <label for="myInput" style="display: block;">My label</label>
    <input id="myInput" placeholder="test" />
  </div>
  <button>My Button</button>
</div>

<h1>Option 1 <span style="font-size: 14px;">(absolute position the label)</span></h1>
<div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
  <div>Test value</div>
  <div style="position: relative;">
    <label for="myInput" style="position: absolute;">My label</label>
    <input id="myInput" placeholder="test" style="margin-top: 1rem"/>
  </div>
  <button>My Button</button>
</div>

<h1>Option 2 <span style="font-size: 14px;">(float label, but label is outside container)</span></h1>
<div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
  <div>Test value</div>
  <div>
    <label for="myInput" style="position: absolute; transform: translateY(-1rem);">My label</label>
    <input id="myInput" placeholder="test"/>
  </div>
  <button>My Button</button>
</div>

2

Answers


  1. Yes, there is a better option: a grid. Grids support align-items: baseline, which will achieve the layout you want.

    body, input, button {
      font-family: sans-serif;
      font-size: 16px;
    }
    
    .d1 {
      display: inline-grid;
      grid-template-columns: auto auto auto;
      align-items: baseline;
      gap: 5px 1em;
    }
    
    .d2 {
      grid-row: 2;
    }
    
    .d3 {
      display: contents;
    }
    
    .d3>label {
      grid-column: 2;
    }
    
    .d3>input {
      grid-column: 2;
      grid-row: 2;
    }
    
    .d1>button {
      grid-column: 3;
      grid-row: 2;
    }
    <div class="d1">
      <div class="d2">Test value</div>
      <div class="d3">
        <label for="myInput" style="display: block;">My label</label>
        <input id="myInput" placeholder="test" />
      </div>
      <button>My Button</button>
    </div>
    Login or Signup to reply.
  2. Instead of "baseline", use "last baseline"

    <h1>Original <span style="font-size: 14px;">(input within label)</span></h1>
    <div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
      <div>Test value</div>
      <div>
        <label for="myInput" style="display: inline-block;">
          <div>My label</div>
          <input id="myInput" placeholder="test" />
        </label>
      </div>
      <button>My Button</button>
    </div>
    
    <h1>Problem <span style="font-size: 14px;">(splitting label and input breaks layout)</span></h1>
    <div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
      <div>Test value</div>
      <div>
        <label for="myInput" style="display: block;">My label</label>
        <input id="myInput" placeholder="test" />
      </div>
      <button>My Button</button>
    </div>
    
    <h1>Option 1 <span style="font-size: 14px;">(absolute position the label)</span></h1>
    <div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
      <div>Test value</div>
      <div style="position: relative;">
        <label for="myInput" style="position: absolute;">My label</label>
        <input id="myInput" placeholder="test" style="margin-top: 1rem"/>
      </div>
      <button>My Button</button>
    </div>
    
    <h1>Option 2 <span style="font-size: 14px;">(float label, but label is outside container)</span></h1>
    <div style="display: flex; flex-direction: row; align-items: baseline; gap: 8px;">
      <div>Test value</div>
      <div>
        <label for="myInput" style="position: absolute; transform: translateY(-1rem);">My label</label>
        <input id="myInput" placeholder="test"/>
      </div>
      <button>My Button</button>
    </div>
    
    <h1>Last baseline <span style="font-size: 14px;">(splitting label and input)</span></h1>
    <div style="display: flex; flex-direction: row; align-items: last baseline; gap: 8px;">
      <div>Test value</div>
      <div>
        <label for="myInput" style="display: block;">My label</label>
        <input id="myInput" placeholder="test" />
      </div>
      <button>My Button</button>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search