I'm trying to figure out if it's possible, with flex, to have a div grow to the available space but up to the space available considering other non shrinkable siblings, and not more, even though its content is larger. The typical use case is a list item with user information: a rectangle with a flex row containing an avatar, user info and actions at the end of the row.
The problem comes when the user info contains a div with a very long username with no spaces: ideally I'd like to ellipsify it, but in order to achieve this I need the parent to have a fixed width. The parent here doesn't have a fixed width but flex-grow, which means it grows at least until it takes the remaining space but possibly more if the content is larger. And without word-break: break-all, the content is actually larger.
So I can't figure out how to break this vicious circle. Can anyone help?
Before flex I would use width: calc(100% - avatarWidth - actionsWidth)
, but actions width isn't fixed...
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.row {
display: flex;
width: 300px;
padding: 1rem;
background-color: green;
}
.avatar {
flex: 0 0 auto;
width: 40px;
height: 40px;
background-color: orange;
margin-right: 1rem;
}
.user-info {
flex: 1 1 auto;
background-color: dodgerblue;
}
.ellipsify {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.actions {
flex: 0 0 auto;
width: auto;
background-color: red;
margin-left: 1rem;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="row">
<div class="avatar">img</div>
<div class="user-info">Normal username</div>
<div class="actions">remove</div>
</div>
<div class="row">
<div class="avatar">img</div>
<div class="user-info">Long username with spaces so that it can wrap</div>
<div class="actions">remove</div>
</div>
<div class="row">
<div class="avatar">img</div>
<div class="user-info ellipsify">
Verylongusernameinashortrectangle
</div>
<div class="actions">remove</div>
</div>
<div class="row">
<div class="avatar">img</div>
<div class="user-info">
<p class="ellipsify">Verylongusernameinashortrectangle</p>
</div>
<div class="actions">remove</div>
</div>
</body>
</html>
EDIT: my snippet was imprecise. The problem comes when the div that grows contains an element with a greater width than it can fit, and ellipsifying that element doesn't work (in the snippet see the 4th row, it's the p element). If the growing div itself only contained text there would be no issue, but usually the user info contain a main line with the username and another line with additional info (last login, other stuff...).