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:
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
$('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
$('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>
Google Web Designer lets you adjust the viewport so that the styles you specified for that size and orientation apply to your document on the stage. If Master rules is selected in the Responsive panel, only universal styles apply. To activate styles that depend on the viewport: In the Responsive panel, select Media rules on the Media queries tab.
When you're creating a responsive layout, it's helpful to see how your document looks in different viewport sizes while you're working on it. This method will let you see changes in percentage-based elements, but not style rules. Select Edit base document in the Responsive panel. A border appears around the viewport.
The Flexible Box Layout Module, makes it easier to design flexible responsive layout structure without using float or positioning. The flexbox properties are supported in all modern browsers. To start using the Flexbox model, you need to first define a flex container.
The flexbox properties are supported in all modern browsers. To start using the Flexbox model, you need to first define a flex container. The element above represents a flex container (the blue area) with three flex items. You will learn more about flex containers and flex items in the next chapters.
Add this code to your flex container:
overflow-anchor: none
This will disable a feature in Chrome known as "scroll anchoring", which is causing the upward expansion of boxes (revised codepen).
In Chrome, the upward / downward direction of expanding boxes is governed by the scroll position in the viewport, not the layout itself.
Chrome takes a unique approach to this behavior for the purpose of improving the user experience.
Basically, they bind a DOM element to the current scroll position. The movement of this particular ("anchor") element on the screen will determine an adjustment, if any, to the scroll position.
They call this approach "Scroll Anchoring". The algorithm is explained on this page: https://github.com/WICG/ScrollAnchoring/blob/master/explainer.md
This behavior is currently unique to Chrome, but Google is pushing for standardization.
In accordance with the Scroll Anchoring documentation, applying overflow-anchor: none
to the appropriate element(s) will disable scroll anchoring adjustments.
More information:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With