cssflexboxscroll

CSS Flexbox no wrap with padding preserved


The following is a css flex box inside a scroll container. The scroll container has left and right padding however with flex-wrap set to no-wrap, padding-right is ignored. This is presumably because flex box does not expand to accommodate items that continue beyond its borders. This is clearly the intended behaviour. Is the a way to adapt and preserve the effective space of the padding.

.scrollable {
  position: relative;
  overflow-x: scroll;
  margin: 0 auto;
  padding: 20px 40px;
  max-width: 300px;
  border: 1px solid #000;
}

.tiles {
  align-items: flex-start;
  display: flex;
  flex-wrap: nowrap;
  gap: 20px;
  justify-content: flex-start;
}

.tiles > div {
  background: green;
  flex: 1 0 60px;
  height: 30px;
  line-height: 30px;
  width: 60px;
  text-align: center;
}
<div class="scrollable">
  <div class="tiles">
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
    <div>Item 4</div>
    <div>Item 5</div>
    <div>Item 6</div>
    <div>Item 7</div>
    <div>Item 8</div>
    <div>Item 9</div>
    <div>Item 10</div>
  </div>
</div>

One way would be to calculate the width of .tiles with javascript and add the style. Another would be to use :before and :after with a width of the desired padding but this would also include the gap as well.

Is there a straightforward way of doing this?


Solution

  • ìnline-flex instead of flex will do the job. It will make sure the .tiles element is not limited to its parent width and is the one overflowing instead of the items inside it.

    .scrollable {
      position: relative;
      overflow-x: scroll;
      margin: 0 auto;
      padding: 20px 40px;
      max-width: 300px;
      border: 1px solid #000;
    }
    
    .tiles {
      display: inline-flex;
      gap: 20px;
      border: 2px solid red; /* with this you can see the differencen between flex and inline-flex */
    }
    
    .tiles > div {
      background: green;
      flex: 1 0 60px;
      height: 30px;
      line-height: 30px;
      width: 60px;
      text-align: center;
    }
    <div class="scrollable">
      <div class="tiles">
        <div>Item 1</div>
        <div>Item 2</div>
        <div>Item 3</div>
        <div>Item 4</div>
        <div>Item 5</div>
        <div>Item 6</div>
        <div>Item 7</div>
        <div>Item 8</div>
        <div>Item 9</div>
        <div>Item 10</div>
      </div>
    </div>