A JavaScript Content Switcher That Works Without JavaScript

A JavaScript Content Switcher That Works Without JavaScriptRecently, while doing research/work on a completely unrelated topic, I came across the beautiful illustrations on Rype Arts, which are displayed inside of a JavaScript-driven content switcher. For some reason, I happened to visit the page with JavaScript disabled and noticed that the content switcher was still working (albeit, with a few flaws).

At first I couldn’t figure out how it was functioning. Normally, with JavaScript disabled, this type of content switcher (or content slider) will just display one item, or else display all items, without allowing any “switching” functionality. After some poking around, I realized it’s not a very difficult thing to do. The switcher utilizes in-page anchors and overflow: hidden to keep the switchability intact.

View the Demo to preview what I’ll be describing below.

Here is the HTML that I’ll be using to demonstrate this effect with and without JavaScript:

<div id="content-slider">
	<ul id="content-slider-inside">
		<li id="one">1</li>
		<li id="two">2</li>
		<li id="three">3</li>
		<li id="four">4</li>
		<li id="five">5</li>
	</ul>
</div>

<ul id="navigation">
	<li><a href="#one">1</a></li>
	<li><a href="#two">2</a></li>
	<li><a href="#three">3</a></li>
	<li><a href="#four">4</a></li>
	<li><a href="#five">5</a></li>
</ul>

The key part of this code is the <div> with the id “content-slider”. Normally, that element would not be necessary, as it seems to be doing nothing. In this case, however, it’s needed in order to hide the unselected content inside the list nested inside it. Also, each list item inside the content switcher is given a unique id, which is needed for the switching to work even without JavaScript.

The CSS to style the content switcher is as follows (I’ve excluded all irrelevant styles):

#content-slider {
	width: 650px;
	overflow: hidden;
	height: 300px;
}

#content-slider-inside {
	list-style: none;
	height: 320px; 		// these 3 lines
	overflow: scroll;	// help Opera
	overflow-y: hidden;	// behave
}

	#content-slider-inside li {
		width: 650px;
		height: 300px;
	}

A few things to note in the CSS above: The outer container has its overflow set to “hidden”. It also has a width equal to one of the content boxes (650px). Inside the container is the <ul> element that holds the list items that represent the content boxes. Finally, the list items are given dimensions of 650px by 300px. Since the container element is equal to one list item, and the container has overflow set to “hidden”, only one list item will be visible at a time.

UPDATE: I added three new lines of code in the CSS above (commented), to get the non-JavaScript version (the first demo) to work in Opera. Thanks to comment by Damian Muti.

How it Works

The navigation links are linked to internal anchors. An HTML page, by default will search the page for an anchor set as <a name="one"></a>, and if it doesn’t find it, will then match the anchor to a corresponding id attribute. This is what allows the content switcher to still change the content inside of the container.

After the above code is in place, we just need to add some CSS to make it look a little nicer, then we have the option to enhance the switcher with JavaScript. The switcher also allows deep linking by means of the hash in the URL, which works with or without JavaScript.

Compatibility

This works in every modern browser, except for Opera, and also works in IE6. Opera doesn’t seem to support in-page anchors that appear in hidden sections of a <div> — or else I’m doing something else wrong, but I couldn’t figure out how to get Opera to recognize the switching without JavaScript enabled.

Take a look at the demo, which also includes a link to a JavaScript/jQuery-enhanced version that I coded myself, as a bonus. And just to demonstrate the deep-linking capabilities, the demo link appends “#three” to the URL — so you should see the number “3″ in the content area, if it’s working correctly.

Advertise Here

49 Responses

  1. Jonathan says:

    Excellent, thanks Louis – another addition to my PE toolkit!

  2. James says:

    I like it, would be awesome if it worked in Opera too! :)

    • PfftOpera says:

      Who gives a crap if it works with Opera? That’s less than 1% of the market share. Not to mention they’re probably used to having to switch browsers for things to look right.

      If you’re paying a developer, and they’re wasting your time and money developing workarounds for Opera, it’s probably time to look for a replacement.

      • Deb says:

        Sadly that’s true, Opera probably will never make it to the mainstream user base. They keep changing versions with cosmetic changes but nothing much changes for the average user. Where Chrome is setting high standards & stealing Firefox loyals every month Opera is clearly lagging behind. I want them to succeed as well, but not sure if they ever will.

        Opera loyals don’t bash me but i was pretty happy to see the new shortened big O menu in 10.50 until i enabled Show Menu Bar and i see this http://i.imgur.com/81Acn.png

        • aza says:

          Opera is strange. As web developer I mentioned that if my design works fine with most browsers then IE 6 and Opera have still kind a similar bugs. Good article! I’m a big fan of css.

      • Stac says:

        This is very local specific.
        As for my projects in Russia, eg., Opera gives up to 30% of visitors,

        And I’ve used “content swither” just yesterday. Grrr…

  3. Mike Smedley says:

    Ha, very cool and simple way of doing this without JS, one of those that makes you think “why didn’t I think of that!”

  4. Johnny says:

    Pretty cool, good job. I love things like this that only use CSS and HTML to make something interactive :D

  5. Damian Muti says:

    Really nice tip, Louis.

    Actually you are right, Opera seems to fail pointing to anchors inside containers with overflow:hidden.
    Tried a few thing to make it work in Opera, and i`ve found a clean solution. Maybe there’s a better one, but as far as i’ve tested, works in IE6, 7, 8, Opera 10.10, Chrome 3.195 and FF 3.5.7.

    Here’s the trick:

    #content-slider-inside {
    	list-style: none;
    	height: 320px;
    	overflow:scroll;
    	overflow-y:hidden;
    }

    As you can see, in the ul style you have to add a height of 20px more than the container div to hide de x overflow and use the CSS3 overflow-y property.
    Adding overflow:scroll makes it work.

    Thats it.

    Keep the good work, mate.

    Cheers! :)

    • Damian, great job in resolving that! I knew there had to be a way to get Opera to behave. I just didn’t have the time to hack away at it.

      I added your code to the demo and updated the article to give you credit.. Thanks!

  6. ricky says:

    Hey, this is really great. Thanks!

    But I noticed that it breaks the back button (using Firefox 3.0.17 on Linux). Is this happening for anyone else? Internal anchors on other pages I visit do not break the back button. But still an awesome tip.

    • The back button will fail with JavaScript enabled, which is a common problem with deep linking via JavaScript. In this case, it’s not as important because this is a content-switcher that would not take up the whole page anyhow.

  7. Jason says:

    Very nice, this will come in handy on a good number of projects, and Damian thanks for the tip to help it work properly in Opera. I’ll see how it goes and how this can be expanded.

  8. Nico Burns says:

    Not sure how it was supposed to work, but worked fine in opera for me (v10.5), just without the animation of the javascript version

    • It was the non-JavaScript version that was not working in Opera 10.10. It works fine now, but I would be curious to test in Opera 10.5. Were you talking about the JS version, or the non-JS version?

  9. eddie says:

    Interesting and very useful. I’ll try this soon. Thanks!

  10. SFdude says:

    Very nice!

    In both demo versions (with & w/o jQuery),
    when you click on a [#] button, the big #, switches OK.

    But…the entire page view jumps to the bottom.
    (ie: the Top Title:
    “Adding jQuery to Enhance the Content Switcher”
    disappears from view , and you see the bottom links of the page:
    “< Go back to the tutorial").

    Is there a way to avoid the page jumping to the bottom,
    when you click a [#] button?

    – in Firefox 3.5.8/XP-SP2 (jumps to page bottom)
    – in CHROME works fine! (no jumps, smooth transitions…)

    SFdude

  11. SFdude says:

    Please, disregard my previous post.
    It works just fine in Firefox 3.5.8.

    The jumping effect (described in my prev post),
    was due to my browser Zoom level being at 120%,
    (which I need due to poor vision),

    So, my new question is:
    ——————————-
    how to modify the script to avoid the “jump effect”
    if the User has set his browser to a Zoom View > 100% ?

    Thanks!
    SFdude

    • Hey SF,

      I’m glad you pointed that out. Basically, that’s happening because I’ve enabled deep-linking via JavaScript. Each click changes the hash (#) in the URL, thus “visiting” that hash, the same as an internal page link (for example, with JS disabled on the first demo).

      So, to prevent the “jump” from happening, just comment out lines 57-59 in the JS, which looks like this:

      if (location.hash !== "#") {
      	location.hash = "#"+myClicked[1];
      	}

      The jump will still happen, however, in the non-JS version, because it uses in-page anchors to work. And, as you pointed out, this really only occurs when the page is zoomed, so it wouldn’t really be much of an issue, I don’t think.

  12. Behzad says:

    awesome !! Thanks Louis :) I’ll try this.

  13. ThaClown says:

    Thx alot really nice!

  14. Iggy Hammick says:

    I like it a lot. Just wonder how this affects accessibility with the back button. When you click through the different content, you cant then click the browser back button to return to the previous page.

    Regardless – great technique!

  15. Anderson Lee says:

    This is a great find, Louis. I’ve wanted a better way to present JS-less pages for months…I’m off to replace the js in my custom pages with this.

  16. Seif says:

    Is ther a way to personnalize links so they can gather information from server using Ajax?

  17. Rob says:

    Hi,

    Thanks alot for this, I love using jQuery, but am always trying to use methods that fallback nicely when javascript is disabled, and this is perfect.

    I’m ok implementing pre-built jQuery effects, but don’t really understand the language itself at the moment, something I want to work on this when I get some time… But is it possible to make this cross-fade between the different content, rather than the fade out to blank and then fade back in… I’ve attempted to modify sections of the coding, but to no reward so far lol….

    So if anyone could help, and guide me to what I’d need to modify to achieve a cross-fading effect it would be greatly appreciated.

    Cheers

    Rob

  18. Docu says:

    Really a good work…
    Thank you !

  19. hello says:

    Thanks for the help, will try this out. Will be useful to me. Thanks for sharing.

  20. Mr. Won says:

    It would be great if there was a non-JS way to make this work for images of differing sizes and shapes, but as is, this is a fantastic solution for a fixed viewport image gallery.

    Thank you.

  21. This is pretty straight-forward, what every competent front-end web developer would do to make their site/slide accessible even without JS.

    A sliding example can be found here http://bit.ly/5u3abB . Disable JS to see how it falls back.

    Its good to have a tutorial for it anyway :)

  22. Vassilis says:

    This is a very open minded approach of a common problem.
    My first guess was an iframe (just lame), but looking your code was just surprising!

    Thanks for posting this.

  23. Interesting article. I never would of thought to do something like this. However now that I’ve read this it makes me wonder what more I could be doing with css. Thanxs for making me think.

  24. thekruser says:

    Have you any idea how to incorporate this script/css in a WordPress page? Would like to incorporate it into my home screen.

    Thanks for the awesome info!!

  25. Mitch Page says:

    Hi

    Great content glider, thanks!
    I wonder just, why can’t I change the light blue colored back ground into an image, like
    background-image: url(../images/myimage.jpg);

    Am I missing something?
    Thanks

    • Mitch, are you talking about the grey background? It’s declared on the list element (<li>) as “background: #ccc;”. If you change it, you have to make sure you remove that declaration completely, replace it with the new “background-image” declaration, and make sure your image is in the correct location relative to the CSS file. Other than that, I don’t know what else to suggest..?

  26. ukm says:

    nice tips
    maybe I must implemented in my website..
    thank you

  27. Esteban says:

    HI, nice post!

    Any one, know if this can be adapted (supporting no javascript) to use only two buttons for the switch?(. Previous and Next button. )

    Regards!
    Esteban

    • You can’t do it that way unless you use JavaScript. The internal page anchors are needed to target the sections, and if you had a “next” button, it would not know which section to go to unless you specified it, or else changed it dynamically via JavaScript.

  28. Stuart M says:

    Mine also jumps so how do you comment out ?
    I am very new to JavaScript, also can i get this to animate with a function is there
    a function we can add i didn’t see any in the post thanks for any help.

    • Stuart,

      For the “jump”, that only happens in the non-js version. If you have a larger screen size, you won’t see the jump, because the jump is just the fact that the page is trying to locate the internal anchor location (the hash in the URL).

      To view the JS version with animation, here is the link:

      http://www.impressivewebs.com/demo-files/content-switcher/content-switcher-javascript.html#four

      You won’t see any jump on that one, because the JS code uses “return false” to prevent the value of the HREF from being followed.

      • Stuart M says:

        Louis thanks for the super fast response . It is a great slider as i had mentioned before i am so new to JavaScript. Making websites is a hobby of mine ,that i really enjoy. I am by profession a Musician
        so these forums give me hope for a better understanding thanks for your help. Stuart M.

  29. Great little find, this. I’m redoing my site at the moment, and this perfectly balanced ease of use with flexibility. Thanks for publishing it, Louis.

  30. Jason Burnett says:

    I have been trying to adapt this code to use Ajax to load the various pages and I can’t get it to work.

    I have tried preloading the content and rebuilding the for the inner-div using AJAX, but that didn’t work.

    I have tried calling the AJAX loadpage function when a nav item is clicked, but that didn’t work either.

    Any suggestions? (Thanks for your great help, btw)

    • Jason,

      You’re going to have to provide an example page, so I can take a look at it. Or you could email me the whole thing. Use the contact page on this website, and we can discuss it, but only if you have an example to show me, otherwise I can’t really help you much.

  31. Dylan says:

    A great script and thanks very much for sharing :)

  32. jennifer says:

    This is fantastic! I’m a jQuery beginner and loved your tutorial on sliding folders — any chance you could do a similar one for the jQuery file behind the “enhanced” version of this content switcher?

  33. Mel0ne says:

    First: this is perfect! a easy to understand code even for beginners, Thanks

    Now, im using the JS Version and i wonder if it is possible to add a automatic rotator, like the content switches every few seconds.

Add to the Discussion

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. Thank you for cooperating.

To Post Code Snippets in Comments: Wrap your code in <code> tags, and make sure you use &lt; and &gt; for HTML, instead of < and >, otherwise your code will not show up properly.