Tuesday, October 30, 2007

Behold: The Cross-Browser Silk Icon Pack!

I figured people wouldn't be satisfied unless it worked in IE, so here you go.

USAGE: <div class="icon"><span class="icon-css"></span></div>


The Good

  1. No JavaScript

  2. Everything is wrapped in appropriate IE conditional comments.

  3. Icons are by default inline, but since they're DIVs they could just as easily be block. In standards-friendly browsers, the icons line right up with normal-sized text so perfectly it's uncanny. IE needs a little padding on the right, but otherwise it's fine.


The Bad

  1. As we all know, Internet Explorer doesn't natively support PNGs, but you can get them to work using DirectX filters. If you can't suffer the stink and indignity of DirectX, I might suggest not using Internet Explorer.

  2. Loading all those DirectX instances (one per icon) can quickly eat into your available RAM. Particularly since each filter is holding a ~260k PNG file—even if you're only seeing 16x16 pixels of it. To clarify: this method is not nearly as cool as the "standards" implementation, but I already went through the trouble of doing the entire Silk icon group and I didn't want to leave the IE folks completely out in the cold.


The Ugly

The DirectX filter that allows IE users to use PNGs with alpha channels doesn't support background positioning. What that means for you is a big, ugly DIV wrapper around the SPAN. Such is the price for peaceful cross-browser coexistence.

If you know you won't have any IE users, I've included the original (faster, better, standards-friendly) version inside the /standards folder.


Final Warnings…

Update: I've included an additional test file (test2.html) that you can check out. This only has a handful of icons and won't bring your operating system to its knees.


The normal test file (test.html) contain 1,000 icons. That's one thousand individual icons. For IE users, that's like dropping an atomic bomb on your CPU. I can get it to run locally with 4GB of memory. I'm not saying you need four gigs of RAM to view the entire 1,000 icon test-suite in Internet Explorer… let's just say you probably shouldn't be burning DVDs when you click the link.

Remember, under normal circumstances, you should only have a few icons on a page at a time. I'm guessing the bulk of the performance overhead is in the DirectX filter itself, which would mean that this isn't much worse than any other PNG-fixed IE. There's just no getting around having to load the filter if you want transparencies. You have been warned.


SilkCSS-1.3.0.zip File Listing:


/

test.html
Silk Icon Pack v1.3 test file [Cross-Browser]
test2.html
Less system-abusive test file [Cross-Browser]

/ie/

icons.png
Icon Tile
icons.png.css
IE 5.5/6 CSS file

/standards/

icons.png.css
data:URI CSS file (non-IE) - Stacked classname
icons.png-alt.css
data:URI CSS file (non-IE) - Single classname
test-standards.html
Silk Icon Pack v1.3 test file - [Standards version, Stacked classname]
test-standards-alt.html
Silk Icon Pack v1.3 test file - [Standards version, Single classname]

silkcss-1.3.0.zip >>

Sunday, October 28, 2007

Bad-Ass CSS 2: The Goods

Ok, no speeches. Mark James's Silk Icon Package speaks for itself as the defacto-standard for good, free web iconography. All the icons should be working--there's a test file so you can see what's what.


silkcss-1.3.0.zip listing:

[Updated]

Original size (1000 PNG files): 662,196 bytes
New size (1 CSS file, GZIP compression): 587,676 bytes

Go GZIP!


Why the different packages?

One allows you to declare your icon with a single CSS classname (the alt package), the other requires two (the standard package). Why would you pick the one that needs two if you could have the one that only needs one? Because the standard package is slightly smaller, and because it uses less client memory—so it's slightly faster. Theoretically, the alt package could be useful for browsers that don't support stacked classes, but in this day and age, the only browser you're going to encounter that doesn't support multiple class definitions is Internet Explorer. Since IE doesn't support the data:URI technique anyway, it's all a bit moot, but I included both versions anyway because I can empathize with the lazy.


500k? That's ludicrous for a style sheet!

You probably don't want to include every single icon, genius.


PNGs? BUT I WANT GIFS!

No. No point. Every modern browser supports PNGs just fine except IE, so it won't be a problem because this doesn't work in IE. Just in case that wasn't clear.

Don't worry. In the next post I'll have an IE-friendly option.


Download >>

Saturday, October 27, 2007

Bad-Ass CSS

You know what's bad-ass? Icons are not bad-ass. GIF files sure aren't bad-ass. Having to create a stupid images/icons directory every time I start a new project, then re-populate the Subversion repository with a million duplicate copies of the stupid "email" icon ain't fucking bad-ass at all.


I know what you're thinking. "But Matt, you could create a separate module for icons," and I'm guessing write some fancy build script that only pulls the files I actually use…


No, no, no. That's way too much work. And work is the antithesis of bad-ass.


This is bad ass:


"WOW. ICONS."

…you reply sardonically. But those images aren't hosted anywhere. I'm not linking to someone's GIF files.

Those images are MADE FROM PURE CSS!


/* Right Arrow icon */
.icon-rarr {
  padding: 8px;
  width: 16px;
  height: 16px;
  background: url("data:image/gif;base64,R0lGODlhCwALANUAAOtxAOqQAOx6AOqZAOxvAOmVAOx5AOmXAOqLAOuBAOt6AOt9AOmcAOtyAOxyAOtwAOt0AOuIAOqaAOt4AOqYAOmYAOqUAOx0AOmbAOFjAOxwAOt1AOqVAOqNAOmSAOqHAOqFAOp%2BAP%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAALAAsAAAZQQFGlMsAYMRKGyMJpHijQ4SBAFS0tTE4B4fFkrN1wpEP%2BisjkxGf9MbMXoDjIKgcZQngrfn%2FZbKwTgQICCg0aGhkQF4t%2BfwQEDxoAkxoOIkEAOw%3D%3D") center left no-repeat;
/* Alternate: URL encoding
  background: url("data:image/gif,GIF89a%0B%00%0B%00%D5%00%00%EBq%00%EA%90%00%ECz%00%EA%99%00%ECo%00%E9%95%00%ECy%00%E9%97%00%EA%8B%00%EB%81%00%EBz%00%EB%7D%00%E9%9C%00%EBr%00%ECr%00%EBp%00%EBt%00%EB%88%00%EA%9A%00%EBx%00%EA%98%00%E9%98%00%EA%94%00%ECt%00%E9%9B%00%E1c%00%ECp%00%EBu%00%EA%95%00%EA%8D%00%E9%92%00%EA%87%00%EA%85%00%EA~%00%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%00%00%00%00%00%2C%00%00%00%00%0B%00%0B%00%00%06P%40Q%A52%C0%181%12%86%C8%C2i%1E(%D0%E1%20%40%15--LN%01%E1%F1d%AC%DDp%A4C%FE%8A%C8%E4%C4g%FD1%B3%17%A08%C8*%07%19Bx%2B~%7F%D9l%AC%13%81%02%02%0A%0D%1A%1A%19%10%17%8B~%7F%04%04%0F%1A%00%93%1A%0E%22A%00%3B") left center no-repeat;
*/

}

USAGE: <span class="icon-rarr"></span>
RESULT:


OMGWTF?

That is the bad-assery known as the data:uri scheme.


Remember USENET? Remember all those naughty alt.binaries.whatever things you downloaded? Same concept: textual representation of binary data. The data is composed of two elements: the MIME type (image/gif or application/pdf for example), and the encoded binary data (base64 and URL encoding are both commonly understood by browsers). I have read of an upper limit imposed by some browsers of ~4k of data per object, which is a good common-sense limit—otherwise your CSS will start to get ugly. These file sizes are perfect for small images like icons. PDFs would probably be a poor choice. You can create your own online at the data:URI Kitchen.


I can't see anything!

Yeah, that's the big drawback. Shut yer yap and get a modern browser, for chrissake.


Benefits

  1. Speed. Every image the client doesn't need to download means the two pipes that the HTTP spec gives you for server-client connections can be better spent downloading more important shit. If you're GZIPing your text files like you should be, the overall size of the encoded CSS should be about the same as the original binary (update: smaller, actually!). As a style issue, remember that base64 encoding takes up about half as much space in the CSS.

  2. Speed, part 2. Try this out: create a thousand DOM nodes of images, pointing them to the same GIF file. Now, change half of them to randomly point to a new image. Watch grass grow.

    An easier way to do this would be to create a class in your CSS file that points to a different image. Then, when you wanted to change half the images, you'd just change their class name and they'd automatically be pointing to the same instance of the image. A lot easier, and a lot faster. With this method, the browser doesn't have to go to the cache to fetch the image, so client-side performance also benefits.

  3. Basically, this allows you to almost completely remove the file and network i/o from the equation, then increase memory efficiency by an order of magnitude or so.

  4. It's just cooler. If you cannot see that, you shouldn't be reading this blog.

Just one thing…

Every browser on the planet—Firefox, Opera, Safari, even fucking Konquerer—supports data:uri, save one.

I leave it as an exercise to the reader to figure out which one, but here's a hint: You'll recognize the authors of the browser in question because the demons they're shackled to in hell will have grins on their faces. They're the ones whose mothers will burn in the pits of flaming tar for all eternity just for having committed the crime of conceiving them.


Why bother?

  1. The aforementioned bad-assness.

  2. Some people have more control over their client's browser choice (Intranet applications) and might be able to take advantage of it.

  3. In the middle of writing this I had the crazy idea of putting all of Mark James's "Silk" icon set into a single CSS "package" and needed an excuse to see the idea through.

Stay tuned.

Blogger Hacks for Fun and Profit

I hadn't really given Blogger much credit until I noticed it's all Google code inside, which means two things right off the bat:


  1. It will probably work on everything.
  2. It will probably be easy to get into the code and play around.

Number one is important. While a skilled code craftsman appreciates the beautiful algorithms that might shave a few milliseconds off code execution, I am but a humble code-monkey, and as such I appreciate the ass-loads of brute-force slogging through browser inconsistencies followed by man-years of unappreciated testing that had to have gone into the code before release. There's code in there that just targets mobile clients, for fuck's sake. And you thought making a page-hugging footer work without tables was 't3h sh1t'. Google's got code just to mock your code.


But number two is the fun stuff. The Blogger API should look familiar to anyone who's dipped their toes into the murky waters of JSP. Lots of this kind of stuff:



<b:if cond="'data:post.numBacklinks"></b:if>
<dl class="'comments-block'" id="'comments-block'">
<b:loop values="'data:post.backlinks'" var="'backlink'"></b:loop>
<div class="'collapsed-backlink">
  <dt class="'comment-title'">
    <span class="'backlink-toggle-zippy'"> </span>
    <a href="http://www.blogger.com/%27data:backlink.url%27" rel="'nofollow'"><data:backlink.title></data:backlink.title></a>
    <b:include data="'backlink'" name="'backlinkDeleteIcon'/"></b:include>
  </dt>
  <dd class="'comment-body">
    <data:backlink.snippet></data:backlink.snippet>
  </dd>
  <dd class="'comment-footer">
    <span class="'comment-author'">
      <data:post.authorlabel>
        <data:backlink.author></data:backlink.author>
      </data:post.authorlabel>
    </span>
    <span class="'comment-timestamp'">
      <data:post.timestamplabel>
        <data:backlink.timestamp></data:backlink.timestamp>
      </data:post.timestamplabel>
    </span>
  </dd>
</div>
</dl>

There's your if…then loop at the start, and your for loop over there… of course, they really need to include an INDEX on the loop to help us out, but there are ways to work around the limitation.


Anyway, it's a workable foundation. In the case of Blogger, most of the components (Links, About Me, etc.) are just black boxes to the database. You have access to a few members ("link" or "name"), but if you want to extend the structure you're SOL. Well… kind of.


ABANDON ALL HOPE
YE DBAs WHO READ PAST THESE LINES


If you want to use their data warehouse, you have to do it through them. But there's no restriction on how you use your fields. The Links List component on the right is an example.


Blogger gives you two fields: the URL and the Link Name. But most website names are dumb. A frantic, violent struggle for the table scraps of words left in the English Lexicon—what ones that haven't already been trademarked and copyrighted to death or stolen by some obscure punk band still playing in their mom's garage—that we then desperately try to assemble into a phrase which can, if you tilt your head sideways a bit, resemble the most meager sliver of our essence.


I mean, just look mine. "Revenge of D'oh!" Christ.


Anyway, I thought it would be far more useful if the website author's actual name could be associated with the link. But since we're only given two fields to work with, I have one doing double-duty. The "name" field is delimited, parsed, then through some fancy JavaScript-ery, appended to the link.


More to come.

Friday, October 26, 2007

The Management Regrets to Inform…

To: Visitors
From: Management

This is a notice to inform visitors that no accommodation will be made for inadequate web experiences due to browser incompatibilities or deficiencies. Sadly, the problem is on your end of the screen and there is simply nothing we can do to help you.

But take comfort—you can help yourself! Just five short minutes of your life and you'll be surfing the web in style in your own modern browser!

Any remaining energy should be channeled into the palm of one of your hands, which you should try to aim in a kind of graceful arcing path towards the middle of your forehead.

Thursday, October 25, 2007

Blog is a Stupid Word.

I have no other comments at this time.