Search code examples
htmlcsscontainersslider

How can I have a horizontal slider in a max-width container?


I'm currently trying to achieve the slider that you can see in the image below. It comes with some special requirements:

  • Red lines indicate the max-width container at the image
  • It needs to be aligned with the centered max-width container from section one
  • It also needs to overflow to the right, till the end of the screen
  • When scrolling through the items it should not overlap the "Work" heading but go underneath it.
  • When scrolling to the end it should stop at the right end of the max-width container
  • In the responsive mobile version the heading doesn't rotate anymore and it is placed before the header.

I've been struggling with this for quite some time. Also tried to do some research and found an article. I played with the CodePen example but can't get it to work, when I try to add the heading next to the slider.

Does anybody know a solution for that? I would appreciate if no JavaScript is included.

My code looks something like this. Please use my updated Code Pen from the mentioned article: https://codepen.io/hraschan-the-looper/pen/VwqLbEv

<section id="home"></section>
<section id="work">
  <div class="flex flex-row">
    <h1>Work</h1>
    <div id="slider">...</div>
  </div>
</section>

screenshot of wide screen layout

screenshot of narrow screen layout


Solution

  • I found a solution for my problem. This is exactly what i tried to achieve. Please have a look at my fiddle in full screen mode.

    :root {
      --space: 1rem;
      --space-md: calc(var(--space) * 2);
      --content-max-width: 60ch;
    }
    .content {
      display: grid;
      grid-template-columns:
        [full-start] 1fr
        [content-start]
        40px min(var(--content-max-width), 100% - var(--space-md) * 2)
        [content-end]
        1fr [full-end];
    }
    
    .content > * {
      grid-column: content;
    }
    
    #work {
      grid-column: 2;
      transform: rotate(270deg);
      width:100%;
      height: 40px;
      padding-right: 10px;
      padding-bottom: 10px;
      display: flex;
      justify-content: flex-start;
    }
    
    .gallery {
      grid-column: 3 / 3 span;
      display: grid;
      padding-right: 40px;
      overflow-x: scroll;
      overscroll-behavior-x: contain;
      scroll-snap-type: x proximity;
      scrollbar-width: none;
    }
    
    .gallery::-webkit-scrollbar {
      inline-size: 0 !important;
      display: none;
    }
    
    .gallery .wrapper {
      grid-column: content;
      display: flex;
      align-items: center;
      gap: var(--space);
    }
    
    .gallery .wrapper::after {
      content: "";
      align-self: stretch;
      padding-inline-end: max(
        var(--space),
        (100vw - var(--content-max-width)) / 2 - var(--space)
      );
    }
    
    .gallery .item {
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      scroll-snap-align: start;
      inline-size: 100%;
      max-inline-size: 25rem;
      aspect-ratio: 16 / 9;
      font-size: 2rem;
      background: hotpink;
      border-radius: 4px;
      overflow: hidden;
    }
     <section class="content">
       <p>In ancient times authors often misinterpret the approval as an enarched spleen, when in actuality it feels more like a feeling bone. The zeitgeist contends that those cautions are nothing more than brokers. A trip of the metal is assumed to be a classless trouser. The septembers could be said to resemble unplumbed breaths.
    
    An incurved health's leopard comes with it the thought that the chichi peak is a sauce. One cannot separate tortellinis from ain laborers. A credit is the effect of a tub. Some stilted needs are thought of simply as fiberglasses.</p>
        <h1 id="work">Work</h1>
        <div class="gallery">
          <div class="wrapper">
            <div class="item">1</div>
            <div class="item">2</div>
            <div class="item">3</div>
            <div class="item">4</div>
            <div class="item">5</div>
            <div class="item">6</div>
            <div class="item">7</div>
            <div class="item">8</div>
            <div class="item">9</div>
            <div class="item">10</div>
            <div class="item">11</div>
            <div class="item">12</div>
            <div class="item">13</div>
            <div class="item">14</div>
            <div class="item">15</div>
            <div class="item">16</div>
          </div>
        </div>
      </section>