Build a Custom Quote Slider with HTML, CSS & jQuery

In this tutorial, you’ll learn exactly how to make a custom quote slider using HTML, CSS, and jQuery from markup to styling to the interactivity. You’ll have a slider that automatically cycles through quotes, allows manual navigation, and responds well to screen sizes.

Build a Custom Quote Slider

Build a basic slider, but they leave out features you probably want in a real site things like pausing when the user hovers, keyboard controls, or responsive tweaks. Some use heavy plugins which add overhead. By building your own quote slider, you:

Project Structure & File Setup

Let’s define a clean project layout. (I like organizing things this way.)

/quote-slider/
  ├── index.html
  ├── css/
  │    └── slider.css
  └── js/
       └── slider.js

This is minimal but functional. In index.html we’ll link to the CSS and jQuery + slider.js. This separation helps for maintainability.

In each heading below, I’ll show the code segments with explanation.

HTML Markup Semantic & Clean

First, the HTML. Put this in index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Custom Quote Slider</title>
  <link rel="stylesheet" href="css/slider.css" />
</head>
<body>

  <div class="quote-slider">
    <div class="slides-wrapper">
      <div class="slide active">
        <blockquote class="quote">“The only way to do great work is to love what you do.”</blockquote>
        <cite class="author">Steve Jobs</cite>
      </div>
      <div class="slide">
        <blockquote class="quote">“Design is not just what it looks like and feels like. Design is how it works.”</blockquote>
        <cite class="author">Steve Jobs</cite>
      </div>
      <div class="slide">
        <blockquote class="quote">“Programming isn’t about what you know; it’s about what you can figure out.”</blockquote>
        <cite class="author">Chris Pine</cite>
      </div>
    </div>

    <div class="controls">
      <button class="prev">‹</button>
      <button class="next">›</button>
    </div>

    <div class="dots">
      <span class="dot active" data-index="0"></span>
      <span class="dot" data-index="1"></span>
      <span class="dot" data-index="2"></span>
    </div>
  </div>

  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script src="js/slider.js"></script>
</body>
</html>

Explanation of key parts:

  • .quote-slider is the container.
  • .slides-wrapper holds all slides, each .slide is a quote + author.
  • One slide has active class by default.
  • .controls has “prev” and “next” buttons.
  • .dots is a series of clickable dots; each has data-index attribute.
  • The jQuery library is included before our slider.js.

This structure is semantic (using <blockquote> and <cite>) and gives hooks for CSS and JS.

CSS Styling & Transitions

Next, in css/slider.css, we style the slider. Here’s a thorough version with responsiveness and transitions:

/* Basic resets */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Container */
.quote-slider {
  position: relative;
  max-width: 600px;
  margin: 50px auto;
  overflow: hidden;
  background: #f9f9f9;
  padding: 40px 20px;
  border-radius: 8px;
  font-family: Arial, sans-serif;
}

/* Slides wrapper: relative so we can stack slides */
.slides-wrapper {
  position: relative;
  height: 200px; /* adjust as needed or make dynamic */
}

/* Each slide */
.slide {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.6s ease, visibility 0.6s;
}

/* Active slide */
.slide.active {
  opacity: 1;
  visibility: visible;
}

/* Quote text */
.quote {
  display: block;
  font-size: 1.2rem;
  line-height: 1.4;
  margin-bottom: 20px;
  color: #333;
  text-align: center;
}

/* Author */
.author {
  display: block;
  text-align: right;
  color: #666;
  font-size: 0.9rem;
  margin-right: 20px;
}

/* Controls */
.controls button {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  font-size: 2rem;
  color: #888;
  cursor: pointer;
  padding: 0 10px;
  transition: color 0.3s;
}

.controls button:hover {
  color: #555;
}

.controls .prev {
  left: 10px;
}

.controls .next {
  right: 10px;
}

/* Dots */
.dots {
  text-align: center;
  margin-top: 20px;
}

.dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin: 0 5px;
  background: #ccc;
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.3s;
}

.dot.active {
  background: #333;
}

/* Responsive tweaks */
@media (max-width: 480px) {
  .quote-slider {
    padding: 30px 15px;
  }
  .quote {
    font-size: 1rem;
  }
  .controls button {
    font-size: 1.5rem;
  }
}

What this CSS does beyond many tutorials:

  • Uses smooth transitions on opacity and visibility many tutorials simply display: none/block.
  • Hides non-active slides via visibility + opacity to enable CSS transitions.
  • Makes the slider responsive (changes font sizes and padding under 480px).
  • Stylizes dots and hover states.
  • Uses box-sizing: border-box for easier layout.

jQuery Logic & Interactivity

Now, in js/slider.js, we make the slider work:

$(document).ready(function() {
  var $slides = $('.slide');
  var $dots = $('.dot');
  var currentIndex = 0;
  var slideCount = $slides.length;
  var interval = null;
  var autoPlayDelay = 5000;

  function goToSlide(index) {
    $slides.removeClass('active')
           .eq(index)
           .addClass('active');
    $dots.removeClass('active')
         .eq(index)
         .addClass('active');
    currentIndex = index;
  }

  function goToNext() {
    var next = (currentIndex + 1) % slideCount;
    goToSlide(next);
  }

  function goToPrev() {
    var prev = (currentIndex - 1 + slideCount) % slideCount;
    goToSlide(prev);
  }

  function startAutoPlay() {
    interval = setInterval(goToNext, autoPlayDelay);
  }

  function stopAutoPlay() {
    clearInterval(interval);
  }

  // Initialize
  startAutoPlay();

  // Button click handlers
  $('.next').click(function() {
    stopAutoPlay();
    goToNext();
    startAutoPlay();
  });
  $('.prev').click(function() {
    stopAutoPlay();
    goToPrev();
    startAutoPlay();
  });

  // Dot click handlers
  $dots.click(function() {
    var idx = $(this).data('index');
    stopAutoPlay();
    goToSlide(idx);
    startAutoPlay();
  });

  // Pause on hover
  $('.quote-slider').hover(
    function() { stopAutoPlay(); },
    function() { startAutoPlay(); }
  );

  // Keyboard navigation (left / right arrow)
  $(document).keydown(function(e) {
    if (e.key === 'ArrowLeft') {
      stopAutoPlay();
      goToPrev();
      startAutoPlay();
    } else if (e.key === 'ArrowRight') {
      stopAutoPlay();
      goToNext();
      startAutoPlay();
    }
  });
});

Explanation of enhancements:

  • goToSlide(index): central function to show a slide and update dot.
  • Auto-play implemented with setInterval and cleared in stopAutoPlay.
  • After user click (next, prev, dot), we stop then restart auto-play for a smooth experience.
  • Pause on hover: many tutorials omit this.
  • Keyboard support: left/right arrow keys for navigation (nice accessibility).
  • Modulo math ensures looping.

Here’s a quick reference table comparing features (mine vs common tutorials):

FeatureThis TutorialMany Basic Tutorials / Medium BlogPlugin Tutorials
Next / Previous buttons
Dot indicators / navigation❌ or basicOften built-in
Auto-play / cycling
Pause on hoverSome plugin support
Keyboard navigationSometimes
Smooth CSS transitionsOften abruptPlugin default
Responsive behaviorRarelyDepends on plugin
Semantic markupBasic divsVaries
Clean project structureSometimes inlinePlugin-based
Explanation of internalsBasicUsually opaque

Summary

We have walked through how to make a custom quote slider using HTML, CSS, and jQuery with full features auto play, manual controls, dots, pause on hover, keyboard support, responsive styling, and clean project structure. We compared this with three competitor tutorials and highlighted how this version is richer and more practical for real websites.

Related blog posts