Create a Scrolling Image Slider in React
I’ve been using React to build try out cool features on my portfolio and built out a simple scrolling image slider to display my skills.

To build this, I am implemented HTML(as JSX in React), CSS, and JQuery. I’ve recreated this functionality in CodePen to walk through how this was built: https://codepen.io/rmody3/pen/EXObmR

Let start with the HTML (as JSX)
We have our main component “App” and in that component we will render all the JSX.
render() {
return <div className="main">
<h1 className="title">Scrolling Image Slider</h1>
<div className="wrapper">
<a className="prev" onClick={this.scroll.bind(null,-1)}>❮</a>
<div className="image-container">
<div className="image">1</div>
<div className="image">2</div>
<div className="image">3</div>
<div className="image">4</div>
<div className="image">5</div>
<div className="image">6</div>
<div className="image">7</div>
<div className="image">8</div>
<div className="image">9</div>
<div className="image">10</div>
</div>
<a className="next" onClick={this.scroll.bind(null,1)}>❯</a>
</div>
</div>;
}React requires each component to only render one DOM element, so we must nest other elements inside a “main” div. Inside this we create a title header. Next we create another div that will wrap the prev and next buttons with a container of all the images. In the example used in CodePen, I created div’s rather than images, but you could easily replace this with an image element.
The CSS
Lets start with formatting the whole “main” div:
.main {
text-align: center;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: space-around;
}We make sure everything is center aligned and the height takes up the whole viewport. Then we can add a display of flex in the column direction with space around, so that the Title and the Image Slide Wrapper are centered and spaced out evenly on the screen.
For the image:
.image {
height: 100px;
width: 100px;
font-size: 25px;
background: blue;
margin: 10px;
display: inline-block;
line-height: 100px;
}We create a square, give a font size, give a margin, and a background. Remember in my example the image is actually just a div. I then provide a display of “inline-block”.
This is one important aspect to make the image slider work. So, what actually is the difference between inline, block, and inline-block. Here is a really good visual to explain:

The Stack Overflow answer by OldSkool for this question provides a good explanation: https://stackoverflow.com/questions/9189810/css-display-inline-vs-inline-block. Basically blocks force line breaks, inline elements can have left and right margins but allow elements to sit left to right, and inline-block elements are a hybrid that allow elements to sit left to right, but respect height and width of elements along with all margins.
Back to creating an image slider. The last bit of css I add for each image is a line-height equal to the size of the element so that the text is vertically centered.
Onto the image-container.
.image-container {
vertical-align: middle;
display: inline-block;
width: 50%;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}We vertically align the image container to the middle. The vertical align property controls how an element's sits next to other elements inline. Without this property, they will align at the baseline, like below:

Once again we add a display of inline-block to the entire container. This time we want to make sure the container is actually line with the arrows. We could use inline, but then we cannot control the width of the element. If we let the width be 100% then the arrows will not be inline with the container and depending on the number of images you have, you would not get a scrolling effect because all images would fit on the full width of the page.
The last 3 CSS properties, white-space, overflow-x, and overflow-y,are what allow the images to be hidden from view until we scroll or click the arrows to scroll. White-space set to “nowrap” will override the default wrapping in a div. Otherwise our image container would look like this:

The overflow-x set to auto and overflow-y set to hidden ensure that we can scroll horizontally and not vertically. The default is that it would visible beyond the size of the div, which we do not want. Setting to auto ensures that we can scroll.
That is pretty much the meat of creating the CSS. The last bit is just adding styling to the arrows.
.prev, .next {
padding-top: 10px;
padding-bottom: 10px;
height: 100%;
margin: 0 auto;
cursor: pointer;
color: black;
transition: 0.6s ease;
}.next {
margin-left: 5px;
}.prev {
margin-right: 5px;
}.prev:hover, .next:hover {
color: white;
height: 100%;
background-color: rgba(0,0,0,0.8);
}
For the arrows we add some padding and margins. We want the cursor to be a pointer when we are pointing on the arrow. On hover we change the color from black to white and add a background color of black with an opacity of 0.8. We also add a transition between the 2 states.
The last step is adding the scroll on click functionality to the arrows.
To do this we use a bit of JQuery. First, lets add a function to our arrow link:
<a className="prev" onClick={this.scroll.bind(null,-1)}>❮</a><a className="next" onClick={this.scroll.bind(null,1)}>❯</a>
Then we add bind the function to “this” class in the constructor and define the function.
class Application extends React.Component {
constructor(){
super()
this.scroll = this.scroll.bind(this)
}scroll(direction){
let far = $( '.image-container' ).width()/2*direction;
let pos = $('.image-container').scrollLeft() + far;
$('.image-container').animate( { scrollLeft: pos }, 1000)
} our
The reason we need to bind the function is because this function is a callback. When this component is mounted we do not want the scroll function to run, only when we click on the arrow do we want it to run. If we don’t want it to run immediately and we don’t bind it the class, then the function will try to look at global scope, but we need it to look specifically to the scope of the class we are in, or the current component, which is why we bind it to “this” on the constructor. We then also bind it to a direction -1 or 1 to be passed as an input into the scroll method without actually calling the function on mounting.
The scroll method uses JQuery to find half the width of the container and then multiplies it by the direction -1 or 1. This gives us how far we want to scroll. If the direction is negative (bound on the previous arrow click) we scroll left half the width of the container, if positive we scroll half the width of the container to the right. We then calculate the position we are going to based on adding the the current position found by the scrollLeft() jquery function and the calculated distance. Lastly we animate the container to scroll to the newly calculated position, with an animation time of 1 second.
Now we have a scrolling image slider in React. This is a basic example and can be modified to determine the right scrolling amount, or even scroll by a set of images. I hope this provided you with a good guideline to implement in your next React project.
