skip to Main Content

How can I split a container with many elements into just two columns, where only the first element appears in the first column and the remainder in the second?

The closest I can get is to float the first element left, but this still allows the subsequent text to flow underneath it as there appears to be no way to force the floated element’s height to become 100% of the container that might preclude this behaviour.

p > :first-child {
  width: 30px;
  height: 30px;
  float: left;
  margin-right: 1ch;
  text-indent: 100%;
  overflow: hidden;
  
  background: hotpink;
}

a {
  color: blue;
  text-decoration: underline;
}
<p>
    <a>Foobar</a>
    Lorem <a>ipsum dolor sit amet</a>, consectetur adipiscing elit. Etiam blandit erat dui, vitae condimentum augue congue non. Nam varius sem nibh, id tempor est aliquam quis. Mauris sagittis et magna a rhoncus. Integer arcu augue, hendrerit et lacinia at, aliquam in diam. Etiam venenatis quam elementum, facilisis diam nec, vestibulum sem. <a>In vitae velit tempus</a>, fermentum ligula ac, vehicula sem. Aenean tempus dui in nisi volutpat, pulvinar pulvinar augue ultricies. Proin sodales maximus metus accumsan sodales. <a>Sed malesuada leo et neque placerat</a>, non posuere mi cursus. Maecenas aliquam felis quis mattis tempor.
</p>

It seems we cannot use a column layout because columns have to be equal width. We cannot use a grid because any elements beyond the second will create implicit columns or rows beyond the desired total of two. We cannot use flex because every element, including the implicit text elements, will be treated as separate blocks and will no longer flow. We cannot use a table because that would require changing the markup.

Without changing the markup, is it possible to achieve a two-column layout as desired using only CSS? That is, there should only be space below the first element (as if it is in a column of its own), with no text flowing directly beneath it.

2

Answers


  1. Frankly the layout you require would indicate that a re-jig of the HTML is required. Whether this is done manually or with JS is another issue.

    BUT, perhaps position: absolute can assist here.

    p {
      padding-left: calc(30px + 1ch);
      position: relative;
      border: 1px solid grey;
    }
    
    p> :first-child {
      width: 30px;
      height: 30px;
      position: absolute;
      left: 0;
      margin-right: 1ch;
      text-indent: 100%;
      overflow: hidden;
      background: hotpink;
    }
    
    a {
      color: blue;
      text-decoration: underline;
    }
    <p>
      <a>Foobar</a> Lorem <a>ipsum dolor sit amet</a>, consectetur adipiscing elit. Etiam blandit erat dui, vitae condimentum augue congue non. Nam varius sem nibh, id tempor est aliquam quis. Mauris sagittis et magna a rhoncus. Integer arcu augue, hendrerit
      et lacinia at, aliquam in diam. Etiam venenatis quam elementum, facilisis diam nec, vestibulum sem. <a>In vitae velit tempus</a>, fermentum ligula ac, vehicula sem. Aenean tempus dui in nisi volutpat, pulvinar pulvinar augue ultricies. Proin sodales
      maximus metus accumsan sodales. <a>Sed malesuada leo et neque placerat</a>, non posuere mi cursus. Maecenas aliquam felis quis mattis tempor.
    </p>
    Login or Signup to reply.
  2. Negative margin can also help here

    p {
      --m: calc(30px + 1ch);
      padding-left: var(--m);
    }
    
    p > :first-child {
      width: 30px;
      height: 30px;
      float: left;
      margin-right: 1ch;
      margin-left: calc(-1*var(--m));
      text-indent: 100%;
      overflow: hidden;
      
      background: hotpink;
    }
    
    a {
      color: blue;
      text-decoration: underline;
    }
    <p>
        <a>Foobar</a>
        Lorem <a>ipsum dolor sit amet</a>, consectetur adipiscing elit. Etiam blandit erat dui, vitae condimentum augue congue non. Nam varius sem nibh, id tempor est aliquam quis. Mauris sagittis et magna a rhoncus. Integer arcu augue, hendrerit et lacinia at, aliquam in diam. Etiam venenatis quam elementum, facilisis diam nec, vestibulum sem. <a>In vitae velit tempus</a>, fermentum ligula ac, vehicula sem. Aenean tempus dui in nisi volutpat, pulvinar pulvinar augue ultricies. Proin sodales maximus metus accumsan sodales. <a>Sed malesuada leo et neque placerat</a>, non posuere mi cursus. Maecenas aliquam felis quis mattis tempor.
    </p>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search