Unmatched Style’s CSS Off Was Slimey Fun

UnmatchedStyle.com hosted a CSS competition for front-end devs to strut their stuff among their peers. Everyone got the same design and it was up the entrant to come up with the most efficient, pixel-perfect, bleeding-edge, fully functioning interpretation. The deceptively simple looking design was lovingly crafted by the rowdy folks of Paravel and sent out two weeks ago. Entries were due at 5pm today. Here’s the low down on my submission.

First, you should probably play around with my finished design and compare it with the static mockup (linked above). Go check it out… I’ll wait. Did you drag the corner of the browser to check how it responds to different browser sizes? Of course you did you CSS nerd.

  •  Somehow I messed up the colors of the design. My layout has really bright colors while the original design uses more muted colors. I have no idea how this happened.
  • The logo is a background image attached to the element of the section. I was inspired by html5forwebdesigners.com.
  • I forgot to add the blue faded slime splat in the header. I kind of screwed myself by using the <head> and <header> elements in the same section though I could have attached it to the <HTML> element. Oh well.
  • Instead of PNGs I used GIFs in some places due to the smaller file size (thanks to increasing the Lossy section in Photoshop’s Save For Web dialog)
  • Navigation links are at the bottom of the page with position:fixed (sticks to the top of the viewport) set for larger screens and an anchor link to the bottom of the page for smaller screens.
  • The obstacles section is built with two sprites using the same background-position offsets. I wanted to just use one sprite for the larger images and use background-size to scale them down for the thumbnails. Performance took a big hit so I simplified.
  • The larger obstacle images are within a
    element with overflow:hidden applied. The thumbnails link to the IDs of the larger version so no JavaScript is required to show/hide them.
  • The labels for the prizes that appear on hover are pulled from the title attribute of the link dynamically using CSS.
  • The form uses required and pattern attributes for validation without any JavaScript. If I had more time I would add a validation script as a fallback.
  • When the countdown reaches zero I “slime” the user using a number of slime splat images already loaded in the design.
  • The two addresses to the studios are marked up with a vCard microformat so machines can easily parse that information.
  • I did not use the <address> element for the studio addresses because that is not what it is for.
  • The custom <select> drop down styles are images with the invisible <select>’s laid overtop. They’re not useable for sighted keyboard users. This is probably my least favorite part of my design.
  • I focused much of my time on making the design accessible and didn’t even bother checking what it looks like in browsers outside of Firefox 7, Chrome 15, and Safari 5 (all Mac versions). I just didn’t have enough time.
  • This layout is sluggish on my Nexus One most likely due to the way I added the semi-transparent grainy texture.
  • I added some ASCII art as an HTML comment at the bottom of the page. I like adding little easter eggs like that.
  • Finding the right element to make a favicon image from was tricky. I settled on the KN from the Knucklelodeon logo because it looked the best at 16×16.
  • You can pin the site to your desktop if you’re using IE9 and Windows 7 since I added a fewelements. Of course I forgot to add the more basic description, keyword and other general elements.
  • Selecting text uses the same colors as the hove styles, yellow background with reddish-orange text and no text shadow.
  • My custom JavaScript code is in a single block at the bottom of the page and not in a separate file. Since it is a single-page site, there is no benefit to externally linking it.

This was also my first responsive design. I started out making the large 1024px version first and then going back to make smaller versions. Big mistake. It’s a lot easier to start with mobile first and then build your design up, larger and larger. Media queries are also a pain in the butt since it requires a ton of going back and forth from the top of the stylesheet to the bottom where the media query styles were. When I changed styles for one target size, I had to double-check that those changes didn’t (or did) cascade into the larger sizes. This also resulted in a lot of duplicate selectors. What would be ideal is to set-up different classes on the HTML element with a class for different resolutions. This would be similar to how we handle conditional styles for Internet Explorer. This way we could group similar styles in the same area which makes it easier to keep track of changes.

Sites I Referenced

Other Noteworthy Entries

So what do people do once the contest comes to an end? Share their work on Twitter for others to comment on of course!  Here are some of the other entries I found searching Twitter for #cssoff.

Finally if you want to show off your entry, @daljo628 is hosting them at http://knucklelodeon.com/ Ping him to have yours added.

Phew! I’m glad I’m not in the judge’s shoes now. Having to go through all the entries and ultimately pick a winner; That’s a tough call.

Update: The top 25 entries have been announced!

WordCamp Mid-Atlantic

This past weekend I got to attend WordCamp Mid-Atlantic, my first WordCamp ever. This years conference took place at Johns Hopkins University in Baltimore City. The venue was a little tricky to get to and the parking situation was a bit limited, but once I got there I had a great time. The place was packed with all kinds of different people who shared one common interest — they all love WordPress.

The camp was divided into two tracks; beginner and pro. I spent the whole day in the pro track and my summary of the talks are below.

Scott Kingsley Clark – WordPress as a CMS


Scott Kingsley Clark led off the first session of the pro track with WordPress as a CMS. His talk covered how to add more fields to the edit screen besides the usual title, post, tags, and categories we’re all used to seeing. He walked through using a plugin called Pods CMS, which he is a co-author of. To me, it seems a little over complicated. I like to use custom meta fields to extend the data contained in posts or pages. For a non-technical user who isn’t comfortable writing PHP, Pods CMS seems like an acceptable solution to get them up and running.

Brad Williams – WordPress Security


I’ve listened to Brad many times as a regular on the SitePoint podcast so it was good to actually meet him in person. His talk (slides available) on WordPress security was well attended as securing a WordPress install is applicable to every blogger. The tips Brad dished out would help anyone lock down their blog with such methods as checking your file permissions, deleting the admin user, changing the prefix on your database tables, and (most importantly) staying up to date with plugins and core updates.

At the end of his talk he mentioned a list of plugins to help with WordPress security.

  • WP Security Scan – Scans your WordPress installation for security vulnerabilities and suggests corrective actions.
  • WP-MalWatch – performs a security scan of your WordPress installation nightly looking for evidence of foul play and if WP-MalWatch finds it, a dashboard widget will tell you were you should take a closer look.
  • ServerBuddy – a plugin that tests server configuration to analyze the quality of your hosting & server configuration, and seek out problems with compatibility with various WordPress themes and plugins.
  • Exploit Scanner – searches the files on your website, and the posts and comments tables of your database for anything suspicious.
  • WordPress File Monitor – Monitor files under your WordPress installation for changes. When a change occurs, be notified via email.
  • Login Lockdown – records the IP address and timestamp of every failed login attempt. If more than a certain number of attempts are detected within a short period of time from the same IP range, then the login function is disabled for all requests from that range.

For lunch a group of us went across the street to Tambers, an indian burger place. Their burgers are perfectly normal but the last page of the menu had indian dishes. Weird. I also got a chance to meet Lokesh Dhakar, the author of the original lightbox script. He’s a smart guy.

Andrew Nacin – Undiscovered APIs

Photo by Nick Whitmoyer

After lunch, Andrew Nacin gave a talk (slides available) about functions and APIs that aren’t as well known about among developers. Since they aren’t well documented, the only way to learn about them is reading the source. I really got a kick out of his talk because I had been looking at some of these functions for a project of mine. Some neat functions include

  • wp_remote_request – to download files to your server from the web. WordPress uses this internally to download updates, themes, and plugins from within the admin screen.
  • wp_handle_sideload – lets you add a file to the media library that is already located somewhere else on your server.
  • oEmbed – allows the embedding of media by simply including the URL in a post. WordPress makes it easy to add your own oEmbed providers.
  • add_feed – lets you make your own feed. Andrew demonstrated how to make a JSON feed of your blog posts with just a few lines of code.

It is no wonder Andrew knows all of this stuff, he’s one of the seven core contributors for the WordPress project.

I liked in-depth technical talks like this. I was probably one of the few people who this didn’t go over their head.

Jacob Goldman – Customizing WordPress Admin

Photo by Nick Whitmoyer

Customizing the back-end admin screen of WordPress is a big selling-point for Jacob’s consulting business. He feels the admin screen should be as simplified and tailored to the clients need as possible. And contrary to what others might say, WordPress makes it simple to tweak the admin screens.

Much of what Jacob talked about was removing sections like menu items that aren’t used and the default widgets on the dashboard. He added his own custom widgets to the dashboard to point to a contact form if the clients need more help. Speaking of help, you can also customize the contextual help menu tab that appears on practically every page. Adding your own help text is a great way to avoid people asking you the same questions over and over. At the least, you can tell them to check the help tab on the page you have a question with. WordPress also lets you customize the look and feel by adding your own stylesheet and overriding the default styles.

Jacob’s talk was inspiring for cleaning up the backend. He put a sample theme file that you can copy and paste from into your own theme.

Jane Wells – Closing Keynote

Photo by Nick Whitmoyer

To wrap up WordCamp Mid-Atlantic, we had the opportunity to hear from the head user experience leader for WordPress, Jane Wells. The keynote was delivered over Skype… from within a moving car! The video was a little blocky, but given the circumstances it was easily forgiven. Some of Jane’s keynote was about the upcoming improvements to WordPress. But most of the talk was gossipy Gnu Public License cruft. It wasn’t that interesting to re-hash the same stuff every other blog was blabbering about a month ago.

So that was WordCamp Mid-Atlantic. A huge thanks goes out to Aaron Brazell for organizing the whole thing and all of the sponsors for making the event possible. I look forward to attending other WordCamps in the future and maybe even hosting a talk of my own.

Making JavaScript And The Blip.tv Player Work

It sure would be nice if the blip.tv player had an easy way to change which video is playing in a playlist using their JavaScript API. But they don’t, so I had to roll my own to make the two play together nicely. Here is the end result (Note there are some line breaks I put in here for visual formatting, it might not work):

var player;
var currentPlaylistItem;
var currentState;
function getUpdate(type, arg1, arg2) {
	switch(type) {
        case "state":
			currentState = arg1;
		break;
		case "item":
			currentPlaylistItem = arg1;
			var episode = player.getCurrentItem();
			document.title = episode.title;
        break;
    }
}
var flashvars = {
	'file': 'http://blip.tv/play/ha0CjMVEh_8o',
    'enablejs': 'true',
    'javascriptid': 'blip_player',
    'autostart': 'false'
};
var params = {
	'allowscriptaccess': 'always',
	'allowfullscreen': 'true',
	'expressinstall': '/millennials/flash/expressInstall.swf'
};
var attributes = {
	'id': 'blip_player',
	'name': 'blip_player'
};
swfobject.embedSWF('http://blip.tv/play/ha0CjMVEh_8o',
'blip_player', '770', '470', '8.0', false, flashvars,
params, attributes, swfCallBack);
function swfCallBack() {
	player = document.getElementById('blip_player');
	$('#agenda h3 a, #agenda a.blip_tv').click(function(){
		var playlistItemNum =
                    $(this).attr('href').split('#')[1];
		changePlaylist(Number(playlistItemNum));
		$.scrollTo('.video .player', 800);
		return false;
	});
}
function changePlaylist(num) {
		var direction = 'prev';
		var diff = currentPlaylistItem - num;
		if (diff < 0) {
			direction = 'next';
			diff = Math.abs(diff);
		}
		for(i=0; i < diff; i++) {
			player.sendEvent(direction);
		}
		if (currentState == 0) {
			player.sendEvent('play');
		}
}

There are three requirements to getting started as outlined in the blip.tv wiki:

  1. The player must be embeded with the enablejs=true Flash variable set
  2. The player must be embeded with allowScriptAccess=always object/embed parameter set
  3. A JavaScript function must exist named getUpdate()

The first part of my script sets up three global variables that we’ll use.

  • player will reference the object/embed element by an ID. It is how we send commands to the show player.
  • currentPlaylistItem is the number of the video selected (or position) in the playlist.
  • currentState is either 2 (playing), 1 (loading), or 0 (stopped) depending on the current state of the player.

The getUpdate() function listens to the blip.tv player for changes like when the player is stopped or a video is changed in the playlist. The type argument is a string which we can send through a switch statement to determine what we need to do.

If the state of player has changed then we update our currentState variable with the value of arg1 (which will be a number between 0 and 2). If the event is an item change, we will update the currentPlaylistItem variable to reflect that. As an added bonus we get the title of the current playing video and change the title of the webpage to reflect this. This has zero SEO value and is really only a convenience to our audience.  Now that we know what is going on, lets get to the fun stuff.

Three variables (which are really Objects) are created for swfobject so we can easily embed the video player dynamically into the page. The ‘blip_player’ paramter is the ID of the player that we’ll be referencing shortly. The swfCallBack() function is called once the blip.tv player has loaded. There we set our player variable to reference the element of the blip.tv player. I used a line of jQuery to set the onClick() events of a group of links that will change the playlist when they are clicked.

In the HTML the links contain direct links to each blip.tv video and an anchor with a number after it. This number is the playlist position of the specific video. jQuery makes it a snap to extract just that number from the URL which we store in the playlistItemNum variable. The playlistItemNum variable is passed along to a function called changePlaylist() which does all of the heavy lifting.

Since the blip.tv show player doesn’t have a direct way of going to a specific video in a playlist, we have to hit the next or previous button on the player programmatically. The direction is set to ‘prev’ initially.  diff is calculated by subtracting the number passed to the function from the position of the currently playing video, currentPlaylistItem.

If diff is a negative number than we need to switch the direction variable to ‘next’ and get rid of the negative number by calling the absolute value method ( Math.abs() ). Now we simply send the player a command to go to the next or previous video as many times as we need to get to the desired video via a loop. Finally, if the player is stopped, we send the video player a command to start playing the video.

As an added nicety, we gently scroll the viewer up the page to the top of the video player so they’re not left wondering why nothing happened. The jQuery scrollTo plugin makes this a breeze to do.

There is one caveat for the changePlaylist() function to work: the playlist needs to be visible on the blip.tv show player. This is simply an option you set on the player configuration screen on blip.tv. Without it showing, we can’t get which video is playing and the whole thing falls apart.

That wraps up how to roll your own playlist changing function as well as shed some light on how you might control other things about the blip.tv show player using JavaScript. You can see this in action on the Pew Research Center Millennial Conference video page. If you have any questions leave them in the comments or get in contact.

Does The IMG Tag Need A Fullsize Attribute?

Drew Wilson is proposing the HTML IMG tag get a new attribute called fullsize. The fullsize attribute would reference “a larger (or fullsize) version of the SRC image. Browsers could then include native support to display the fullsize image in a [modal] pop-up.” according to addfullsize.com, Wilson’s site dedicated to the effort. Mr. Wilson has even gone to the trouble of creating a jQuery plug-in that simulates how the behavior would work. He hopes the Internet will make enough buzz about it to get the attention of the W3C in order to get the fullsize attribute included in the official HTML spec. As of this writing, the petition to add a fullsize attribute has 185 “signatures”. I am not one of them.

Drew Wilson is proposing the W3C add a new attribute to the IMG tag called fullsize.

I’m not against the idea of including a reference to a larger version of an image right inside the tag. HTML is all about structuring and describing content, and the fullsize attribute is just another piece of meta-data. My biggest problem is this is already possible today by wrapping a link pointing to the fullsize image around the original image. Is it sexy? No. But it is still flexible. It can be customized and jazzed up with JavaScript and CSS but for devices that don’t support those technologies, a link around an image would still be accessible.

What I’m weary wary about is letting the browser manufacturers determine the default pop-up behavior and then relying on them for easier customization options. Take drop down input elements for example. Getting these to look consistent across all of the different browsers and operating systems in the world today is impossible. Roger Johansson went through the effort and documented them on his blog 456bereastreet.com. Any saved time from browsers handling a pop-up would be wasted trying to work around the different limitations for each browser.

To summarize:

  • I’m all for a fullsize attribute for meta-data purposes
  • Browsers handling the pop-up functionality will do more harm than good

Homer Simpson In Pure HTML/CSS

Román Cortés managed to create a dead-on recreation of Homer Simpson using nothing but HTML/CSS. To boot it is essentially a vector image that will scale if you increase the text size of your browser. Go to the page and press the control and the ‘+’ key at the same time to see what I mean.


Homer Simpson in HTML/CSS

The source code isn’t too pretty but for this spectacle it is certainly understandable. It just makes a good case that open technologies like SVG, which will make it easier to construct vector graphics out of XML code, need to be adopted much faster.

Adobe Air Reaches 1.0, Twitter Clients Blossom

Adobe Air Logo
Adobe released it’s Air product today making it official and peeling off the cliche` beta title. Adobe Air allows developers to build desktop applications using web technologies like HTML for structure, CSS for presentation, and JavaScript for behavior. Flash and Flex, Adobe’s own web technologies, are also rolled up in the mix. Professional authoring tools like Flash CS3 and Dreamweaver CS3 saw updates today to allow development within the popular tools. Aptana also offers a free plugin for their open-source development tool Aptana Studio.

I have been playing with Air apps for the last couple of months while the product was still in beta. There are a lot of clever applications that are more like widgets then conventional full-blown desktop programs. For example, the Adobe sample app PixelPerfect was a simple ruler overlay letting you measure anything on your screen. This little tool comes in handy for web development where there aren’t any rulers on the side or measuring tools like in Photoshop. Powerhouse auction site eBay created their own Air app that banishes the concept of refreshing the page so bidders can watch their auctions in real time. But perhaps the biggest crowd of Air apps belongs to Twitter clients. Thwirl, Spaz, Tweetr, and Snitter are just a handful.

Snitter Next To Tweetr Couresy of Andy Piper

I thought John Ballinger had let his Twitter client, Tweetr, go to pasture without an update since the end of November. With each new Air beta release more functionality would break edging me towards Jonathan Snook’s Snitter. But alas, Tweetr is alive again with version 3.0 launching today to coincide with the official Air release. I’m happy as a clam to have my favorite Twitter client back and to see so many great ideas that have seemingly sprung out of Air.

Hot Or Not For XHTML Code

Valentin Agachi’s XHTML Challenge takes the rating meme under the hood letting users compare websites based on their (X)HTML markup. When a challenge is set up between two sites, a PHP script from XHTMLChallege.com slurps up the source code and begins a detailed analysis. Facets for competition include which doctype was declared, validation, content length in bytes, a ratio of content/markup/ and whitespace, use of conditional comments, and the number of table tags used.

XHTML Challenge Screenshot

As I have written about before, there is more than just HTML that goes into making a sexy source. I think XHTML Challenge could expand their analysis to include the number and positioning of CSS and JavaScript files, use of microformats (which results in more semantic, though bulkier, markup), and total file size of all components. This would paint a better overall picture of all the necessary components that go into a modern design.

Frontend web developers, like myself, take a lot of pride in how we structure our code. HTML coding is all about semantic, well-organized markup that is as small as possible while providing a solid structure for the content. It is good to see that there are others out there like myself that can appreciate the thought and planning that goes in to the under pinnings of a modern website.

XHTML Challenge should not be confused with Command Shift 3 which rates the aesthetics of a site not its code. Maybe the two sites should get together producing the ultimate website rating tool!

via (Web Designer Wall)

Google Releases API For Charts

Google has impressive, interactive charts incorporated into many of their products. The best place to see them in action is Google Finance where stock prices are graphed over time allowing the user to zoom in or out, stretch or expand the selected view, and other fancy interactions. The result is a rich experience for viewing and manipulating data.

Today Google unveiled the public application programming interface to interact with their chart engine. While not as rich as Google Finance charts, this public charting tool is extremely flexible in
creating line charts, scatter plots, bar graphs, Venn diagrams, and even pie charts. Charts are generated by constructing a URL with various parameters, or options, to customize a chart dynamically. Making a URL request returns a PNG image which can be saved to disk or embedded on any web page. Some examples of the charts are shown below.




Documentation for charts can be found at http://code.google.com/apis/chart/ which provides a smattering of examples.

I am very excited by this release as there are a ton of different applications these could be used in. Using some simple JavaScript, you could take these charts a step further and create animated charts using various URLS with one incrementing data parameter. Kind of like this (JavaScript code borrowed from Chip Chapin).

I would like to see a user-friendly interface built on top of the API so those who are less developer inclined can make charts and graphs easily. It wouldn’t be too hard to make a simple JavaScript program to construct the URLs. I will try to crank something out tomorrow at work, because this is simply too cool to pass up.