Join our HiFi mailing list to receive the latest news & updates

HiFi on Forrst

4 Comment(s) | Posted | by Joel Sutherland | |

We've been working away, readying our next major release that will provide better support for agencies and those managing multiple sites.  While this has been in the works, our team discovered Forrst.

forrst

It has turned out to be a great community of people interested in web design/development as a whole, not just some part of it.  We've been putting up some of our ideas and feature screenshots and have been getting some great feedback:

We've also had some good conversations about web technologies that we care about:

If you're on Forrst and want to follow the some of the HiFi team, here are our accounts:

If you're not on Forrst and interested in an invite...we've got a couple, so let us know who you are in the comments.

Overview of Image Formats for the Web

1 Comment(s) | Posted | by Joel Sutherland | |

Graphical elements are a crucial part of every website design. Many people however, do not pay close enough attention to the details of deciding which type of graphical element to use in different circumstances. We've put together a detailed explanation of what an online image is and when it's appropriate to help you decide what type of image to use on your website, depending on the situation. 

The Basics of Online Images

What is an image file?

 An image is a rectangular collection of pixels. On the web, each pixel is made of three colors, Red, Green and Blue. We know what color the pixel is based on the ratio of the different colors. Each color can range from dark (low number) to bright (high number).

How can colors be represented?

There are two different ways that these color values are represented. Some formats are 24-bit, meaning they use 8-bit color depth. This means that each color is stored using 8-bits, or a value from 0 (dark) to 255 (light). So to show a purple pixel, our values would look something like Red(200), Green(0), Blue(200). Because we have 256 possible levels, that gives us a lot of possible colors to work with. To be exact, there are 256^3 possible colors.

The other way of storing color values is using indexed color. The two formats that use this on the web are 8-bit .png and .gif. These work by taking those 256^3 possible colors and then only choosing a subset of them to use in the image. These are then mapped to an index at the beginning of the file. So lets say we’re using a 16 color gif. Rather than needing to store the 24 bits of information for each pixel, only the index number needs to be stored. In our 16 color example, that is only 4 bits!

Which color representation is better?

 As you can imagine, there isn’t a correct answer. Different image types optimize better for different styles.

When you have images that contain a limited number of colors, you are better off choosing an indexed color type. Think about cartoons or screenshots of text. There aren’t many colors in these situations and often using an indexed color format will be much better. You can tell if you don’t have enough colors available by looking for “banding” or “dithering”.

When you are working with photographs or images that contain gradients, you are often better off with a 24-bit format. This will give you more colors to use.

How are images compressed?

 So our image is a collection of pixels, each pixel being a color. In the very worst case situation, all of the pixels are random and unique, so we have to save the value of every single pixel. But what if our image contains patterns? If our image is just a solid rectangle that is one color, you can imagine that we don’t need to save every single pixel. There are two main types of compression that get used on the web:

Lossless compression: This type of compression preserves the exact correct pixel. In a way it works like indexed color. It searches for repeating patterns in the image and gives those an index value. So rather than saving something that repeats multiple times, it just saves it once to an index, and then makes a note every time it repeats. When using lossless compression, you won’t be able to tell the compressed image from the original.

Lossy compression: Lossy compression does exactly what it sounds like. It throws away data. The compressed image is different from the original. This sounds terrible, but in practice it can work great. It works by looking for areas in an image that are close in color and it blurs away the detail. A classic example would be a photo that contains a bunch of blue sky. There might be bits of randomness in the sky, but you typically won’t notice it if that gets blurred away since the sky is very uniform. Lossy compression can also uses some of the same indexing tricks that lossless compression uses, but it can have the advantage of doing the blurring first to massage areas into looking the same.

Which compression method is better?

 Like color representation, there isn’t a correct answer. Lossless compression will work better on images that contain repeating elements. It does a poor job with noise, randomness and photographs because these often don’t contain things that repeat. Lossless compression will never look bad, it will just result in large image sizes.

Lossy compression does a poor job when it is absolutely important to maintain detail. You can tell when lossy compression is failing when images start to look blocky; this is called “artifacting”. Use lossy compression when lossless results in images that are too large and there aren’t noticeable artifacts.

Transparency

 Often you’ll want to place an image over a background and let that background show through. To do this requires transparency. There are two types of transparency, 1-bit and 8-bit. 8-bit transparency means that an an additional value, 0-255 is stored with each pixel. As you can imagine, this can make file sizes much larger since 33% more information gets stored per-pixel.

1-bit transparency means that a pixels is either completely transparent or it is a color. This is only used in combination with indexed colors.

24-bit transparency works exactly as you would expect. Things like dropshadows look great. 1-bit color can be a bit weird. It only works perfectly if there are clean, hard edges on the image. Otherwise you’ll be able to see the transition point between the image and the background. One trick to avoid this is to apply a matte color to the image so it appears to blend with the background. This only works when the image is going to be over fairly uniform background.

Putting it all together: a look at the web formats

JPG (24-bit color, lossy, no transparency)

 JPG can work great for images that are photographs or that have photographic-type detail that can be compressed away. It also works well in images that have a lot of gradients or shading. It does create artifacting which can be particularly noticeable on clean lines or text.

8-bit PNG (Indexed color, lossless, 1-bit transparency)

 This is a great first option to try for non-photographic images. If you can get away with 8-bit pngs, go for it since they compress very well and are lossless. If your image has a lot of gradients, or shading, the 256 color limit can be an issue. You can tell if your gradients contain bands or images look like they are filled with dots. If you’re working with transparency against a solid color, it can work great, otherwise the single bit transparency can be an issue.

24-bit PNG (24-bit color, lossless, 8-bit transparency)

 This is the only web format that has 8-bit transparency. It should be used when the image doesn’t look good as an 8-bit PNG or if full 8-bit transparency is required. It often compressed very poorly so in a sense it should be used as a last resort. Additionally, older versions of internet explorer cannot display them without some hassle.

GIF (Indexed color, lossless, 1-bit transparency)

 Gif is the same as 8-bit png but it uses a different (worse) compression algorithm. Don’t use it unless your project has weird requirements about using gifs.

Conclusion

While there is no one type of image that should be used in all scenarios online, there are definite guidelines that can help you maintain a quality image without unnecessarily slowing down the webpage's load time. Understanding the differences between different image types will help you make accurate decisions when it comes to deciding what kind of images to use when designing your website. 

 

Images from FreeDigitalPhotos.net artists: Salvatore Vuono, Simon Howden and Arvind Balaraman

How we made a jQuery Events Calendar for The Salvation Army

7 Comment(s) | Posted | by Josh Lockhart | |

New Media Campaigns recently developed and launched http://www.keepthebellringing.org for the Salvation Army of Wake County. Springboard Eydo, an agency partner, provided the excellent layout design that we incorporated into our content management system. Although the Salvation Army's website features are many, I want to focus on one feature in particular — the calendar.

Overview

Calendar

The Salvation Army of Wake County website includes a monthly calendar that may be paginated into the past or future. Each calendar cell (representing one day of the current month) contains a list of events, similar to Apple iCal or Google Calendar. When you click an event link, a modal window appears featuring details about the selected event. This calendar is the result of carefully woven design, HTML markup, CSS styles, and jQuery scripts.

The Markup

We developed The Salvation Army website using the XHTML 1.0 Transitional DTD. In most cases, the markup will validate as XHTML 1.0 Strict. However, we opted for the Transitional DTD since a majority of the website's content is provided and controlled by the client. Here is a sample of the calendar's markup.

<ul id="full-calendar-legend">
	<li class="all" id="all-events">All Events</li>
	<li class="orange" id="community-center-events">Community Center</li>
	<li class="blue" id="church-events">Church</li>
</ul>
<table id="calendar">
	<thead>
		<tr class="calendar-heading-days">
			<th title="Sunday">Sun</th>
			<th title="Monday">Mon</th>
			<th title="Tuesday">Tue</th>
			<th title="Wednesday">Wed</th>
			<th title="Thursday">Thu</th>
			<th title="Friday">Fri</th>
			<th title="Saturday">Sat</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td class="calendar-cell calendar-cell-weekend first"></td>
			<td class="calendar-cell"><span class="calendar-cell-date">1</span></td>
			<td class="calendar-cell"><span class="calendar-cell-date">2</span></td>
			<td class="calendar-cell"><span class="calendar-cell-date">3</span>
				<ul class="calendar-cell-events">
					<li class="all orange">
						<a href="/page/summer-basketball-registration" title="See details for this event" class="thickbox calendar-event-orange">Summer Basketball Registration April 6-June 5</a>
					</li>
				</ul>
			</td>
			<td class="calendar-cell"><span class="calendar-cell-date">4</span></td>
			<td class="calendar-cell"><span class="calendar-cell-date">5</span></td>
			<td class="calendar-cell"><span class="calendar-cell-date">6</span></td>
			<td class="calendar-cell calendar-cell-weekend last"><span class="calendar-cell-date">7</span></td>
		</tr>
	</tbody>
</table>

Yes, we used a table for the calendar markup. A calendar is, in fact, tabular data. Week days (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday and Saturday) are table columns, and days of the month are table cells. We added meta annotations to the calendar markup in the form of class attributes. For example, we annotated table cells with classes like calendar-cell and calendar-cell-weekend.

The CSS

Our CSS is clean and easy to understand. This simplicity is the result of well-annotated HTML markup. By annotating our HTML markup, we can quickly and easily isolate and style the appropriate calendar elements.

#calendar{ width: 800px; font-family: helvetica, arial, verdana, sans-serif; font-size: 0.917em; margin: 40px 30px 0 30px; }
#calendar thead tr.calendar-heading-days th{ text-align: center; font-weight: normal; }
#calendar tbody tr td{ width: 100px; height: 80px; border-top: 1px solid #b8b096; border-right: 1px solid #b8b096; }
#calendar tbody tr td.last{ border-right: none; }
#calendar tbody tr td.today{ background: #b8b096; }
#calendar tbody tr td ul{ margin: 0 0.5em; }
#calendar tbody tr td a{ color: #fff; text-decoration: none; font-size: 10px; color: white; line-height: 11px; display: block; width: 100%; margin: 2px 0; padding: 1px 2px; }
#calendar tbody tr td a.calendar-event-blue{ color: blue; background: blue; }
#calendar tbody tr td a.calendar-event-red{ color: red; background: #bb2f2d; }
#calendar tbody tr td a.calendar-event-orange{ color: #d53b27; background: #FF6600; }
#calendar tbody tr td span.calendar-cell-date{ display: block; text-align: right; padding: 0.25em 0.5em; }

The Javascript

Popup

The calendar behavior was created using jQuery and Thickbox. Here is the relevant snippet from the HTML markup above.

<a class="thickbox calendar-event-orange" title="See details for this event" href="/page/summer-basketball-registration">Summer Basketball Registration April 6-June 5</a>

We annotated the hyperlink with the thickbox class. When the link is clicked, a Thickbox modal window appears and loads the referenced resource with AJAX. We also provided a mini calendar that is used throughout the rest of the Salvation Army website. You can see this mini calendar on the home page in the left column.

Sidebar mini calendar

Like it's larger version, the mini calendar provides a small color-coded link in the appropriate table cell for each event. Each event link's color represents a specific calendar, as described in the calendar legend. When a color-coded link in the calendar legend is clicked, all relevant events in the mini calendar are shown; events with other colors are hidden. We relate events visually with colors and programatically with class annotations. For example, each link in the calendar legend has a class attribute similar to <li class="blue">...</li>. Each event link in the mini calendar has a class attribute similar to <li class="all blue">...</li>. Class annotations create a parent-child relationship between calendar and event; class annotations also establish calendar view states using the following jQuery script. We referenced the color class attribute in our CSS style sheet to customize the calendar appearance. We also referenced the color class in our Javascript (see below) to customize behavior.

function showMainEvents(eventClass){
	$('.calendar-cell-events .all').hide();
	$('.calendar-cell-events .' + eventClass).show();
}
$('#full-calendar-legend li').click(function(){
	showMainEvents($(this).attr('class'));
});

Merging design and programming

The Salvation Army website and calendar demonstrates how New Media Campaigns merges design and programming to create stellar user experiences. Head over to our portfolio to view more of our work.

Controlling typographic weight and contrast with text-shadows

0 Comment(s) | Posted | by Eli Van Zoeren | |

Face it, we don't have a lot of control over typography on the web. We have about a half-dozen fonts to pick from, we don't know what size or exactly what color the type will be, and the exact same type will render very differently on a Mac than a PC. But the increasing browser support of the CSS text-shadow property is giving us more fine-grained control of text weight and contrast.

Text shadow has been supported in Safari since version 1.1 (as well as other Webkit-based browsers like Google Chrome) and in Opera since version 9.5. With the release of Firefox 3.5 last week, all the major browsers aside from Internet Explorer support shadows. Fortunately, since we will only be making subtle adjustments to our typography, it isn't a big deal even if the viewer is using a browser that doesn't support shadows. They will simply see the default look.

Typographic Weight

Normally, there are two font weights on the web: normal and bold (in theory there are a range of weights from 100 to 900, but there is little practical support for that). However, we can fake an intermediate text weight by setting the text-shadow color to the text color, and setting the blur to zero.

Normal text / Bold text / Text with text-shadow: 0 0 0 #000;

We can also reverse the trick and make the text a bit lighter with nearly-transparent shadow with 1 pixel of blur behind the text. I first saw a similar trick on Wilson Miner's site, although he has since removed it. The version using alpha transparency was developed by Komodo Media. Unfortunately, this technique is a little less predictable in browsers other than Safari, particularly in the current version of Chrome which actually darkens the text.

This has no text-shadow / This has text-shadow: 0 0 1px rgba(0,0,0,.01);

Local Contrast Enhancement

There is a trick commonly used in Photoshop to make photos "pop" with more contrast, but without modifying the overall tonal range of the photo. You can read more about local contrast enhancement elsewhere, but the essence of it is increasing the contrast of every edge in the photo—making the darker side a bit darker and the lighter side a bit lighter. We can use text-shadow to do the same thing with low contrast text.

Note: I am not advocating low-contrast text on your website! Make sure the text is readable even before you add any shadows.

So for instance if we have some brown text on a tan background, we would need to add a lighter tan "glow" around the text. That will increase the contrast immediately around the text itself, without changing the rest of the background.

No contrast adjustment / With text-shadow: 0 0 5px #f1e2cd;

You can see that this method lightens the text-weight slightly (just as in the previous example) but it also makes the text look sharper. The trick here is to pick a shadow color that sets off the text without looking artificial. In particular, this can be useful when you are overlaying text on a background image: the slight glow will make the text easier to read.

With all of these techniques the trick is getting the right combination of shadow color and blur radius: keep experimenting until you get it looking the way you want. And make sure to browser test! We are using cutting-edge technology here, so it will look a little different from browser to browser.

Finally, there are undoubtedly many other interesting effects to be had by manipulating the text-shadow property. If you find others, please share them in the comments.

CSS Sprites2 Refactored: Building an Unobtrusive jQuery Plugin

30 Comment(s) | Posted | by Joel Sutherland | |

Note:

This post is in reference to the recent A List Apart article in which Dave Shea expands upon the classic CSS Sprites technique by using jQuery. His technique allows for animations between the link states while still being fully degradable for visitors that do not run javascript.

Link to the original CSS Sprites2 Article.

In this post I am going to revisit the markup, css and javascript in the CSS Sprites2 article to address some of the concerns I had when viewing it. I will also clean up the function and turn it into a handy jQuery plugin that allows for more control over the animation while requiring less initial configuration. To start things off, here is the end product of this technique using either Dave's method or the method described in this post.

To set the stage for my plugin writeup, it is important that I first describe how this technique works and the ways I would like to change it. Below is a quick overview of the original technique along with some minor changes I made to the markup and css. If you would like to jump straight to the plugin writeup, click here.

How CSS Sprites Works

CSS sprites were written up in A List Apart back in March of 2004. The premise behind sprites is that instead of slicing up an image into each of its states, we are able to use the background-position declaration in css to just reposition one giant image.

Background image containing all states.

Background image containing all states

There are a couple of benefits to using this technique. First, there is no reason to worry about image preloading, since all of the states are loaded at the same time. When you mouseover a button for the first time, there will be no flicker or pause before the hover state is shown.

Second, and perhaps more importantly, only one image is downloaded by the browser instead of as many as 4 for each button. Had we sliced the above image and implemented the menu without sprites, there could have been as many as 16 images used. Each of those images would have needed a separate request to the server and hurt the performance of your site. This is such a big issue that the Yahoo developers site considers minimizing http requests the #1 thing you can do to your content to improve page load times. (Performance Factors, YSlow Firefox add-on)

What Changes with CSS Sprites2

CSS Sprites2 keeps all of the advantages of the original technique, and then adds animation. Rather than relying directly on CSS styles to immediately show the different states, instead it uses javascript to animate between the different states. Should a user not have javascript, the technique degrades gracefully.

The javascript adds animation to the technique by placing an invisible over the original link, setting its background-position to show the appropriate state, and transitioning it in and out on the appropriate mouse events.

Now that the technique has been covered, I am going to go over the quick changes I made to the original article and then walk through the creation of the plugin.

Change to the markup

A quick concern I had with the implementation was how an active list item was indicated. Rather than giving the item itself a class, the parent unordered list is given an additional class.

Original Markup


If this seems hacky, it's because it is. Essentially it avoids an IE6 issue with multiple classes on a single element. There is not a good way around this problem while maintaining semantically clean markup. My solution was to avoid the issue by using ids instead of classes to identify the individual nav items. This has obvious drawbacks, but the IE6 Deathmarch has begun and I consider this my small contribution to the movement.

New Markup

Change to the CSS

Since I made a change to the markup, I also needed to make a change to the css. Below is the CSS for a single nav item using the original technique:

.nav .home a:link, .nav .home a:visited {
	left: 23px;
	width: 76px;
}
.nav .home a:hover, .nav .home a:focus {
	background: url(blue-nav.gif) no-repeat -23px -49px;
}
.nav .home a:active {
	background: url(blue-nav.gif) no-repeat -23px -98px;
}
.current-home .home a:link, .current-home .home a:visited {
	background: url(blue-nav.gif) no-repeat -23px -147px;
	cursor: default;
}
.nav-home, .nav-home-click {
	position: absolute;
	top: 0;
	left: 23px;
	width: 76px;
	height: 48px;
	background: url(blue-nav.gif) no-repeat -23px -49px;
}
.nav-home-click {
	background: url(blue-nav.gif) no-repeat -23px -98px;
}

Looking over this css, the purpose of most of it is obvious. It covers the LVHA states and treats the :focus state the same as the :hover state. Since the information about which state is selected is in the parent

  • It pollutes the namespace with another function.
  • All of the parameters are required, though they don't need to be.
  • Passing in a selector for this purpose doesn't seem very "jQuery"
  • The options for animation are unnecessarily limited
    • allowClick - Allows click events to be disabled by setting this to false.
    • show - A hash of animation options to be used when the hover is enabled.
    • hide - A hash of animation options to be used when the hover is disabled.
    • activeClass - The class the plugin should use to determine which nav items are active and therefore shouldn't have mouse events attached.
    • clickClass - The class that should be added to the placeholder div when a nav item is clicked.

By pulling declarations upwards where possible and switching to ids, the following is the CSS for the same nav item with the new markup:

.spritesnav #snhome a:link,
.spritesnav #snhome a:visited,
.spritesnav #snhome div{
	left: 23px;
	width: 76px;
}
.spritesnav #snhome a:hover,
.spritesnav #snhome a:focus,
.spritesnav #snhome div{
	background: url(blue-nav.gif) no-repeat -23px -49px;
}
.spritesnav #snhome a:active,
.spritesnav #snhome div.click {
	background: url(blue-nav.gif) no-repeat -23px -98px;
}
.spritesnav #snhome.active a:link,
.spritesnav #snhome.active a:visited {
	background: url(blue-nav.gif) no-repeat -23px -147px;
	cursor: default;
}

 

Changes to the Javascript

The javascript code in the original article is well written and clean, but I believe it takes the wrong approach. Rather than use jQuery's defined plugin architecture, it is just a simple function call with a number of parameters:

$(document).ready(function(){
    generateSprites(".spritesnav", "current-", true, 150, "slide");
});

While this solution gets the job done, it has a couple of problems:

The obvious solution to these problems is to take the code that Dave wrote and turn it into a proper jQuery plugin. Once we are done with this, we will be able create the same sprites enabled menu using the following code:

$(document).ready(function(){
	$('.spritesnav').sprites();
}

By following jQuery's plugin authoring guidelines, I am making all of the parameters optional by supplying sensible defaults. When implementing a plugin, this is done by using the jQuery.extend() function. Additionally, I am following their animation guidelines which allows for any type of animation to be used that jQuery or its extensions support. Below is the plugin declaration and the jQuery.extend() call I use to set up defaults for all of my parameters:

jQuery.fn.sprites = function(settings) {
	settings = jQuery.extend({
		allowClick: true,
		show: {opacity: 'show'},
		hide: {opacity: 'hide'},
		activeClass: 'active',
		clickClass: 'click'
	}, settings);

The optional parameters above do the following:

With this set up I am ready to execute the logic of the plugin. I followed Dave's work pretty closely. The only place I parted was that I used chaining and traversal where I could rather than initiating a new selection. This probably makes the plugin (negligibly) faster while also making it a little bit easier to follow. I also kept everything in one function, eliminating a few more selections. Below is the rest of the code for my plugin with my comments stripped.

jQuery(this).children().each(function(){		
  if(!jQuery(this).hasClass(settings.active)){

    jQuery(this).children('a').css({background: "none"});
    jQuery(this).hover(function() {
      jQuery('')
	  .prependTo(this).animate(settings.show);		
    },function(){
      jQuery(this).children('div').animate(settings.hide, function(){
        jQuery(this).children('div').remove();
      });
    });
	
    if(settings.allowClick){
      jQuery(this).children('a').mousedown(function(){
        jQuery(this).prev().addClass('click');
      }).mouseup(function(){
        jQuery(this).prev().removeClass('click');
      });
    }
	
  }
});

As you can see it is extremely compact and nearly everything has become an option. If you know just a little bit of jQuery, you might be wondering why the famous '$' isn't being used in the code above. When writing a plugin, it is important to be mindful of potential collisions with other libraries. For that reason it is recommended that you use 'jQuery' instead. If you really want to use the '$' or other alias in your plugin, you can wrap your plugin in an anonymous function:

(function($) {
  // plugin code here, use $ as much as you like
})(jQuery);

If you like this plugin and want to add it to your site, below is an example you check out and a zip file containing all of the files for this project.

Check out a demo.
Download a .zip of the files