Here it is slightly simplified for clarity's sake. The main change is reverting the flex-direction
back to row
, adding a flex-wrap: wrap
property, and making the main
container height: 100%
.
In your original code the main container was simply growing to the height of the flex items, triggering an overflow on the body and not on that container.
Original solution with flex-direction: row
:
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
body {
scroll-behavior: smooth;
}
main {
display: flex;
flex-wrap: wrap;
width: 100vw;
height: 100%;
overflow: auto;
scroll-snap-type: y mandatory;
}
section {
height: 100vh;
width: 90vw;
border: 1px solid red;
margin: 0 auto;
}
main section {
scroll-snap-align: start;
}
<head>
</head>
<body>
<main dir="ltr">
<section>
<h1>content1</h1>
</section>
<section>
<h1>content2</h1>
</section>
</main>
</body>
</html>
Edit:
On closer inspection I've realised that it's not actually necessary to change the flex-direction if you give the flex items a flex-basis
instead. By default flex-box will try to fit its children inside it's own height so you need to specify their starting size. You also need to provide flex-grow
and flex-shrink
which control how the element resizes relative to the container.
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
width: 100%;
}
body {
scroll-behavior: smooth;
}
main {
display: flex;
flex-direction: column;
width: 100vw;
height: 100%;
overflow: auto;
scroll-snap-type: y mandatory;
}
section {
flex-basis: 100vh;
flex-grow: 1;
flex-shrink: 0;
width: 90vw;
border: 1px solid red;
margin: 0 auto;
}
main section {
scroll-snap-align: start;
}
<html>
<body>
<main dir="ltr">
<section>
<h1>content1</h1>
</section>
<section>
<h1>content2</h1>
</section>
</main>
</body>
</html>
It's another way of achieving the same essential result; that the container will overflow and trigger the scroll behaviour.
flex: row
break snapping? – Millard