Search code examples
htmlcssalignment

How to float right only 2nd div in container and have it wrap when first div is too long


I have rows that contain both text and data.

Text box must align to the left, with text-align left. Numbers box must align to the right, with text-align right.

They should exist side by side unless the name is too long, at which point the numbers box wraps below within the row. all numbers for the row should wrap together. each name has a different length on each row.

When the numbers box wraps, the outer container must expand vertically because it has a border below it that must remain below the numbers, and the next row has a margin-top that must get pushed down.

The 2 columns of numbers for each row must align vertically for all rows.

Because there are so many rows, hundreds, it should minimize excess markup to keep rendering time low.

What I tried:

I tried using float, but float unbinds the div from the parent container, and won't cause the parent box to expand vertically when it wraps.

I tried using position with right:0px, but the numbers box won't wrap.

I tried using flex, but the numbers no longer align with the other rows because each text and numbers is a different length for each row.

HTML

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
  <br />
  <br />
  <div class="container">
    <div class="row">
      <div class="rowName">short name</div>
      <div class="rowData">
        <div>000 xx</div>
        <div>000 %</div>
      </div>
    </div>
    <div class="row">
      <div class="rowName">long name long name long name</div>
      <div class="rowData">
        <div>000 xx</div>
        <div>0 %</div>
      </div>
    </div>
  </div>
</body>
</html>

CSS

.container {
  width: 300px;
}
.row {
  width: 100%;
  margin-top: 6px;
  margin-bottom: 4px;
  padding-bottom: 2px;
  border-bottom: 1px solid #cccccc;
}

.row > div:nth-child(2) {
  text-align: right; /* has no effect */
}

.row > .rowName {
  display: inline-block;
}

.row > .rowData {
  display: inline-block;
}

.row > .rowData > div {
  display: inline-block;
  width: 50px;
  text-align: right
}

Similar questions have answers that do not solve for all requirements.

How can I achieve the 1st div (text) aligns left while the 2nd div (sets of numbers) aligns right, keeping the columns in line, wrapping when out of space, and in a way that causes its parent container to expand vertically with it wraps.


Solution

  • You didn't post any expected result so I can only guess... Is this what you want?

    .container {
      width: 300px;
    }
    
    .row {
      width: 100%;
      margin-top: 6px;
      margin-bottom: 4px;
      padding-bottom: 2px;
      border-bottom: 1px solid #cccccc;
    }
    
    
    /* fix floated children taken out of parent's size */
    
    .row::after {
      content: '';
      display: block;
      clear: both;
    }
    
    .row>.rowName {
      display: inline-block;
    }
    
    .row>.rowData {
      display: inline-block;
      float: right;
    }
    
    .row>.rowData>div {
      display: inline-block;
      width: 50px;
      text-align: right
    }
    <div class="container">
      <div class="row">
        <div class="rowName">short name</div>
        <div class="rowData">
          <div>000 xx</div>
          <div>000 %</div>
        </div>
      </div>
      <div class="row">
        <div class="rowName">long name long name long name</div>
        <div class="rowData">
          <div>000 xx</div>
          <div>0 %</div>
        </div>
      </div>
    </div>