1

In this snippet

 <div style='display: flex; border: 1px solid red;'>
         <div style=' flex: 1'>test</div>
         <div
            style='flex: 1; overflow: auto; white-space:nowrap'
            >
            valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk ghjkghjkf ghfjkd hgjkfgh fjk ghfjkd hfjkd ghfjkd hfjkd hfjkdg hfjk hfjkd ghfdjk hgha skjd hjkah jdkshad hdsa jkhsajk sjkd hsajkdh sajkdh asjkd hasjkd hsjakdh sajkd hsajk d
         </div>
</div>

Regardless of the size of the text the scrollbar for the last div starts at 50% of width of screen.

In this example (just put above code inside a display:flex div):

<div style='display: flex'>
       <div style='display: flex; border: 1px solid blue;'>
         <div style=' flex: 1'>test</div>
         <div
            style='flex: 1; overflow: auto; white-space:nowrap'
            >
            valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk ghjkghjkf ghfjkd hgjkfgh fjk ghfjkd hfjkd ghfjkd hfjkd hfjkdg hfjk hfjkd ghfdjk hgha skjd hjkah jdkshad hdsa jkhsajk sjkd hsajkdh sajkdh asjkd hasjkd hsjakdh sajkd hsajk d
         </div>
      </div>
</div>

the scrollbar starts at a different position (actually depending on width of text, the scrollbar starts at different position).

I know this question is related to this, that flex container has min width, but my question is not about that exactly.

My question is in the second snippet why is the scrollbar positioned where it is? and why not earlier, or later? If you experiment and put text of varying width inside it, you will see scrollbar starts at different position (also its width changes).

Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90
  • The first code snippet doesn't show a horizontal scroll bar. In the second snippet, I do notice the width of the scroll bar changes. But I'm not seeing it's position change, even when adding more text to the container, it still starts at the left under the "test" text. – Tanner Dolby Feb 17 '21 at 06:46
  • 1
    @TannerDolby You are referring to a different scrollbar, I am referring to the scrollbar of the last div. – Giorgi Moniava Feb 17 '21 at 06:48
  • This is how flexibility works. This is because you set `overflow: auto` and `flex: 1` for a **child-child**. So you get this result. (I'm sorry for my bad english) – s.kuznetsov Feb 17 '21 at 06:50
  • @s.kuznetsov Yes, but I am looking for explanation, *how* is the calculation of the scrollbar width done in this case? Why does the width of scrollbar for last div change, depending on text width? – Giorgi Moniava Feb 17 '21 at 06:51
  • @gmoniava I see what your referring to now with the scroll bar for the nested flex container. Thanks for the clarification. – Tanner Dolby Feb 17 '21 at 06:53
  • @TannerDolby do you also find it odd? – Giorgi Moniava Feb 17 '21 at 06:59
  • Yeah I do find it a bit odd as well. – Tanner Dolby Feb 17 '21 at 07:05

1 Answers1

2

Here is an illustration to better understand:

without flex:1
<div style='display: flex'>
  <div style='display: flex; border: 1px solid blue;'>
    <div style='/* flex: 1*/'>test</div>
    <div style='/*flex: 1;*/ overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
</div>
adding flex:1
<div style='display: flex'>
  <div style='display: flex; border: 1px solid blue;'>
    <div style=' flex: 1'>test</div>
    <div style='flex: 1; overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
</div>
<hr>
without flex:1
<div style='display: flex'>
  <div style='display: flex; border: 1px solid blue;'>
    <div style='/* flex: 1*/'>test</div>
    <div style='/*flex: 1;*/ overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
</div>
adding flex:1
<div style='display: flex'>
  <div style='display: flex; border: 1px solid blue;'>
    <div style=' flex: 1'>test</div>
    <div style='flex: 1; overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
</div>

Note how in both cases, the width of the inner container (the flex item) is the same defined by the width of both text. Then the flex:1 will use that reference and will split that width equally between both item.

In other words, the width is defined by the content side by side (this may give you an overflow). That width is later used as a reference for the flex:1. Adding flex:1 will not change that width, it will simply divide it equally between both items


It's different from the first snippet because in your first example you are dealing with a flexbox container (a block element) and a width of block element is defined as full width of the containing block (the parent element) and it doesn't depend on the content inside.

Here is another example width an inline-flex container

<p>without flex:1</p>
  <div style='display: inline-flex; border: 1px solid blue;'>
    <div style='/* flex: 1*/'>test</div>
    <div style='/*flex: 1;*/ overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
<p>adding flex:1</p>
  <div style='display: inline-flex; border: 1px solid blue;'>
    <div style=' flex: 1'>test</div>
    <div style='flex: 1; overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
  <hr>
<p>without flex:1</p>
  <div style='display: inline-flex; border: 1px solid blue;'>
    <div style='/* flex: 1*/'>test</div>
    <div style='/*flex: 1;*/ overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
<p>adding flex:1</p>
  <div style='display: inline-flex; border: 1px solid blue;'>
    <div style=' flex: 1'>test</div>
    <div style='flex: 1; overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>

And if we use float combined with flex:

p {
 clear:both;
}
<p>without flex:1</p>
  <div style='display:flex; float:left; border: 1px solid blue;'>
    <div style='/* flex: 1*/'>test</div>
    <div style='/*flex: 1;*/ overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
<p>adding flex:1</p>
  <div style='display:flex; float:left; border: 1px solid blue;'>
    <div style=' flex: 1'>test</div>
    <div style='flex: 1; overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
    <hr>
<p>without flex:1</p>
  <div style='display:flex; float:left; border: 1px solid blue;'>
    <div style='/* flex: 1*/'>test</div>
    <div style='/*flex: 1;*/ overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>
<p>adding flex:1</p>
  <div style='display:flex; float:left; border: 1px solid blue;'>
    <div style=' flex: 1'>test</div>
    <div style='flex: 1; overflow: auto; white-space:nowrap'>
      valuedfg dfjg hjfkdhkjg hkjghdfjk gfjkd hfjkgh dfjk hkjghdfjk gfjkd hfjkgh dfjk
    </div>
  </div>

To use easy words: some elements have their width defined based on their parent (most block element) while other have their width defined based on their content (inline-block, float, position:absolute, flex item, etc). In each case, the result is different.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415