Make items equal to widest column and center

Viewed 89

I have two cells side by side.

The cells are bounded by an inner container and that container is bound by an outer container.

The idea is for the two cells to be equal width, even though their content isn't.

The width of each cell must be the width of the widest element.

The inner container will then be centered (width should be twice the widest cell).

At the moment I have two results:

  1. They are the same width but extend to half the available page width.
  2. The inner container shrinks to the center but the cells are uneven in width.

Is it possible to achieve what I want without javascript?

body {
  background-color: lime;
}
.container {
  margin: 20px;
}

.fb {
    display: flex;
    justify-content: center;
}
.fb-container {
    display: flex;
    align-items: center;
    flex: 1;
    /* flex: 0; */
    
    background-color: #fff;
    border: solid 0.1rem rgba(0,0,0,.12);
}
.fb-item {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;

    color: rgba(0,0,0, .87);
    font-size: 14px;    height: 46px;
    padding: 0 16px;
}

.fb-item:not(:first-child) {
    border-left: solid 1px rgba(0,0,0,.12);
}
<div class="container">
    <div class="fb">
        <div class="fb-container">
            <div class="fb-item">
                <span class="fb_label">Much longer</span>
            </div>
            <div class="fb-item">
                <span class="fb_label">Short</span>
            </div>
        </div>
    </div>
</div>

3 Answers

This is more suitable for CSS grid. You can keep the flexbox for centring.

body {
  background-color: lime;
}

.container {
  margin: 20px;
}

.fb {
  display: flex;
  justify-content: center;
}

.fb-container {
  display: grid; /* Added this */
  align-items: center;
  grid-template-columns: 1fr 1fr; /* Added this */
  /* to replace the middle border*/
  grid-gap:1px;
  background:#e6e6e6 padding-box;
  /* */
  border: solid 0.1rem #e6e6e6;
}

.fb-item {
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(0, 0, 0, .87);
  font-size: 14px;
  height: 46px;
  padding: 0 16px;
  background-color: #fff;
}
<div class="container">
  <div class="fb">
    <div class="fb-container">
      <div class="fb-item">
        <span class="fb_label">Much loooooonger</span>
      </div>
      <div class="fb-item">
        <span class="fb_label">Short</span>
      </div>
    </div>
  </div>
</div>

Or a hacky idea with flexbox that I don't recommend:

body {
  background-color: lime;
}

.container {
  margin: 20px;
}

.fb {
  display: flex;
  justify-content: center;
}

.fb-container {
  display: flex;
  flex-direction:column; /* This will make them both equal */
  transform:translateX(-50%); /* Hack */
}

.fb-item {
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(0, 0, 0, .87);
  font-size: 14px;
  height: 46px;
  padding: 0 16px;
  background:#fff;
  border: solid 0.1rem rgba(0,0,0,.12);
}
.fb-item:not(:first-child) {
  border-left: none;
  transform:translateY(-100%) translateX(100%);  /* Hack */
}
<div class="container">
  <div class="fb">
    <div class="fb-container">
      <div class="fb-item">
        <span class="fb_label">Much loooooooonger</span>
      </div>
      <div class="fb-item">
        <span class="fb_label">Short</span>
      </div>
    </div>
  </div>
</div>

You can make the items the same size but not conditionally sized with css, just set the width to 0 so that flex listens to the grow rather than the text.

div {
  display:flex;
}

div div {
  flex-grow:1;
  border :1px solid black;
  width:0;
}

https://codepen.io/logan-murphy/pen/ewyqQG

It also looks to me like a typical table-layout (via display:table) without any hack and should be avalaible down to IE8:

table-layout see https://developer.mozilla.org/en-US/docs/Web/CSS/table-layout

auto

By default, most browsers use an automatic table layout algorithm. The widths of the table and its cells are adjusted to fit the content.

fixed

Table and column widths are set by the widths of table and col elements or by the width of the first row of cells. Cells in subsequent rows do not affect column widths.

Under the "fixed" layout method, the entire table can be rendered once the first table row has been downloaded and analyzed. This can speed up rendering time over the "automatic" layout method, but subsequent cell content might not fit in the column widths provided. Cells use the overflow property to determine whether to clip any overflowing content, but only if the table has a known width; otherwise, they won't overflow the cells.

DEMO :

body {
  background-color: lime;
}

.container {
  margin: 20px;
}

.fb {/* can be removed  
  display: flex;
  justify-content: center;
  */
}

.fb-container {
  display:table;
  table-layout: fixed;/* reset table-layout */
  margin:auto;
  background-color: #fff;
  border: solid 0.1rem rgba(0, 0, 0, .12);
}

.fb-item {
  display: table-cell;
  color: rgba(0, 0, 0, .87);
  width: 50%;/* make cols same width , adjust to numbers of ccols */
  vertical-align: middle;
  font-size: 14px;
  height: 46px;
  padding: 0 16px;
}

.fb-item:not(:first-child) {
  border-left: solid 1px rgba(0, 0, 0, .12);
}
<div class="container">
  <div class="fb">
    <div class="fb-container">
      <div class="fb-item">
        <span class="fb_label">Much longer</span>
      </div>
      <div class="fb-item">
        <span class="fb_label">Short</span>
      </div>
    </div>
  </div>
</div>

<div class="container">
  <div class="fb">
    <div class="fb-container">
      <div class="fb-item">
        <span class="fb_label">Much much longer</span>
      </div>
      <div class="fb-item">
        <span class="fb_label">Short</span>
      </div>
    </div>
  </div>
</div>

Related