Search code examples
htmlcssflexboxslider

Css slider with flex


I have a container with some content based on flex positioning so it is adaptive. And i have silde block which is display:flex. I want to have only 2 items in a row for my slider. Other items should be hidden. I don't know the width of container.

This is my html:

<div class="slider">
    <div class="item">lorem100</div>
    <div class="item">lorem100</div>
    <div class="item">lorem100</div>
    <div class="item">lorem100</div>
</div>

This is my css:

.slider {
    display: flex;
    overflow: hidden;
}

.item {
    height: 150px;
}

I have:

I have

I want:

I want

Update How it works now

enter image description here


Solution

  • Use flex: 1 0 50%; for your child items

    .slider {
      display: flex;
      width: 300px;      /* just for this demo */
      margin: 0 auto;    /* just for this demo */
      background: gold;  /* just for this demo */
      /* overflow: hidden; /* Uncomment once you understand the demo */
    }
    
    .item {
      flex: 1 0 50%;
      outline: 1px solid red;
      height: 150px;
    }
    <div class="slider">
      <div class="item">lorem100</div>
      <div class="item">lorem100</div>
      <div class="item">lorem100</div>
      <div class="item">lorem100</div>
    </div>

    Example without the CSS comments:

    .slider {
      display: flex;
      overflow: hidden;
    }
    
    .item {
      flex: 1 0 50%;
      outline: 1px solid red;
      height: 150px;
    }
    <div class="slider">
      <div class="item">lorem 1</div>
      <div class="item">lorem 2</div>
      <div class="item">lorem 3</div>
      <div class="item">lorem 4</div>
    </div>

    Simple Prev/Next Carousel

    To spare you some brain pain,
    if you plan to animate your .slider, you should not set the overflow:hidden to it, but to a parent element.
    Here's a small example using pure JavaScript:

    const els = (sel, par = document) => par.querySelectorAll(sel);
    const el = (sel, par = document) => par.querySelector(sel);
    const mod = (n, m) => (n % m + m) % m;
    
    els(".slider-wrapper").forEach(elPar => {
      const elSlider = el(".slider", elPar);
      const elsItems = els(".item", elPar);
      const sub = +elPar.dataset.items ?? 1;
      const tot = Math.ceil(elsItems.length / sub);
      let c = 0;
      
      const anim = () => elSlider.style.transform = `translateX(-${c*100}%)`;
      const prev = () => (c = mod(c-1, tot), anim());
      const next = () => (c = mod(c+1, tot), anim());
      
      el(".prev", elPar).addEventListener("click", prev);
      el(".next", elPar).addEventListener("click", next);
    });
    /* QuickReset */
    
    * {
      margin: 0;
      box-sizing: border-box;
    }
    
    /* Slider */
    
    .slider-wrapper {
      overflow: hidden;
    }
    
    .slider {
      position: relative;
      display: flex;
      transition: 0.5s;
    }
    
    .item {
      flex: 1 0 50%;
      min-height: 150px;
    }
    <div class="slider-wrapper" data-items="2">
      <div class="slider">
        <div class="item" style="background:#0bf;">Item 1</div>
        <div class="item" style="background:#fb0;">Item 2</div>
        <div class="item" style="background:#f0b;">Item 3</div>
        <div class="item" style="background:#b0f;">Item 4</div>
        <div class="item" style="background:#bf0;">Item 5</div>
        <div class="item" style="background:#0fb;">Item 6</div>
        <!-- Never use inline style. This is just for demo. -->
      </div>
      <button class="prev" type="button">&larr;</button>
      <button class="next" type="button">&rarr;</button>
    </div>