Search code examples
htmlcsscss-grid

Prevent CSS grid contents from flowing out of the borders, and wrap to new rows instead


I'm trying to render some form data.

One form row consists of the label and the form data, each form row is presented inline as label: data.

I need to have all labels right aligned and form data left aligned. I've decided to use the CSS grid layout to achieve this with two columns, left column holding the labels and the right column holding the values.

Since both labels and form data is unknown in advance, I would like to make the label column as wide as the widest content is, and the data column to take the rest.

Additionally, the form can contain some text data, i.e. a paragraph, which should span both columns.

In other words, the general layout I need is this:

right-aligned-label: | left-aligned data
Paragraph with some random words.
        short label: | data
              label: | data too long to fit into one
                     | one column so it wraps
      another label: | data

The structure is this:

<div class="container">
  <div class="form-data-wrapper">
    <div class="form-label"><span>Label: </span></div>
    <div class="form-value"><span>Some value</span></div>
    ...
  </div>
</div>

Here's the CSS excerpt that tries to accomplish the layout:

.form-data-wrapper {
  display: grid;
  grid-template-columns: max-content 1fr;
  grid-gap: 5px;
}

.form-data-wrapper .form-value {
  min-width: 0;
  min-height: 0;
  word-wrap: break-word;
  max-width: 100%;
}

The part that doesn't work is that the data that is too long to fit the container doesn't wrap, but rather leaves the container and goes to the right infinitely, leaving the container boundaries, which is a problem because the incoming form data can come from a text area.

.container {
  width: 500px;
}

.form-data-wrapper {
  display: grid;
  grid-template-columns: max-content 1fr;
  grid-gap: 5px;
}

.form-data-wrapper .form-label {
  font-weight: bold;
  text-align: right;
}

.form-data-wrapper .form-label,
.form-data-wrapper .form-value {
  padding: 0px 2px;
  white-space: pre;
}

.form-data-wrapper .form-value {
  min-width: 0;
  min-height: 0;
  word-wrap: break-word;
  max-width: 100%;
}

.form-data-wrapper .form-value.form-field-header,
.form-data-wrapper .form-value.form-field-paragraph {
  grid-column: 1 / span 2;
  text-align: left;
  padding: 6px 2px;
}

.form-data-wrapper .form-label.form-field-paragraph {
  font-weight: normal;
}
<div class="container">
  <div class="form-data-wrapper">
    <div class="form-label form-field-checkbox-group"><span>Checkbox Group: </span></div>
    <div class="form-value"><span>Option 1, Option 2</span></div>
    <div class="form-label form-field-date"><span>Date Field: </span></div>
    <div class="form-value"><span>2021-03-10</span></div>
    <div class="form-label form-field-number"><span>Number: </span></div>
    <div class="form-value"><span>2</span></div>
    <div class="form-value form-field-paragraph"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip</span></div>
    <div class="form-label form-field-radio-group"><span>Radio Group: </span></div>
    <div class="form-value"><span>Option 2</span></div>
    <div class="form-label form-field-select"><span>Select: </span></div>
    <div class="form-value"><span>Option 3</span></div>
    <div class="form-label form-field-textarea"><span>Text Area: </span></div>
    <div class="form-value"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip</span></div>
    <div class="form-label form-field-text"><span>Text Field: </span></div>
    <div class="form-value"><span>t1</span></div>
  </div>
</div>


Solution

  • Just change the following style:

    white-space: break-spaces;   /* changed */
    

    See in the snippet:

    .container {
      width: 500px;
    }
    
    .form-data-wrapper {
      display: grid;
      grid-template-columns: max-content 1fr;
      grid-gap: 5px;
    }
    
    .form-data-wrapper .form-label {
      font-weight: bold;
      text-align: right;
    }
    
    .form-data-wrapper .form-label,
    .form-data-wrapper .form-value {
      padding: 0px 2px;
      white-space: break-spaces;   /* changed */
    }
    
    .form-data-wrapper .form-value {
      min-width: 0;
      min-height: 0;
      word-wrap: break-word;
      max-width: 100%;
    }
    
    .form-data-wrapper .form-value.form-field-header,
    .form-data-wrapper .form-value.form-field-paragraph {
      grid-column: 1 / span 2;
      text-align: left;
      padding: 6px 2px;
    }
    
    .form-data-wrapper .form-label.form-field-paragraph {
      font-weight: normal;
    }
    <div class="container">
      <div class="form-data-wrapper">
        <div class="form-label form-field-checkbox-group"><span>Checkbox Group: </span></div>
        <div class="form-value"><span>Option 1, Option 2</span></div>
        <div class="form-label form-field-date"><span>Date Field: </span></div>
        <div class="form-value"><span>2021-03-10</span></div>
        <div class="form-label form-field-number"><span>Number: </span></div>
        <div class="form-value"><span>2</span></div>
        <div class="form-value form-field-paragraph"><span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip</span></div>
        <div class="form-label form-field-radio-group"><span>Radio Group: </span></div>
        <div class="form-value"><span>Option 2</span></div>
        <div class="form-label form-field-select"><span>Select: </span></div>
        <div class="form-value"><span>Option 3</span></div>
        <div class="form-label form-field-textarea"><span>Text Area: </span></div>
        <div class="form-value">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip</div>
        <div class="form-label form-field-text"><span>Text Field: </span></div>
        <div class="form-value"><span>t1</span></div>
      </div>
    </div>