Search code examples
htmlcssjsxcss-grid

Stack checkboxes to the right column and label to the left using CSS grid


I'm having trouble getting the checkboxes to stack properly on top of each other in their own grid column. I'm using ReactQL (jsx) so I don't think it will show up properly in the code-snippet editor. Floats aren't useful here.

/* checkboxes */

.section__checkboxes {
  display: grid;
  grid-template-columns: 2fr 4fr;
  grid-column-gap: 2em;
}

.description {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}

.checkbox {
  grid-column: 2 / 2;
  grid-row: 2 / 3;
}

.choice {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div className={cn (css.section__checkboxes, css.section_wrapper)}>
  <label className={css.description} htmlFor="checkbox_2">email notifications</label>

  <input id="checkbox_2_1" name="checkbox_2_1" className={css.checkbox} type="checkbox" value="1" />
  <label className={css.choice} htmlFor="checkbox_2_1">new direct messages</label>
  <input id="checkbox_2_2" name="checkbox_2_2" className={css.checkbox} type="checkbox" value="1" />
  <label className={css.choice} htmlFor="checkbox_2_2">new user signups</label>
  <input id="checkbox_2_3" name="checkbox_2_3" className={css.checkbox} type="checkbox" value="1" />
  <label className={css.choice} htmlFor="checkbox_2_3">new uploads</label>
</div>

enter image description here


Solution

  • You can use grid-row: span 3 for the description to span the rows in the left. If you want to preserve the current markup, you can and add grid-template-columns: 1fr auto 2fr. See demo below:

    .section__checkboxes {
      display: grid;
      grid-template-columns: 1fr auto 2fr;
      grid-column-gap: 2em;
    }
    
    .description {
      grid-row: span 3;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div class="section__checkboxes section_wrapper">
      <label class="description" for="checkbox_2">email notifications</label>
      <input id="checkbox_2_1" name="checkbox_2_1" class="checkbox" type="checkbox" value="1" />
      <label class="choice" for="checkbox_2_1">new direct messages</label>
      <input id="checkbox_2_2" name="checkbox_2_2" class="checkbox" type="checkbox" value="1" />
      <label class="choice" for="checkbox_2_2">new user signups</label>
      <input id="checkbox_2_3" name="checkbox_2_3" class="checkbox" type="checkbox" value="1" />
      <label class="choice" for="checkbox_2_3">new uploads</label>
    </div>

    If you'd change your markup and wrap the label and checkboxes together, you can do it like this:

    .section__checkboxes {
      display: grid;
      grid-template-columns: 1fr 2fr;
      grid-column-gap: 2em;
    }
    
    .description {
      grid-row: span 3;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div class="section__checkboxes section_wrapper">
      <label class="description" for="checkbox_2">email notifications</label>
      <div>
        <input id="checkbox_2_1" name="checkbox_2_1" class="checkbox" type="checkbox" value="1" />
        <label class="choice" for="checkbox_2_1">new direct messages</label>
      </div>
      <div>
        <input id="checkbox_2_2" name="checkbox_2_2" class="checkbox" type="checkbox" value="1" />
        <label class="choice" for="checkbox_2_2">new user signups</label>
      </div>
      <div>
        <input id="checkbox_2_3" name="checkbox_2_3" class="checkbox" type="checkbox" value="1" />
        <label class="choice" for="checkbox_2_3">new uploads</label>
      </div>
    </div>