Sunday, August 18, 2013

Part 2: Adding Arrows in Carousel Using CarouFredSel

This is part 2 of the series on using the CarouFredSel plugin. If you haven't read Part 1 of this series, then I would recommend you to go through it before you continue with this post.

So, today we're going to look at how to add "Next" and "Previous" buttons to our carousel using CarouFredSel. 

What we're starting with

We'll continue from where we had left our demo template in Part 1. To give you a quick overview, in part 1, we had designed and coded a very simple one page HTML/CSS based website where we applied CarouFredSel plugin on our featured image area. Here's the screenshot of what we have right now.


Currently, this is how our site looks like

The area where you see an image of a biker is our featured area. Anyway, we're going to take this template a step further by adding "Previous" and "Next" buttons to our existing carousel.

Step 1: Visit CarouFredSel's Website

As I mentioned earlier, carouFredSel has a very detailed documentation on its official website. To get an idea of how to add Previous/Next buttons, we'll visit its website. On its homepage, scroll down a little bit until you get to the section named Examples. Here, you should see 2 example sliders. The first one is a simple carousel with no interaction capabilities (no pagination and no prev/next buttons). The second slider is the one we're interested in because it has both, pagination as well as prev/next buttons embedded in it (refer to the screenshot below).

Slider No. 2 on carouFredSel's official website

Notice that both slider examples have 3 links at the bottom of their container (namely view JavaScript, view HTML and view CSS) that are used to view the corresponding HTML, CSS and JavaScript (see the screenshot below). 

Buttons for viewing slider code

Since we want to find out how to implement Previous and Next buttons, therefore, we'll first click on the view HTML tab to see what additional markup do we need. The screenshot below highlights the area that we should add in our HTML code. For your convenience, I've also pasted that code below.
<a class="prev" id="foo2_prev" href="#"><span>prev</span></a>
<a class="next" id="foo2_next" href="#"><span>next</span></a>

HTML code for Previous and Next buttons

To copy the code I've highlighted above, hover over the black area, where all the HTML coding is shown. You'll notice that at the top-right corner of the black area, four icons will suddenly appear. (see the screenshot below)

Icons on the view source window

From the icons shown above, click on the first one to view the source code as plain text inside a separate popup window.

View Source Code Window

Just select and copy the code I've highlighted above and move on to step 2.

Step 2:  Edit Existing HTML

Now that we've copied the markup from carouFredSel's website, the next step is to paste this code into our own HTML (the one we wrote in Part 1). So open up the HTML file we were working on previously and find the div with a class of .featured-area-container. Inside this div, paste the code that you copied in step 1, just after the .featured-area div. Refer to the screenshot below.


Updated .featured-area-container div
After copy/pasting the code, our  updated .featured-area-container will look something like the following:

<div class="featured-area-container">
     <div class="featured-area">
          <img src="images/image1.jpg" alt="#" />
          <img src="images/image2.jpg" alt="#" />
          <img src="images/image3.jpg" alt="#" />
          <img src="images/image4.jpg" alt="#" />
     </div><!-- end .featured-area -->
     
     <a class="prev" id="foo2_prev" href="#"><span>prev</span></a>
     <a class="next" id="foo2_next" href="#"><span>next</span></a>
</div><!-- end .featured-area-container -->

The id attribute used for the prev and next buttons is very important as they'll be used inside our JS to attach previous and next events to our slider. Feel free to name these ids anything you like.

Note: In the comments section of part 1, a guy named Sangeeth pointed out that the div with a class of .featured-area is never used in the CSS. You might be thinking that "yea he's right, so why the heck are you using this div?". And yes this div might not be very useful from the CSS point of view but the thing is that this kind of structure is very important for carouFredSel to work properly, otherwise strange things can happen. We have to have a main container div (in our case .feartured-area-container) inside which there should be another div for containing all the images or content we want to scroll through (in our case .featured-area ). As for the Prev/Next buttons, they should reside inside the main container div, but outside the inner div.

Let's open up our website in the browser and see what output do we get.

Prev/Next buttons are displayed

Notice that we've successfully managed to show the Prev/Next button's text but since we haven't added any JavaScript inside carouFredSel, therefore it doesn't know what relation these buttons have with our slider images. We need to somehow connect these buttons with our slider. For that, move on to step 3.

Step 3:  Add Some JS

Visit carouFredSel's website again and scroll down to Slider No. 2 (as discussed above). This time rather than viewing the HTML, click on the view JavaScript tab. 


JavaScript for Slider No. 2
Clicking on the JavaScript tab will reveal the JS for Slider No. 2. The code revealed might look somewhat similar to the one we wrote in our last tutorial when we activated the carouFredSel slider by using the following code.

<script>
$(function() {
   $(".featured-area").carouFredSel();
});
</script>

The difference is that the newly revealed code has some configuration options written inside the carouFredSel function which we didn't add in our previously written JS. To connect the prev/next buttons to our featured slider, we need to add some part of these configuration options to our existing JS as well. So let's filter out what code do we need from the view JavaScript tab.


Code to be added to our existing JS

The screenshot above highlights the code that we need to add in our existing JavaScript. Note that I've highlighted the starting and ending curly braces as well. These braces should be added inside the parenthesis of the carouFredSel function, after which we'll start adding all the configuration options. By adding this code, our updated JS will become something like the one I've written below:

$(".featured-area").carouFredSel({
   prev : {
      button : "#foo2_prev",
      key : "left"
   },

   next : { 
      button : "#foo2_next",
      key : "right"
   }
});

Notice that in the screenshot above, I've asked you to remove the comma after the next block of code. This is because although every configuration option is separated by a comma, but if we'll add it at the end of the last option, the browser might not run the plugin properly. Therefore, it is necessary to remove the comma after the last configuration option.


Brief Explanation of the JS

In the code above, prev and next are built-in options for carouFredSel. Inside these options, several property-value  pairs are possible. In our case we've used the button and key properties. 

The button property is used to hook an id to the prev option after which that particular anchor/button will move the slider content backwards. Same is true for the next option, with the exception of moving the slider forward (Duhh!!!).

The key property is used to attach a keyboard-key (in the form of its keyCode number or a string like "up", "down" etc.) to scroll the carousel. In our case, we've used "left" value for the prev option and "right" for the next


To find a complete list of these configuration options with their brief description, visit carouFredSel's official website and navigation to the Configuration page. There you'll find all possible options and their properties that are available for carouFredSel.


Configuration page on carouFredSel's website

Test it out!!!
Let's refresh our webpage again to see if everything's working properly. And voila! it has started working. Click on the next and prev buttons to scroll forward and backwards respectively. Also, try your keyboard arrow keys ("right" and "left") to scroll the slider and hopefully it'll work properly as well.

So this is actually it!!!. At this point we have a perfectly working carousel with Previous/Next buttons attached to its movement. But you might be thinking "Well I don't see any arrows!!!" well for those arrows, we'll be working on that shortly. But at this point, just make sure that you've followed every single step I've mentioned above and all is working fine.


Section 2: Replacing Text with Arrows

This is the next section of this tutorial where we'll replace the prev/next buttons with arrow images. We'll be using CSS sprites in this section.

Download PSD for Arrows
The first step in replacing text links with arrows is to actually find some PSD arrows. I searched Google and found the following link:


Download Page for PSD Arrows

On this page, you'll immediately notice that there's a big red download button at the bottom. Click on this button which will direct you to a page where you'll again see a download button. Click on it to start the download.


2nd Download Page for PSD Arrows


After you click on the download button, you'll get a .ZIP file that contains a PSD file for the arrows. Just right-click on the .ZIP file and select the Extract Here option from the context menu. Once extracted, you'll see a PSD file.


Extract the downloaded .ZIP file 

Open up the downloaded Photoshop (.PSD) file. The screenshot below shows what this PSD contains.


Contents inside the PSD 

Creating PSD Sprite for Arrows

To create the sprite of these arrows, we first need to isolate them. Open up the arrows' PSD, if it is not already opened. Now press F7 to invoke the Layers Panel or simply click on the Layers panel icon on the right (as shown in the screenshot below).


How Layers Panel icon looks like in Photoshop

After opening the layers panel, you'll notice that the layer groups are assigned different colors for easy identification. Blue colored layers contain blue arrows and orange color represents layers with orange arrows. For our featured slider, we need to create a sprite from these blue and orange arrows.


Layer associated with arrows


Side Note: A sprite is basically one big image that contains all the different states (normal, hover or active state) of an object(s). For a detailed article about sprites visit this website.


Once you understand how layers and their contents are organized, the next step is to select these arrow layers and move/drag them on a separate file. To do this, create a new document that is 225px wide and 216px high with a resolution of 72 (72 because we're working for the web). 


New document for arrow sprite


After creating the new document, switch to the arrows PSD and select all the 4 small arrows by selecting their layers from the Layers Panel. To achieve this, first make sure that the Move tool is selected (press "V" to select the move tool it if it isn't already selected) and then click on the top-most layer (the layer named "Arrow Left Small Blue") and then while holding down the Shift key, click on the fourth layer (the layer named "Arrow Right Small Orange"). This will select all the layers that are in between these two layers (refer to the screenshot below).


Selection of all arrow layers


After you're done with the selection, click on the arrows that are visible on the artboard and drag them on the new file tab that we made for our arrow sprite (the file with the name Untitled-1). When you drag the layers on the Untitled-1 file tab, make sure to hold your left mouse button for a second on this tab until Photoshop switches to the file named Unititled-1. Once switched, release the mouse button and then adjust the arrows such that they're centered on the document.




Drag arrows to the file tab Untitled-1

After positioning the arrows in the center of the new document, hide the Background layer by clicking on the eye icon on the left of this layer. We did this because we want these arrows to have a transparent background so that we can place them on any background on our website.


Hide the Background Layer

After hiding the background layer, press CTRL + ALT + Shift + S or go to File > Save for Web to save these arrows for the web.

File menu to Save for web

When you choose the Save for Web option, its dialog box will appear. There you'll see a dropdown where you have the option to select the type of file you want to save your images into. Select the PNG-24 option from the dropdown and then click on the save button at the bottom.

Save for Web dialog

After clicking on the Save button, you need to tell Photoshop the location where you want this file to be saved. In our case, we'll save it inside the images folder which resides in our website's root folder. You can give this file a name of your choice. Press the Save button and we've successfully saved our PSD arrows as a sprite.



Save sprite in images folder


Applying Sprites into our Website
Now that we've saved our sprite, the next step is to replace the prev/next links with our newly saved arrows. This process entirely relates to CSS and nothing else. Open up the index.html and style.css (the files we created in Part1 of this series) in a text editor of your choice (As always, I'll be using Sublime Text 3). As discussed earlier, our HTML has the following div with a class of .featured-area-container (see below).

<div class="featured-area-container">
   <div class="featured-area">
      <img src="images/image1.jpg" alt="#" />
      <img src="images/image2.jpg" alt="#" />
      <img src="images/image3.jpg" alt="#" />
      <img src="images/image4.jpg" alt="#" />
   </div><!-- end .featured-area -->
   <a class="prev" id="foo2_prev" href="#"><span>prev</span></a>
   <a class="next" id="foo2_next" href="#"><span>next</span></a>

</div><!-- end .featured-area-container -->

To replace the prev/next text with our sprite arrows, we need to target them in our CSS by using either their corresponding class or id (it's totally up to you). I normally use classes instead of ids because classes have lower specificity and whenever I want to override a specific rule, ids come in handy. Anyway, to target the Previous button, we'll be using its .prev class and for the Next button, .next class will be used.

Now switch to the style.css file and add a new section comment for featured arrows. I usually comment my CSS sections like so:

/**
=================================================================
FEATURED ARROWS
=================================================================
**/

Commenting your code is a good practice but is not necessary. After the section comment, we'll start styling the prev and next buttons. We'll start off by writing all the properties that are common to both the .prev and .next classes. To do this, we'll separate both class names by a comma as shown below:

.prev, .next { }

Inside the curly braces, the first property we're going to apply is the background property. We'll use shorthand for this property to apply a background image and at the same time tell the browser not to repeat the image by using the no-repeat value. Our code now looks like the code shown below:

.prev, .next {
   background: url("../images/arrow-sprite.png") no-repeat;
}

When a background image is used in CSS, it is necessary to specify the image's width and height property, otherwise the image won't show up. Since we're working with sprites, therefore, we'll specify only the area that we want to be visible at one time (which is the width and height of a single arrow). 

To find out the width and height of an arrow, open up the .PNG sprite file that we saved previously in Photoshop and select the Rectangular Marquee tool from the Tools panel on the left. Create a rectangular selection around any one of the 4 arrows such that the selection is just about the size of the arrow. While the selection is still active, open the Info Panel by either pressing F8 key on the keyboard or going to Windows > Info. Inside the Info panel you'll notice that there's a section where W: and H: are written (as highlighted in the screenshot below). This is where you can see the size of the selection you've just made (in our case both width and height are equal to 89 pixels). We'll use these width and height values in our CSS.


Marquee Selection to find width & height of an arrow

Once we know the width and height of the area we want to be visible, switch back to the style.css file and after the background property, add the width and height property with a value of 89px. Our code now becomes something like below:

.prev, .next {
   background: url("../images/arrow-sprite.png") no-repeat;
   height: 89px;
   width: 89px;
}

We've added the size of the background image but still if you'll refresh the browser, you won't see any change in your website. Why? That's because the width and height property won't work until we change the display of our buttons to block. So that's exactly what we're going to do next. Below is our updated code.

.prev, .next {
   background: url("../images/arrow-sprite.png") no-repeat;
   display: block;
   height: 89px;
   width: 89px;
}

After adding the display: block declaration, our website will now look like the screenshot below:


Arrow are visible but with some problems

As you can see in the image above, despite the fact that our arrow images are visible in the background of their corresponding buttons, there are still 3 problems we're facing.

Problem # 1: The text of Prev and Next buttons are still visible.
Problem # 2: The arrow image that is displayed in the background of the Next button is not correct. We need to somehow tell the browser to change the image position inside the sprite, such that the arrow that points to the right is visible.
Problem # 3: The arrow images we've added are cropped from their right edge.


Solution for Problem # 1:
This is kind of a hack that designers usually use to make the text invisible. There's a CSS property named text-indent that pushes the text as much as we like. So actually we don't make the text invisible, rather we push the text to such an extent that it is not visible within the boundaries of our website. I normally use a value of -9999px for the text-indent property, just to be on the safe side. So after adding this declaration to our previous CSS, our updated code looks like below:

.prev, .next {
   background: url("../images/arrow-sprite.png") no-repeat;
   display: block;
   height: 89px;
   text-indent: -9999px;
   width: 89px;
}

Here's the result:


Problem # 1 is solved


One down, two to go!!!

Solution for Problem # 2:
To solve this problem, you need to understand how CSS sprites work. Well it's a bit difficult to explain this, but I'll give it a shot. 

The thing is that even though the sprite we usually create, consists of many icons or images, the browser only shows the area that has a size equal to what we specify for the the width and height property of the sprite background. Moreover, this width and height area we specify is calculated from the top-left corner of the sprite image. In other words, the top-left corner is its origin (where x and y coordinates are equal to zero). 



Width & height calculation for sprites

So in simple words, CSS sprites have an origin fixed to the image's top-left corner and any width and height that we specify is calculated from this origin. At the moment, we can see that the blue-left arrow is in the range of our specified width and height so that's why the browser is displaying it in the background of both Previous and Next buttons.

If we want to display the blue-right arrow in place of the next button, we have to change the background-position property for the .next class. So create a new class selector for the class that is linked to the Next button in our markup (i-e: .next) and give it a background-position property of -128px 0. The first value, -128px, is for the x-axis and the second (0) is for the y-axis. Our code will look like the one shown below:

.next {
   background-position: -128px 0;


Here's the result:


Problem # 2 is solved


Why -128px?
You might be wondering about the usage of a negative value for the x-axis. Well as I've mentioned earlier, the display frame for a sprite remains at the top-left corner (origin) of the image and the size for the display frame is calculated from the width and height property we specify for our sprite. So instead of moving the display frame, we have to change the position of the sprite until the desired part of the sprite comes inside the display frame. 

In our case, we want the blue-right arrow to be displayed in the background of the next button, so we'll move our sprite to the left by specifying a background-position of -128px for the x-axis. Just remember one thing, x-axis values become negative when the sprite is moved to the left and it becomes positive when the sprite is moved to the right. Similarly, when the sprite is moved upwards, y-axis values become negative and when moved downwards, it becomes positive (refer to the two screenshots below).

Sprite position axis



Sprite movements with their values


Solution for Problem # 3:
After understanding the way sprites work and how we can change the position of a background image by using the background-position property, solving problem # 3 is not a big deal. 

Since the problem was that the arrow images are cropped from their right edge, therefore, if we'll just move the background position of the sprite slightly to its left, then the image will fit into the display frame and hence will display properly. 

First we'll apply the background-position property to the Previous arrow image by using the following code.

.prev {
   background-position: -5px -2px;


We've moved the sprite to its left by giving it a value of -5px in place of its x-axis and we've used a value of -2px to move the sprite upwards. 


Before and After states of the Previous button


As for the Next button, we've already set its x-position (horizontal) in step # 2, all we need to adjust is its y-axis (vertical) value. For that, we'll use the following code to correct its background position.

.next {
   background-position: -128px -2px;




Before and After states of the Next button

Adding Hover States
We've come a long way now and fortunately, we're almost there. The next thing we need to consider is adding a hover state on both previous and next arrows. For that we'll use the .prev and .next classes with a :hover pseudo class prefixed with their class names. See the code below:

.next:hover {
   background-position: -128px -124px;
}

.prev:hover {
   background-position: -5px -124px;
} 

For the hover states, I've moved the sprite image in a such a way that the orange arrow comes within the display frame. It's really a trial and error method where we decide what values suit our needs, so don't worry if you don't get these positions correct in your first attempt. Now you can hover over both buttons and you'll see that they're replaced by the orange colored arrow. This is how our prev button looks like in its hover state:



Hover state for the Previous arrow button

Final Step - Positioning the Arrows
The final step of this tutorial is about positioning the arrows in their proper location. For that, we need to position these arrows relative to the .featured-area-container div. So our first step is to set the positioning context for the .featured-area-container to relative.

.featured-area-container {
   position: relative;
}

An absolute position element is positioned relative to the first parent element that has a position

Positioning relatively means that this element is positioned relative to its normal position. Next, we need to confine both .prev and .next buttons within the .featured-area-container div. So we'll set the position for the .prev and .next classes to absolute. An absolutely positioned element is positioned relative to the first parent element that has a position value of relative (in our case, .prev and .next buttons are positioned relative to the .featured-area-container div). Our updated code for the two classes become as follows:

.prev, .next {
   background: url("../images/arrow-sprite.png") no-repeat;
   display: block;
   height: 89px;
   text-indent: -9999px;
   width: 89px;
   position: absolute;
}

After setting a positioning context, our website will look like the screenshot below:


Our website after setting a positioning context

From the look of the screenshot above, It may appear that something has gone wrong (like the previous button has disappeared), but actually everything is in its place. Since we've positioned both arrows relative to the .featured-area-container div, therefore, one arrow is now on top of the other. 

After setting an absolute or relative positioning context, elements can be positioned by using the top, right, bottom and left properties. To position these arrows in the middle of the slider, we need to first specify a top value that is common to both .prev and .next buttons and then a separate left and right values for the .prev and .next buttons respectively. See the updated code below:

.prev, .next {
   background: url("../images/arrow-sprite.png") no-repeat;
   display: block;
   height: 89px;
   text-indent: -9999px;
   width: 89px;
   position: absolute;
   top: 180px;
}

.prev {
   background-position: -5px -2px;
   left: 10px;
}

.next {
   background-position: -128px -2px;
   right: 10px;
}

Here's the final screenshot of our website after applying the above properties.


Final screenshot of our website


Final Code
Below is the final CSS code that we discussed/added in this tutorial.

/**
=================================================================
FEATURED ARROWS
=================================================================
**/

.featured-area-container { position: relative; }

.prev, .next {
   background: url("../images/arrow-sprite.png") no-repeat;
   height: 89px;
   width: 89px;
   display: block;
   text-indent: -9999px;
   position: absolute;
   top: 180px;
}

.prev { 
   background-position: -5px -2px;
   left: 10px;
 }

.prev:hover { background-position: -5px -124px; }

.next { 
   background-position: -128px -2px;
   right: 10px;
}


.next:hover { background-position: -128px -124px; }


Conclusion
In this tutorial, we've looked at how we can add arrows in our carousel using carouFredSel plugin. As always, I tried my best to explain every single step in as much detail as possible. But I'm always open to answer your questions, so feel free to ask me anything related to this post in the comments section. I'm not sure but I may write another part for this tutorial series but until then, try to experiment with the options this plugin has to offer. See you later.


No comments:

Post a Comment