Compact News Previewer with jQuery

Today we will create a news previewer that let’s you show your latest articles or news in a compact way. The news previewer will show some list of articles on the left side and the preview of the article with a longer description on the right. Once a news on the left […]


View demoDownload source

Today we will create a news previewer that let’s you show your latest articles or news in a compact way. The news previewer will show some list of articles on the left side and the preview of the article with a longer description on the right. Once a news on the left is clicked, the preview will slide in.

Let’s start with the markup.

The Markup

We will have a main container “cn_wrapper” that will contain a right element with the class “cn_preview” and a left one with the class “cn_list”. The preview div will contain content elements. Each one of them contains a preview image, a title and description along with some spans and a link to the real article.
In the list on the left side we will have the according short description items. We will also add a navigation for stepping through the pages in the end of that container:

<div class="cn_wrapper">
	<div id="cn_preview" class="cn_preview">
		<div class="cn_content" style="top:5px;">
			<img src="images/polaroidphotobar.jpg" alt=""/>
			<h1>Polaroid Photobar Gallery with jQuery</h1>
			<span class="cn_date">28/09/2010</span>
			<span class="cn_category">Tutorials</span>
			<p>In this tutorial we are going to create an...</p>
			<a href="http://tympanus.net/codrops/2010/09/28/polaroid-photobar-gallery/" target="_blank" class="cn_more">Read more</a>
		</div>
		<div class="cn_content">
			<img src="images/fullpageimagegallery.jpg" alt=""/>
			<h1>Full Page Image Gallery with jQuery</h1>
			<span class="cn_date">08/09/2010</span>
			<span class="cn_category">Tutorials</span>
			<p>In this tutorial we are going to create a stunning...
				</p>
			<a href="http://tympanus.net/codrops/2010/09/08/full-page-image-gallery/" target="_blank" class="cn_more">Read more</a>
		</div>
		...
	</div>
	<div id="cn_list" class="cn_list">
		<div class="cn_page" style="display:block;">
			<div class="cn_item selected">
				<h2>Polaroid Photobar Gallery with jQuery</h2>
				<p>Tutorial on how to create a gallery in polaroid style</p>
			</div>
			<div class="cn_item">
				<h2>Full Page Image Gallery with jQuery</h2>
				<p>Another tutorial on how to make a full gallery</p>
			</div>
			...
		</div>
		<div class="cn_page">
			...
		</div>
		<div class="cn_page">
			...
		</div>
		<div class="cn_nav">
			<a id="cn_prev" class="cn_prev disabled"></a>
			<a id="cn_next" class="cn_next"></a>
		</div>
	</div>
</div>

The first content item in the preview container will have already the style of being slided in, namely the position of top 5 pixels. All the other previews are “hidden” because they will have a top of 310 pixels.

The items list will be divided into pages where each page contains at most 5 item.

Let’s take a look at the style.

The CSS

We will use a lot of CSS3 properties to create some neat effects. We will use shadows, rounded borders and gradients with both RGB and hexadecimal values.

Let’s start with the main container. We will set it relative so that we can then use some absolute positioning inside of it:

.cn_wrapper{
	margin:90px auto 0px auto;
	width:500px;
	height:300px;
	position:relative;
	color:#fff;
	overflow:hidden;
	padding:5px;
	text-shadow:1px 1px 1px #000;
	border:1px solid #111;
	background-color:#333;
	-moz-box-shadow:1px 1px 4px #222;
	-webkit-box-shadow:1px 1px 4px #222;
	box-shadow:1px 1px 4px #222;
	-moz-border-radius:5px;
	-webkit-border-radius:5px;
	border-radius:5px;
}

The headings inside of our viewer will have the following style:

.cn_wrapper h1{
	font-size:20px;
	text-transform:uppercase;
}
.cn_wrapper h2{
	font-size:12px;
	border-bottom:1px solid #000;
	padding-bottom:4px;
	text-transform:uppercase;
}

The h2 is used in the preview list and we give it a bottom border to create a nice engraved line under it. This will work because we will give the p that follows it a top border with a lighter color.

The preview and the list will both be positioned absolute, so we will first define the common style and then we overwrite the left for the preview:

.cn_preview, .cn_list{
	width:250px;
	height:300px;
	position:absolute;
	top:2px;
	left:6px;
}
.cn_preview{
	left:255px;
}

Inside of the preview we will have several content elements that will be styled as follows:

.cn_content{
	border:1px solid #444;
	top:310px;/*5*/
	left:5px;
	width:219px;
	padding:10px;
	position:absolute;
	background-color:#101010;
	height:275px;
	-moz-border-radius:5px;
	-webkit-border-radius:5px;
	border-radius:5px;
}

These elements will be animated in the JavaScript. Initially, we want to hide them, so we set a top that is bigger than the whole wrapper itself. This is why we set the overflow of the wrapper as hidden, so that we will not see anything that moves out of the boundaries of the wrapper.

Now we will style the elements inside of the content div.
The image will always have the maximum width of 215 pixels in our case. Note that if you have differently sized images, you will have to adapt all the elements under it as well. In this case the image will have the height of 119 pixels. That’s the value we will base all the following elements’ heights on.

.cn_content img{
	width:215px;
	-moz-box-shadow:1px 1px 4px #000;
	-webkit-box-shadow:1px 1px 4px #000;
	box-shadow:1px 1px 4px #000;
}

The date and the category will be positioned absolutely at the bottom of the content div:

.cn_date{
	position:absolute;
	bottom:30px;
	right:8px;
	font-size:11px;
}
.cn_category{
	position:absolute;
	bottom:30px;
	left:8px;
	font-size:11px;
	padding:1px 3px;
	background:#ccc;
	border:1px solid #ddd;
	color:#000;
	text-shadow:-1px 0px 1px #fff;
	-moz-border-radius: 3px;
	-webkit-border-radius: 3px;
	border-radius: 3px;
}

The description, which is a p element will have a fixed height and if it is longer, it will be cut off:

.cn_content p{
	height:57px;
	margin-top:2px;
	overflow:hidden;
}

The more button which will be the link to the original article will be spiced up with some gradient, a box shadow and rounded borders at the bottom left and right to fit the content:

a.cn_more{
	position:absolute;
	padding: 4px 0px;
	left:0px;
	bottom:0px;
	width:236px;
	color:#fff;
	text-align:center;
	font-size:12px;
	letter-spacing:1px;
	text-shadow:1px 1px 1px #011c44;
	text-transform:uppercase;
	text-decoration: none;
	border:1px solid #4c7ecb;
	outline:none;
	cursor:pointer;
	background-color: #1951A5;
	background-image:
		-moz-linear-gradient(
			top,
			rgba(255,255,255,0.25),
			rgba(255,255,255,0.05)
		);
	background-image:
		-webkit-gradient(
			linear,
			left top,
			left bottom,
			color-stop(0, rgba(255,255,255,0.25)),
			color-stop(1, rgba(255,255,255,0.05))
		);
	-moz-border-radius: 0px 0px 5px 5px;
	-webkit-border-bottom-left-radius: 5px;
	-webkit-border-bottom-right-radius: 5px;
	-border-bottom-left-radius: 5px;
	-border-bottom-right-radius: 5px;
	-moz-box-shadow:1px 1px 3px #111;
	-webkit-box-shadow:1px 1px 3px #111;
	box-shadow:1px 1px 3px #111;
}

Changing the color of the font on hover will create a nice engraved effect:

a.cn_more:hover{
	color: #011c44;
	text-shadow: 1px 1px 1px #ccdffc;
}

Now we will style the items in the list. They will have a gradient as background which will change on hover. We will also apply the hover effect on the selected item.

.cn_item{
	border:1px solid #090909;
	cursor:pointer;
	position:relative;
	overflow:hidden;
	height:49px;
	color:#fff;
	padding:5px;
	margin:6px 5px 0px 0px;
	text-shadow:1px 1px 1px #000;
	background:#2b2b2b;
	background:
		-webkit-gradient(
			linear,
			left top,
			left bottom,
			from(#171717),
			to(#2b2b2b)
		);
	background:
		-moz-linear-gradient(
			top,
			#171717,
			#2b2b2b
		);
	-moz-box-shadow:1px 1px 3px #111;
	-webkit-box-shadow:1px 1px 3px #111;
	box-shadow:1px 1px 3px #111;
	-moz-border-radius:5px;
	-webkit-border-radius:5px;
	border-radius:5px;
}
.cn_item:hover, .selected{
	border-color:#4c7ecb;
	background-color: #1951A5;
	background-image:
		-moz-linear-gradient(
			top,
			rgba(255,255,255,0.25),
			rgba(255,255,255,0.05)
		);
	background-image:
		-webkit-gradient(
			linear,
			left top,
			left bottom,
			color-stop(0, rgba(255,255,255,0.25)),
			color-stop(1, rgba(255,255,255,0.05))
		);
}

The engraved line under the heading will also change color:

.cn_item:hover h2,
.cn_list .selected h2,
.cn_item:active h2{
	border-color:#2C5FAC;
}
.cn_item:hover p,
.cn_list .selected p,
.cn_item:active p{
	border-color:#527CBB;
}

The active pseudo class, i.e. when we click on an item will have an engraved text effect by using the following style:

.cn_item:active {
	color: #011c44;
	text-shadow: 1px 1px 1px #ccdffc;
}

The short description in a list item will have a fixed height and a top border which, together with the bottom border of the h2 will create an engraved looking line:

.cn_list p{
	height:29px;
	padding-top:2px;
	overflow:hidden;
	border-top:1px solid #333;
}

Let’s style the navigation now. We will set it absolutely at the bottom of our list container:

.cn_nav{
	width:55px;
	height:24px;
	position:absolute;
	bottom:0px;
	left:94px;
}

The next and previous elements will have the following common style:

a.cn_next, a.cn_prev{
	float:left;
	height:23px;
	width:23px;
	background-color:#212121;
	background-repeat:no-repeat;
	background-position:center center;
	cursor:pointer;
	outline:none;
	border:1px solid #111;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-radius: 5px;
	-moz-box-shadow: 1px 1px 3px #000;
	-webkit-box-shadow: 1px 1px 3px #000;
	box-shadow: 1px 1px 3px #000;
}

Now we just set the individual styles which are the background images:

a.cn_next{
	background-image:url(../images/next.png);
}
a.cn_prev{
	margin-right:5px;
	background-image:url(../images/prev.png);
}

On hover we just change the background color:

.cn_nav a:hover{
	background-color:#101010;
}

When we click on a navigation item, we will move it down 1 pixel, so that it looks pressed. That we can do by setting the margin top to 1 pixel:

.cn_nav a:active{
	margin-top:1px;
	background-color:#000;
}

An inactive navigation element will have an opacity of 0.5:

.cn_nav a.disabled{
	opacity:0.5;
}

The last thing that we need to define is that the pages of the list are not visible. We will then make them visible in the JavaScript:

.cn_page{
	display:none;
}

That was the style. Now, let’s add the effects with jQuery!

The JavaScript

For the effects we will be using some easing so don’t forget to include the the jQuery easing plugin.
In our jQuery function we will start by defining some variables:

//caching
//next and prev buttons
var $cn_next	= $('#cn_next');
var $cn_prev	= $('#cn_prev');
//wrapper of the left items
var $cn_list 	= $('#cn_list');
var $pages		= $cn_list.find('.cn_page');
//how many pages
var cnt_pages	= $pages.length;
//the default page is the first one
var page		= 1;
//list of news (left items)
var $items 		= $cn_list.find('.cn_item');
//the current item being viewed (right side)
var $cn_preview = $('#cn_preview');
//index of the item being viewed.
//the default is the first one
var current		= 1;

For each item we store its index relative to all the document. We bind a click event that slides the current or clicked item up or down. Depending on the current item (if it comes before or after the newly clicked one), the clicked one will be moving from up or down:

$items.each(function(i){
	var $item = $(this);
	$item.data('idx',i+1);

	$item.bind('click',function(){
		var $this 		= $(this);
		$cn_list.find('.selected').removeClass('selected');
		$this.addClass('selected');
		var idx			= $(this).data('idx');
		var $current 	= $cn_preview.find('.cn_content:nth-child('+current+')');
		var $next		= $cn_preview.find('.cn_content:nth-child('+idx+')');

		if(idx > current){
			$current.stop()
					.animate({
						'top':'-300px'
					},600,'easeOutBack',function(){
						$(this).css({'top':'310px'});
					});
			$next.css({
				'top':'310px'
			}).stop()
			  .animate({
				'top':'5px'
			  },600,'easeOutBack');
		}
		else if(idx < current){
			$current.stop()
					.animate({
						'top':'310px'
					},600,'easeOutBack',function(){
						$(this).css({'top':'310px'});
					});
			$next.css({
				'top':'-300px'
			}).stop()
			  .animate({
				'top':'5px'
			  },600,'easeOutBack');
		}
		current = idx;
	});
});

Now we will define what happens when we click on the next in the navigation. The next page should fade in if it exists and the button needs to get disabled if there is no next page:

$cn_next.bind('click',function(e){
	var $this = $(this);
	$cn_prev.removeClass('disabled');
	++page;
	if(page == cnt_pages)
		$this.addClass('disabled');
	if(page > cnt_pages){
		page = cnt_pages;
		return;
	}
	$pages.hide();
	$cn_list.find('.cn_page:nth-child('+page+')').fadeIn();
	e.preventDefault();
});

The same holds for the previous page:

$cn_prev.bind('click',function(e){
	var $this = $(this);
	$cn_next.removeClass('disabled');
	--page;
	if(page == 1)
		$this.addClass('disabled');
	if(page < 1){
		page = 1;
		return;
	}
	$pages.hide();
	$cn_list.find('.cn_page:nth-child('+page+')').fadeIn();
	e.preventDefault();
});

To give the whole thing an even nicer look, we will cufonize the headings, by adding the following lines to the header of the HTML:

<script src="js/cufon-yui.js" type="text/javascript"></script>
<script src="js/Bebas_400.font.js" type="text/javascript"></script>
<script type="text/javascript">
	Cufon('.cn_wrapper h1,h2', {
		textShadow: '-1px 1px black'
	});
</script>

And that’s it! We hope you enjoyed this tutorial and found it useful!!

View demoDownload source

Message from TestkingWe offer comptia a+ training to help you pass ccie and ccsp exam and lean jQuery and css to improve your web page accessibility.
Previous:
Next:

Tagged with:

Mary Lou (Manoela Ilic) is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://tympanus.net/

Related Articles

Feedback 62

Comments are closed.
  1. 1

    This is really fantastic!! I have one thing though – in IE 8 or 9 after I click on the prev or next nav buttons the entire left panel drops down 3px. Was wondering if anyone else has had this issue, or knows of a fix. So odd :) Thanks!!

  2. 2

    how to use it in wordpress
    I’ve tried to download and install via plugin
    but failed, “plugin does not have valid header”
    how to fix it
    thanks

  3. 3

    This look great, buy i have a problem using is whith a Mysql database. I try to ad a php code to get the different news from my database, I don’t want to re-wright the page each time I have a new one, but it doesn’t work. Can someone help me?

  4. 4

    i tested this in IE9 but the button text no appear and the menu cn_page no appear. can you test this why can´t see it.

  5. 5

    I’m so amazed by your stuff, that I have to use it somehow. But, I have a question here: I put this previewer in a page, it works like a charm, no problems. However, when I put the script in a extern file, other than the html page, it ceases to work (in other terms, the plugin doesn’t work if the script is not located in the html page… to be clear). Did I missed something?
    Thanks in advance
    A happy reader.

  6. 6

    First of all – GREAT previewer. I love the look.

    I am trying to resize the whole thing… make it taller. I was able to do so, but the problem that I am running in to is that when I click on other previews, it doesn’t seem to reset the one that goes away back to the “top” value. So what happens is it looks great until you click on another preview and then they start showing up together and overlapping. Any help would be greatly appreciated! Thank you!

    http://www.azcampers.com/Development/Development%202/index.html

  7. 7

    Forgot my last comment, I realized that it is NOT a plugin. Hu!.
    I made it a plugin (after one hundred millions tutorials I finally understood the differences…). Thanks your patience.

  8. 8

    So first off… love this code, it’s perfect for what I need.

    However, when coding, anytime I try to add other elements (like tables), because the margin for the wrapper is set to 90px, it offsets everything. So, I thought I’d do a general margin of 90. Turns out, the text jumps down like so

    http://66.147.244.234/~pixelrep/archive.html

    Any ideas?

  9. 9

    Is there a way to make it automatically change items? So that it will change every, say 10 seconds to the next item in the list?

  10. 12

    This is by far one of the best looking slider/previewers I’ve used.

    As others have stated, is there a simple auto play function that can be added?

    Thanks for sharing your News Previewer!

  11. 14

    IE 9 does not appear in the left side of the transition to the second page. What should I do

  12. 17

    Hi Mary, this is really cool tutorial and thank you very much for sharing such wonderful stuff.

    I need a small help with this feature here, the list on left is limited it seems when i tried adding more items on list after few items that content overflows, can you pls help me with how I can add more items to list without overflow. Am new jquery so pls help me with this pls pls pls. Thank you in advance :-)

  13. 18

    Oopsiee nothing related to jquery it’s just html, as I was in hurry couldn’t figure it out. Anyhow thank you very much for sharing really good stuff. :)

Comments are closed.