Flex container with overflow ignore last child margin

Viewed 137

I'm trying to add a width constraint on a flex container, and an horizontal overflow.

Children have margins, but I don't know why, last margin stays out of the container ; I can see it with Chrome debug, but the container simply ignore it...

Is there a way to force the flex container to take this margin in account ?

I tried to play with flex-wrap, box-sizing, even with padding the result is the same...

Thanks !

Here is a simple demo that you can run ; if you scroll to the end, there isn't any space left on the right.

<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <style type="text/css">
    .container {
      width: 300px;
      border: 1px #000 solid;
      display: flex;
      overflow: auto;
      scroll-snap-type: x mandatory;
    }
    .child {
      min-width: 200px;
      width: 200px;
      border: 1px #f00 solid;
      margin: 20px;
      scroll-snap-align: center;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="child"><p>blablabla</p><p>blablabla</p></div>
    <div class="child"><p>blablabla</p></div>
    <div class="child"><p>blablabla</p></div>
    <div class="child"><p>blablabla</p></div>
  </div>
</body>
</html>

3 Answers

I found that it works with an intermediate container, between .container and .child, with a display: flex property.

At least it works, but I don't know why I have to do this :/

<!doctype html>
<html lang="fr">
<head>
  <meta charset="utf-8">
  <style type="text/css">
    .container {
      width: 300px;
      border: 1px #000 solid;
      display: flex;
      overflow: auto;
      scroll-snap-type: x mandatory;
    }
    .intermediate {
      display: flex;
    }
    .child {
      min-width: 200px;
      width: 200px;
      border: 1px #f00 solid;
      margin: 20px;
      scroll-snap-align: center;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="intermediate">
      <div class="child"><p>blablabla</p><p>blablabla</p></div>
      <div class="child"><p>blablabla</p></div>
      <div class="child"><p>blablabla</p></div>
      <div class="child"><p>blablabla</p></div>
     </div>
  </div>
</body>
</html>

It is the overflow that is ignoring the margin because it applies only to content. So the inner container is the solution like you did.

Working example with inline-flex (i removed scroll-snap since it is not necessary here):

.container {
  width: 300px;
  border: 1px #000 solid;
  overflow: scroll;
}
.inner {
  display: inline-flex;
}
.child {
  min-width: 200px;
  width: 200px;
  border: 1px #f00 solid;
  margin: 20px;
}
<div class="container">
    <div class="inner">
        <div class="child"><p>blablabla</p><p>blablabla</p></div>
        <div class="child"><p>blablabla</p></div>
        <div class="child"><p>blablabla</p></div>
        <div class="child"><p>blablabla</p></div>
    </div>
</div>

You can handle this by adding :after to the .container

.container {
  width: 300px;
  border: 1px #000 solid;
  display: flex;
  overflow: auto;
  scroll-snap-type: x mandatory;
}
.container::after {
  content: '';
  width: 20px;
  flex-shrink: 0
}
.child {
  min-width: 200px;
  width: 200px;
  border: 1px #f00 solid;
  margin: 20px;
  scroll-snap-align: center;
}
<!doctype html>
<html lang="fr">
<body>
  <div class="container">
    <div class="child"><p>blablabla</p><p>blablabla</p></div>
    <div class="child"><p>blablabla</p></div>
    <div class="child"><p>blablabla</p></div>
    <div class="child"><p>blablabla</p></div>
  </div>
</body>
</html>

Related