CSS Selector Browser Support

As many web developers know, CSS support is highly varied amongst browsers. I often find myself hunting for which selectors are more heavily supported. As such, I thought I’d post a direct link to a quality resource here so I wouldn’t have to hunt anywhere besides on BorkWeb.

Here’s some decent resources:

Luminis: Forcing CSS/JavaScript Updates to Clients

[[innerindex]]

Introduction

I gave a talk at SunGard Summit in Anaheim this spring on Plymouth State‘s portal (myPlymouth). There were a number of really great questions that came up following my presentation, one of which is the topic of this post:

“How do you force a client’s browser to always use the correct version of CSS and/or JavaScript in Luminis?”

When upgrading Plymouth State’s Luminis installation from III to IV, we had to tackle this same issue and after banging my head against the wall a number of times, I found our answer. I wanted to:

  1. Ensure that the JavaScript and CSS that is being served up to our users can be cached by their browser in order to optimize their download speeds.
  2. Control when a user’s browser has to re-download a new version of the code.
  3. Do the above within the bounds of the very restrictive caching provided by the Luminis product.

All of it was super easy to do, although I must admit I knocked my head against the wall a few times coming up with the solution to the 3rd in that list.

Step 1: Basic Browser Caching

When I sat down to tackle this problem, I knew that the inline JavaScript within nested_tables.xsl was an unforgiving issue – if I wanted to make a change to some of the inline JavaScript, those changes would not be forced upon the users until Luminis decided to let go of its cached nested_tables.xsl.

That didn’t work for me. So I ripped the inline styles out and combined a few JavaScript files into one…called combined.js.

My header within the regularLayout template in nested_tables.xslnow looked something like this:

<head .......>
   <title>.........</title>
   <script type="text/javascript" src="/js/clientsniffer.js"></script>
   <script type="text/javascript" src="/js/util.js"></script>
   <script type="text/javascript" src="/psu/js/combined.js"></script>
   <script type="text/javascript" src="/psu/js/behavior.js"></script>
   <link rel="stylesheet" type="text/css" href="/psu/style.css"/>
</head>

The files clientsniffer.js and util.js are SunGard delivered and I did not touch those two. As I mentioned before, I yanked out all the inline JavaScript (provided by SunGard) and dropped that into combined.js along with a number of jQuery code. Our own custom Luminis JavaScript that controls a lot of our Ajax-like functionality in myPlymouth is in behavior.js. And of course, style.css holds the CSS for our portal.

All of these files could now be cached by users’ browsers. Yay. I bounced the development portal and saw my changes in all their glory. Life was good.

Step 2: Browser Cache, Code Changes, and You

Invigorated by my recent success of effectively doing nothing, I grabbed a soda and began tackling the next objective. I had done this numerous times in my PHP applications and it was as simple as placing a version number at the end of the URLs used in the link and script tags. As such:

<head .......>
   <title>.........</title>
   <script type="text/javascript" src="/js/clientsniffer.js"></script>
   <script type="text/javascript" src="/js/util.js"></script>
   <script type="text/javascript" src="/psu/js/combined.js?v=1.0.0"></script>
   <script type="text/javascript" src="/psu/js/behavior.js?v=1.0.5"></script>
   <link rel="stylesheet" type="text/css" href="/psu/style.css?v=1.0.5"/>
</head>

Once again, I bounced our portal, saw the changes, and danced around the room. Step 2. Accomplished.

Step 3: Taming Versioning/Cache Expiration in Luminis

The goal of taming this versioning/cache expiration was to do so without the need for bouncing the portal so I could make changes on the fly without planning for down times. Step 2 – as I detailed above – only gets you so far. With Step 2 in place, I could easily make a change in my CSS file and edit nested_tables.xsl to one-up my version number. But, because nested_tables is cached by Luminis, that wasn’t good enough. Here’s what I came up with:

I removed the script and link tags in the header of the regularLayout template in nested_tables, created a file called load.js, and dropped the homeless script/link tags as document.writes in load.js…as so:

Start of a Solution: load.js

document.write('<script type="text/javascript" src="/js/clientsniffer.js"></script>');
document.write('<script type="text/javascript" src="/js/util.js"></script>');
document.write('<script type="text/javascript" src="/psu/js/combined.js?v=1.0.0"></script>');
document.write('<script type="text/javascript" src="/psu/js/behavior.js?v=1.0.5"></script>');
document.write('<link rel="stylesheet" type="text/css" href="/psu/style.css?v=1.0.5"/>');

But wait…

This gave me a file with all of my script/link tags and their appropriate versions. However…I couldn’t simply replace all those script/link tags with a script tag that pointed at load.js because load.js itself would be cached by users’ browsers. So this got past the Luminis caching, but not our end users. So I came up with this:

Final Solution: pre_load.js

So…I wanted to cache all my sub-files and prevent load.js from caching so that I could version my scripts easily without bouncing the portal. The solution? Yet another file! I called it pre_load.js and it looks something like this:

document.write('<script type="text/javascript" src="/psu/js/load.js?nocache=' + (new Date()).getTime() + '"></script>');

A simple document.write of a script tag with an appended variable based on time in order to prevent caching on the browser side. Yup…load.js is never cached, but it is a small price to pay.

Now my header in the regularLayout template in nested_tables.xsl looks like this:

<head .......>
   <title>.........</title>
   <script type="text/javascript" src="/psu/js/pre_load.js"></script>
</head>

How it works

  1. Luminis happily caches the pre_load.js script tag in the nested_tables.xsl.
  2. The JavaScript within pre_load.js writes another script tag to the document at render time. That script’s URL is a call to load.js along with a variable that changes each page load thus preventing load.js from being cached.
  3. load.js then document.writes the appropriately versioned script/link tags into the document.
  4. The individual script/link tags load the associated JavaScript/CSS files. If the browser has already cached that script/link URL (remember, we change the version numbers when we make changes to the JS or CSS), then the cached file is loaded…otherwise the new version is retrieved from the server.

Summary

The set-up is fairly basic but the results just what we were hoping! And all it took was:

  1. Placing inline JavaScript into a file (combined.js)
  2. Creating load.js to document.write script/link tags
  3. Creating pre_load.js to document.write a script tag that uses a cache-free URL call to load.js

To date, we have not had any reported issues with local or server-side caching of our JS/CSS files using this method! You just need to make sure you remember to version your URLs in load.js!

Faster Page Loads With Image Concatenation

[[innerindex]]

Introduction

When designing web applications, icons and images are used to enhance the user experience, give visual cues, and simply look sexy. For complex web apps, the quantity and resulting latency of icons and images used can greatly impact page load times…and developers, in most cases, generally try to reduce page load time with a sweet web app rather than increase it.

To reduce latency in my apps, I use Image Concatenation! Coupled with a bit of CSS magic, performance improves and life is great.

Image Concatenation…WTF?

The basic idea is this: Change X number of image downloads to 1 image download by making 1 big image that contains the X images.

As an example, lets say we have these icons:

help settings maximize shade grow close

While those are pretty tiny in size, on page load the user must still deal with downloading 6 individual images. Instead, we can simply concatenate those images using whatever image software that suits your fancy. Like so:

icons

Displaying Concatenated Images

Now that we have our sweet concatenated image we can’t simply drop that image into an image tag and call it good…that’ll display all icons at once. So…how do we display it?

To display the concatenated image, you need to place that image as a background on an appropriately sized DOM element using CSS to adjust the background positioning to make the appropriate image display. Now, when I say a DOM element…it could really be anything as you can plop a background image on any element with CSS pretty easily:

.whatever{
  background: url('/path/to/image.png');
}

Even though you can use any element, only a few make sense. I’ve seen spans and divs used to accomplish this task, but styling those elements to work cross-browser is flaky at best and really churns my stomach. The element that his handled pretty universally is the img tag.

Yes…yes…I know, I just said don’t place the concatenated image in an img tag. I still hold to that statement. You place the concatenated image as a background on the img tag. So what goes in the src of the img tag? Our old friend the 1 pixel by 1 pixel transparent gif, of course! This way, the image will still act as an image, can be styled like an image, and be super easy to update via CSS.

An Example

Lets say we have the following concatenated image: sidebar_icons that we want displayed in the sidebar with the appropriate links.

Lets set up the HTML first using transparent.gif (a transparent 1×1 pixel image) as the src of the image tags:

...
<ul id="sidebar">
  <li><a href="index.html" title="Home"><img src="images/transparent.gif" class="icon icon-home" alt="Home"/>Home</a></li>
  <li><a href="search.html" title="Search"><img src="images/transparent.gif" class="icon icon-search" alt="Search"/>Search</a></li>
  <li><a href="bookmarks.html" title="Bookmarks"><img src="images/transparent.gif" class="icon icon-bookmarks" alt="Bookmarks"/>Bookmarks</a></li>
</ul>
...

Note the class names on the images…those will be used in the CSS as such:

#sidebar img.icon{
  background: url('/path/to/concatenated/image.gif') no-repeat;
  height: 16px;
  margin-right: 3px;
  vertical-align: middle;
  width: 16px;
}

#sidebar img.icon-home{
  background-position: 0px 0px;
}


#sidebar img.icon-search{
  background-position: -16px 0px;
}


#sidebar img.icon-bookmarks{
  background-position: -32px 0px;
}

That’s really all there is to it. The icon class allows us to set the same image background and dimensions for all icons in the sidebar. The individual classes allow us to change the image that actually shows through.

More CSS Magic

Since CSS is being used to display the appropriate image, you can do your typical property manipulation as normal (e.g. :hover, set transparencies, etc).

A little trick I picked up at Zimbra‘s presentation (the same presentation I learned the benefit of image concatenation) at The Ajax Experience last October was how to reduce the number of images used by representing inactive icons with CSS transparency rather than using individual images for inactive icons. Like so:

#sidebar img.inactive{
  filter:alpha(opacity=50);
  -moz-opacity: 0.5;
  opacity: 0.5;
}

If you wanted to make the icons partially transparent all the time but on mouse over make them 0% transparent, you can do so like so:

#sidebar img.icon{
  filter:alpha(opacity=50);
  -moz-opacity: 0.5;
  opacity: 0.5;
}

#sidebar img.icon:hover{
  filter:alpha(opacity=100);
  -moz-opacity:1.0;
  opacity:1.0;
}

Basically, whatever CSS magic you can weave can be done.

Additional Benefits

If you are a developer working in a painful development environment, the above methods are extremely valuable. Oh…and by painful I mean: any change to the base document structure requires a restart of the application. I’ve been doing a lot of development in an XSLT/Java environment recently and this method has saved me countless restarts :)

Now, if I decide an icon should change from a “house” to a “moon” (for some strange reason) I can make that change easily in CSS without needing to change the XSLT…thus no restart needed. Beautiful.

Heck…I use this CSS method for a number of non-concatenated images as well just so I can make general image changes with ease.

What Not To Do

When using the above image concatenation methods, it is important to note that concatenating similar images is a good plan. Avoid concatenating images of vastly different sizes because the wasted space on the concatenated image increases the amount of data being downloaded which can counter-act what we are attempting to reduce by concatenation.

Drawbacks

Update: This section was added a couple of hours after posting as per someone’s suggestion.
Using this method can affect the printability of your page as background images assigned with CSS don’t show in print too well :)

Conclusion

Image concatenation can be a beautiful thing when dealing with large numbers of icons/images. But, as with anything, weigh its benefit. Thus far, I’m pretty happy with the results!

The Ajax Experience: Plan of Attack

The Ajax Experience is next Monday (although I arrive Sunday afternoon) through Wednesday and I’ve prepared my plan of attack:

Monday

10:00am-11:30am: Leveraging Ajax for Enterprise Application Development – Conrad Damon
12:30pm-1:15pm: Keynote: Towards a Service-Oriented Applications Stack – Matt Quinn
1:30pm-3:00pm: Simplify Ajax development with Apache XAP – Bob Buffone
3:30pm-5:00pm: Ruining the User Experience – Aaron Gustafson
5:15pm-6:45pm: Scriptaculous – Justin Gehtland
8:00pm-9:30pm: Expert Panel Discussion

Tuesday

8:30am-10:00am: Intro to Dojo – Alex Russell
10:30am-12:00pm: Yahoo! Experiences with Accessibility, DHTML, and Ajax in Rich (Dunno what Rich is…probably the start of “Rich Internet Applications” [RIA], probably) – Nate Koechley
1:00pm-1:45pm: Keynote: Ajax from AOL’s Perspective – William Morris
2:00pm-3:30pm: RAD 2.0: Working with symfony (PHP) – Dustin Whittle
4:00pm-5:30pm: Markup & CSS for Developers: Empowering the Application Developer with Front End Magic – Molly Holzschlag
7:00pm-7:45pm: Keynote: The Once & Future Web – Chris Wilson
9:00pm-10:30pm: Expert Panel Discussion

Wednesday

9:30am-10:30am: Designing for Ajax – Bill Scott
11:00am-12:30pm: Dojo Cookbook – Dustin Machi

My schedule is subject to change based on buzz or sudden interest in other presentations. I look forward to seeing what they have to offer and will be blogging along the way!

Learning What I Know

I recently received an e-mail from one of my subscribers that asked a question. The answer may be useful to some so I’m placing it here.

The original question

It seems so interesting developing websites application these days, thanks to the web 2.0 phenomena. I can’t call myself a web developer or anything near that, but I’m interested to learn these kind of [things].

[...]

Since you seem to be real world developer to me, I have a couple of questions to ask you. I’ve been messing around with XHTML, CSS, Javascript, PHP and MySQL [for] a couple of months now, and it frustrates me sometimes when I sort of forget things and [can]‘t understand the flow of the design of what I’m trying to achieve. [..]

Based on your experience, do you do everything by your own, i mean there are the front end and the back end [things], do you do both?

Talking of object oriented programming (i guess that’s what prototype, script.aculo.us and ajax are really about), which OOP did u learn first? I [learned] simple Java before but does that come into play for web development as well? I mean, does it help if i go into detail learning Java?

Any other useful advice? I would appreciate your comments. Thank you.

My Reply

Web 2.0 phenomenon…Yeah, its good to stay on top of things like that :)

Development. XHTML, CSS, Javascript, PHP and MySQL…I do it all, however, I did not learn them all at once…but over a series of years. I think the key concept is to really try and keep your logic from your design – keep the MySQL/PHP side of things separate from the XHTML/CSS side of things ( e.g. Ajax, Templating, and the Separation of Layout and Logic). Javascript is a bit of a wildcard and bridges between both the presentation and logic.

You can do the above with and without Object Oriented Programming…although OOP is the preferred method. My first OOP language was Java. Next I branched out to Object Oriented PHP, and finally (last year) I learned Object Oriented Javascript.

All you really need is the OO concept in your head before you branch out and if you’ve used Java, you should be good to go. So to answer your question: “Does it help if you go into detail learning Java.” is this: It won’t hurt, but isn’t necessary to succeed in learning the above languages/tools. When using Object Orientation and switching languages, its all about learning the syntax and the gotchas associated with your chosen language.

The biggest chunks of advice I can give regarding your tools of choice are as follows:

XHTML/CSS

  • keep it simple
  • use ids/classes rather than inline styles

PHP

  • live on php.net
  • learn through irritation with your own code…mine goes through constant revisions and optimizations
    - pick up a templating engine to help keep your layout and logic separate. I use XTemplates. I’m thinking about looking into SmartyTemplates….use whatever you wish…but templates save TONS of time.

MySQL

  • know your data
  • know how to normalize your data
  • download open source applications and look at their database structure for a good idea of what their doing and go from there

Javascript

Site Redesign

It was high time I re-design BorkWeb. I’ve been screwing around with this design for a few weeks now and I’ve finally got it working for go-live today :D I began construction on the site using LifeAfterCoffee’s Caffeine Theme. Jon did a great job in structuring the templates and a fairly solid CSS stylesheet.

However, I took it and butchered it beyond recognition. I did a lot of restructuring of the templates, location of elements, and I ripped apart the CSS stylesheet and pasted its parts back together with a some additions. I’ll adjust this theme some more, add a header graphic, zip it up and make it available for download soon.

UPDATE: I already think this needs more work….hrm. I’ll have to brainstorm on what to do to it.

Slashdot Redesign

slashdotLast month Slashdot held a very open-ended competition for a redesign of the long overdue layout. I had initially thought I’d enter but laziness took the best of me and I never completed my design. The winner was Alex Bendicken who created a pretty clean and snazzy design. CmdrTaco estimates that the new design will go live in a couple of days…say goodbye to the eyesore that was the circa 1990′s layout.

The winner of the contest will be receiving a sweet laptop (valued at up to $4000) plus the bragging rights of redesigning one of the world’s most popular tech/geek blogs. Good times. Over the course of the contest I had been hoping Peter Lada’s design would win out, but Alex’s is just as snazzy (with fewer frills) so I’m happy.

CSS Declaration Grabber Regular Expression

2b-or-not-2bI use the same tools for development as Zach over at NoSheep. EditPlus is a sexy editor with all its FTP goodness, and packaged along with it are a number of syntax definitions for various languages as well as regular expressions for grabbing function declarations for those languages. Whats so cool about EditPlus and those regular expressions is: when you hit CTRL+F11 a handy window pops up with all the function definitions so you can click and jump to them quickly.

Sadly, EditPlus does not provide the the declaration regular expression for CSS by default…Most likely because CSS does not have any functions. Well, I live in CSS files while developing web UIs and as most people know, the CSS declarations can be hell to find. So, if you find yourself in the same place and don’t want to bother with an easy regular expression…here’s mine:

^[\t]*[a-zA-Z0-9\.# -_:@]+[\t]*\{.*[\t]*$

Oooo event:Selectors for Prototype

event_selectorsMy article on the Separation of Layout and Logic touched on a key point of heavy Javascript use in an Ajax rich environment…the need for separation of Javascript code – namely events – from the HTML. Behaviour was my suggested CSS/Javascript event selector framework.

Behaviour is a stand-alone event framework. You can use it regardless of whether or not you are using Prototype (or some other Ajax/Javascript library) – which is pretty cool. But…if you are using Prototype there is a lot of code duplication between the two libraries. Luckily, Mir.aculo.us has brought event:Selectors to my attention which is causing me to sing a different tune! Justin Palmer, event:Selector’s creator is crediting Behaviour for the idea, but he’s has what Behaviour has done a few steps further.

  • event:Selectors is dependant on Prototype which reduces code duplication.
  • It has reduced the layer of complexity of event selecting by one layer of abstraction.
  • The framework allows concatenation of CSS elements for event assignment.
  • Lastly, its added a loaded event that is triggered when an element loads.

Here’s an example of Behaviour event handlining:

  var rules = {
    '#item li': function(element) {
      Event.observe(element, 'click', function(event) {
        var element = Event.element(element);
        element.setStyle('color': '#c00');
      });
    },
    
    '#otheritem li': function(element) {
      Event.observe(element, 'click', function(event) {
        var element = Event.element(element);
        element.setStyle('color': '#c00');
      });
    }
  };
  Behaviour.register(rules);

Here’s the equivalent in event:Selectors:

  var Rules = {
    '#item li:click, #otheritem li:click': function(element) {
      element.setStyle('color': '#c00');
    }
  };

EventSelectors.start(Rules);

Simplification makes me happy. I’m a convert.

Ajax; Templating; and the Separation of Layout and Logic

[[innerindex]]

The Background

I have often mentioned my process of expanding my proficiency of Ajax. Through my journey I have made a number of wrong turns and hit my share of stumbling blocks. All of that has been a learning experience and I’m learning still. I began fiddling with XMLHttpRequest as many do – blissfully ignorant of the many frameworks that exist to make Ajax super easy. My code was bloated with some neat…’features’ (pronounced: bugs).

Then I discovered the Simple Ajax Toolkit (SAJAX), which was simpler than doing raw XMLHttpRequest but really not all that simple. My latest step into the world of Ajax, and the toolkit that holds my love (currently) is Prototype…and I like my Prototype served with a side of Script.aculo.us. *drool* UPDATE: I now use jQuery for all my Ajax and DOM manipulation goodness.

While Ajax is the cause for the article, the heavy focus is on templating. For the past few years I have been using XTemplate as my templating library (I’m a PHP buff) and have been happily separating my logic from my layout…unitl I ran smack dab into the power of Javascript. My PHP still kept its separation from HTML as is the purpose of XTemplate, but it was my HTML that became littered with little nuggets of Javascript all over the place. No matter the method to my Ajax madness, this was my problem.

What Exactly Is Templating And Why Do It?

Templating is definately not new and its use has been debated back and forth for quite some time. But like I stated above, the goal of templating is to keep logic separate from layout which is a good thing for a couple of reasons:

  1. Less clutter. Face it, HTML and whatever server-side scripting language you choose to use are two different beasts. Mixing them together is visually unappealing making code hard to read…and hard to read code is hard to debug.
  2. Coders can develop code. Designers can develop layout. With templating, you are able to achieve this separation and avoid the need for a developer to butcher a designer’s layout to make it function with an application. Each can design/code on their own then combine their efforts with ease.
  3. With separation such as this, applications are more easily skinned and/or receptive to complete UI overhauls.
  4. Did I mention less clutter?

Let me give you an example of what I mean with a simple Goodbye Cruel World application:

Here’s the PHP script: goodbye.php

< ?php
include('xtemplates.php');

$tpl=new XTemplate('goodbye.tpl');
$tpl->assign('CHEEZEWHIZ','Bork, bork, bork!');

$tpl->parse('main');
$tpl->out('main');
?>

Here’s the Template: goodbye.tpl

<!-- BEGIN: main -->
  <div style="font-size:18px;font-weight:bold;">Goodbye Cruel World! {CHEEZEWHIZ}</div>
<!-- END: main -->

Here’s the output:

Goodbye Cruel World! Bork, bork, bork!

Obviously that is an extremely simplistic example. With XTemplates I can get pretty complex and include files, loop over and parse out some complex block structures, assign arrays into template variables, etc. If you want to see a more complex example of a template, check it out here.

Templating Seems Sexy, How Does It Work In An Ajax-ified Environment?

I thought you’d never ask. For this, I have created a diagram to detail how I combine Ajax, PHP, and Templating all in one.


ajax_with_templating.gif

It all works like this:

  1. A User makes a request to view a page
  2. The server-side script calls a series of application functions that generate blocks of templates
    1. Each section that can be updated/rendered by Ajax calls are separated into their own templates, which enables them to be called on initial page load and separate Ajax-triggered calls from the client.
  3. The complete template blocks are sent to the user as a rendered page.
  4. As the user interacts with the interface, two specific things can occur:
    1. An Ajax.Updater (see Script.aculo.us) is triggered, which makes an Ajax callout. The callout is sent to the Ajax Handler (which is a PHP script) which handles the call and invokes the appropriate application functions. Those functions initialize template blocks and output HTML. The HTML output by the server is received by the client and inserted into the User Interface.
    2. An Ajax.Request (see Script.aculo.us) is triggered, which makes an Ajax callout. The callout is sent to the Ajax Handler (which is a PHP script) which handles the call and invokes the appropriate application functions. No templates are initialized or output to the client…instead, the client manipulates the DOM on its own to give proper feedback to the user.
  5. Rinse and repeat as needed.

If we keep all HTML within templates and use modularized functions to initialize and render those templates, we achieve extreme layout/code reuse.

Sounds Cool…So What’s The Problem?

Well, a server-side scripting language coupled with a templating engine is all well and good. But if as we throw Ajax into the mix, suddenly we are working with a lot of Javascript in addition to the a server-side language and HTML. Through my journey in Ajax development my templates – which were havens away from code – were overrun with Javascript code! Eegad.

Now, don’t worry. I place my Javascript in separate Javascript files and include them where appropriate with ye olde <script> tag, which I have done from the beginning. No, the issue has been handling user events; onClick, onMouseOver, onMouseOut, etc. Ajax functions primarily based on user interaction, so onClicks and whatnot are core. My templates soon began to look like this:

<!-- BEGIN: stuff -->
<div>
  <div>[<a href="javascript:void(0);" onClick="Element.show('add_item');">Add</a>]</div>
  <div id="add_item" style="display:none;">
    <form id="add_item_form" onSubmit="Ajax.Request('ajax.php?'+Form.serialize('add_item_form'),{method: 'post'});return false;">
      Name: <input type="text" name="name"/> <input type="submit" value="save"/> <input type="reset" value="cancel" onClick="Element.hide('add_item');"/>
    </form>
  </div>
</div>
<!-- END: stuff -->

As you can see, the once separate layout was laden with code.

The Solution

In a fully layout separate from logic in an Ajax environment, you need to make use of Javascript event handlers. My personal choice is Behaviour which my friend, Zach, posted about yesterday.

Behaviour (coupled with Prototype) gives you easy-to-follow separation of javascript and HTML. Hugely cool. Hugely useful. Here’s an example:

The HTML:

<ul id="example">
  <li>
    <a href="/someurl">Click me to delete me</a>
  </li>
</ul>

The Javascript:

var myrules = {
  '#example li' : function(el){
    el.onclick = function(){
      Element.removeChild(this);
    }
  }
};

Behaviour.register(myrules);

That example creates a bulleted list (as is readily obvious in the HTML code). What nifty is the Behaviour Javascript logic. myrules says that any <li> tag with a parent id of #example will have an onclick that causes the li tag to be removed.

And of course, besides Behaviour there is a slew of other solutions that when combined together make for a sweet, modularized, separated solution. Here’s what I use for my PHP/Ajax applications:

Here are some standards I stick to:

  • Keep CSS (.css) styles separate from the Template files
  • Keep JavaScript (.js) files separate from Template files
  • Keep HTML in the Template, don’t spatter it around the PHP scripts
  • Modularize as much as possible
  • Heavy Code reuse

The Drawbacks

Obviously in a Templated/Event Handled environment there are some drawbacks and I’d be stupid not to mention them. Here goes:

  • There is some overhead when using a templating engine. With XTemplate, the layout engine is a PHP class that loads the template and parses through it as dictated by the application functions
  • True separation – separating out your Javascript into .js files, your CSS into .css files, your server-side scripts into various files (the initial script, a functions script, and your ajax handler(s)), and your layout into template files – generates a lot of files to deal with. The larger your application, the more you will need to micro-manage the organization of these files, which in and of itself can be a daunting task.
  • Ummm…I can’t think of any more just yet. I’m sure more will come when I’ve lived in this environment a lot longer.

Summary

Layout and Logic separation is a beautiful thing; keeping one language from another has some true value in readability. To do it half-way gains you nothing. True separation has been a blessing in my development and debugging. If you haven’t at least tried it, check it out, it may be what you were looking for (even if you didn’t know it).

Oh and a definate Kudos to Zach Tirrell for starting me down the road of templating and Gmail/Google Maps/Casey Bisson for driving me to check out Ajax.

20 CSS Tips and Tricks

Pete Freitag as generated a list of 20 CSS Tips and Tricks. Definately some useful stuff in there!

  1. Rounded Corners
  2. Rounded Corners without images
  3. Creating a Netflix style star ratings
  4. Tableless forms
  5. Styling Lists with CSS
  6. 2 Column Layout Technique
  7. 3 Column Layout with CSS
  8. 3 Column Fixed width centered layout
  9. Printing with CSS
  10. Adding a CSS stylesheet to an RSS feed
  11. Footer Stick
  12. CSS Element Hover Effect
  13. Styling Horizontal Rules
  14. Clearing Floats
  15. CSS Popups
  16. Box Punch
  17. CSS Badge
  18. Orange RSS Buttons with pure CSS
  19. 10 CSS Tricks you may not know
  20. 10 More CSS Tricks you may not know

One of the comments on Pete’s site says the following:

Technique #12 does NOT work for most browsers, since uses CSS features not implemented in most popular browsers.

Slashdot Getting a Face Lift

Finally! I have been frequenting Slashdot for quite a few years now and the current layout…well…sucks. I have often remarked to my friends that the geek news site really needed a new look. You see, I wouldn’t consider myself a super graphic designer or artsy person but I know what I like. I’m somewhat critical with sites and their layouts, especially with ones that are extremely high profile like Slashdot. There is a LOT of great news articles that come from them but I can never fully get past the icky layout. Well, I have been praying to the binary gods of THE internet and they have seen fit to answer. Slashdot – after 8 years – will be moving to a CSS layout with a more up-to-date look’n’feel. Read the article!