23

I'm getting stuck on a test project using flexbox. The goal is to build a dashboard with some lists of cards inside, side-by-side with infinite overflowing.

I managed to do just that, the problem is: each one those lists have a header, a card list and a footer inside, and the lists height can't exceed the parent available height. If that happen, the list must only apply overflow on the card list.

On chrome it works just fine, but on firefox... It seems the renderer can't handle the possibility of the content overflowing that way! I'm getting really mad with this one.

Example:

The code (also on Plunker)

// Code goes here
(function (angular) {
  angular.module("app", []);  
  
  angular.module("app").controller("AppController", AppController);
  
  AppController.$inject = ["$scope"];
  
  function AppController($scope) {
    var ctrl = this;
    ctrl.addCard = function (list) {
      list.cards.push({title: "Card " + (list.cards.length + 1)});
    };
    ctrl.lists = [
      {
        title: "List 1",
        cards: [
          {title: "Card 1"},
          {title: "Card 2"},
          {title: "Card 3"},
          {title: "Card 4"},
          {title: "Card 5"}
        ]
      },
      {
        title: "List 2",
        cards: [
          {title: "Card 1"},
          {title: "Card 2"},
          {title: "Card 3"},
          {title: "Card 4"},
          {title: "Card 5"},
          {title: "Card 6"},
          {title: "Card 7"},
          {title: "Card 8"},
          {title: "Card 9"},
          {title: "Card 10"},
          {title: "Card 11"},
          {title: "Card 12"},
          {title: "Card 13"},
          {title: "Card 14"},
          {title: "Card 15"},
          {title: "Card 16"},
          {title: "Card 17"},
          {title: "Card 18"},
          {title: "Card 19"},
          {title: "Card 20"}
        ]
      },
      {
        title: "List 3",
        cards: [
          {title: "Card 1"},
          {title: "Card 2"},
          {title: "Card 3"},
          {title: "Card 4"},
          {title: "Card 5"}
        ]
      },
      {
        title: "List 4",
        cards: [
          {title: "Card 1"},
          {title: "Card 2"},
          {title: "Card 3"},
          {title: "Card 4"},
          {title: "Card 5"}
        ]
      },
      {
        title: "List 5",
        cards: [
          {title: "Card 1"},
          {title: "Card 2"},
          {title: "Card 3"},
          {title: "Card 4"},
          {title: "Card 5"}
        ]
      }
    ];
  }
}(angular))
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  width: 100%;
}

.container {
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-direction: column;
  -moz-flex-direction: column;
  flex-direction: column;
  float: column;
  height: 100%;
  margin: 0;
  max-height: 100%;
  max-width: 100%;
  padding: 0;
  width: 100%;
}

.container .container-head {
  background: red;
  padding: 10px;
  -webkit-flex-grow: 0;
  -moz-flex-grow: 0;
  flex-grow: 0;
}

.container .container-head .header-title {
  margin: 0;
  padding: 0;
}

.container .container-body {
  background: green;
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-direction: column;
  -moz-flex-direction: column;
  flex-direction: column;
  -webkit-flex-grow: 1;
  -moz-flex-grow: 1;
  flex-grow: 1;
  padding: 5px;
}

.container .container-body .view {
  background: blue;
  box-sizing: border-box;
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  float: left;
  overflow-x: auto;
  padding: 0;
  -webkit-flex-grow: 1;
  -moz-flex-grow: 1;
  flex-grow: 1;
}

.container .container-body .view .list-block {
  box-sizing: border-box;
  background: darkblue;
  display: inline-block;
  flex: 0 0 auto;
  float: left;
  margin: 0;
  padding: 5px;
  width: 280px;
  min-height:0;
}

.container .container-body .view .list-block .list {
  background: darkorange;
  border-radius: 4px;
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-direction: column;
  -moz-flex-direction: column;
  flex-direction: column;
  float: left;
  max-height: 100%;
  margin: 0;
  min-height: 0;
  min-width: 0;
  width: 100%;
}

.container .container-body .view .list-block .list .list-header {
  background: orange;
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
  border-bottom: 1px solid darkorange;
  -webkit-flex-grow: 0 0 auto;
  -moz-flex-grow: 0 0 auto;
  flex-grow: 0 0 auto;
  float: left;
  height: auto;
  padding: 10px;
}

.container .container-body .view .list-block .list .list-cards {
  background: orange;
  border-bottom: 1px solid darkorange;
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-direction: column;
  -moz-flex-direction: column;
  flex-direction: column;
  float: left;
  max-height: 100%;
  overflow-y: auto;
  padding: 5px;
}

.container .container-body .view .list-block .list .list-cards .card {
  background: #ffc107;
  border-radius: 4px;
  float: left;
  margin: 5px;
  padding: 10px;
}

.container .container-body .view .list-block .list .list-cards .card:hover {
  background: #fdc002;
}

.container .container-body .view .list-block .list .list-footer {
  background: orange;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
  -webkit-flex-grow: 0;
  -moz-flex-grow: 0;
  flex-grow: 0;
  height: auto;
  padding: 10px;
  float: left;
  text-align: center;
}
<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <title></title>
    <script data-require="angular.js@1.6.2" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
    <link rel="stylesheet" href="./style.css" />
  </head>

  <body ng-app="app">
    <div class="flexbox container" ng-controller="AppController as ctrl">
      <div class="container-head">
        <h3 class="header-title">Flexbox</h3>
      </div>
      <div class="container-body">
        <div class="view">
          <div class="list-block" ng-repeat="list in ctrl.lists">
            <div class="list">
              <div class="list-header">{{list.title}}</div>
              <div class="list-cards">
                <div class="card" ng-repeat="card in list.cards">
                  {{card.title}}
                </div>
              </div>
              <div class="list-footer">
                <a style="cursor: pointer;" ng-click="ctrl.addCard(list)">
                  Add Card
                </a>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <script type="text/javascript" src="./script.js"></script>
  </body>

</html>

On Chrome (Everything working) On Chrome works!

On Firefox (Doesn't apply the vertical overflow control correctly) enter image description here

Hope you guys can help me out.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Kaciano Ghelere
  • 393
  • 1
  • 4
  • 14
  • did you tried fixing the max-height of the container? – Jefree Sujit Jul 06 '17 at 11:57
  • 5
    An initial setting on flex items is `min-height: auto`. This means that flex items cannot be shorter than the height of their content. Chrome automatically adjust for this, which is why your layout works there. Firefox, Edge and others adhere strictly to the spec. You need to override this default for cross-browser compatibility. Use `min-height: 0` on the overflowing item. – Michael Benjamin Jul 06 '17 at 12:35
  • @Michael_B Thanks much for that tip. I've been wondering why Firefox's handling of flex is different than Chrome's in so many cases (requiring work-arounds), but it seems the difference you listed above is the cause of most of them! Saves a lot of time being able to use a standard fix instead of maxHeight: "calc(100% - margin)" workarounds. – Venryx May 04 '18 at 03:17
  • 2
    @Venryx, you're welcome. Glad I could help. For a more detailed explanation see the bottom of my answer ("Browser Rendering Notes") here: https://stackoverflow.com/q/36247140/3597276 – Michael Benjamin May 04 '18 at 03:26
  • Hmm, the latest version of Chrome appears to be requiring the `min-height: 0;` fix as well. Has anyone else noticed this, or am I mistaking something? (your demo above does not have in-list scrolling in Chrome anymore, which doesn't match your screenshot anymore) – Venryx Jul 20 '19 at 22:06
  • Okay, the change appears to have been made in Chrome by this developer here: https://bugs.chromium.org/p/chromium/issues/detail?id=927066#c39 – Venryx Jul 20 '19 at 22:08

1 Answers1

54

Just put min-height: 0; to .container-body this will fix your issue

.container .container-body {
  min-height: 0;
}

See this answer for more details

Ismail Farooq
  • 6,309
  • 1
  • 27
  • 47
  • 1
    Dude, you're a life saver. I tried to do that, but not in the .container-body. Thanks a lot! – Kaciano Ghelere Jul 06 '17 at 12:15
  • 3
    Like I want to upvote 100 times... – Nigiri Nov 30 '17 at 07:03
  • 3
    This is the fix for Firefox only. For the same issues in IE11 use min-height: 1px; – Cypher Mar 06 '18 at 15:13
  • Hmm, the latest version of Chrome appears to be requiring the `min-height: 0;` fix as well. Has anyone else noticed this, or am I mistaking something? (see OP demo in Chrome -- doesn't have in-list scrolling anymore for me) – Venryx Jul 20 '19 at 22:06
  • Okay, the change appears to have been made in Chrome by this developer here: https://bugs.chromium.org/p/chromium/issues/detail?id=927066#c39 – Venryx Jul 20 '19 at 22:08
  • yes it's not working in chrome either – Ismail Farooq Jul 20 '19 at 22:56