Search code examples
htmlcssflexbox

Limit viewport scrolling to part of content with CSS


I like to have a line of elements (eg. inline-blocks, maybe in a flex container), that can overflow the viewport. However the first and last are dummy ones, considered as non-content, only to appear partially at the viewport edges.

Let's say we have:

#container {
  display: flex;
}

#container div {
  margin: 100px;
  min-width: 500px;
  min-height: 500px;
  background: grey;
}

#container div.dummy {
  background: pink;
}
<div id="container">
  <div class="dummy">Element 1</div>
  <div>Element 2</div>
  <div>Element 3</div>
  <div>Element 4</div>
  <div class="dummy">Element 5</div>
</div>

How can I restrict the scrolling to a smaller area, eg. crop 500px from each side for example, having the container overflow the viewport, but without the possibility to scroll there? Is this possible with simple and clean CSS ?


Solution

  • You can use negative margins. Without a wrapper you can use CSS grid instead to clip both sides correctly. This works because grid's content-size is calculated based on track sizes, and the margins on grid items on the side seems to effect their track size (can't find how exactly in the spec).

    On the other hand, if the width of the two dummy elements is fixed and known, you could simply limit the size on these two instead of the below solution.

    Below example I've restricted 400px instead of 500px for better demonstration.

    #container {
      display: grid;
      grid-auto-flow: column;
      width: fit-content;
      overflow: hidden;
    }
    
    #container div {
      margin: 100px;
      min-width: 500px;
      min-height: 500px;
      background: grey;
    }
    
    #container div.dummy:first-child {
      background: pink;
      margin-left: -400px;
    }
    
    #container div.dummy:last-child {
      background: pink;
      margin-right: -400px;
    }
    <div id="container">
      <div class="dummy">Element 1</div>
      <div>Element 2</div>
      <div>Element 3</div>
      <div>Element 4</div>
      <div class="dummy">Element 5</div>
    </div>