Recreating the MLB.com Content Switcher with jQuery and CSS3

This article was first published on June 1, 2010 and has been updated to include a few extra features and an improved code base.

I’m a huge baseball fan, so earlier this year, just for a fun side project, I recreated the MLB.com Flash content switcher using jQuery and CSS3.

My goal with this project was to try to recreate the switcher without any extraneous images or other non-essential elements that tend to make stuff less maintainable.

My version uses CSS3’s border-radius, RGBA colors, opacity, and a small use of a gradient, and still looks acceptable in non-supportive browsers (although the jQuery is not as smooth in IE6 & IE7). Be sure to look at the real version on MLB.com for comparison; there are a few small differences, but mine is basically the same.

Although this is not a step-by-step tutorial, for those interested in the JavaScript/jQuery used, I’ve provided extensive commenting in the JavaScript file, so you can see exactly what each section of the code does. The data is contained in a JavaScript object in order to keep the code clean, and to separate it from the main code. Normally, the data would be pulled from a database, or accessed via Ajax, so feel free to alter it to your own needs.

To illustrate the features using CSS3, here is an infographic that points those elements out (plus the newly-added play/pause button, which is unfortunately an image, but the only image other than the content images):

New Additions to the Updated Version

When I updated this version, I added a new feature: auto-run functionality with a play/pause button, just like on the real version. The auto-run functionality will pause when the user interacts by clicking to switch content. I think this is a good usability choice, because it prevents the slider from moving at unexpected times. The real MLB version seems to work similarly.

I also made the thumbnails slide up/down instead of fade in/out, to mimic the updates to the real version.

The Real Version Has Since Switched to JavaScript

I haven’t had a chance to examine the code on the real version yet, but interestingly, some time after I first published this article the MLB version switched from a Flash-based content slider to JavaScript. I really have no idea if my version had anything to do with that.

The only major difference between mine and theirs is the nice little clock-like timers that appear on each of the circle links, counting down the time left before the next slide appears. That wouldn’t be too hard to implement, I’d just have to use animated GIFs in place of the circles. But then I would lose the use of border-radius, which I like because it shows how certain CSS3 features can be used in different ways (although the circles don’t look exactly right in Firefox 3.6, which is a bit annoying).

Finally, there’s a Cuban Baseball website that’s using my version on their home page, which you can see here. They had mentioned to me that they would like to see the auto-run functionality added, so that was kind of the extra inspiration I needed to figure it out and add it.

The code is over 200 lines commented, but will drop down to about 20 lines minified, so it’s not too bad. I’m sure the code could be better, so if anyone has any suggestions, feel free to add to the comments.

Oh and for those wondering, Baseball season is less than 100 days away. :)

You should be able to write a javascript function to call your jQuery swapping functions sequentially with an interval and loop until another call interrupts it back into non-looping mode. I don’t know how to do it offhand but I’m fairly certain it’s possible. forEach thing in object wait so many seconds, then do image swap and increment a counter, compare the counter to the max number of images and when the last one is reached reset the counter and start again? (there may be a more elegant solution but I’m still a noob).

Just have the play and pause buttons be DIVs or form buttons that hide themselves when pressed and swap in the opposite button. the pause div can be a square with three vertical 33% width bars and appropriate background colors. I suspect a css3 transform with a hard 50/50 100%alpha/100%color gradient could be used to fake in a triangular play button.

Or you could pull in some SVG for the play/pause buttons and give the finger to IE users. Since you’re designing with CSS3 anyway I’m guessing that’s the plan until IE9 rolls out with 2005’s hottest web tech finally built in.

Also, great tutorial. While I’m a fan of Flash, I’m also a fan of only using Flash when you need to and in this instance, I think MLB would be smart to move to stuff like this instead of relying on Flash for everything.

The opacity is done using RGBA, which is not supported in IE8. For IE6-IE8 I have a background color in place that’s not semi-transparent.

Anyhow, there is a way to mimic RGBA using IE-only filters, so I added a filter for IE6-IE8 for the navigation element. Unfortunately, because I’m changing the opacity levels via jQuery for the “thumbs” section, I could not get the filter to work on that. The jQuery is overriding it.

I have started to fiddle with this image/content slider you made, it’s pretty sweet, there are two things I have came accross that you may be able to provide me with some answers with.

1. Is there a way to add a link or links in the long-desc portion of the data.js? When I tried this the jquery would fail to function.

2. In the general.js the slider width is relevent to the #photo width, when I change the width of my photo and update it in the css, the code miss calculates the slide distance. Any suggestions would be helpful.

1. Yes, inside the data.js file, inside the “descText” object, just add your hyperlinks inside the text as you would normally — except use single quotes for the attributes. Like this:

descText: [
"Phillies ace <a href='index.html'>Roy Halladay</a> made history in Miami on Saturday, tossing the 20th perfect game in MLB history vs. the Marlins in a 1-0 win. It was the first no-hitter of Halladay's brilliant career.",

2. If you change the width of any single photo, you have to change the width of every photo. The slider will only work correctly when all the photos are the same size. So, in this case, they are each 480px wide. If you change one to 580px, you have to change all of them to be 580px.

Also, you have to change the #photo element’s width in the CSS (which I think you already did, as you said). I would also recommend changing the #photo ul width to a much higher number. That can be anything, as long as it’s long enough to hold all the images side-by-side. I will likely update the code to reflect this, just haven’t gotten around to that.

Oh, I am so *not* a JavaScript or jQuery expert! Still a lot of work to do to improve in those areas. For example, in that last response to you, I referred to the descTextobject, but I should have said descTextproperty. :)

One last request, when hovering over the navigation, the hover-box only apears when the next or previous buttons and slide icon buttons are rolled over. Is there a way to make it so that when the navigation div is moused onto or rolled over the hover-box will apear?

James, I’m not sure if I understand exactly what you’re asking for. From what you describe, it seems that the functionality works as you say. I don’t see it working any differently from what you’re asking. You might have to explain again, and maybe provide a link to a screen shot that points to the areas you’re talking about.

I see the problem now. The problem you’re describing is an IE-only issue. If you test in Chrome, Firefox, Safari, or Opera, it will do exactly what you want.

I’m guessing the problem occurs in IE8 and below. I don’t currently have IE9 installed, but I’ve tested in IE10, and it works fine in that. I’ll have to check out the code when I get a chance, it might be a z-index thing or another problem.

Cool, I guess I would have found that out sooner if I had some other browsers to test with at work. lol. I just started working for a company that has never had a real inhouse web dev and The IT department is lagging on giving me admin privileges, so I cant install any browser and have been testing in just IE8.

I’m trying to find a nice image carousel like yours for a business site I’m building, and I re-purposed it for 1250 x 600px images. Everything fine except I found that the images line up in a vertical stack instead of horizontally, thus after the first image cycles, you cant see the rest of them. Tried everything. Any ideas how to keep them horizontally aligned?

Hey, Justin. Most likely, the problem is occurring because of the following section of CSS in the stylesheet:

#photo ul {
margin-left: 0;
width: 2880px;
}

You’ll notice that the unordered list element is given a width of “2880px”. You need to change that to be a number larger than the sum of all the image widths. That’s something that I need to correct in the code, to make it more flexible.

Really, that should not be set in the CSS. I should be calculating the width of all the images, then setting the width of that element in JavaScript, once the browser knows how many images there are, and how wide they are.

So in your case, you can change that to 1250 multplied by the number of images you’re including. If it’s 6 images, then it would be width: 7500px. To be on the safe side, you should probably make it even bigger than that, maybe 8000.