A word of caution, I've not made any attempt for this to work cross-browser and it's only been formally tested in FF & Chrome, that said, if there are any problems they will be trivial to resolve.
There are three main areas of the component which I'll take in turn:-
- templating and options of the latest news module
- css styling
- jQuery for the hover effect
Latest News
I want my latest 3 featured articles to appear with images in the main module (module 1 for now) and all other articles to be listed in the single line article module (module 2 - this is not shown, you can see it here though).We can achieve this with the following settings in module 1: -
- Featured articles to top: true
- Number of articles: 3
- Featured articles to top: true
- Number of articles: 10 (as many as you want to see on the page)
- Start Point: 3 (in filter settings)
The template for the main module is as follows:-
All the content within the UL (i.e. the list item) should be in the HTML body for the template - my syntax checker isn't happy splitting the code into header, body, footer.
You should now see three images and titles displayed down the page.
The design will look best if all the images are the same size, but if not the css will crop them to fit.
css styling
The first task is to style the outer container, latestNews :-
ul.latestNews {
position:relative;
overflow:hidden;
}
We don't need to specify dimensions on this container. It's going to be as wide as the containing module skin allows and the height will be defined by the list items.
The overflow: hidden is going to crop any image too high for our container.
ul.latestNews li img {
position:absolute;
left:0;
top:0;
width:200px;
}
The images have absolute positioning relative to the outer container (specified by the position:relative on the ul).
Now our images are stacked one on top of the other and we've assured that the width of the image will fit our design.
ul.latestNews li p {
margin:0 0 0 200px;
}
The only task of the paragraph element, is to shift the text to the right of the images.
You'll probably find your paragraph element picks up some styling for the DNN default.css, so make sure you clear this.
ul.latestNews li a {
height:40px;
display:block;
}
Setting a height on an inline element, such as an anchor, is not going to work. We need to make it a block element.
The list item's height is a third of the parent ul's height(in this case, our image height), taking into account borders, padding etc.
ul.latestNews li a:link, ul.latestNews li a:visited {
text-decoration:none;
color:#666;
}
ul.latestNews li a:hover {
background:#F3D154 url(images/newsLatest_bg.png) repeat-x scroll 0 0;
color:#fff;
}
ul.latestNews li a:hover img{
z-index:1;
}
When the user hovers over the article, we apply a background image to the text holder, and flip the article's image to the front of the image stack.
So short of a bit of polishing we more or less have all the functionality we want without a line of jQuery or javascript in site. This is our 'degrade gracefully' state if the user isn't using js.
The downside is our rest state. With no hover, the last article's image will be the one displayed and none of the articles are going to be highlighted. As soon as we hover over one of the articles, all is fine.
There is a CSS solution for this. The :first-child & :last-child psuedo classes would give us the functionality we need. Unfortunately :first-child is not supported in IE6 and support for :last-child is even more patchy.
So we'll add a little jQuery. This is just going to make sure the first item and first image is selected as a default state.
We need to add an additional selector to the hover states.
ul.latestNews li a:hover,ul.latestNews li a.activeArticle {
background:#F3D154 url(images/newsLatest_bg.png) repeat-x scroll 0 0;
color:#fff;
}
ul.latestNews li a:hover img, ul.latestNews li a.activeArticle img{
z-index:1;
}
And a little jQuery to apply the class to the first article's anchor element when hover is not active, and remove it when it is.
var $firstArticle=jQuery('ul.latestNews li a:first');
var activeClass='activeArticle';
jQuery($firstArticle).addClass(activeClass);
jQuery('ul.latestNews li a').hover(
function(){
$firstArticle.removeClass(activeClass);
},
function(){
$firstArticle.addClass(activeClass);
}
);
We need to polish the CSS a bit so things look a little nicer.
ul.latestNews {
position:relative;
height: 134px;
border-top:1px solid #ffffff;
border-bottom:1px solid #ffffff;
overflow:hidden;
}
ul.latestNews li {
border-bottom:1px solid #FFFFFF;
background-color:#F3D154;
}
ul.latestNews li p {
margin:0 0 0 200px;
}
ul.latestNews li a {
font-size:16px;
font-family: "Trebuchet MS", sans-serif;
height:40px;
padding:2px 6px 2px 4px;
display:block;
overflow:hidden;
}
ul.latestNews li img {
position:absolute;
left:0;
top:0;
width:200px;
}
ul.latestNews li a:link, ul.latestNews li a:visited {
text-decoration:none;
color:#666;
}
ul.latestNews li a:hover,ul.latestNews li a.activeArticle {
background:#F3D154 url(images/newsLatest_bg.png) repeat-x scroll 0 0;
color:#fff;
}
ul.latestNews li a:hover img, ul.latestNews li a.activeArticle img{
z-index:1;
}
Implementation
I've created a unique skin for the page and a css file with the same name. All the above css will go in the myskin.css file and will only be loaded with this page.I've added the script to the bottom of the skin file (in this case an .ascx file) and included the jQuery library (you may already have this on your page):-
You can get rid of the flicker as the images are loaded by giving them a style of display:none and using jQuery or JS to make them visble once they have loaded.
This solution won't degrade gracefully if no JS is available. You can avoid this using the noscript tag in your header.

