5

I'm trying to create a layout with tabs and an unordered list which expands vertically to 100% of its container's height. I managed to get it working as expected in Chrome and even IE11 without much trouble.

However, Firefox seems to have a bit of a quirk where the UL expands about 20px outside of its container in my case.

View Plnkr Test Case

Screenshot of what's happening: enter image description here

HTML:

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <script src="script.js"></script>
</head>

<body>
  <div id="wrapper">
    <header>Some header...</header>
    <div class="board-panel">
      <div id="board-list">
        <ul class="lobby-tabs nav nav-tabs">
          <li ng-class="{active: activeTab == 'favorites'}">
            <a ng-click="switchTab('favorites')">Favorites</a>
          </li>
          <li ng-class="{active: activeTab == 'public'}">
            <a ng-click="switchTab('public')">Public</a>
          </li>
          <li ng-class="{active: activeTab == 'private'}">
            <a ng-click="switchTab('private')">Private</a>
          </li>
          <li class="pull-right" ng-class="{active: activeTab == 'create'}">
            <a ng-click="switchTab('create')">Create a Board</a>
          </li>
        </ul>
        <div ng-show="activeTab != 'create'">
          <div class="board-controls">
            <button class="btn btn-default pull-right" ng-click="refresh()">
              <i class="glyphicon glyphicon-refresh"></i> Refresh
            </button>
          </div>
          <ul class="list-group">
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
            <li class="list-group-item" ng-repeat="item in items | filter: filter track by $index">Some item...</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</body>

</html>

CSS:

html,
body,
#wrapper {
  height: 100%;
}

#wrapper {
  display: flex;
  flex-direction: column;
}

#wrapper > header {
  height: 50px;
  flex: 0;
  background: rgba(129, 219, 255, 1);
}

#wrapper > div {
  flex: 1;
  background: rgba(129, 219, 255, 0.5);
  max-height: 100%;
}

#board-list {
  display: flex;
  flex-direction: column;
  background: #eee;
  height: 100%;
  max-height: 100%;
  overflow: hidden;
  width: 476px;
  margin: 0 auto;
}

#board-list > div {
  border: 1px solid #AAB3B3;
  border-top: none;
  display: flex;
  flex: 1;
  flex-direction: column;
  height: 100%;
  max-height: 100%;
}

.board-controls {
  padding: 5px 10px;
  background: #F1F1F1 none repeat scroll 0% 0%;
}

.board-controls .filter-label {
  margin: 10px 5px 10px 0;
  font-weight: 700;
  float: left;
}

.list-group {
  overflow-y: scroll;
}

View Plnkr Test Case

TylerH
  • 20,799
  • 66
  • 75
  • 101
user1960364
  • 1,951
  • 6
  • 28
  • 47

1 Answers1

2

This is because the way Firefox handles min/max width/height in flex elements changed in version 34 in response to an update in the Flexbox spec:

To provide a more reasonable default minimum size for flex items, this specification introduces a new auto value as the initial value of the min-width and min-height properties defined in CSS 2.1.

To fix it, you'll need to add min-height: 0; to your #item-list > div selector to override the default value of auto that Firefox uses:

JSFiddle Example

html, body {
    height: 100%;
}
#wrapper {
    height: 50%;
    background: #EAF9FF;
}
#item-list {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: #B8E8F8;
    width: 476px;
    margin: 0 auto;
    padding: 10px;
}
#item-list > .nav-tabs {
    border: none;
}
#item-list > div {
    display: flex;
    flex: 1;
    flex-direction: column;
    height: 100%;
    max-height: 100%;
    background: #9FD9F0;
    padding: 10px;
    min-height: 0; /* This property is new */
}
.list-group {
    overflow-y: scroll;
    background: #82C8E0;
    padding: 10px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div id="wrapper">
    <div id="item-list">
        <ul class="nav nav-tabs">
            <li><a href="#">tab1</a></li>
            <li><a href="#">tab2</a></li>
            <li><a href="#">tab3</a></li>
            <li class="pull-right"><a href="#">tab4</a></li>
        </ul>
        <div ng-show="activeTab != 'create'">
            <ul class="list-group">
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
                <li>Some item...</li>
            </ul>
        </div>
    </div>
</div>

I guess other browsers haven't updated to match the spec yet, or they've updated and also adjusted their flexbox implementations to compensate? I'm not sure.

TylerH
  • 20,799
  • 66
  • 75
  • 101