jQuery Vertical News Slider

on | 40 Comments

The last thing developers need today is another jQuery and/or CSS3 based content slider or carousel. I think the problems with these types of modules have been well documented.

About a year ago, however, I wrote a step-by-step tutorial for Issue #203 of Web Designer Mag that involved creating a “news content switcher”. I’ve been meaning to revisit, tweak, and release the code for that here and so I finally got around to it.

jQuery Vertical News Slider

This module, like the original in the magazine, is responsive and uses CSS3 for animation. What I find is more practical about this one (compared to the usual carousels and whatnot) is the fact that there’s no mystery as to what’s coming next; all the news items are clearly on display.

The content that shows in the preview (the image and description) is really incidental. That is, it’s not necessary to the readability and/or scannability of the module’s content, so I think it’s much more usable than other content sliders and switchers. In this way it’s a little more like a tab switcher, which has visible and clear options, rather than mystery items sliding in by surprise.

It’s not a jQuery plugin, it’s just a plug-and-play script with simple editable markup. This is because, other than speed and auto-rotating, I couldn’t find many significant “options” to include. Those two options are very easy to change in the code by reading the code comments.

Also, if you want different colors, the styles in the CSS file can be changed easily to accommodate any context.

I’m sure this has a few weaknesses (like accessibility; the clickable news headlines are not using anchors — is that bad?), so I’m glad to look at suggestions for improvements. You can view it on GitHub or use the links below to download and view a demo.

Update (November 21, 2016): Fixed the problem that caused it to break in jQuery versions 1.9 and higher. It now should work in every version of jQuery, including 2.x, 3.x, and jQuery slim. Thanks to those in the comments who pointed out the problem.

Advertise Here

40 Responses

  1. You are right about this being better usability than most “mystery” sliders. The other big advantage comes from being more persuasive. when changing the slider from one feature to the next the eye moves along a shorter path than in most sliders where the eye must move outside the picture and down to a little number for the slide. in your version the person viewing is absorbing and remembering in short term memory the headline for the new article instead of keeping their short term memory fixed on an arbitrary slide number 4 they need to click. If you want your readers looking at your content what you have is good. if you are satisfied with readers spending the time they’ve planned for your site to be spent looking at numbers and counting slide rotations, then a traditional jquery slider should be just fine.

    I would possibly recommend adding a next and previous button because sometimes users want to use case: click, see picture, click, see picture, click see picture. quickly or at a speed of their choosing this should be doable without having to look at the mouse pointer and focus on moving the pointer to the next location. A fixed position next and previous button allows the user to position their mouse over the next button and then focus visually on the photo or headline while clicking quickly. If you satisfied with users having to stop looking at the content to track the movement of the mouse to the correct slide then you don’t need the next and previous buttons.

    Also there’s a slight confusion over when do we switch slides. in my opinion simply mousing over the text with a hover intent delay should be enough to switch slides since it indicates the user is focused on a particular slide earlier and easier then clicking. One related problem that always bothers me with this sort of slideshow is that you have to click twice to get to a news article. first you click on the tab to get the slide photo and page link, then you have to look for the mouse, move the mouse to the correct link for the page featured in the slide, then click on the page link. A better plan might be to let hover select the slide when you hover over a title and clicking the title on the left goes directly to the article. That would be less clicking and maybe more intuitive if done right.

    • That’s a good point about the hovering. I personally prefer clicking though, so I’ll probably keep it as is, as it’s simple enough to use.

  2. I would love to hide some of the lists and use a vertical scroller, how can I do that?

  3. Joe:

    I have been trying to get text color in news-headlines change when it is in selected state. How do i go about doing that?

  4. Armadillo:

    is it possible for the animation to start automatically, rather than having to click to start it?

    • Wow, you really had me stumped there!

      The auto-sliding feature was always working, and it worked on page load. But you were right, for some reason it was only starting after clicking an item. I couldn’t figure it out. So I went back to the code on JS Bin, and I noticed that the older version of the code was using jQuery 1.8.1, while the live demo on this website was using jQuery 1.10.2. So it turns out, for some reason, I had made some changes and then updated the jQuery version and it broke the auto-sliding feature.

      I still can’t figure out what was causing the breakage. It seems to have either been the trigger() method, the index() method, or else one of the jQuery selectors was incorrect. I’m still not sure.

      I reverted the code and the demo to jQuery 1.8.1 so it should now work as expected. Sorry about that. Let me know if there are any other problems.

  5. Woody:

    I like it! Thank you for sharing.

    Do you have any idea how to make the animation stop when cursor is hovering over content? Thinking along the lines of “focus” but cannot seem to get anything to work. Like to stop advancement to next area when mouse/cursor is over content.

    • That’s actually a really nice idea. Adds to the usability. You can do it quickly by adding the following lines anywhere in the JS file inside the main closure:

      $('.news-content').on('mouseover', function () {
      $('.news-content').on('mouseout', function () {

      I’ll see about adding that to the code base, I think it’s good. Thanks!

      • Woody:

        Thanks Louis.

        I was trying to hard or in other words trying to make it hard with difficult code:)

        Very nice code. Going to use this as a “squeeze page” (opt-in page) to showcase a product. Betting it will convert very well.

        Wishing you and yours a great week ahead.


      • Woody:

        Opps. Does not work for me.

        Placed the code into (at very bottom) vertical.news.slider.js. Then tried it right on page and hovering does not stop the scroll.

        I do get some errors:

        Uncaught ReferenceError: myTimer is not defined vertical.news.slider.js:114
        Uncaught ReferenceError: doTimedSwitch is not defined vertical.news.slider.js:118

        Not sure where to define myTimer, but do see it at line 17 with a null value.

        Keep hacking away ans see what I can come up with.


        • I edited my original comment immediately after I posted it, so maybe you read the wrong comment. I originally said to put the code “anywhere” but you actually have to put it inside the big function closure. Notice the following line at the top:

          $(function () {

          And the following line at the bottom:


          Put it above that last line, so it’s inside the closure. Those opening/closing lines prevent naming collisions with other code, so if you put it outside, then the “myTimer” and “doTimedSwitch” objects are not recognized, which explains the errors.

  6. Duy:

    First of all, I would like to thank you for this wonderful news slider.

    I have a question for you regarding the slider. When the content was too much, it broke the bottom border. Is there a way to make the box’s height auto expand (down) as the content get bigger?

    • Hi Duy,

      Thanks for pointing that out. The reason that was happening is because each of the content elements that hold the photo and text are positioned absolutely in CSS, so they overlap each other. I then would give them a min-height value. But that was not really enough.

      So, I fixed it by adding a couple of new lines in the JavaScript. Please download the new version from GitHub and it should work as you want now.

      Let me know if there are any problems.

      • Duy:

        Wonderful ! It’s exactly what I mean. Thank you. I just bought the volume 1 of your book. Hopefully after reading them, I won’t have to ask you any more questions :)

        By the way I have another question. When I tried to add google address maps (with the “iframe” code provided by google) to different news-contents, only the top-content shows the map correctly. The other contents show the top half of the map, but they’re not even the correct addresses.

  7. Sumaya:

    It is wonderful thanks for you,
    I want to view items by listview control how can do that , I tried but it doesn,t work

  8. Matt:

    This is a great plugin, thanks! It would be even more fantastic if it worked with jQuery 1.10.2 just to keep it running in projects going forward. If you had a fix for this that would fab!

  9. Mac:

    I’m building my first wp theme ever. I did tried to add this to wp, but no luck. This is how i’v done.
    Can you take a look and tell me what i am doing wrong ?

    • If it’s a WordPress theme, then you have to make sure the script is inside the correct folder, and you reference it correctly.

      For example, you have:

      <script src="js/vertical.news.slider.js"></script>

      But that’s not correct for a WP theme. It would instead be something like this:

      <?php bloginfo('template_directory');?>/js/vertical.news.slider.js">

      Or whatever the path to your theme directory is. You might have to hard-code it or use a different WP function. Just make sure it points to the right file, and the file exists in that location.

      You also need to remove this:

        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-1965499-1']);   _gaq.push(['_trackPageview']);
       (function() {
          var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
          ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

      That’s my Google Analytics, and should not appear on your website. (It won’t hurt anything, but it’s loading scripts for nothing, which slows the page down).

      • Mac:

        Hey, thanks for a reply. I noticed later analytic code which i removed. I tried all the same with default html code and it works. But when instead of html i add php it appears but doesnt work. Also the right side shows all the posts, so as for one i need a proper php code to add. What confuses me is that it has two , selected class and a normal one, so i am not sure how php code for this would look like. Second thing is , that the right side .news-content all posts are shown in streched box. I did try to set a fixed height and to add overflow:hidden but no luck, which brings me back to php code. According to you, the one i added in previous comment is good ?

        Kind regards

        • Mac:

          Html is erased . I meant here about li tags ” What confuses me is that it has two , selected class and a normal one, so i am not sure how php code for this would look like “

        • I really don’t know. Can you send me the entire WP theme, as a zip file, so I can test it myself? I’ll be glad to debug it for your, but I need the original PHP files, not just an HTML demo, and not just the code.

  10. I used to create a website through WordPress. So, if the client requires a carousel, it won’t be difficult as some plugins are ready to use, and you just have to install it from the control panel. However, right now, I am trying to create a website from scratch, i.e. through pure html, css, PHP, etc., and I find your post very helpful in my learning process. Thank you for this.

  11. NC:


    cool script – thanks for sharing!

    Now I wanted to use this with jQuery 1.10.2 but – as mentioned above – it didn’t work. In my opinion elCount is the problem: From V1.9.0 on it is 0 until you activate the first anchor. So I chose .length instead of .index() for counting the children and it worked out.

    Maybe this helps improving this script.

    Greetings from Germany!

  12. mohamed nashaat:

    Thanks for sharing brother…

    I have been trying for a while now to remove the bullets but it’s not going anywhere. pls help?

    • It’s in the CSS using a pseudo-element. It looks like this:

      .news-headlines li:before {
        content: "";
        display: inline-block;
        width: 5px;
        height: 5px;
        background: #888;
        vertical-align: middle;
        margin-left: -12px;
        margin-right: 7px;

      Just edit that section (or just remove it) to change the bullet style.

  13. plz provide me tutorial for this slider

  14. Hi Louis,

    Is it possible to add dynamic content. I have been trying to append a news item and it never picks up the new news-headlines. So if it do an ajax call to pull back a headline (which I can do all this) how would I update the ticker to reflect the new item programmatically?

    • Figured it out! Put all the variable calls in the custom btn add or function. Drop your script above the btn/function where you add new items. In your original variables set those like the following…

      var hl, newsList = ''; newsListItems = ''; firstNewsItem = ''; newsPreview = ''; elCount = ''; vPadding = ''; vMargin = ''; cPadding = '';
          var speed = 5000, myTimer = null, siblings = null, totalHeight = null, indexEl = 1, i = null;

      And here is the btn_add which injects each item into the placeholders in the html.

      // configure ticker
      $(document).on('click', ".btn_add_slide", function (e) {
        //add items
        var img_title = $(".img_title").val();
        var img_desc = $(".img_desc").val();
        var img_url = $(".img_url").val();
        var img_btn_text = $(".img_btn_text").val();
        var img_btn_url = $(".img_btn_url").val();
        var select_message_group = $(".select_message_group").val();
        $('.news-headlines li').removeClass('selected');
        // add anchor to new item
        $(".news-headlines").prepend('' + img_title + '');
        // add content to new item
        var newHtml = '' +
              '' +
              '' + img_title + '' +
              '' + img_btn_text + '' +
              '' + img_btn_text + '' +
              '' + img_btn_text + '' +
              '' + img_btn_text + '' +
        // add new content
        // remove old highlight so we can change its position
        $(".news-headlines .highlight").remove();
        // add li highlight
        // reset variables
        hl = $('.highlight');
        newsList = $('.news-headlines'),
        newsListItems = $('.news-headlines li'),
        firstNewsItem = $('.news-headlines li:nth-child(1)'),
        newsPreview = $('.news-preview'),
        elCount = $('.news-headlines').children(':not(.highlight)').length,
        vPadding = (parseInt(firstNewsItem.css('padding-top').replace('px', ''), 10)) +
                   (parseInt(firstNewsItem.css('padding-bottom').replace('px', ''), 10)),
        vMargin = (parseInt(firstNewsItem.css('margin-top').replace('px', ''), 10)) +
                  (parseInt(firstNewsItem.css('margin-bottom').replace('px', ''), 10)),
                  cPadding = (parseInt($('.news-content').css('padding-top').replace('px', ''), 10)) +
                  (parseInt($('.news-content').css('padding-bottom').replace('px', ''), 10))
        // this is where everything gets initialized

      And for the css I remove the padding so my Bootstrap buttons were not affected. And removed the yellow backgrounds…


      .news-holder * {
        margin: 0;
        padding: 0;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;


      .news-holder * {
        margin: 0;
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;

      Hope this helps someone in the future! Great Script Louis! Going to work nicely for the skip logic in my Natural Language Chat Bot Builder!

Leave a Reply

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. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.