Building a Portfolio Carousel with Synchronized Sliders

Undoubtedly, one of the fundamental sections that every personal or business website must have is a Portfolio. In this section the most outstanding works are generally shown, becoming a showcase of our potential.

As well as having a Portfolio full of good works that endorse our performance, the design and functionality of it helps a lot to impress a potential client. For this reason, many of us choose to develop unique Portfolios, with amazing designs and great functionality.

Without further ado, in this tutorial we invite you to develop this elegant and functional Portfolio to get the attention of your potential clients:

Portfolio Carousel

The original design belongs to Francesco Zagami, and is published in Dribbble.

If you follow this tutorial, you will see that it is not very complicated to achieve, especially thanks to the MomentumSlider library, which we already introduced in a previous tutorial. It is highly recommended that you take a look at that tutorial, since that explains the basics about this library.

Let’s start!


Before launching ourselves to develop the design, we must think about how we are going to carry it out, always taking into account the technology that we have available.

In this case, carefully observing the design, we can see that the Portfolio Carousel is composed of 4 independent sliders (images, numbers, titles and links), but synchronized.

With this in mind, we can use the MomentumSlider library without problems, since it allows synchronizing one or several sliders to a main slider. The images could be taken as the main slider, and synchronize the others (numbers, titles and links).

The particularities of each slider are also compatible with our library, so we can start the development!

HTML Structure

Our HTML code will be minimal this time. This is because all the sliders will be generated from JavaScript with the help of the MomentumSlider library. Therefore, our markup will be very simple:

<!-- Container for all sliders, and pagination -->
<main class="sliders-container">
    <!-- Here will be injected sliders for images, numbers, titles and links -->

Please note that we have not included the rest of the decorative elements that you will see in the final demo, in order to focus on the Portfolio code. In the same way, we will not include the CSS code corresponding to these decorative elements, which undoubtedly will make this tutorial more understandable and easier to follow.

In any case, you can always check the complete code in the Github repository.

Adding styles using the new MomentumSlider mixin

Even before we have our sliders in the HTML (because they will be generated dynamically with Javascript), we can already define some styles for them. This will be very easy if we use the new SCSS mixin offered by the MomentumSlider library.

The SCSS mixin to generate the basic CSS styles of any slider created with MomentumSlider, can be found in the path scss/_ms-mixin.scss, and can receive the following parameters:

  • $cssClass: CSS class to match the slider container.
  • $slider-length: Length (width or height) of slider container.
  • $slider-center: If slider should be centered.
  • $slide-width: Fixed width for each slide.
  • $slide-height: Fixed height for each slide.
  • $vertical: If slider should be vertical (true), or horizontal (false).
  • $reverse: If slider should have reversed slides (first items at the end).
  • $debug: Show helpful background colors to help debugging.

And a simple example, using the default values, would be the following:

@import "ms-mixin";

@include ms(
  $cssClass: 'ms-container',
  $slider-length: 400px,
  $slider-center: false,
  $slide-width: 90px,
  $slide-height: 90px,
  $vertical: false,
  $reverse: false,
  $debug: false

Of course, all parameters are optional, using the previous values by default.

As you can see, with this mixin it is very easy to give style to our sliders. Let’s see what the SCSS code for our main slider (images) would look like:

@import "ms-mixin";

// Images

$ms-images-slide-width: 700px;
$ms-images-slide-height: 400px;

// Using SCSS mixin to generate the final CSS code for the slider
@include ms(
  $cssClass: 'ms--images', // CSS class to match the slider container
  $slider-length: 100%,    // The slider container will have full width
  $slider-center: false,   // Don't need to center it, as it is full width
  $slide-width: $ms-images-slide-width,   // Fixed width for each slide
  $slide-height: $ms-images-slide-height, // Fixed height for each slide
  $vertical: false, // The slider should be horizontal
  $reverse: false,  // Normal order
  $debug: false     // No debbug backgrounds in production

Maybe you have noticed that there are several unnecessary parameters, since they are equal to the default values. However, writing all parameters is recommended to avoid confusion, or to be constantly consulting the mixin code.

Also keep in mind that at the beginning, to define the position and dimensions of our slider, it is advisable to define the parameter $debug: true, because this will generate very useful background colors for each element of our slider.

Initializing the slider with Javascript

With all the basic styles defined, we can initialize our main slider (for the images) as follows:

// Initializing the images slider
var msImages = new MomentumSlider({
    // Element to append the slider
    el: '.sliders-container',
    // CSS class to reference the slider
    cssClass: 'ms--images',
    // Generate the 4 slides required
    range: [0, 3],
    rangeContent: function () {
        return '<div class="ms-slide__image-container"><div class="ms-slide__image"></div></div>';
    // Syncronize the other sliders
    sync: [msNumbers, msTitles, msLinks],
    // Styles to interpolate as we move the slider
    style: {
        '.ms-slide__image': {
            transform: [{scale: [1.5, 1]}]

This code will be quite easy to understand, especially if you followed the previous tutorial on the MomentumSlider library.

As you can see, the sync parameter receives an Array with instances of other sliders that we want to synchronize with the new slider we are creating. Obviously, you must have previously initialized those sliders.

In order to focus on the new functionalities of MomentumSliders, we will not detail the code needed to initialize the other sliders, since it is quite similar to what we have already seen. Anyway, in case of any doubt you can consult the full code in Github.

Customizing styles

Having the images slider working properly, we can add the other styles needed to make our Portfolio Carousel look like the original design:

// Custom styles for images slider
.ms--images {
  left: calc(50% - #{$ms-images-slide-width / 2 - 70px});

  &.ms-container--horizontal .ms-track {
    left: -70px;

  // Slides images
  .ms-slide {
    &:nth-child(1) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/harvey-gibson-498362-unsplash.jpg');
    &:nth-child(2) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/andre-hunter-461305-unsplash.jpg');
    &:nth-child(3) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/joanna-nix-389128-unsplash.jpg');
    &:nth-child(4) .ms-slide__image {
      background-image: url('../portfolio-carousel/img/jurica-koletic-321003-unsplash.jpg');

  .ms-slide__image-container {
    width: 80%;
    height: 80%;
    background-color: rgba(0, 0, 0, 0.3);
    overflow: hidden;

  .ms-slide__image {
    width: 100%;
    height: 100%;
    background-size: cover;

One of the main advantages of MomentumSlider is that it allows us to modify the CSS styles of our slider according to our needs without affecting its functionalities. We can add styles of all kinds, as long as we take care not to overwrite the dimensions of the slides.

Adding pagination

The library offers several functionalities out of the box, but if we want a pagination component we must implement it ourselves. However, this is very simple, as we will describe next.

This will be the HTML code that we will use, just one element for each slide:

<!-- Simple pagination for the slider -->
<ul class="pagination">
    <li class="pagination__item"><a class="pagination__button"></a></li>
    <li class="pagination__item"><a class="pagination__button"></a></li>
    <li class="pagination__item"><a class="pagination__button"></a></li>
    <li class="pagination__item"><a class="pagination__button"></a></li>

In this case we will not detail the CSS code needed to make our pagination component looks like the design. Instead, let’s look at the Javascrip code to make it works properly:

// Get pagination items
var pagination = document.querySelector('.pagination');
var paginationItems = [];

// Update initialization for images slider
var msImages = new MomentumSlider({

    // Update pagination if slider change
    change: function(newIndex, oldIndex) {
        if (typeof oldIndex !== 'undefined') {

// Select corresponding slider item when a pagination button is clicked
pagination.addEventListener('click', function(e) {
    if ('.pagination__button')) {
        var index = paginationItems.indexOf(;;

As you have seen, adding a pagination component is relatively easy, thanks to the features offered by the library.

Making it responsive

Making our Portfolio Carousel looks great on small screens is not such a complex task neither. We just have to fix some positions and solve some minor issues:

// Responsive styles

@media screen and (max-width: 860px) {
  .ms--numbers {
    left: calc(50% - #{$ms-numbers-slide-width / 2});

  .ms--titles {
    left: calc(50% - #{$ms-titles-slide-width / 2});
    top: calc(50% - #{$ms-titles-slide-height / 2 + 50px});
    text-align: center;

  .ms--links {
    left: calc(50% - #{$ms-links-slide-width / 2});
    top: calc(50% + #{$ms-links-slide-height / 2 + 50px});

  .pagination {
    left: 50%;
    top: calc(100% - 50px);
    transform: translateX(-50%);

@media screen and (max-width: 600px) {
  .ms--images {
    overflow: visible;

@media screen and (max-width: 400px) {
  .ms--titles {
    .ms-slide {
      transform: scale(0.8);

That’s it, now our Portfolio Carousel looks great on screens of any size.


And that is all! During this tutorial we have seen the essential elements to create an elegant Portfolio Carousel.

You can see the final result, as well as the Codepen demo. Also, remember that you can check the complete code in the Github repository, where you can see all the details.

We hope you get a lot out of the MomentumSlider library, which we will continue improving to allow us to create even more amazing sliders 🙂

Happy coding!


0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x