Yami Odymel
Yami Odymel

Reputation: 1898

Flexbox child element expands the parent when it didn't reach the edge of the parent

I'm making a chat bubble with flexbox, and there're three child elements in the container (avatar, content, meta).


what I expected.

The avatar, content elements share the same row, and the meta element owns a row.

enter image description here

The container should fits the content.

enter image description here


what actually happened.

The container expands based on the width of the text of the meta element even if the text hasn't reached the edge of the container.

enter image description here


demo

Here's the code. Is it possible to prevent the container expands when the text of the meta element hasn't reached the edge of the container? (without adding any wrappers or changing the flex-direction)

.chat {
  display       : flex;
  flex-wrap     : wrap;
  flex-direction: row;
  width         : max-content;
  background    : black;
}

.chat .avatar {
  width     : 32px;
  height    : 32px;
  background: blue;
}

.chat .content {
  height    : 32px;
  background: yellow;
}

.chat .meta {
  width     : 100%;
  background: red;
}
<div class="chat">
  <div class="avatar"></div>
  <div class="content">
    This is a chat.
  </div>
  <div class="meta">
    10:31 AM
  </div>
</div>

Upvotes: 3

Views: 319

Answers (3)

vals
vals

Reputation: 64164

This can be achieved easily with display : grid

I am not sure if you want the black background to show. But it can be changed with a single line change (commented in the snippet)

.chat {
  display       : inline-grid;
  background    : black;
  grid-template-columns: auto 1fr;
}

.chat .avatar {
  width     : 32px;
  height    : 32px;
  background: blue;
  grid-row: 1;
}

.chat .content {
  height    : 32px;
  background: yellow;
  grid-row: 1;
  justify-self: start; /* comment this line to make it expand */
}

.chat .meta {
  width     : 100%;
  background: red;
  grid-column: span 2;
}
<div class="chat">
  <div class="avatar"></div>
  <div class="content">
    This is a chat.
  </div>
  <div class="meta">
    10:31 AM
  </div>
</div>
<div class="chat">
  <div class="avatar"></div>
  <div class="content">
    This is a chat.
  </div>
  <div class="meta">
    10:31 AM 10:31 AM 10:31 AM
  </div>
</div>

Upvotes: 1

Mattia Astorino
Mattia Astorino

Reputation: 1576

If you want the yellow content to fill the space, just add flex-grow: 1; to it. You can avoid the container expansion by adding display: inline-flex; to it.

.chat {
  display       : inline-flex;
  flex-wrap     : wrap;
  flex-direction: row;
  width         : max-content;
  background    : black;
}

.chat .avatar {
  width     : 32px;
  height    : 32px;
  background: blue;
}

.chat .content {
  height    : 32px;
  background: yellow;
  flex-grow: 1;
}

.chat .meta {
  width     : 100%;
  background: red;
}
<div class="chat">
  <div class="avatar"></div>
  <div class="content">
    This is a chat.
  </div>
  <div class="meta">
    10:31 AM
  </div>
</div>

Upvotes: 1

Blazemonger
Blazemonger

Reputation: 92893

Instead of assigning a width to flexbox elements, use flex or flex-basis.

.chat {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  width: max-content;
  background: black;
}

.chat .avatar {
  flex: 0 0 32px;
  height: 32px;
  background: blue;
}

.chat .content {
  flex: 1 0 auto;
  height: 32px;
  background: yellow;
}

.chat .meta {
  flex: 0 0 100%;
  background: red;
}
<div class="chat">
  <div class="avatar"></div>
  <div class="content">
    This is a chat.
  </div>
  <div class="meta">
    10:31 AM
  </div>
</div>

Upvotes: 3

Related Questions