0

I'm adding a toolbar to an application with multiple levels of flex elements.

 <div class="toolbar">
   <div class="button">Button1</div>
   <div class="button">Button2</div>
   <div class="button">Button3</div>
   ...
 </div>

It's gonna take up the whole width of the parent and use horizontal scrolling on overflow.

.toolbar {
  display: flex;
  flex-direction: row;
  overflow: scroll;
  width: 100%;
}

This works swimmingly in an empty document. However, because the application itself uses display: flex, toolbar's width: 100% becomes the width of the whole document, not the width of its immediate parent. width: 100% affects the outside flex layout! But having a fixed width, e.g. width: 300px works perfectly fine.

A demo: https://jsfiddle.net/6s23o7Lf/

Basically, I'm trying to get this: enter image description here

But get this instead: enter image description here

Is there a way to say that a flex item should take up all of the parent's width (all of its space along the secondary axis) without affecting its layout? Like align-items: stretch, but also cut off contents on overflow.

I tried making toolbar not a flex element (using display: block on it and display: inline-block on the buttons, with white-space: nowrap and all that jazz), but the width still comes from up the DOM tree.

For context, my end goal is similar to what you see at the bottom of an Excel document (left/right arrows are used for scrolling there):

enter image description here


[Edit] Note that this is quite different from this question, because it involves nested flex elements with don't have fixed sizes.

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181

3 Answers3

1

There's a quick fix for this. Add min-width: 50%; to .section:

.section {
  width: 100%;
  min-width: 50%;
}

This will prevent either section from shrinking to less than half the width but allow them to grow to fill the full width.

NOTE: This is a simple fix that may not work if there are more sections!

UPDATE:

For more columns don't use the min-width property as shown above.

You should instead add overflow: hidden; to .section to prevent their children from forcing the width to increase.

phuzi
  • 12,078
  • 3
  • 26
  • 50
  • Makes sense, thanks! As you say, this is tricky to make work in a more complex application, unfortunately... – Nikita Rybak May 04 '23 at 09:59
  • @NikitaRybak Added an update that will take care of more `.sections`. – phuzi May 04 '23 at 10:08
  • Wow, `overflow: hidden` did it... I'd love to understand flexbox logic in this case, but it does solve the example in the question! – Nikita Rybak May 04 '23 at 12:11
  • I had to use other workarounds in my actual application (`overflow: hidden` did not do it, unfortunately) and ended up 'fixing' the issue with `width: 100%` on some of the parent classes. `width: 100vw` also worked quite well. Mentioning in case somebody else is looking for a solution. – Nikita Rybak May 04 '23 at 12:13
  • A similar-but-different solution with `min-width: 0` https://css-tricks.com/flexbox-truncated-text/ – Nikita Rybak May 04 '23 at 12:14
0

edited from previous version this version only use grid. Grid is really to structure the page, or an element in a page. Flex is ok to align element inside 1.

Here you have a grid with the external structure of 2 sections. second section is a grid (nested grid). And tool bar is a nested of the nested.

.everything {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: 1fr;
  height: 200px;
  width: 100%;
}

.section {
  border: 1px solid black;
}

.section:nth-child(2) {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: repeat(2, 1fr);
}

.toolbar {
  display: grid;
  grid-template-columns: repeat(14, 1fr);
  grid-template-rows: auto;
  background-color: lightblue;
  overflow: scroll;
  align-self: end;
}

.toolbar .button {
  padding: 5px;
  cursor: pointer;
}

.toolbar .button:hover {
  background-color: lightgreen;
}
<div class="everything">
  <div class="section">
    <div class="title">
      Section A
    </div>
  </div>

  <div class="section">
    <div class="title">
      Section B
    </div>
    <div class="toolbar">
      <div class="button">Button1</div>
      <div class="button">Button2</div>
      <div class="button">Button3</div>
      <div class="button">Button4</div>
      <div class="button">Button5</div>
      <div class="button">Button6</div>
      <div class="button">Button7</div>
      <div class="button">Button8</div>
      <div class="button">Button9</div>
      <div class="button">Button10</div>
      <div class="button">Button11</div>
      <div class="button">Button12</div>
      <div class="button">Button13</div>
      <div class="button">Button14</div>
    </div>
  </div>
</div>
pier farrugia
  • 1,520
  • 2
  • 2
  • 9
0

the css of section has "width: 100%", your sectionA and section B all have the section class. The sectionA's parent is div of class everything, the sectionB's parent also is div of class everything. It is same to "width: auto".

If you want get right, you can replace the css section class of this:

.section {
  border: 1px solid black;
  width: 50%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
stul
  • 1
  • 2
  • Thanks stul. When I use this code, I still see "Section B" take nearly whole width while "Section A" is squeezed into a tiny space. Does it look different to you? – Nikita Rybak May 04 '23 at 09:43
  • @NikitaRybak the code of before is a error. I have updated the code, and you can try again。 – stul May 04 '23 at 09:47
  • I see, thanks! Unfortunately, there are more elements in the application (such as a sidebar, as well as borders/margins/padding), so I cannot specify exact width of the container... – Nikita Rybak May 04 '23 at 09:55
  • you can fix the width of the sectionA, and do not set "section" class to sectionB' container . And the section B will fill whole left width – stul May 04 '23 at 10:09