SjSorc
SjSorc

Reputation: 59

Flex shrink in nested containers

I am trying to mimic a nav bar with flex box where i have 2 sets of items - nav-left aligned to the left and nav-right aligned to the right. Each item has 50px width.

nav-right should take the width of the children. nav-left should take up the rest of the space.

https://jsbin.com/xanaxaruxo/edit?html,css,output

nav bar

.nav-group {
  display: flex;
  flex-direction: row;
  border: 2px solid;
  padding: 2px;
}

.nav-group-left {
  border-color: turquoise;
  flex: 1 1 auto;
}

.nav-group-right {
  border-color: lime;
  flex: 0 1 auto;
}

My expectation is this -

The nav-left container should take the available space but when i shrink, this space should shrink first but when total is more than the container- all the elements should shrink together.

I have put flex: 1 1 auto - but the elements are overflowing the container; (2nd bar)

But it works when the flex containers are not nested.

https://jsbin.com/bapaqecabe/edit?html,css,output

My question is why does not shrink work with nested flex containers.

Upvotes: 0

Views: 455

Answers (2)

John
John

Reputation: 13720

An explicit width will override flex-grow and flex-shrink. For flex-grow and flex-shrink to work their direct parent must be set to display: flex;. Their widths will be rendered relative to the width of their content.

<div style="display: flex;">
<div style="flex-grow: 1;"><p>Div should use up remaining space.</p></div>
<div style="flex-shrink: 1;"><p>Div should shrink to minimal space.</div>
</div>

Use flex-grow when you have an element (typically display: inline;) to use up the rest of the space (e.g. an input that you use for meta descriptions).

Use flex-shrink for elements (typically display: block;) that you do not want using up more than it's equal share of space.

Upvotes: 0

eMontielG
eMontielG

Reputation: 416

It doesn't work when the items are nested because they have a defined width. Their parents have flex basis of auto and shrink set to true, they do what they're supposed to, but their children will expand them regardless.

If you require your navigation items to have a static width, one solution I see being used a lot is to have them show as a list on smaller devices.

If you're fine with them shrinking a bit, you could make them flexible, set their basis to 50px, and modify both containers to grow, but the left one more than the right one, say 3 to 1.

.nav-group-left {
  border-color: turquoise;
  flex: 3 1 auto;
}

.nav-group-right {
  border-color: lime;
  flex: 1 1 auto;
}

.item {
  border: 3px solid;

  display: flex;
  flex-basis: 50px;
}

Example

Upvotes: 1

Related Questions