Google Chrome viewport-anchored expand direction with flexbox

Viewed 1509

There is an issue in Google Chrome where elements expand/collapse in different directions relative to the viewport when placed inside a flexbox container with an adjacent flex item having space-between or center justified content.

This is not a problem in Firefox, IE11, Edge, or Safari as the elements always expand downward.

I'm curious:

  • Does Chrome's behavior here follow some spec? If so, which one?
  • If not, then why was this done in Chrome? (IMHO, it is horrible UX for the click trigger to disappear offscreen randomly.)
  • Can Chrome's behavior be modified or disabled in someway? Eg. through CSS or meta-tag?

Update 1: I've filed issue #739860 on chromium bug tracker seeking insight/explanation from Chromium devs, if possible.


Here are two examples inserted below. The full test suite describing the problem can be found in this pen: https://codepen.io/jameswilson/full/xrpRPg/ I've chosen to use slideToggle in this example so that the expand/collapse motion is animated and visible to the eye. The same behavior happens with the details tag, but cross-browser support is not there yet, and the expand/collapse is too janky.

Ex 1: Chrome's expand/collapse behavior for space-between justified flexbox

chrome's expand/collapse behavior for space-between justified

$('button').click(function() {
  $(this).next().slideToggle();
})
body {
  margin: 30px;
  font-family: sans-serif;
}
aside,
aside div,
summary,
main,
button,
details p,
button + p {
  background: rgba(0,0,0,.09);
  border: none;
  padding: 20px;
  margin: 0;
}

.flexcontainer {
  display: flex;
}
aside {
  flex: 1;
  position: relative;
  max-width: 25%;
  background: mintcream;

  display: flex;
  flex-direction: column;
  position: relative;
}
aside.space-between {
  justify-content: space-between;
}
aside.center {
  justify-content: center;
}

main {
  flex: 3;
  position: relative;
  max-width: 75%;
  background: aliceblue;
  vertical-align: top;
  height: 100%;
}
main > * + * {
  margin-top: 20px;
}

button + p {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<section class="flexcontainer">
  <aside class="space-between">
    <div>Top Sidebar</div>
    <div>Bottom Sidebar</div>
  </aside>
  <main>
    <div>
      <button>slideToggle</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Should always expand downward because Top Sidebar is always visible.</p>
    </div>

    <div>
      <button>slideToggle (usually expands down)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Should expand downward while Bottom Sidebar and Top Sidebar are both visible. But will expand upward if you scroll down far enough so that Top Sidebar is off-screen.</p>
    </div>
    
    <div>
      <button>slideToggle (usually expands down)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Should expand downward while Bottom Sidebar and Top Sidebar are both visible. But will expand upward if you scroll down far enough so that Top Sidebar is off-screen.</p>
    </div>
  </main>
</section>

Ex 2: Chrome's expand/collapse behavior for center justified flexbox

Chrome's expand/collapse behavior for center justified flexbox

$('button').click(function() {
  $(this).next().slideToggle();
})
body {
  margin: 30px;
  font-family: sans-serif;
}
aside,
aside div,
summary,
main,
button,
details p,
button + p {
  background: rgba(0,0,0,.09);
  border: none;
  padding: 20px;
  margin: 0;
}

.flexcontainer {
  display: flex;
}
aside {
  flex: 1;
  position: relative;
  max-width: 25%;
  background: mintcream;

  display: flex;
  flex-direction: column;
  position: relative;
}
aside.space-between {
  justify-content: space-between;
}
aside.center {
  justify-content: center;
}

main {
  flex: 3;
  position: relative;
  max-width: 75%;
  background: aliceblue;
  vertical-align: top;
  height: 100%;
}
main > * + * {
  margin-top: 20px;
}

button + p {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="flexcontainer">
  <aside class="center">
    <div>Center Sidebar</div>
  </aside>
  <main>

    <div>
      <button>slideToggle (usually expands downwards)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Usually expands downwards. Expands in both directions when the top-edge of the container scrolls out of the viewport.</p>
    </div>

    <div>
      <button>slideToggle</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Usually expands downwards. Expands in both directions when the top-edge of the container scrolls out of the viewport.</p>
    </div>

    <div>
      <button>slideToggle (usually expands downwards)</button>
      <p>Other browsers: always expands downward.<br>
        Chrome: Usually expands downwards. Expands in both directions when the top-edge of the container scrolls out of the viewport, but then resumes expanding downwards again when Center Sidebar scrolls out of view.</p>
    </div>
  </main>
</section>

1 Answers
Related