7

I am using a bootstrap slider.

  • On desktop, it has three slides with 4 tiles each

enter image description here

  • On Tabs, they have to be 4 slides with 3 tiles each

  • On Mobile, there needs to be 12 different slides

I am thinking of the most effective and optimized way of implementing this.

Option 1 - Create 3 different set of sliders. Make only one visible at a time

Option 2 - Detect the screen width with jquery and programmatically add extra tiles as slides, hide the extra ones. I guess this will be very complicated.

Please help if there is a better way to implement this.

Stacy J
  • 2,721
  • 15
  • 58
  • 92

1 Answers1

8

Here it is:

.carousel-inner .item.active {
  display: flex; 
}

.carousel-inner .item {
  background-color: #212121;
  color: white;
  padding: 0 15px; 
}
#desktopCarousel .carousel-inner .item > .row {
  min-height: 480px;
}
#tabletCarousel .carousel-inner .item > .row {
  min-height: 360px;
}
.carousel-inner .item > .row {
  flex-grow: 1;
  min-height: 320px;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch; 
}
.carousel-inner .item > .row [class^="col-"] {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  text-align: center; 
}
.carousel-inner .item > .row .row {
  flex-grow: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch; 
}
.carousel-inner .item > .row .row [class^="col-"] {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center; 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<div id="desktopCarousel" class="carousel slide hidden-xs hidden-sm" data-ride="carousel">
  <ol class="carousel-indicators">
    <li data-target="#desktopCarousel" data-slide-to="0" class="active"></li>
    <li data-target="#desktopCarousel" data-slide-to="1"></li>
    <li data-target="#desktopCarousel" data-slide-to="2"></li>
  </ol>

  <div class="carousel-inner" role="listbox">
    <div class="item active">
      <div class="row">
        <div class="col-sm-6">
          First item
        </div>
        <div class="col-sm-6">
          <div class="row">
            <div class="col-sm-6">
              Second item
            </div>
            <div class="col-sm-6">
              Third item
            </div>
          </div>
          <div class="row">
            <div class="col-sm-12">
              Fourth item
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-6">
          Fifth item
        </div>
        <div class="col-sm-6">
          <div class="row">
            <div class="col-sm-6">
              Sixth item
            </div>
            <div class="col-sm-6">
              Seventh item
            </div>
          </div>
          <div class="row">
            <div class="col-sm-12">
              Eighth item
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-6">
          Nineth item
        </div>
        <div class="col-sm-6">
          <div class="row">
            <div class="col-sm-6">
              Tenth item
            </div>
            <div class="col-sm-6">
              Eleventh item
            </div>
          </div>
          <div class="row">
            <div class="col-sm-12">
              Twelfth item
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <a class="left carousel-control" href="#desktopCarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#desktopCarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

<div id="tabletCarousel" class="carousel slide hidden-xs hidden-md hidden-lg" data-ride="carousel">
  <ol class="carousel-indicators">
    <li data-target="#tabletCarousel" data-slide-to="0" class="active"></li>
    <li data-target="#tabletCarousel" data-slide-to="1"></li>
    <li data-target="#tabletCarousel" data-slide-to="2"></li>
    <li data-target="#tabletCarousel" data-slide-to="3"></li>
  </ol>

  <div class="carousel-inner" role="listbox">
    <div class="item active">
      <div class="row">
        <div class="col-sm-6">
          First item
        </div>
        <div class="col-sm-6">
          <div class="row">
            <div class="col-sm-12">
              Second item
            </div>
            <div class="col-sm-12">
              Third item
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-6">
          Fourth item
        </div>
        <div class="col-sm-6">
          <div class="row">
            <div class="col-sm-12">
              Fifth item
            </div>
            <div class="col-sm-12">
              Sixth item
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="item">
     <div class="row">
        <div class="col-sm-6">
          Seventh item
        </div>
        <div class="col-sm-6">
          <div class="row">
            <div class="col-sm-12">
              Eighth item
            </div>
            <div class="col-sm-21">
              Nineth item
            </div>
          </div>
        </div>
      </div>     
    </div>
    <div class="item">
     <div class="row">
        <div class="col-sm-6">
          Tenth item
        </div>
        <div class="col-sm-6">
          <div class="row">
            <div class="col-sm-12">
              Eleventh item
            </div>
            <div class="col-sm-12">
              Twelvth item
            </div>
          </div>
        </div>
      </div>     
    </div>
  </div>

  <a class="left carousel-control" href="#tabletCarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#tabletCarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

<div id="mobileCarousel" class="carousel slide hidden-sm hidden-md hidden-lg" data-ride="carousel">
  <ol class="carousel-indicators">
    <li data-target="#mobileCarousel" data-slide-to="0" class="active"></li>
    <li data-target="#mobileCarousel" data-slide-to="1"></li>
    <li data-target="#mobileCarousel" data-slide-to="2"></li>
    <li data-target="#mobileCarousel" data-slide-to="3"></li>
    <li data-target="#mobileCarousel" data-slide-to="4"></li>
    <li data-target="#mobileCarousel" data-slide-to="5"></li>
    <li data-target="#mobileCarousel" data-slide-to="6"></li>
    <li data-target="#mobileCarousel" data-slide-to="7"></li>
    <li data-target="#mobileCarousel" data-slide-to="8"></li>
    <li data-target="#mobileCarousel" data-slide-to="9"></li>
    <li data-target="#mobileCarousel" data-slide-to="10"></li>
    <li data-target="#mobileCarousel" data-slide-to="11"></li>
  </ol>

  <div class="carousel-inner" role="listbox">
    <div class="item active">
      <div class="row">
        <div class="col-sm-12">
          First item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Second item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Third item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Fourth item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Fifth item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Sixth item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Seventh item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Eighth item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Nineth item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Tenth item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Eleventh item
        </div>
      </div>
    </div>
    <div class="item">
      <div class="row">
        <div class="col-sm-12">
          Twelveth item
        </div>
      </div>
    </div>
  </div>

  <a class="left carousel-control" href="#mobileCarousel" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#mobileCarousel" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

Note you don't actually need the CSS (it just creates the layout for desktop sliders, centers the contents in each item (with flexbox) + colors, but I assume you already got those covered). CSS is un-prefixed and, in case it helps, you'll find the SCSS in the fiddle.

Also, you might want to set different min-heights for items on mobile/tablet/desktop.

Other than that, it's pretty clean... bootstrap. No custom JS, no custom CSS. Just markup.


Edit: (as per comment) If you don't want all sliders running at all times and prefer to initialize each based on a resize listener, when changing the @media interval (I recommend enquire.js for this - 0.8k minified, runs on any browser/device), place each carousel's markup in a script, with different id's:

<script id="desktop-markup" type="text/template">
  <div id="desktopCarousel" class="carousel slide" data-ride="carousel">
    <!-- carousel markup here -->
  </div>
</script>
<script id="tablet-markup" type="text/template">
  <div id="tabletCarousel" class="carousel slide" data-ride="carousel">
    <!-- carousel markup here -->
  </div>
</script>
<script id="mobile-markup" type="text/template">
  <div id="mobileCarousel" class="carousel slide" data-ride="carousel">
    <!-- carousel markup here -->
  </div>
</script>

On page load and on changing the media interval, get the contents of the template according to current @media interval (i.e. $('#mobile-markup').html()), place it inside the designated DOM container and run .carousel() on it:

$('.carousel-container').html(
  $('#mobile-markup').html()
).find('.carousel').carousel(options); 
// where options is optional. :) 
// see http://getbootstrap.com/javascript/#carousel-options
tao
  • 82,996
  • 16
  • 114
  • 150
  • So you are using three different set of carousel. Each loading on the same page but visible one at a time based on screen dimension. Am I correct..? – Stacy J Apr 12 '17 at 13:46
  • 1
    @StacyJ: you are correct. Considering we're only using Bootstrap and jQuery, you don't really have lighter methods. Having a single instance and creating/removing slides + moving contents on the fly is, IMHO, even worse because a) it implies a lot of DOM manipulation and b) it requires either placing a `resize` listener (which is expensive) or using `enquire.js`. DOM might be lighter, but the transitions on resize might get sluggish, depending on number of slides. You'd also need to reinitialize the slider each time you change it. The other option is to use another slider (slick.js would fit). – tao Apr 12 '17 at 15:15
  • I used the resize listener method to create 3 sets of slider and calling each of them through ajax based on screen width. To be honest, the transition during resizing does take a toll. I will stick with it for a while and see the entire site performance. If it gets really bad I will try the above way. – Stacy J Apr 12 '17 at 15:42
  • @StacyJ, instead of using `$.ajax()` you can always use script templates. See addition to answer. This markup inside the ` – tao Apr 12 '17 at 16:07
  • Will try this out – Stacy J Apr 12 '17 at 16:12