Search code examples
htmlcsspositioning

Multi-line inline-block element to take remaining width but not more


I have fake checkbox to style it according to app style guide.

<label>
    <input type="checkbox" />
    <span class="fake-checkbox"></span>
    <span class="actual-label">
        ...
    </span>
</label>

I hide input and style both SPAN as inline-block. This works great as long as checkbox label is narrow enough to fit a single line. The problem becomes apparent when label text is too long to fit a single line in which line it breaks into a new line, keeping checkbox alone in the line.

If I set label { white-space: nowrap; } and .actual-label { white-space: normal; }, then checkbox and text stay on the same line, actual label text does break into multiple lines, but it has 100% content width instead of less fake checkbox.

My checkboxes must allow positioning of several in the same line or columns etc... Just like regular checkboxes do. This simply means that floats are ruled out.

Flexbox does it

I can achieve exactly what I want by using flexbox, but unfortunately I need to support older browsers without flexbox.

Question

What ways do I have to make multi-line actual label span take all the rest width and break into several lines. Things I can't use:

  • flexbox
  • floats

I've created a Plnkr example where the same control is shown twice. First in the problematic form and second the way that it should be displayed. Second control is styled using flexbox which I can't use.

label {
  display: inline-block;
  outline: 1px solid rgba(0, 0, 0, 0.25);
  white-space: nowrap;
  font-size: 0;
}
label * {
  white-space: normal;
  font-size: initial;
}
label .fake-checkbox {
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 1px solid #ccc;
  border-radius: 2px;
  margin-right: 8px;
  vertical-align: top;
  box-sizing: border-box;
}
label .fake-checkbox:before {
  content: "";
  display: inline-block;
}
label .actual-label {
  display: inline-block;
  vertical-align: top;
  outline: 1px solid rgba(0, 0, 0, 0.25);
}
section {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-content: flex-end;
  align-items: flex-start;
  outline: 1px solid rgba(0, 0, 0, 0.25);
}
section .fake-checkbox {
  flex-shrink: 0;
  flex-grow: 0;
  display: block;
  width: 18px;
  height: 18px;
  border: 1px solid #ccc;
  border-radius: 2px;
  margin-right: 8px;
  box-sizing: border-box;
}
section .actual-label {
  outline: 1px solid rgba(0, 0, 0, 0.25);
}
<label>
  <span class="fake-checkbox"></span>
  <span class="actual-label">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec in nunc porta, congue purus ut, pharetra purus. Donec vitae sem viverra, iaculis ante ac, feugiat massa. Sed vitae ultrices dui, porttitor rutrum metus. Donec feugiat porta nisi, sit amet elementum nunc interdum eu. Curabitur aliquet ipsum molestie, rutrum neque nec, tincidunt odio. Vestibulum eget malesuada lorem. Pellentesque et lobortis augue, vel hendrerit nulla. Sed augue sapien, fringilla sit amet justo id, mollis congue massa. Praesent vitae turpis ac neque tincidunt dignissim. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur consequat scelerisque nibh ac cursus.
  </span>
</label>
<br/>
<br/>
<section>
  <span class="fake-checkbox"></span>
  <span class="actual-label">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec in nunc porta, congue purus ut, pharetra purus. Donec vitae sem viverra, iaculis ante ac, feugiat massa. Sed vitae ultrices dui, porttitor rutrum metus. Donec feugiat porta nisi, sit amet elementum nunc interdum eu. Curabitur aliquet ipsum molestie, rutrum neque nec, tincidunt odio. Vestibulum eget malesuada lorem. Pellentesque et lobortis augue, vel hendrerit nulla. Sed augue sapien, fringilla sit amet justo id, mollis congue massa. Praesent vitae turpis ac neque tincidunt dignissim. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur consequat scelerisque nibh ac cursus.
  </span>
</section>


Solution

  • CSS Tables

    Support is good back to IE8

    section {
      display: table;
      outline: 1px solid rgba(0, 0, 0, 0.25);
    }
    section .fake-checkbox {
      display: table-cell;
      display: block;
      width: 18px;
      height: 18px;
      border: 1px solid #ccc;
      border-radius: 2px;
      margin-right: 8px;
      box-sizing: border-box;
    }
    section .actual-label {
      display: table-cell;
      outline: 1px solid rgba(0, 0, 0, 0.25);
    }
    <section>
      <span class="fake-checkbox"></span>
      <span class="actual-label">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec in nunc porta, congue purus ut, pharetra purus. Donec vitae sem viverra, iaculis ante ac, feugiat massa. Sed vitae ultrices dui, porttitor rutrum metus. Donec feugiat porta nisi, sit amet elementum nunc interdum eu. Curabitur aliquet ipsum molestie, rutrum neque nec, tincidunt odio. Vestibulum eget malesuada lorem. Pellentesque et lobortis augue, vel hendrerit nulla. Sed augue sapien, fringilla sit amet justo id, mollis congue massa. Praesent vitae turpis ac neque tincidunt dignissim. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur consequat scelerisque nibh ac cursus.
          </span>
    </section>