27 Sidebar Slider

Posted: Dec 3, 2005, under WordPress, DHTML. Updated: Apr 6, 2006. Add a comment!

Let me ask you some questions: what use is an empty sidebar? Does the layout of your blog use columns? Do you often find yourself scrolling down a long page and having a column empty for miles and miles? If the answer is yes, this plugin is for you.

Note: This plugin works in WordPress versions 1.5.x and 2.x. I haven’t tested it with older versions so I have o idea whether it would work.

1. Plugin overview

1.1. Background

Together with JS Toggle Boxes, this plugin is part of my personal vendetta against what I consider to be one of the biggest usability problems with blogs: long, disproportionate columns, which run forever without any practical use.

This is actually a well known issue with multi-column layouts, and is even more pressing on blogs. Because of their particularities, almost all blogs need a sidebar. Having the height of the sidebar match the height of the content is a coincidence at best. Most often, one of them runs short at some point during scrolling, and you’re left with empty space for the remainder of the page.

1.2. What it does

This WordPress plugin makes block elements slide up and down on their respective columns as if they were elevators, while you scroll through the page. This way, visitors can always have the contents of the sidebar, for instance, within easy reach. You’ll never waste screen space again.

The plugin uses JavaScript, which is available to some 98% of all visitors, according to statistics. Those that don’t have it activated, won’t miss a thing: they’ll simply get static columns, which they’re already getting now.

The plugin uses a smart positioning algorithm. As such, it will follow the visitor’s scrolling in a sensible manner, allowing him to access any part of the page (be it sliding or not) at any time, with minimal effort.

1.3. Plugin demo

Just watch the sidebar and the main page content on this blog. Scroll the pages up and down and see how the useful content follows you around efortlessly.

1.4. Distribution terms

This plugin can be freely distributed, modified and used under the terms of the MIT License.

1.5. Additional credits

  • Thanks to ppk and www.quirksmode.org for some great JavaScript documentation.
  • t.A.T.u. and their single “Friend or Foe”, which helped on the final stretches for the 1.0 release.

1.6. Contact

Leave a comment or use the contact page. I’m pretty busy so I don’t guarantee a response, but I read all mail and comments.

2. Get the plugin

  1. Current version is 1.1.
  2. Grab the plugin here: sidebar_slider.txt.
  3. Rename it to sidebar_slider.php.
  4. Upload it to the wp-content/plugins/ directory under your WP installation.
  5. Go to your WP administration panel, under “Plugins”, look it up in the list and activate it.

3. How to use the plugin

The plugin can be used with almost any WP theme. However, it takes a bit of (X)HTML and CSS to know what page elements to hook it up to. For those with the knowledge, it should be pretty easy. I will try to make the instructions very helpful so even beginners can use them, but I can’t possibly cover all possibilities. You have been warned.

3.1. Initialize the plugin

First, you have to edit your theme and add a call to the SLIDE_init() function somewhere. The best place is within the <head></head> part of the page, which is usually located in the header.php file in the themes. Edit it and add a line such as this:

<?php if (function_exists('SLIDE_init')) SLIDE_init(true); ?>

The function takes one parameter, which is optional.

If set to false, the JavaScript code is made part of every site page. If set to true, it instructs the plugin to offload the largest part of the JavaScript code at a separate URL, so that browsers can cache it better.

Caution: Depending on the characteristics of your hosting service, NOT offloading may make your pages load faster! Test both ways.

False is the default for the offloading, because there’s less potential for trouble that way.

Note: If you protect your plugins via .htaccess AND you offload the code, you will have to make an exception for the plugin file.

In order to make an exception for the offloading to work, edit your .htaccess and add something like this:

<Files ~ "^sidebar_slider.php">
  Allow from all
</Files>

3.2. Identifying the (X)HTML elements

3.2.1. Finding the slider

Here comes the tricky part: identifying the page element (or elements) that should be sliding, through their id attributes.

Note: It has to be an id attribute. Using class attributes won’t work.

Finding a slider should be easy with a well done theme. Usually, most of them already have a <div> XHTML element with id="sidebar". That name (”sidebar”) is what you’re looking for.

3.2.2. Finding the container

Alongside the slider, we also need to identify a container element, which will act as sort of a guideline, like the rails for a train, if you want. The slider will use the container’s top edge to know how high it can go, and the container will also serve to guide the slider in its up-down motion.

Note: The container must also have a unique id attribute.

It may be a bit trickier to find a good container.

  • Some themes already have a <div> called “page” or “wrapper” or something along those lines, placed close to the <body> element.
  • If they don’t, you can try applying an id="something" to the <body> element itself (yes, it works… sometimes).
  • You can try to create an empty <div> in a strategic place yourself, and give it an id.

3.2.3. Finding a breaker

There is a special case you may run into with some themes. Let’s say you chose the slider and container well. The slider works, goes up and down as needed, and stops well at the top. BUT it doesn’t stop well at the bottom, and overlaps with the footer (the part where you write about copyright and stuff).

For such special cases, you must identify the footer as a breaker. This means that the slider will know it should watch out for it and not go lower than it. The overlap effect is thus prevented.

Why does this happen? Take the following example, which I’ve seen in some of Becca’s themes:

<div id="wrapper">
  <div id="content">...</div>
  <div id="sidebar">...</div>
  <div id="footer">...</div>
</div>

This case is in obvious need of a breaker. “Wrapper” is the container, while either “content” or “sidebar” (or both) are the sliders. But “wrapper” also envelops “footer”. Therefore the sliding elements will follow it all the way down and overlap the footer at the bottom. So we mark “footer” as a breaker.

3.2.4. Tips and tricks

These are some tips and tricks you can take a look at when all seems lost:

  1. Ideally, the container should envelop the slider, but there are imaginable cases where a container and its slider can run side by side. But try not to use “sidebar” as the slider and “content” as the container. If anything, it can lead to some pretty strange effects. Plus, you won’t be able to slide the content as well.
  2. Sometimes you want to slide the contents of a table cell. I’ve done it in the theme you see on this side: the sidebar is a table cell. This can be achieved by using the <td> as a container and a <div> inside it as the slider.
  3. Don’t be afraid to create your own <div> elements, in order to obtain either a container or a slider.
  4. Don’t forget: elements need to open, but they also need to close! For every <div> there’s a matching </div>.
  5. Hot tip: apply text styling to the sliders, not to the containers! Padding is especially important for sliders, and particularly top and bottom padding. If you apply padding on the container, things will look fine… at first. But as you scroll through the page, the slider comes to touch against the top or bottom margin of the browser window! So if the slider itself doesn’t have padding, the text will touch the browser margin and it will look crammed and ugly.
  6. You can slide more than one element at the same time! Of course you can. Not only sidebars can run short alongside a beefy content; it can happen the other way around, when you write a short post and the sidebar is too big. So you can slide both the sidebar and the content. I’ve done it on this very site. Check out my contact page to see it in action.

3.2.5. Examples

I will attempt to add some of the most common case scenarios here, to help those who have trouble locating the elements in their themes. You can also read the comments to add or ask for real world examples.

  1. <div id="wrapper">
      <div id="content">...</div>
      <div id="sidebar">...</div>
      <div id="footer">...</div>
    </div>
    “Wrapper” is the container, “content” and “sidebar” can be sliders, “footer” has to act as a breaker.
  2. <table>
    <td id="content">...</td>
    <td id="sidebar">...</td>
    </table>
    Create <div> elements inside the cells, and use them as sliders and the cells as containers. No need for breakers in this case. Remember to transfer text styling, and especially padding, to the sliders.
    <table>
    <td id="content"><div id="slider-c">...</div></td>
    <td id="sidebar"><div id="slider-s">...</div></td>
    </table>

3.3. Mark the elements

So, you’ve sweated a lot, but now you’ve identified the id’s for the slider, the container, and possible for a breaker. Time to tell the plugin their names.

Warning: You can call SLIDE_add() anywhere you’d like, but do it after SLIDE_init() and before SLIDE_activate().

To mark elements, use something like in the following example.

<?php
  if (function_exists('SLIDE_add')) {
    SLIDE_add(
      'wrapper', // container id
      'sidebar', // slider id
      'slide the sidebar', // short description
      'SLIDE_sidebar', // cookie name
      0.75, // sliding speed
      100, // update interval
      'footer' // breaker id
    );
  }
?>

Parameter explanation:

  1. Container id: a string which contains the name of the container element.
  2. Slider id: a string which contains the name of the slider element.
  3. Description: not used for now. Later, I plan to allow your visitors to enable and disable sliders at will. When that happens, this text will be used to accompany a checkbox. For now, you can just use an empty string. Or you can prepare for the future and use proper text already.
  4. Cookie name: again, not used for now. Use an empty string or prepare for the future and use a good text already.
  5. Sliding speed: a fractional number between 0 (zero) and 1 (one). This is optional, and the default is 0.75. The bigger the number, the higher the speed at which the slider moves. Use 0 (zero) to make the slider teleport directly to the new position, without sliding.
  6. Update interval: an integer number, expressed in milliseconds (1/1000th’s of a second). This is optional and the default is 100 (1 tenth of a second). It defines how often the slider checks and updates its position. 100 is a good value. At 200 you will probably notice the slider going in a “jerky” motion, instead of a smooth one. But you can also use a big number here (such as 2000 = 2 seconds) and zero for the speed, which will consume the least CPU on the visitors’ machines. Experiment yourself with these values.
  7. Breaker name: a string which contains the name of the breaker element. This is optional, since not all sliders need a breaker. If you don’t need it you can use an empty string or omit it altogether. (But mind that last comma! Parameters shouldn’t end with a comma.)

The last 3 parameters are optional and can be omitted from the right. That is, you can omit the breaker and the update interval, but not just the interval.

Tip: You can use more than one SLIDE_add() call. It is probably a good idea to slide both your sidebar AND your content.

3.4. Activating the sliders

This is done with a simple call to SLIDE_activate(). You must do this after all the SLIDE_add() calls.

This is best done towards the very end of your page. Ideally, you should do it very close to the </body> marker (the closing of the page body). This is usually found in the footer.php file in your theme.

Caution: It’s important to do this at the very end of the page, because this function outputs some JavaScript which will check for all the elements you’ve indicated.

If you call it from inside a slider, for instance, JavaScript won’t acknowledge its existence, because it’s not “fully defined” yet, as far as it is concerned. So do it right before </body> to save yourself the trouble of wondering why it doesn’t work.

Here’s the magic code:

<?php
  if (function_exists('SLIDE_activate'))  SLIDE_activate();
?>

3.5. Using the plugin without WordPress

It’s possible to use the slider without having WordPress. Just put the PHP file somewhere on your webserver, include() it, and call the functions as described above. All the notes (about where to use the functions in your (X)HTML) still apply.

The only WordPress-dependent part is the get_settings() call when you use SLIDE_init(true). In other words, the offloading won’t work out of the box. But you can fix it, by replacing the following lines:

function SLIDE_stub() {
  echo '<script type="text/javascript" src="'.get_settings('home').
    '/wp-content/plugins/sidebar_slider.php?'.SLIDE_GET_MARKER.'"></script>';
}

…with this:

function SLIDE_stub() {
  echo '<script type="text/javascript" src="/path/to/sidebar_slider.php?'.SLIDE_GET_MARKER.'"></script>';
}

In other words, you replace the use of get_settings() with a hardcoded Web path to the script.

How to determine what the hardcoded path should be: adjust the following URL in the browser until you manage to see some JavaScript code:

http://www.yourserver.com/path/to/sidebar_slider.php?javascript

When you suceed, everything between yourserver.com and ? is the hardcoded path.

4. Development information

Here’s how the plugin works, for the benefit of curios developers.

4.1. PHP

The plugin is a wrapper for the JavaScript code. It starts by outputting all the essential JS code as functions, either in the <head></head> section, or by referring itself via src and outputting the bare JS code.

The plugin then builds up an internal array which is populated by calls to SLIDE_add(). Each call adds an item with all the needed information for that particular slider.

Finally, SLIDE_activate() translates the internal array into a JavaScript array, and outputs JS code which cycles through it and attempts to activate each slider.

4.2. JavaScript

The JavaScript code is where the real fun begins.

First of all, some sanity checks are done to ensure that the browser is recent enough and that it offers access to some essential DOM elements.

Then, for each slider, we check to see if the slider, container and (if provided) the breaker can indeed be accessed via the provided names. Each of them is then checked to see if they have the proper DOM properties. If any of them doesn’t, that slider is not activated.

Once all checks have been done, we can proceed. For each sliders, the update function is called. The function checks the current slider position, in order, against the browser viewport, the container top and bottom edges, and (if provided) against the breaker top edge.

After all the checks, the new position is imposed upon the slider using its .style.top property. Then the update function sets a later call to itself using setTimeout() and the update interval for that slider.

4.3. Advanced issues

There are three important tricks used by this plugin.

  1. The way it offloads the biggest part of the JavaScript, by referring itself. This trick is based on the fact that the plugin file will always be called sidebar_slider.php. If that fails, offloading won’t work, and the entire plugin stops working.
  2. In JavaScript, position="relative" is forced upon the slider elements. I’ve decided to do this instead of making users do it manually in their CSS files. Relative positioning is, naturally, essential to being able to slide an element.
  3. Reflow detection. There are several ways in which the user can cause a reflow of the page layout, and they must be dealt with.
    • Changes in the size of the slider itself. They are taken care of by the regular positioning code. This is nice, because it means that stuff like JS Toggle Boxes can work fine.
    • Changes in the size of the viewport/window, or the user changing the size of the fonts. These are detected by keeping some values around and using them to detect anomalies and to adapt to changes.
    • The Opera zoom feature is particularly tricky and currently messes up the sliders’ control. I will need to do more testing to see if this can be fixed as well. Hopefully, I’ll be able to detect when the zoom takes place and issue a “reset” to the sliders.

4.4. Version history

  • 1.1, Dec 5, 2005:
    • Bugfix: Internet Explorer doesn’t support calls to setTimeout() with function pointer and extra parameters. Replaced with inline expression.
  • 1.0, Dec 3, 2005:
    • First release.

4.5. To do

Learn how to detect the Opera zoom, in order to reset the sliders.

Find out why even the block that dictates the page height slides a little when you jump to the end or beginning of the page.

Allow visitors to turn sliding on/off, either globally or individually.

5. Known issues

5.1. Graceful degradation

Your visitors will need JavaScript for this to work. The huge majority have it on. For those that don’t, nothing bad will happen; the layout will simply remain fixed, as if you didn’t have the plugin.

5.2. Cross-browser compatibility

The JavaScript used by this plugin is not perfect. It cannot be, as long as there are so many browsers out there with so many different implementations. ppk really said it well: “The hell is other browsers.” :cry:

I tried hard to make it as cross-browser as possible, but I don’t have all the possible browsers at my disposal, and there’s no substitute for actual testing. I read a lot from what other people had to say about the involved tricks and gotcha’s, but I can’t guarantee anything.

In particular, I haven’t tested it on Mac and older browsers. I’d appreciate feedback on them.

5.3. Some layouts are not suitable

Not all WP themes out there are suitable for this plugin. That’s because some designers use tricks in building the layouts. If, for instance, a layout uses background tricks to integrate the columns with the overall page design, that design will break when the column moves. You’ll know this kind of problem when you see it. ;)

5.4. The Opera zoom feature

Using the zoom in Opera will mess the sliders up. I need more testing to see what’s going on and how this can be fixed.

The zoom used by the Web Developer extension for Firefox is NOT affected.