Slider

The slider is a proposed replacement for what is commonly referred to as a carousel. It consists of multiple slides which can expand upon user focus or interaction. It differ from the classic carousel in that all its slide are always visible, even when one of them is expanded.

Slider: 3 Slides

Component Preview
<div class="slider">
    <div tabindex="0" class="slider__slide" aria-expanded="true">

        <div class="banner  banner--medium banner--reversed vertical-bottom horizontal-left">
            <div class="banner__image">
                <img src="https://sandbox.prod.drupal.uiowa.edu/sites/sandbox.uiowa.edu/files/2021-03/feature1.jpg">
            </div>

            <div class="banner__container">
                <div class="banner__content">

                    <h2 class="headline bold-headline--serif bold-headline bold-headline--negative">
                        <span class="headline__text">Having an Impact</span>
                    </h2>

                    <div class="banner__text">
                        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
                    </div>

                </div>
            </div>

        </div>

        <div class="slider__teaser">
            <p class="slider__teaser-heading">Having an Impact
                <span aria-hidden="true" class="fas fa-plus"></span>
            </p>
        </div>

    </div>
    <div tabindex="0" class="slider__slide">

        <div class="banner  banner--medium banner--reversed vertical-bottom horizontal-left">
            <div class="banner__image">
                <img src="https://sandbox.prod.drupal.uiowa.edu/sites/sandbox.uiowa.edu/files/2021-03/feature2.jpg">
            </div>

            <div class="banner__container">
                <div class="banner__content">

                    <h2 class="headline bold-headline--serif bold-headline bold-headline--negative">
                        <span class="headline__text">2019 Graduates</span>
                    </h2>

                    <div class="banner__text">
                        <p>Receiving a diploma signals both an ending and a beginning</p>
                    </div>

                </div>
            </div>

        </div>

        <div class="slider__teaser">
            <p class="slider__teaser-heading">2019 Graduates
                <span aria-hidden="true" class="fas fa-plus"></span>
            </p>
        </div>

    </div>
    <div tabindex="0" class="slider__slide">

        <div class="banner  banner--medium banner--reversed vertical-bottom horizontal-left">
            <div class="banner__image">
                <img src="https://sandbox.prod.drupal.uiowa.edu/sites/sandbox.uiowa.edu/files/2021-03/feature3.jpg">
            </div>

            <div class="banner__container">
                <div class="banner__content">

                    <h2 class="headline bold-headline--serif bold-headline bold-headline--negative">
                        <span class="headline__text">Turning the Tide</span>
                    </h2>

                    <div class="banner__text">
                        <p>Alumna Lauren Palmer aims to rehabilitate animals</p>
                    </div>

                </div>
            </div>

        </div>

        <div class="slider__teaser">
            <p class="slider__teaser-heading">Turning the Tide
                <span aria-hidden="true" class="fas fa-plus"></span>
            </p>
        </div>

    </div>
</div>
  • Content:
    .slider__slide:first-child:focus-within {
      margin-left: 2px; }
    
    .slider {
      flex-wrap: wrap;
      display: flex;
      flex-basis: 100%; }
      @media (min-width: 768px) {
        .slider {
          align-content: stretch;
          align-items: stretch;
          flex-direction: row;
          justify-content: flex-start; } }
      .slider__slide {
        cursor: pointer;
        pointer-events: auto;
        position: relative;
        overflow: hidden;
        color: #fff;
        flex: 1 0 100%; }
        .slider__slide:focus {
          z-index: 2; }
        .slider__slide:first-child:focus-within {
          margin-left: 2px; }
        .slider__slide:last-child:focus-within {
          margin-right: 2px; }
        @media (min-width: 992px) {
          .slider__slide {
            align-self: auto;
            flex: unset;
            order: 0;
            min-height: 500px;
            transition-timing-function: linear;
            transition: 0.8s;
            width: 20%; } }
        @media (min-width: 768px) {
          .slider__slide .banner--medium {
            min-height: 33rem; } }
        .slider__slide .banner__image img {
          display: block;
          width: 100%;
          -o-object-fit: cover;
          object-fit: cover; }
          @media (min-width: 855px) {
            .slider__slide .banner__image img {
              height: 33rem; } }
        @media (min-width: 768px) {
          .slider__slide .banner__text {
            opacity: 0;
            transition: opacity .2s ease-in; } }
        @media (min-width: 768px) {
          .slider__slide .bold-headline {
            opacity: 0;
            transition: opacity .2s linear; } }
        .slider__slide .banner__content {
          opacity: 1;
          padding-top: 2.5rem;
          padding-right: 2.5rem;
          padding-bottom: 2.5rem;
          padding-left: 2.5rem;
          width: 100%; }
          @media (min-width: 768px) {
            .slider__slide .banner__content {
              opacity: 0;
              position: absolute;
              bottom: 0;
              top: unset;
              transition: opacity .2s linear; } }
        @media (min-width: 768px) {
          .slider__slide[aria-expanded="true"] {
            flex-grow: 1; } }
        .slider__slide[aria-expanded="true"] .banner__content {
          opacity: 1; }
        .slider__slide[aria-expanded="true"] .bold-headline {
          opacity: 1;
          transition: opacity 1s linear; }
        .slider__slide[aria-expanded="true"] .banner__text {
          opacity: 1;
          transition: opacity 1.5s ease-in; }
        .slider__slide[aria-expanded="true"] .slider__teaser {
          opacity: 0; }
        @media (min-width: 768px) {
          .slider__slide[aria-expanded="true"]:after {
            /*
              position: absolute;
              top: 0;
              right: 0;
              bottom: 0;
              left: 0;
              content: "";
              background: linear-gradient(transparent 1%, transparent 29%, rgba(0, 0, 0, .9));
              */ } }
      .slider__teaser {
        position: absolute;
        z-index: 1;
        bottom: 0;
        width: 100%;
        padding: 1.05rem;
        opacity: 0;
        color: #fff;
        background: rgba(0, 0, 0, 0.75);
        box-shadow: 0 5px 30px 10px rgba(0, 0, 0, 0.3);
        display: flex;
        align-items: center; }
        @media (min-width: 768px) {
          .slider__teaser {
            opacity: 1; } }
      .slider__teaser-heading {
        display: flex;
        margin: 0;
        color: #fff;
        font-size: 1.2rem;
        font-weight: 600;
        font-style: normal;
        line-height: 1;
        padding-right: 2rem;
        display: flex;
        align-items: center; }
        .slider__teaser-heading span {
          padding-left: 0.625rem;
          position: absolute;
          right: 20px; }
          .slider__teaser-heading span.fa-plus:before {
            padding: 0.325rem;
            color: #FFCD00;
            border: 1px solid #fff;
            border-radius: 50%;
            font-size: 0.8rem; }
    
  • URL: /components/raw/slider/slider.css
  • Filesystem Path: src/components/slider/slider.css
  • Size: 3.6 KB
  • Content:
    function Slider(element) {
      this.slides = element.getElementsByClassName('slider__slide');
    
      for (let i = 0; i < this.slides.length; i++) {
        this.slides[i].onmouseover = this.slides[i].onfocus = () => {
          this.setActiveSlide(this.slides[i]);
        };
        this.slides[i].addEventListener('keyup', (event) => {
          this.handleKeyEvent(event);
        }, false);
      }
    }
    
    Slider.prototype.setAriaFalse = function() {
      for (let i = 0; i < this.slides.length; i++) {
        let el = this.slides.item(i)
        if (el) {
          el.setAttribute('aria-expanded', 'false');
        }
      }
    }
    
    Slider.prototype.setActiveSlide = function(element) {
      this.setAriaFalse();
      element.setAttribute('aria-expanded', 'true');
    }
    
    Slider.prototype.getActiveSlideIndex = function() {
      for (let i = 0; i < this.slides.length; i++) {
        if (this.slides[i].getAttribute('aria-expanded') === 'true') {
          return i;
        }
      }
    
      return false;
    }
    
    Slider.prototype.handleKeyEvent = function(event) {
      if (event.keyCode === 37) {
        // left - previous
        let index = this.getActiveSlideIndex();
        if (index !== false && index > 0) {
          // @todo Allow looping?
          this.setActiveSlide(this.slides[index-1]);
        }
      } else if (event.keyCode === 39) {
        // right - next
        let index = this.getActiveSlideIndex();
        if (index !== false && index < this.slides.length-1) {
          this.setActiveSlide(this.slides[index+1]);
        }
      }
    }
    
    // Instantiate sliders on the page.
    const sliders = document.getElementsByClassName('slider');
    
    for (let i = 0; i < sliders.length; i++) {
      let slider = new Slider(sliders[i]);
    }
    
  • URL: /components/raw/slider/slider.js
  • Filesystem Path: src/components/slider/slider.js
  • Size: 1.6 KB
  • Content:
    @import '../../assets/scss/variables';
    @import '../../assets/scss/utilities';
    
    .slider__slide:first-child:focus-within {
      margin-left: 2px;
    }
    
    .slider {
      flex-wrap: wrap;
      @include flexbox;
      flex-basis: 100%;
    
      @include breakpoint(sm) {
        align-content: stretch;
        align-items: stretch;
        flex-direction: row;
        justify-content: flex-start;
      }
    
      &__slide {
        cursor: pointer;
        pointer-events: auto;
        position: relative;
        overflow: hidden;
        //min-height: 300px;
        //transition: all 0.4s cubic-bezier(0.61, -0.44, 0.33, 1.39);
        color: $white;
        @include flex(1, 0, 100%);
    
        &:focus {
          z-index: 2;
        }
    
        &:first-child:focus-within {
          margin-left: 2px;
        }
    
        &:last-child:focus-within {
          margin-right: 2px;
        }
    
        @include breakpoint(md) {
          align-self: auto;
          flex: unset;
          order: 0;
          min-height: 500px;
          //transition: all 0.6s ease;
          transition-timing-function: linear;
          transition: 0.8s;
          width: 20%;
        }
    
        // banner overrides
    
        .banner--medium {
          @include breakpoint(sm) {
            min-height: 33rem;
          }
        }
    
        .banner__image img {
          display: block;
          width: 100%;
          -o-object-fit: cover;
          object-fit: cover;
    
          @include breakpoint(menu) {
            height: 33rem;
          }
        }
    
        .banner__text {
          @include breakpoint(sm) {
            opacity: 0;
            transition: opacity .2s ease-in;
          }
        }
    
        .bold-headline {
          @include breakpoint(sm) {
            opacity: 0;
            transition: opacity .2s linear;
          }
        }
    
        .banner__content {
          opacity: 1;
    
          @include breakpoint(sm) {
            opacity: 0;
            position: absolute;
            bottom: 0;
            top: unset;
            transition: opacity .2s linear;
          }
    
          @include padding($top: $xlg, $right: $xlg, $bottom: $xlg, $left: $xlg);
          width: 100%;
        }
    
        // Expanded overrides.
        &[aria-expanded="true"] {
          @include breakpoint(sm) {
            flex-grow: 1;
          }
    
          .banner__content {
            opacity: 1;
            //transition: opacity 1s linear;
          }
    
          .bold-headline {
            opacity: 1;
            transition: opacity 1s linear;
          }
    
          .banner__text {
            opacity: 1;
            transition: opacity 1.5s ease-in;
          }
    
          .slider__teaser {
            opacity: 0;
          }
    
          &:after {
            @include breakpoint(sm) {
              /*
              position: absolute;
              top: 0;
              right: 0;
              bottom: 0;
              left: 0;
              content: "";
              background: linear-gradient(transparent 1%, transparent 29%, rgba(0, 0, 0, .9));
              */
            }
          }
        }
      }
    
      &__teaser {
        position: absolute;
        z-index: 1;
        bottom: 0;
        width: 100%;
        padding: $md;
        //transition: opacity .4s linear;
        opacity: 0;
    
        @include breakpoint(sm) {
          opacity: 1;
        }
    
        color: $white;
        background: rgba(0, 0, 0, 0.75);
        box-shadow: 0 5px 30px 10px rgba(0, 0, 0, 0.3);
        @include center(vertical);
      }
    
      &__teaser-heading {
        display: flex;
        margin: 0;
        color: $white;
        font-size: $h6-font-size;
        font-weight: $font-weight-medium-bold;
        font-style: normal;
        line-height: 1;
        padding-right: 2rem;
        @include center(vertical);
    
        span {
          padding-left: $sm;
          position: absolute;
          right: 20px;
    
          &.fa-plus:before {
            padding: $xsm;
            color: $primary;
            border: 1px solid $white;
            border-radius: 50%;
            font-size: $small-font-size;
          }
        }
      }
    }
    
  • URL: /components/raw/slider/slider.scss
  • Filesystem Path: src/components/slider/slider.scss
  • Size: 3.6 KB