Overview:
This snippet allows you to easily create a grid of images from the media tab. You upload however many image you want, and then using custom fields, specify how wide you want the container to be and the number of images you want on each row.
All of the images are then automatically resized and placed in the grid.
Requirements:
No external requirements.
Components:
Template:
{% include 'common/image-grid.html' with ['images':this.media, 'width':this.custom.tych.width, 'layout':this.custom.tych.layout] %}
Installation:
To install this snippet, you just need to upload the file in the zip to your theme and include it in your desired template. All of the required CSS and image resizing is done inside the template itself.
You need to make sure that you're passing in variables for images, width and layout. This means that you need to set up custom fields for width and layout.
- width: This is the width of the container that holds the images. Use a text field for this.
- layout: This is a textarea that explains how many images go on each row.
All the magic happens in the layout field. The following would display 5 images total, 2 on the first line, 3 on the second:
2
3
It is also possible to indicate how tall you want each row to be in pixes. You can optionally do that by using a bar ("|") and then putting in the number of pixels you want. Here is an example that displays 6 images, 1 on the first row, 2 on the second, 3 on the third. The second row is set to 100px high:
1
2|100
3
Here is a screenshot showing the custom fields. Note that I am also using an "Enabled" dropdown so that it runs optionally.

Overview:
This snippet is a core part of every HiFi theme. It allows you to easily build navigation, menus, sitemaps or any feature that needs a nested list of your site content.
The idea behind the snippet is that you provide a piece of content as a starting point and a depth, and this will build a tree for you. Typically, the starting point will be your homepage, and the depth will be 1 or 2 depending on whether you want drop downs in your navigation.
By default, this snippet generates nice and clean markup, but you can pass in other templates if you need to change that markup dramatically. Most common things, like adding ids and classes can be done with the default templates.
Requirements:
No external requirements -- although this snippet won't do you any good if you're not on HiFi.
Instructions:
Template:
The default options will generate nested unordered lists starting from your homepage, two levels deep. Here is how you make the default call:
{% import '/common/navigation/navigation.html' as navigation %}
{{ navigation.draw() }}
This will generate something like the following:
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a>
<ul>
<li><a href="/about/philosophy">Philosophy</a></li>
<li><a href="/about/history">History</a></li>
<li><a href="/about/team">Team</a></li>
</ul>
</li>
<li><a target="_blank" href="http://www.yahoo.com">Yahoo</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
If you need to do something beyond the defaults, you can add in options by passing in an options object. Here is an example that changes the maxDepth to 3 and has two other fake options. It doesn't matter what order they are in.
{% import '/common/navigation/navigation.html' as navigation %}
{{ navigation.draw({
maxDepth: 3,
option: 'value',
otherOption: 'value'
}) }}
Options Reference
root:
A query to find the starting point for the nav. So {type: 'page', url: '/about'} would start from the about page. It uses the first result from the query.
Default: {type: 'home'}
maxDepth:
The number of levels this should traverse.
Default: 2
childQuery:
This is the query used to restrict the items that are found. It is used at each depth level.
Default: {type: 'content', inMenu: true, orderBy: 'ordinal', count: 100}
activeClass:
The class to put on the active nav item based on url.
Default: 'active'
ancestorActiveClass:
The class to put on ancestors to the active nav item based on url.
Default: 'active'
includeParent:
If true, the root is included in the first level nav.
Default: true
includeLevelClass:
Display a level class on each li (ie. class="level_3")
Default: false
levelClassPrefix:
Specify the string you want to prefix the level number
Default: 'level_'
cssId:
The id attribute assigned to the nav's first ul
Default: ''
cssClass
The class attribute assigned to the nav's first ul
Default: ''
newWindowAttribute:
For link types that have newWindow set, what attribute do you want to add to the link.
Default: 'target="_blank"'
linkFolders:
Specify whether folder links should have the href attribute
Default: false
wrapperTemplate:
Path to the template to use for wrappers
Default: '/common/navigation/wrapper.html'
itemTemplate:
Path to the template to use for items
Default: '/common/navigation/item.html

This morning we're making it official the HiFi Snippet Library has launched.
A great thing about working with HiFi is that you can use the web technologies you know (HTML/CSS/JS) with no restrictions. Many systems say this, we actually mean it. This means that it is extremely easy to build reusable snippets that can save you all kinds of time when building your client sites.
If none of this makes sense to you, hopefully we can answer your questions here. If you have any others, let us know in the comments.
What is a snippet?
A snippet is a combination of HTML, CSS and JS that you can drop into your sites' templates to quickly implement a feature. Since it is based in just HTML/CSS/JS, it is easy to customize or change them.
Why is this cool?
Snippets let you quickly add functionality to your sites without forcing you to use particular HTML. Design and code the sites the way you want, and then hook up the functionality with snippets.
How much do they cost?
The snippets are completely free. Most can even be used on non-HiFi sites!
Where are they coming from?
The HiFi snippets are being written both by the HiFi team as they build sites, and by customers using HiFi. If you have a snippet you would like to see, or a snippet you want to contribute to the library, get in contact.
How often will they be released?
We have committed to release at least one snippet a week, but through community contributions, the number may be even higher! Whenever we release a snippet, we will be posting it to the HiFi blog. So be sure to subscribe to the blog to get updated on the newest snippets.
Your snippets are stupid. Why don't you have an XYZ snippet?
We like your attitude. Shoot us a message and we'll make sure it gets added!
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.

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.
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

We soft-launched HiFi about two weeks ago. This meant closing down the beta program and launching our pricing and sign-up pages. We've been writing posts on this site for some time so we get a fair amount of traffic to the blog from people who might be interested in our product.
Like most new products there is a lot of marketing left for us to do. We haven't come close to explaining all of the features and advantages that HiFi has on this site. Since the our team knows the product well, it only made sense to try letting our customers contact us and ask us about it. We turned to Olark to help make this possible.
The results are already pretty impressive.
Just over 25% of our signups have been from people that have chatted with us first. About 50% of the people that chat with us have gone on to sign up!
Generally the conversations have gone really well: our customers are web designers and developers and our staff is made up of web designers and developers so both parties have a lot in common. For the most part, customers have been happy that we have been able to answer their questions with as much depth as we have.
How to set it up
Olark works through a simple Javascript file you include at the bottom of your page. On HiFi this is super easy to do. We like to set up a JS block that allows us to add scripts only on the pages they are needed. We just wanted Olark to run on the pricing and signup page. To get it to work there, I edited the JS block on both pages as follows:
{% block js %}
{% parent %}
<!-- begin olark code --> <script type="text/javascript">...</script> <!-- end olark code -->
{% endblock %}
Once you've done that, Olark will recognize that it has been installed. From there, you can sign in to just about any IM client and link it to your account. I use Google Talk so I linked that up. When you do this, Olark will automatically request to chat with you from a number of different names like "webuser1@olark.com". Once you approve this, you're good to go.
Now, whenever somebody is browsing a page on your site with Olark installed, you'll see an active buddy on your chat list. Either you or your customer can initiate the conversation, it's that simple!
One great feature for those on gchat is that Olark is smart about when to show up. If you aren't logged in or have your status set to 'Busy' it won't give visitors the option to chat with you.
Also, you can connect it with multiple gchat accounts. Once one of them responds, it blocks the others. This allows for several of us to be available at the same time without having to worry about whether someone else is already chatting with a customer.
How it looks

You can control where on the page Olark shows up. The bottom right is default and probably most common so we put it there. It starts closed, but will open when you click on the title. You can control 100% of the copy that people see.
Conclusion
Our experience might not be 100% typical. We're able to make our founders and developers available to our customers. I don't know that it would be working as well otherwise. Additionally, our product has high switching costs. Before someone commits to using HiFi as a CMS they will need to be willing to build a site on it! This means that our customers likely want to do a lot more research before making a purchasing decision.
That said, we would highly recommend giving Olark a shot. It's so easy to install and its defaults are really sensible. You'll be able to get a feel for how well it works quickly and uninstall it if you don't think it's worth it. There is a 14-day free trial so you can figure out if it works for you at no charge.
One of the best features of jQuery is its simple AJAX functionality. This allows you to easily pull data from other sites and services onto your own site. Learning how to use this functionality makes it easy to integrate any number of services into your websites, making them richer and more interesting to your visitors. It will also make you less dependent on the widgets that companies provide, allowing you to create your own.
For this post, I am going to show how I created URL Tweet Compete, a tool that allows you to enter multiple urls into a textarea, and it then returns the number of tweets that the they have on Twitter. Be sure to try it out so that you can understand what this post is all about.
The tools uses the Topsy Otter API. This is a fun API to play around with because it is easy to understand and it doesn't require any authentication. Additionally, it supports jsonp which is important as I will explain later.
The core call in jQuery for this project looks like this:
$.ajax({
url: "http://otter.topsy.com/urlinfo.js?url=http://www.nytimes.com",
dataType: 'jsonp',
success: function(results){
console.log(results);
}
});
Now lets get in to the mechanics of how this works.
What are APIs? What is AJAX?
This might be old news, but it's worth covering quickly. You could read all day about APIs and AJAX, but they are also easy enough to understand in concept.
An API is a tool that makes information available to progams in a more convenient format. As an example, humans can go to Twitter's website in their browser to see a pretty display of tweets. The Twitter API however presents the tweets in a way that is convenient for programs. It just gives the info.
AJAX is a phrase that roughly means "fetching information on a loaded page using Javascript". It is an acronym with a specific meaning, but it is now used more generally. The "X", for example, stands for XML, but now AJAX is used whenever there is any kind of dynamic content is being displayed, including JSON. Typically, AJAX is used in conjunction with an API.
So how does it work?
In the example above we are initializing an AJAX request to the Topsy API. You can see exactly what happens by checking out the URL yourself, directly: http://otter.topsy.com/urlinfo.js?url=http://www.nytimes.com As you can see, the following is shown:

So when that request is made, some data is sent back. We're now able to use this data however we like on the page. In the case of the URL Tweet Compete app, we're displaying the "trackback_total" value which represents the total number of tweets that have been received.
What is JSONP?
When making AJAX requests to external domains, there are a number of restrictions that apply for security reasons. JSONP is a technique to get around these restrictions. jQuery builds it into their $.ajax() method to make it easy to use.
Whenever you're using an API that is hosted on another domain, you'll need to make sure you're using the jsonp version of the API. Topsy offers an XML, JSON and JSONP version. A common mistake is attempting to use the JSON version which is impossible with javascript on another domain.
With Topsy (and many other APIs), you can select which version you want by changing the extension on your request. For the XML version, use ".xml", for the JSON version use ".json". Usually to get the jsonp version, you'll use either ".jsonp" or ".js".
Putting it All Together
So in order to request information from the Topsy API and display it on a page, you'll need some code like this:
$.ajax({
url: "http://otter.topsy.com/urlinfo.js?url=http://www.nytimes.com",
dataType: 'jsonp',
success: function(results){
var title = results.response.oneforty;
var numTweets = results.response.trackback_total;
$('#results').append(title + ' has ' + numTweets + ' tweets.');
}
});
This code goes and fetches information about the url: http://www.nytimes.com and then displays the number of tweets it has. Notice that we're doing the displaying within the 'success' function. This is because we don't get the information back from our Topysy AJAX request immediately.
Instead, once it comes back, jQuery calls the success function that we define and passes in the results so that we can use them.
Hopefully this post is helpful for those new to using APIs and AJAX. If there are any questions or comments, please leave them below!

See the Demo | Download the Zip
Writing the CSS for websites can be a very time consuming process. There are often big things that need to be done when creating stylesheets like layout, that leave a developer exhausted when it comes time to handle the details. One detail that is often overlooked is ensuring good coverage of all typographic elements as well as setting up a clean typographic framework.
This is especially an issue when setting up a site on a Content Management System. As new content is created, it is important that the CSS developer has anticipated all of the elements that will show up on the site and set up rules for them. By my count, there are over 20 elements that need to be considered in a variety of combinations.
Using a solid boilerplate foundation can make this task much easier. For that reason, I've developed a CSS Typography Boilerplate that I use to ensure coverage of all elements. As a bonus, using this as a starting point makes it really easy to set up a typographic baseline grid. This post covers this boilerplate, explains what a typographic baseline is and gives you the stylesheet you can use as a starting point.
What is a Baseline Grid?
When taking about grids and the web, we're usually talking about vertical columns. A typographic baseline grid establishes a vertical order, rhythm and spacing for your text that aligns with a grid.
The idea is to set the font-size, line-height and margins of all of your typographic elements, such that text automatically fits into a grid.
This might seem like overkill, but it is a great way to ensure that the content type on a page looks great. By no means, do I advocate the strict adherence to a grid though. Often it makes sense to break the grid or to not use a grid at all. I do however, think that using a grid is a great starting point for most sites. Additionally, I've found that starting with a grid and modifying from there is a big timesaver.
To see this project's starting grid in action, check out the demo.
How to Use this Boilerplate
This project includes a zipped directory of a good type starting point. There is a good html-ipsum that contains greeked text showing nearly every element you need to cover. Additionally there is a typography.css file that contains the rules for each element in a fairly organized fashion.
By default, all rules are preceeded with ".content". This is to make it easy to apply this stylesheet to a particular container. If you want to use it globally, which I recommend, just do a search replace to kill all instances of ".content".
/* Block Baselines */
.content h1, .content h2, .content h3, .content h4, .content h5, .content h6,
.content p, .content ul, .content ol, .content pre, .content blockquote {
margin-bottom: 20px;
}
When configuring this stylesheet for your site, there are three primary rules to consider: font-size, line-height, and margin-bottom. Keeping these consistent or mindfully changing them is the best way to keep the grid. By default, copy is 12px on a 20px grid.
I've also included a set of rules to display the grid on a container class as well as give a background to all block elements. This is great for debugging when you really want to hit the grid exactly. The rules look like this:
/* Baseline Debugging Backgrounds */
.showBaseline {
background: url(../images/baseline-20.png);
}
.showBaseline h1, .showBaseline h2, .showBaseline h3, .showBaseline h4, .showBaseline h5, .showBaseline h6,
.showBaseline p, .showBaseline ul, .showBaseline ol, .showBaseline pre, .showBaseline blockquote {
background: rgba(255,200,200,.3);
}
If you want to use a baseline of a different height, just make a 1px wide image of the height you need with the bottom pixel filled in.
A Sidenote on Using Pixels
Starting some time ago, the use of pixels for font-sizing has been making a comeback. To give a quick recap, pixels were basically abolished as a best practice because IE6 and older did not give the option to rescale pixel-sized text. Beginning with IE7, IE has allowed for page-zoom style scaling. As IE6 has lost significant browser share, pixels have become a viable option for sizing text again. I am 100% for this and that is why you see pixels in this boilerplate. I do plan on releasing a version that is not dependent on pixel sizing at some point. (If a reader wants to give a hand with this it would be appreciated!)
To read more about this debate, here are some good articles:
Demo and Download
Last updated: 11/12/2010
Release Notes:
- <select> breaks the grid. Not sure what to do about this.
- No default styles for tables yet.
If you have any questions, comments, or improvements, be sure to leave them in the comments.
Since the launch of the private beta, HiFi has gone through quite a few fixes and improvements. As we make them, we're sure to both update the documentation at docs.gethifi.com as well as put a notice on the HiFi Changelog. If you haven't yet, go ahead and subscribe to the changelog to get the latest updates on the improvements and fixes we're adding to HiFi.
In the meantime, here is a recap of some of the more exciting changes and improvements to HiFi.
Improved Page Picker
Everywhere in HiFi that you can add a link, there is also an option to use the Page Picker. This lets you quickly add links to content that you've already developed for your site. This is now being loaded dynamically for improved performance and there is also the option to quickly search as well as browse for content.
Additional SEO Controls
HiFi automatically does a whole bunch of great SEO things as well as gives fine grained control over things like URL structure, meta descriptions and more. With an update early last week, it is now possible to have more control over the sitemap.xml and robots.txt files that are generated. It is now possible to exclude live pages (and their children) from the sitemap.xml file as well as make the entire site un-indexable via robots.txt. This is really helpful when either working on a new site that you want to hide, or just a section of a site.
Better Notification Controls

Now, site owners have the option to be notified of all non-spam comments and form submissions, even if there are other people set up to be notified as well. This makes it easier to track what is going on when areas of the site have been delegated to others.
HiFi.Merge()
We added an awesome new method to the HiFi API. It's called merge, and it does just that. You can pass it as many arrays of HiFi objects or even HiFi queries and it will returned a single array of all the unique results. If you pass in a string, it will even order them for you. This is great for putting together searches or feeds from many areas of a site. It's also a great example of why the HiFi Templating system is so awesome -- with full access to your data, just about any site is possible.
There is more
This is just an overview of some of the changes and improvements we've been making. As always, if there are any questions feel free to drop them in the comments or shoot us an email.
We've relaunched the HiFi site! The previous version is on the left below, and the new version is on the right:

While the new version may be less intense and impressive, we feel that it will be a good foundation for the site as we move towards our product launch.
The first site put a premium on design, which paid off in a couple of ways. First, it led to HiFi getting reviewed on several Design and Development sites, which drove some great targeted traffic and quickly accumulated links for the new product. Second, it showed the versatility of the system that we were able to faithfully reproduce such an intense design on HiFi and have it deliver great performance to visitors.
The new site is aimed at quickly giving visitors an idea of why HiFi is the CMS for them. It more prominently features specific feature details above the fold and gives a first-time visitor much more information about the product than the old site. The new design also highlights efforts to convert visitors to our Beta program (and eventually our pricing page), which is a nice step forward to make this site more product oriented.
Some of the cool pages to check out on the new site are the features page and examples page. The features page gives a 10,000 foot view of what HiFi is all about and features our new product video. The examples page shows just a few of the sites that are already in production on HiFi. Flipping through those should show you that there truly are no design constraints on HiFi!
The HiFi Overview Video
We also now have a great overview video of the HiFi system. It was put together by Alex Pomer, one of the project managers from New Media Campains. Alex has been using HiFi every day for over six months and has really fallen in love. Watching this video is a great introduction to the system as a whole:
Let us know your thoughts on the new site and content, and be sure to share it with your friends! We've got some exciting stuff that has come out of the beta program that we should be sharing soon. As always, shoot us an email if there are any questions!