Flex items overlapping in Chrome and IE11

I am trying to create a fixed-height flexbox layout that scrolls inside content when inside content is too large.

Also, if the content does not cause scrolling, I want to fix the div with buttons at the bottom of the container.

I have a layout that works fine in Firefox, but in Chrome it forces the bottom div button to click on top of the content when it is large enough to trigger a scroll.

This is the correct layout in Firefox:

Actual rendering of Firefox

Here's how it doesn't display correctly in Chrome:

Incorrect Chrome Rendering

In addition, this is how it should behave if there is not enough internal content to cause scrolling:

Small content rendering

.container { height: 150px; width: 300px; display: flex; flex-direction: column; overflow-y: auto; border: 1px solid #000; padding: 4px; } .options { display: flex; flex-direction: row; flex-wrap: wrap; } .spacer { flex: 1 1 auto; } .buttons { display: flex; flex-direction: row; justify-content: space-between; } 
 <div class="container"> <div class="options"> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> </div> <div class="spacer"></div> <div class="buttons"> <input type="button" value="Cancel"> <input type="button" value="Save"> </div> </div> 

https://jsfiddle.net/tdghqyuu/1/

+4
source share
3 answers

Decision

Add this to your code:

 .container > * { flex-shrink: 0; } 

Description

The initial configuration of flex items, in accordance with the flexbox specification , should be flex-shrink: 1 . This means that flexible elements are allowed to be compressed to avoid overflowing the container.

Chrome and IE11 seem to stick with this guide.

Other browsers, such as Firefox, Edge, and Safari, set flex-shrink to 0 by default.

On the other hand, this may have little or nothing to do with flex-shrink . The problem may relate to the default settings of min-height and min-width for flex items. (See Here: Why aren't flexible elements reducing the size of the content? )

Or maybe this is a combination of both. It really depends on the browser.

The fact is that browser versions vary. That is why you should test.

Spec's initial settings are not completely reliable since

  • browsers are independent objects that can do whatever they want, and
  • the use of "interventions".

Interventions

Intervention is when a user agent decides to deviate slightly from standardized behavior to provide a significantly enhanced user experience.

In other words, the browser commits itself to providing settings that, in its opinion, are best suited for its users, regardless of specifications.

Chrome seems to be doing this a lot. Here are some examples:

One thing is clear: if you disable flex-shrink , your layout will work in all browsers. Add this to your code:

 .container > * { flex-shrink: 0; } 

 .container>* { flex-shrink: 0; } .container { height: 150px; width: 300px; display: flex; flex-direction: column; overflow-y: auto; border: 1px solid #000; padding: 4px; } .options { display: flex; flex-direction: row; flex-wrap: wrap; } .buttons { display: flex; flex-direction: row; justify-content: space-between; margin-top: 10px; /* new; for demo only */ } 
 <div class="container"> <div class="options"> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> </div> <div class="buttons"> <input type="button" value="Cancel"> <input type="button" value="Save"> </div> </div> 

You can also consider moving the scroll bar only to the options window, after which you really fixed the buttons at the bottom of the screen. Make this setting in your code:

 .container { height: 150px; width: 300px; display: flex; flex-direction: column; /* overflow-y: auto; */ border: 1px solid #000; padding: 4px; } .options { display: flex; flex-direction: row; flex-wrap: wrap; overflow-y: auto; /* NEW */ flex: 1; /* NEW; may be necessary for overflow to work in some browsers */ } 

 .container > * { flex-shrink: 0; } .container { height: 150px; width: 300px; display: flex; flex-direction: column; /* overflow-y: auto; */ border: 1px solid #000; padding: 4px; } .options { display: flex; flex-direction: row; flex-wrap: wrap; overflow-y: auto; /* NEW */ flex: 1; /* NEW; may be necessary for overflow to work in some browsers */ } .buttons { display: flex; flex-direction: row; justify-content: space-between; margin-top: 10px; /* new; for demo only */ } 
 <div class="container"> <div class="options"> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> </div> <div class="buttons"> <input type="button" value="Cancel"> <input type="button" value="Save"> </div> </div> 

In addition, I deleted the spacer element that you had. This does not seem necessary when there are many clean ways to create space between elements in a flexible container.

+4
source

.container does not have to be "flex", the min-height for .options may be enough:

  .container { height: 150px; width: 300px; /*display: flex;*/ flex-direction: column; overflow-y: auto; border: 1px solid #000; padding: 4px; } .options { display: flex; flex-direction: row; flex-wrap: wrap; min-height: 125px; } .options > div { display: inline-block; } .spacer { flex: 1 1 auto; } .buttons { display: flex; flex-direction: row; justify-content: space-between; } 
 <div class="container"> <div class="options"> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> <div class="option"> <input type="checkbox"> Option </div> </div> <div class="spacer"></div> <div class="buttons"> <input type="button" value="Cancel"> <input type="button" value="Save"> </div> </div> 
0
source

This has nothing to do with flex. You see that the parameters overflow the container (the <div class="options"> element). The element itself is the correct size, but the container itself is a fixed height. If you add overflow: hidden or overflow: scroll to .options , it will display as you expect (although you may not need a scroll bar).

0
source

Source: https://habr.com/ru/post/1274747/


All Articles