Blog

38 posts 2009 16 posts 2010 50 posts 2011 28 posts 2012 15 posts 2013 7 posts 2014 10 posts 2015 5 posts 2016 4 posts 2017 7 posts 2018 2 posts 2019 17 posts 2020 7 posts 2021 7 posts 2022 11 posts 2023 6 posts 2024

Help me: take the color survey

1 min read 0 comments Report broken page

If you are a creative professional, or just passionate about colors, please take my survey:

http://bit.ly/colorsurvey

It will greatly help me to make a future project of our company more usable (some of its features at least) and it only takes a few minutes (it contains 10-19 questions, depending on your responses).

Any suggestions, corrections, questions etc are of course welcome.

Thanks a lot in advance to everyone that takes the survey! :D

Of course, when it ends and I find the time to analyze the results, I’ll post them here for anyone interested. (Hint: That means that if you are interested in the results, you can promote the survey yourself as well, since more responses = more accurate results)


Advocacy of JavaScript

3 min read 0 comments Report broken page

I frequently meet these “hardcore” developers that deep (or not so deep) inside them, tend to underestimate JavaScript developers and boast about their own superiority. I’m sure that if you spent an important percentage of your career working with JavaScript and are even barely social, you definitely know what I’m talking about. It’s those desktop application programmers or these back-end developers that tend to consider JavaScript a toy, and try to convince you to engage in “more serious stuff” (if they appreciate you even a little; if they don’t they just mock you endlessly and/or look down on you).

Funnily enough, when most of these people are required to write JavaScript for some reason, one of the following happens:

  1. They write 2000-style code, which is usually the reason that most of them underestimate JavaScript so much: They think that everybody codes in JavaScript like themselves.
  2. They desperately look for “a good library” because “it’s not worth wasting my time to learn that stuff”.
  3. They actually learn the darn language and the relevant browser quirks and change their attitude towards JavaScript developers.

Douglas Crockford did it much better than me, but I would like to take my turn in arguing against their most frequent claims, if I may.

“Javascripters are not really developers.”

Oh r’ly? Is it because JavaScript doesn’t follow what you’ve learned to expect from most languages? Well, newsflash: Assembly doesn’t either and every programming language is actually an abstraction to it. It’s in fact much harder to write the same thing in a language that lacks what we’ve learned to expect. Think about low level coding: Even the simplest tasks seem hard. At a smaller extent, it’s the same with JavaScript: Things that are easy to do in other languages, are a pain in JavaScript, even if we leave out the implementation differences across browsers. For instance, in Java there is a built-in class for most common tasks. JavaScript isn’t that rich, and it penalizes you for every external library you use, by forcing your users to download extra Kilobytes of code. JavaScript is probably the only modern language in which short code isn’t only elegance, but also a necessity.

Also, in other languages, you only have to deal with one implementation. Even when using Java to code for multiple operating systems, the differences are minor for most applications. With JavaScript, you are dealing with at least 5 implementations with many differences and bugs to circumvent. Writing a piece of code that works in one browser is not good enough, you have to make it work across all major browsers, in all their versions that still have significant market share. And yeah, this is most of the times just as dreadful as it sounds, if not more.

Of course, I’m not implying that everyone who wrote a script in JavaScript is a developer, just like everyone that wrote a Hello World application in C++ is not a programmer. JavaScript is notorious for being used mostly by amateurs for the following reasons:

  1. Most people that ever wrote a webpage needed something that could only be done with JavaScript. Most of these people weren’t developers and didn’t have any interest in programming.
  2. Because of (1) there are many JavaScript tutorials and books around for accomplishing simple tasks, most of them being leftovers from the 2000 era and promote bad code practices. During that era, people didn’t care about nice code, usability, accessibility and cross-browser functionality. They just wanted to get the job done spending the least possible time and they only cared if it worked in Internet Explorer.
  3. Most people just copy and paste stuff from the tutorials mentioned in (2), leading to duplicate functionality, bad code, bad usability, complete absence of accessibility and buggy results in browsers other than the target one. This caused JavaScript to be related to these vices although these things were actually caused by abusing the language.

“Javascript is a toy, not a real programming language”

It may have been a toy in the 2000 era where your mind is still stuck. Currently, browser vendors are constantly adding new features to it, in order to make it able to compete with a fully-fledged programming language and competent front-end developers have been pushing JavaScript to an extent that was unimaginable when it was first introduced. If you are not convinced, pay a visit to Chrome Experiments (as the name suggests, you are advised to use Google Chrome when viewing them).

JavaScript is not a light version of Java, nor is it a light version of any programming language. It has a soul of it’s own, so stop comparing it to other languages and pointing out the areas where it lacks. Open your eyes instead to see the areas where it’s superior to all other languages you probably know (lambda for instance).

“How can I respect a language that only lives inside a browser?”

Newsflash: You are wrong, again. You can code in JavaScript for the server, create Windows executable files (.exe), create  plugins and extensions for a plethora of applications, and actually even Flash’s ActionScript is based on ECMAScript, a standard that was derived from and currently controls JavaScript implementations.

Disclaimers

Ah, these are always necessary in rants :)

  1. I didn’t have any particular individual in mind when writing this post, so if you think it’s about you, get over it. My memory is too bad to do so anyway. ;)
  2. I am not implying that JavaScript is the best programming language around. I actually don’t think there is such a language. My point was that JavaScript is not inferior to the others. That doesn’t mean I consider it superior either.
  3. I don’t claim to be a programming guru (anyone who does so is usually ignorant anyway), nor do I claim to be always right. Feel free to argue, if you have thought a valid counterargument. :)

Extend Math.log to allow for bases != e

1 min read 0 comments Report broken page

As Math.log currently stands, it’s a bit useless. It only calculates natural logarithms (base e).  We can easily modify it however, to calculate logarithms of any base:

Math.log = (function() {
	var log = Math.log;
	return function(n, a) {
		return log(n)/(a? log(a) : 1);
	}
})();

We can now specify the base as a second parameter, or still use the default one (Math.E) if we don’t specify one, so older scripts won’t break or if we want a shortcut to the natural logarithm. ;)


100% Cyan in CMYK is NOT rgb(0,255,255)!!

2 min read 0 comments Report broken page

As I mentioned in an earlier post of mine, I have to create a color picker, so I’ve already started to write the code for the Color class it’s going to use. I need it to natively support RGB, HSL, Lab and CMYK. And the latter part is causing unexpected trouble.

It seems that there is the notion out there that conversion from CMYK to RGB is easy. Newsflash: It’s not. As every graphic designer knows, the CMYK color gamut is smaller than the the RGB color gamut (even the sRGB color gamut). You can’t take a CMYK color and convert it to an out-of-CMYK-gamut RGB color! That’s nonsense! And it’s precisely what most conversion algorithms and color pickers out there do! Even Adobe Kuler!!! Since yesterday, I’ve studied dozens of algorithms and color pickers that claim to do CMYK -> RGB conversion, and every single one of them is wrong.

You can test a color picker that claims to support CMYK, or a CMYK <–> RGB conversion algorithm in the following simple way: Test how it converts the color CMYK(100%, 0, 0, 0) to RGB. If the result is rgb(0,255,255) then the algorithm is crap. rgb(0, 255, 255) is neither the same color, nor is it even in the CMYK color gamut! So basically, these algorithms convert a CMYK color to an RGB color that is outside of the CMYK color gamut! A color that cannot be represented with CMYK is supposed to be the result of a CMYK->RGB conversion? This is madness!

So far the only CMYK -> RGB converter that I’ve seen and does it right, is the one used by Adobe CS products (Photoshop, Illustrator, etc). And that makes me wonder why Kuler does it the wrong way, since they have already figured the algorithm! It’s crazy!

What’s even more strange is that I can’t even find which sRGB colors are usually out of the CMYK color gamut, so that I can adjust the algorithm I use properly (even if it just clipped the color to the nearest in-gamut one, it would be an improvement). I’ve been searching since yesterady even for that with no luck. I hope I don’t end up using the wrong algorithm myself too…


Cross browser, imageless linear gradients

2 min read 0 comments Report broken page

I have to write a color picker in the near future and I wanted it to have those little gradients on top of the sliders that show you the effect that a slider change will have on the selected color. Consequently, I needed to create imageless gradients, in order to easily change them. My very first thought was creating many div or span elements in order to show the gradient. I rejected it almost instantly, for ovbious reasons (*cough* performance *cough*). My second thought was SVG for the proper browsers, and gradient filters for IE. As it turned out, inline SVG was too much of a hassle and I didn’t want to use Data URIs. My final thought was canvas for the proper browsers and gradient filters for IE.

Since I consider such a script very entertaining, I didn’t google it at all, I started coding right away. Time to have fun! :D After finishing it though, I googled it just out of curiosity and didn’t like the other solutions much (either the solution itself, or the code), so I decided to post it in case it helps someone. I also made a little test page, so that you may test out how it works. :)

The script is a class for the creation of linear 2-color gradients in any browser. It’s used like this:

var g = new Gradient(200, 100, '#000000', '#ff1166', true);
document.body.appendChild(g.canvas);

You can create and manipulate the Gradient object at any point (during or after DOM parsing) but you have to insert the element somewhere in the DOM after the DOM has finished parsing (which is common sense).

All the parameters in the constructor are optional and can be manipulated later. Their order is width, height, startColor, endColor, vertical.

Some notes:

  • Its object oriented and doesn’t throw any strict warnings
  • Tested in IE6, IE7, IE8, Firefox 3, Safari 4b and Opera 9.6. Probably works with older versions of Firefox, Opera and Safari as well (as long as they support <canvas>), I’m just not able to test in them currently.
  • All it’s methods return the object, so they can be chained.
  • You can modify it to support RGBA as well, but you’d have to use a different format for IE (extended hex) and a different one for the proper browsers. I didn’t need that and it would make the script unnecessarily complex, so I didn’t implement it.

Limitations (all these limitations are enforced by IE’s gradient filter):

  • Only does linear gradients
  • The gradient can be either vertical or horizontal. No other angles.
  • The only color format supported is #RRGGBB.

Properties

canvas (HTMLElement)

The HTML Element that is being used to render the gradient. Either a <canvas> or a <span>. You have to use it at least once, in order to insert the element in the DOM. I preferred not to do this automatically, since it would be too restrictive.

startColor (String)

The current start color of the gradient.

endColor (String)

The current end color of the gradient.

vertical (Boolean)

True if the gradient is vertical, false if it’s horizontal.

width (Number)

The width of the gradient in pixels

height (Number)

The height of the gradient in pixels

Methods

paint(startColor, endColor, vertical)

Used to change the colors and/or the orientation of the gradient. All parameters are optional.

resize(width, height)

Used to change the size of the gradient. Both parameters are optional.

flip()

Reverses the gradient (swaps endColor with startColor)

rotate()

Rotates the gradient by 90 degrees clockwise (should I add CCW too?)

Download

Hope you find it useful :)


Mockup viewer bookmarklet

1 min read 0 comments Report broken page

I usually view mockups in a browser, so that the impression I get is as close as possible to reality (I learned this the hard way: A mockup that seemed great in the neutral and minimalistic environment of a picture viewer, ended up looking way too fancy when viewed in a browser, something that I realized after having worked for 6 months on the site). If you do the same, I’m sure you’ll feel my pain: Every time I do that, I have to carefully scroll down just as much as to hide the margin that the browser adds, and left just as much as to center the image. Not to mention the click required to enlarge the image to full-size.

Not any more! I was so fed up today, that I wrote a little bookmarklet that does this. It enlarges the image to full size, removes the margins and scrolls the page left so that the image is centered. It works on any recent browser I’ve tested, and I think it will probably work in most browsers that web designers use (hint: not old IEs) :P

Enjoy.

Mockup viewer

JS code:

(function(){
	document.body.style.margin = 0;
	var inner = window.innerWidth || document.body.clientWidth, img = document.getElementsByTagName('img')\[0\];
	img.removeAttribute('width');
	img.removeAttribute('height');
	document.body.scrollLeft = (img.offsetWidth - inner)/2;
})();

If only it could also write the XHTML & CSS for the site… :P


CSS3 colors, today (MediaCampAthens session)

1 min read 0 comments Report broken page

Yesterday, I had a session at MediaCampAthens (a BarCamp-style event), regarding CSS3 colors. If you’ve followed my earlier posts tagged with “colors”, my presentation was mostly a sum-up of these.

It was my first presentation ever, actually, the first time I talked to an audience for more than 1 minute :P . This caused some goofs:

  • When introducing myself, I said completely different things than I intended to and ended up sounding like an arrogant moron :P
  • I tried not to look at the audience too much, in order to avoid sounding nervous, and this caused me to completely ignore 2 questions (as I found out afterwards)! How embarrasing!
  • At a certain point, I said “URL” instead of “domain” :P

Also, I had prepared some screenshots (you’ll see them in the ppt) and the projector completely screwed them up, as it showed any dark color as black.

Apart from those, I think it went very well, I received lots of positive feedback about it and the audience was paying attention, so I guess they found it interesting (something that I didn’t expect :P ).

Here is the presentation:

Please note that Slideshare messed up slide #8 and the background seems semi-transparent grey instead of semi-transparent white.

By the way, I also thought afterwards that I had made a mistake: -ms-filter is not required if we combine the gradient filter with Data URIs, since IE8 supports Data URIs (for images at least). Oops, I hate making mistakes that I can’t correct.

Here are some photos from my session. If I did it correctly, every facebook user can see them. If I messed things up, tell me :P


CMYK colors in CSS: Useful or useless?

2 min read 0 comments Report broken page

As someone who dealed a bit with print design in the past, I consider CMYK colors the easiest color system for humen to understand and manipulate. It’s very similar to what we used as children, when mixing watercolors for our drawings. It makes perfect sense, more than HSL and definately more than RGB. I understand that most of us are so accustomed to using RGB that can’t realise that, but try to think for a moment: Which color system would make more sense to you if you had no idea and no experience at all with any of them?

Personally, even though I have lots more experience with RGB, given the fact that most of my work will be displayed on screen and not printed on paper, when I think of a color I want, I can instantly find out the percentages of Cyan, Magenta, Yellow and blacK needed to create it. I can’t do that with HSL or RGB, I’d have to play a little bit with the color picker’s sliders. I sometimes start by specifying a color in CMYK and then tweaking it via RGB or HSL to achieve the exact color I need (since the CMYK gamut is smaller than the RGB gamut) and I find that much faster than starting with RGB or HSL right away.

Also, when you don’t have a color picker, it’s much easier to create beautiful colors with CMYK than it is with RGB. For example the CMYK magenta (0% Cyan, 100% Magenta, 0% Yellow, 0% blacK) is a much better color than the RGB Magenta (255 Red, 0 Green, 100% Blue).

Given the above, I’ve always thought how much I wanted to be able to specify CMYK colors in my CSS. I agree that sometimes this would result in crippling myself, since as I said above the CMYK gamut is smaller, but it has other significant advantages that I think it would make it a useful option for some people. There are algorithms available for CMYK to RGB conversion, and the browser could use those to display the specified color on the screen. Then, if the user decided to print the page, The CMYK colors could be used as-is for the printer. Another advantage, as none of the current CSS color formats allow us to control that. People who don’t find the CMYK color system easier for them to understand, they could still use it for their print stylesheets.

Also, graphic designers who decided to switch to web design would find it much easier to specify color values in a format they are already comfortable with.

To sum it up, the advantages that I think this option would provide us are:

  1. A color system that’s easier for most people to understand and manipulate.
  2. The colors you get when combining “easy” CMYK values (0%, 50%, 100%) are more beatuful than the ones you get with “easy” RGB values (0, 128, 255). Bored people and people without a taste in color selection would create more beatuful websites this way and our eyes wouldn’t hurt.
  3. We would be able to specify how our colors will get printed, something that is not currently possible at all. Extremely useful for print stylesheets.
  4. It would be easier for graphic designers to switch to web design.

And the format is very easy to imagine:

background-color: cmyk(0, 100, 50, 0);

or

background-color: cmyk(0%, 100%, 50%, 0%);

or

background-color: cmyk(0, 1, 0.5, 0);

So, what do you think? Useful or useless?

Edit: As it turns out, I’m not crazy! The W3 already considers this for CSS3 with the 3rd format (from 0 to 1)! However, no browser supports it yet, not even Webkit nightlies… :(

Translations


On native, single-input, multiple file uploads

2 min read 0 comments Report broken page

If you are following the current news on web development, you probably heard that the new Safari 4 has a great feature: It natively allows the user to select multiple files via a single input control, if you specify a value for the attribute multiple:

<input type="file" multiple>

or, in XHTML:

<input type="file" multiple="multiple" />

You might not know that Opera supported multiple file uploads for a while now, based on the earlier Web Forms 2.0 standard in a slightly different (and more flexible) format:

<input type="file" min="1" max="9999″ />

Can we use those currently?

Sure we can, but we should provide fallbacks for the other browsers. Using these features will put pressure on the other browser vendors to implement them as well and generally, native is always better.

How can we find out whether the browser supports them?

Opera

Opera supports accessing those min and max properties as properties of the element. So, it’s quite trivial to check whether Opera-style multiple inputs are supported:

var supportsMin = (function(){
	var fi = document.createElement('input');
	fi.type = 'file';
	return fi.min === '' && fi.max === '';
})();

Safari 4

In Safari 4 the check would be equally simple, if it supported accessing the multiple attribute as a property. Then we could easily check whether it’s boolean and conclude that Safari-style multiple inputs are supported:

var supportsMultiple = (function(){
	var fi = document.createElement('input');
	fi.type = 'file';
	// The second check is probably redundant but what if in the future an implementor
	// decides to make the file inputs to handle multiple selections by default?
	// Yeah, it's not likely, but it's not entirely impossible.
	return fi.multiple === false || fi.multiple === true;
})();

However, that’s currently not the case. The good news are that I reported this as a bug today, and the Webkit team fixed it, so it will be possible in the next Webkit nightly!

Combining the two

You can easily combine these two together with the workaround you prefer:

// Create a file input that allows multiple file selection
var fi = document.createElement('input');
fi.type = 'file';

if(fi.multiple === false || fi.multiple === true) { fi.multiple = true; } else if(fi.min === ‘’ && fi.max === ‘’) { fi.min = 1; fi.max = 9999; } else { // Our preferred workaround here }

What about Mozilla?

Ok, we all know that IE will probably take years to implement similar functionality. But usually, the Mozilla team implements new and exciting stuff quite fast.

As it turns out, there is a relevant ticket sitting in their Bugzilla for a while now. If you want them to implement it, vote for it so that it’s priority increases.

If they do implement it in the way suggested, the code posted above will work for that too, without any changes - The advantages of feature detection baby! ;)


Check whether the browser supports RGBA (and other CSS3 values)

2 min read 0 comments Report broken page

When using CSS, we can just include both declarations, one using rgba, and one without it, as mentioned in my post on cross-browser RGBA backgrounds. When writing JavaScript however, it’s a waste of resources to do that (and requires more verbose code), since we can easily check whether the browser is RGBA-capable, almost as easily as we can check whether it suppports a given property. We can even follow the same technique to detect the support of other CSS3 values (for instance, multiple backgrounds support, HSLA support, etc).

The technique I’m going to present is based on the fact that when we assign a non-supported CSS value on any supported CSS property, the browser either throws an error AND ignores it (IE-style), or simply ignores it (Firefox-style). Concequently, to check whether RGBA is supported, the algorithm would be:

  1. Get the color (or backgroundColor, or borderColor or any property that is widely supported and accepts color values) value of the style object of any element that exists in the page for sure (for instance, the first script tag) and store it in a variable.
  2. Assign an RGBA color to the color property of that element and catch any errors produced.
  3. Assign to a variable whether the color of that element did change (boolean true or false).
  4. Restore the previous color to the color property, so that our script doesn’t interfere with the designer’s decisions.
  5. Return the stored result.

and it would result in the following code:

function supportsRGBA()
{
	var scriptElement = document.getElementsByTagName('script')[0];
	var prevColor = scriptElement.style.color;
	try {
		scriptElement.style.color = 'rgba(1,5,13,0.44)';
	} catch(e) {}
	var result = scriptElement.style.color != prevColor;
	scriptElement.style.color = prevColor;
	return result;
}

Performance improvements

The code above works, but it wastes resources for no reason. Every time the function is called, it tests RGBA support again, even though the result will never change. So, we need a way to cache the result, and return the cached result after the first time the function is called.

This can be achieved in many ways. My personal preference is to store the result as a property of the function called, named 'result':

function supportsRGBA()
{
	if(!('result' in arguments.callee))
	{
		var scriptElement = document.getElementsByTagName('script')[0];
		var prevColor = scriptElement.style.color;
		try {
			scriptElement.style.color = 'rgba(0, 0, 0, 0.5)';
		} catch(e) {}
		arguments.callee.result = scriptElement.style.color != prevColor;
		scriptElement.style.color = prevColor;
	}
	return arguments.callee.result;
}

Making it bulletproof

There is a rare case where the script element might already have rgba(0,0,0,0.5) set as it’s color value (don’t ask me why would someone want to do that :P ), in which case our function will return false even if the browser actually supports RGBA. To prevent this, you might want to check whether the color property is already set to rgba(0,0,0,0.5) and return true if it is (because if the browser doesn’t support rgba, it will be blank):

function supportsRGBA()
{
	if(!('result' in arguments.callee))
	{
		var scriptElement = document.getElementsByTagName('script')[0];
		var prevColor = scriptElement.style.color;
		var testColor = 'rgba(0, 0, 0, 0.5)';
		if(prevColor == testColor)
		{
			arguments.callee.result = true;
		}
		else
		{
			try {
				scriptElement.style.color = testColor;
			} catch(e) {}
			arguments.callee.result = scriptElement.style.color != prevColor;
			scriptElement.style.color = prevColor;
		}
	}
	return arguments.callee.result;
}

Done!


"Appearances can be deceiving Mr. Anderson" - a.k.a. short code is not always fast code

2 min read 0 comments Report broken page

I used to take pride in my short, bulletproof and elegant String and Number type checks:

// Check whether obj is a Number
obj + 0 === obj

// Check whether obj is a String obj + ‘’ === obj

I always thought that apart from being short and elegant, they should be faster.

However, some quick tests gave me a cold slap in the face and proved my assertion to be entirely false. When comparing the following 4 methods for string and number type checking:

  1. “My” method (mentioned above)
  2. Object.prototype.toString method: Object.prototype.toString.call(obj) === '[object String]' or Object.prototype.toString.call(obj) === '[object Number]'
  3. Typeof method: typeof obj === 'string' or typeof obj === 'number'
  4. Contructor method: obj.constructor === String or obj.constructor === Number

It turned out that the Object.prototype.toString method was 50% faster than my method, and both typeof and constructor methods were a whopping 150% faster than my method! No wonder jQuery uses the typeof method for their String/Number tests.

Now that I think about it, it does actually make sense - my method converts obj to a String or Number, then concatenates/adds it with another String/Number, then compares value and type. Too much stuff done there to be fast. But I guess I was too innocent and subconsciously thought that it wouldn’t be fair if elegant and short code wasn’t fast too.

Of course the overall time needed for any of these tests was neglible, but it’s a good example of how much appearances can be deceiving - even in programming! ;)

The moral: Never assume. Always test.

So, which method is ideal for String/Number checks? (added afterwards)

The typeof method and my method fail for non-primitive String/Number objects, as you can easily observe if you type in the console:

typeof new String('foo') // 'object'
typeof new Number(5) // 'object'
new String('foo') + '' === new String('foo') // false

This can easily be solved if you also check the type via instanceof (the decrease in speed is negligible):

foo = new String('foo');
typeof foo === 'string' || foo instanceof String
foo + '' === foo || foo instanceof String

Don’t use instanceof alone, since it fails for String and Number primitives. The instanceof method also fails for Strings and Numbers created in another window, since their constructor there is different. Same happens with the Constructor method mentioned above.

It seems that if you need a bulletproof check the only method you can use is the Object.prototype.toString method and luckily, it’s one of the fastest (not the fastest one though), so I guess we can safely elect it as the ideal method for String and Number checks (and not only for arrays, as it was first made popular for).

PS: For anyone wondering what the quote in the title reminds him/her, its from the Matrix Revolutions movie.


Quick & dirty way to run snippets of JavaScript anywhere

1 min read 0 comments Report broken page

Ever wanted to run a snippet of JavaScript on a browser that doesn’t support a console in order to debug something? (for instance, IE6, Opera etc)

You probably know about Firebug Lite, but this either requires you to already have the bookmarklet, or include the script in the page. Although Firebug Lite is a great tool for more in depth debugging, it can be tedious for simple tasks (eg. “What’s the value of that property?”).

Fortunately, there is a simpler way. Do you remember the 2000 era and the javascript: URIs? Did you know that they also work from the address bar of any javascript-capable browser?

For instance, to find out the value of the global variable foo, you just type in the address bar javascript:alert(foo). You can write any code you wish after the javascript: part, as long as you write it properly to fit in one line.

Of course these URIs are a no-no for websites, but they can be handy for simple debugging in browsers that don’t support a console. ;)


20 things you should know when not using a JS library

5 min read 0 comments Report broken page

You might just dislike JavaScript libraries and the trend around them, or the project you’re currently working on might be too small for a JavaScript library. In both cases, I understand, and after all, who am I to judge you? I don’t use a library myself either (at least not one that you could’ve heard about  ;) ), even though I admire the ingenuity and code quality of some.

However, when you take such a brave decision, it’s up to you to take care of those problems that JavaScript libraries carefully hide from your way. A JavaScript library’s purpose isn’t only to provide shortcuts to tedious tasks and allow you to easily add cool animations and Ajax functionality as many people (even library users) seem to think. Of course these are things that they are bound to offer if they want to succeed, but not the only ones. JavaScript libraries also have to workaround browser differences and bugs and this is the toughest part, since they have to constantly keep up with browser releases and their respective bugs and judge which ones are common enough to deserve workaround and which ones are so rare that would bloat the library without being worth it. Sometimes I think that nowadays, how good of a JavaScript developer you are doesn’t really depend on how well you know the language, but rather on how many browser bugs you’ve heard/read/know/found out. :P

The purpose of this post is to let you know about the browser bugs and incompatibilities that you are most likely to face when deciding againist the use of a JavaScript library. Knowledge is power, and only if you know about them beforehand you can workaround them without spending countless debugging hours wondering “WHAT THE…”. And even if you do use a JavaScript library, you will learn to appreciate the hard work that has been put in it even more.

Some of the things mentioned below might seem elementary to many of you. However, I wanted this article to be fairly complete and contain as many common problems as possible, without making assumptions about the knowledge of my readers (as someone said, “assumption is the mother of all fuck-ups” :P ). After all, it does no harm if you read something that you already know, but it does if you remain ignorant about something you ought to know. I hope that even the most experienced among you, will find at least one thing they didn’t know very well or had misunderstood (unless I’m honoured to have library authors reading this blog, which in that case, you probably know all the facts mentioned below :P ) . If you think that something is missing from the list, feel free to suggest it in the comments, but have in mind that I conciously omitted many things because I didn’t consider them common enough.

DOM

  1. getElementById('foo') also returns elements with name="foo" in IE and older versions of Opera.
  2. getElementsByTagName('*') returns no elements in IE5.5 and also returns comment nodes in all versions of IE (In case you’re wondering: DOCTYPE declaration will count, Conditional comments will not).
  3. getElementsByClassName() in Opera (even Opera 10 Alpha) doesn’t match elements with 2 or more classes when the one you’re looking for is not the first but it’s also a substring of the first. Read the discussion between me and John Resig on the latter’s blog post mentioned below if this seems a bit unclear.
  4. There is no element.children collection in Firefox 3-. You have to create it yourself by filtering the childNodes collection if it doesn’t exist.
  5. If your code involves preformatted elements (for instance if you are making a syntax highlighter), beware when setting the innerHTML of those: IE won’t preserve line breaks (\r\n s) and whitespace. You have to use outerHTML, which will actually replace the element so you should find a way to obtain a reference to the newly created one in case you still need to perform stuff on it.
  6. To get the dimensions of the viewport, standard compliant browsers use window.innerWidth (and innerHeight) whereas IE uses document.documentElement.clientWidth (and clientHeight).
  7. To get the scroll offsets of the current page, standard compliant browsers use window.pageXOffset (and pageYOffset) whereas IE uses document.documentElement.scrollTop (and scrollLeft).
  8. To make matters worse, in both cases above, you need to use document.body instead of document.documentElement when in Quirks mode.

John Resig (of the jQuery fame), recently posted a great presentation, which summarized some browser bugs related to DOM functions. A few of the bugs/inconsistencies mentioned above are derived from that presentation.

Events

  1. When using IE’s attachEvent() the this reference inside the callback refers to the useless window object
  2. eventObject.target is eventObject.srcElement in IE
  3. eventObject.stopPropagation() is eventObject.cancelBubble = true; in IE
  4. eventObject.preventDefault() is eventObject.returnValue = false; in IE
  5. There are many more event object incompatibilities for specific events (the ones above are for all events). Take a trip to QuirksMode for more information.
  6. IE leaks horribly (especially IE6) in various cases.
  7. If you register the same event handler X times, IE fires it X times.
  8. Determining when the DOM is ready is a complete mess. Firefox and Opera 9+ support the DOMContentLoaded event, Safari doesn’t but you can check it’s document.readyState property and in IE document.readyState is unreliable and you should either inject a deferred script, either poll the DOM untill there are no errors or use an external behavior file. Of course you could always just put a script tag at the bottom of the page, just before the body closing tag, which will fire all attached handlers which is actually the best approach in terms of which way fires earliest (but not too early) according to my tests, but that hardly qualifies as unobtrusive…
  9. (edit, thanks Sobral!) The Event object is not passed as a parameter to the callback but resides in window.event in older versions of IE

Type detection

  1. The typeof operator is almost useless:

    • typeof null == 'object'
    • typeof new String('foo') == 'object'
    • typeof [] == 'object'

    Use Object.prototype.toString instead.

CSS

  1. Although most CSS properties are converted to their JavaScript equivalents in a standard way (characters after dashes are Uppercase, others are lowercase, the dashes get removed), float is an exception: It’s converted to cssFloat in most browsers and styleFloat in IE. Check which one exists and use that.
  2. Getting the current (computed) style of an element is another complete mess. IE uses element.currentStyle[propertyJS] whereas standard compliant browsers use document.defaultView.getComputedStyle(element, null).getPropertyValue(propertyCSS). And as if this wasn’t enough, there are various problems associated with specific properties or browsers, like:
    • IE returns the cascaded values and not the computed ones (for instance, it might return ems for a property that was specified in ems, and not pixels). Dean Edwards has thought a very clever hack to workaround this and didn’t even blog about it (it’s simply a comment in a blog post of Erik Arvidsson’s!).
    • Any hidden (via display:none;) element, yields a width/height/top/right/bottom/left value of zero.
    • auto or normal might be returned for properties that are left at their defaults. For instance, IE does this with width/height for elements that don’t have dimensions explicitly set via CSS.
    • In most browsers, shorthands (like border) will yield a blank string. You’d have to use the most specific property (for instance, border-left-width).
    • Colors will be returned in different formats across browsers. For instance, IE uses #RRGGBB whereas Mozilla uses rgb(red, green, blue).

So, what now?

Never, EVER use a browser detect to solve the problems mentioned above. They can all be solved with feature/object detection, simple one-time tests or defensive coding. I have done it myself (and so did most libraries nowadays I think) so I know it’s possible. I will not post all of these solutions to avoid bloating this post even more. You can ask me about particular ones in the comments, or read the uncompressed source code of any library that advertises itself as “not using browser detects”. JavaScript Libraries are a much more interesting read than literature anyway. :P

Are the facts mentioned above actually 20?

I’m not really sure to be honest, it depends on how you count them. I thought that if I put a nice round number in the title, it would be more catchy :P


Silent, automatic updates are the way to go

2 min read 0 comments Report broken page

Recently, PPK stated that he hates Google Chrome’s automatic updates. I disagree. In fact, I think that all browser vendors should enforce automatic updates as violently as Google Chrome does. There should be no option to disable them. For anybody.

But what about the user’s freedom of choice?

This might sound a bit facist at start, but imagine a world where all browsers would get automatically updated, without the possiblity of an opt-out. If you went online, you would be bound to have the very latest version, regardless of how computer (i)literate you were (Many — if not most — home users that don’t upgrade are like that because they think it’s too difficult for their computer expertise level). Sure, if you were a developer you wouldn’t be able to test a website in older browser versions. But why would you need to do so? If everybody had the latest browser version, you would only develop for the latest version and perhaps for the next one (via nightlies and betas, that could still be separate in that ideal world).

Imagine a world where your job wouldn’t have to involve tedious IE6 (and in a few weeks, no IE7 either), Firefox 2, Opera 9.5 and Safari 3.1- testing. A world where you would spend your work hours on more creative stuff, where you wouldn’t want to bang your head on the wall because you know you did nothing wrong but the ancient browser that you are currently testing in is just incompetent and YOU have to fix it’s sh*t. A world where the size of your Javascript code (and the JS libraries’ code) would be half its size and constantly decreasing as new browser versions come out. A world where you would only have 1 CSS file in most websites you develop. A world where you wouldn’t feel so bad because IE8 doesn’t support opacity, border-radius or SVG, because you would know that in 1-2 years everyone would have IE9 and it will probably support them. A world where designing a website would be as much fun as designing your personal blog.

Doesn’t such a world sound like a dream? Would it harm anyone? Users would browse a much lighter and beautiful web, with a more feature-rich and secure browser. Developers would work half as much to produce better results and they would enjoy their work more.

What about corporate intranets and abandoned sites that won’t keep up?

Oh come on, that isn’t a good enough reason to not make that dream come true! Companies and individuals could be allowed to have an older version of the browser installed as well. They still wouldn’t be able to opt out from the automatic upgrade, but they could apply somehow to have an older version of the browser in the same system as well. Similarly to what happens now with browser betas. People would use the older version to access corporate intranet applications and obsolete sites and the latest version to surf the web. I may be overly optimistic, but I think that if a user had both versions of a browser installed, (s)he would prefer the latest wherever (s)he can. Perhaps another step towards enforcing that would be if the OS prevented an older browser version from being set as the default browser, but I guess that would be too hard to do, especially if the browser in question is not the OS default one.

Other people who agree with me

What’s your opinion?


Bulletproof, cross-browser RGBA backgrounds, today

4 min read 0 comments Report broken page

UPDATE: New version

First of all, happy Valentine’s day for yersterday. :) This is the second part of my “Using CSS3 today” series. This article discusses current RGBA browser support and ways to use RGBA backgrounds in non-supporting browsers. Bonus gift: A PHP script of mine that creates fallback 1-pixel images on the fly that allow you to easily utilize RGBA backgrounds in any browser that can support png transparency. In addition, the images created are forced to be cached by the client and they are saved on the server’s hard drive for higher performance.

Browsers that currently support RGBA

These are:

  • Firefox 3+
  • Safari 2+
  • Opera 10 (still in beta)
  • Google Chrome

In these browsers you can write CSS declarations like:

background: rgba(255,200,35,0.5) url(somebackground.png) repeat-x 0 50%; border: 1px solid rgba(0,0,0,0.3); color: rgba(255,255,255,0.8);

And they will work flawlessly.

Internet Explorer

Surprisingly, it seems that Internet Explorer supported RGBA backgrounds long before the others. Of course, with it’s very own properietary syntax, as usual:

filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#550000FF, endColorstr=#550000FF);

And since nothing is ever simple with IE, IE8 requires a special syntax which has to be put before the first one to work properly in IE8 beta1:

-ms-filter: “progid:DXImageTransform.Microsoft.gradient(startColorstr=#550000FF, endColorstr=#550000FF)”;

The code above actually draws a gradient from rgba(0,0,255,0.33) to rgba(0,0,255,0.33) using a Microsoft-proprietary “extended” hex format that places the Alpha parameter first (instead of last) and in the range of 00-FF (instead of 0-1). The rest is a usual hex color, in that case #0000FF.

Caution: The “gradients” that are created via the gradient filter are placed on top of any backgrounds currently in effect. So, if you want to have a background image as well, the result may not be what you expected. If you provide a solid color as a background, it will also not work as expected (no alpha transparency), since the gradients created are not exactly backgrounds, they are just layers on top of backgrounds.

Problems with the filter method

  • Filters are bad for client-side performance.
  • Filters cause the text rendering to be aliased and especially when it’s bold and there is no background-color set it becomes completely unreadable. (the worst disadvantage if you ask me)
  • Filters only work with IE. What about Firefox 2- and Opera 9.6-?
  • Filters are lengthy (especially now that you have to include 2 different syntaxes) so they significantly increase the size of your CSS when used frequently.
  • You have to convert the red, green and blue values to hex to use that method.
  • To use a filter, the element has to have Layout. This is usually done via zoom:1. More non-standard clutter in your CSS.
  • Doesn’t play along well with other workarounds, since it doesn’t modify the background of the element.

So, personally, I only use that approach sparingly, in particular, only when “no/minimum external files” is a big requirement.

A bulletproof solution

My favored approach is to use rgba() for all RGBA-capable browsers and fallback pngs for the ones that don’t support RGBA. However, creating the pngs in Photoshop, or a similar program and then uploading them is too much of a fuss for me to bare (I get bored easily :P ). So, I created a small PHP script that:

  • Creates a 1-pixel png image with the parameters passed for red, green, blue and alpha. No need to convert to hex.
  • Supports named colors, to speed up typing even more for colors that you use commonly in a site (it includes white and black by default, but you may easily add as many as you like).
  • Stores the generated images on the server, so that they don’t have to be created every time (generating images on the fly has quite an important performance impact).
  • Forces the images to be cached on the browser so that they don’t have to be generated every time (even though their size is very small, about 73 bytes).

Here it is: rgba.php

You use it like this:

background: url(rgba.php?r=255&g=100&b=0&a=50) repeat; background: rgba(255,100,0,0.5);

or, for named colors:

background: url(rgba.php?name=white&a=50) repeat; background: rgba(255,255,255,0.5);

Browsers that are RGBA-aware will follow the second background declaration and will not even try to fetch the png. Browsers that are RGBA-incapable will ignore the second declaration, since they don’t understand it, and stick with the first one. Don’t change the order of the declarations: The png one goes first, the rgba() one goes second. If you put the png one second, it will always be applied, even if the browser does support rgba.

Before you use it, open it with an editor to specify the directory you want it to use to store the created pngs (the default is 'colors/') and add any color names you want to be able to easily address (the defaults are white and black). If the directory you specify does not exist or isn’t writeable you’ll get an error.

Caution: You have to enter the alpha value in a scale of 0 to 100, and not from 0 to 1 as in the CSS. This is because you have to urlencode dots to transfer them via a URI and it would complicate things for anyone who used this.

Edit: It seems that IE8 sometimes doesn’t cache the image produced. I should investigate this further.

IMPORTANT: If your PHP version is below 5.1.2 perform this change in the PHP file or it won’t work.

Why not data:// URIs?

Of course, you could combine the IE gradient filter, rgba() and data:// URIs for a cross-browser solution that does not depend on external files. However, this approach has some disadvantages:

  • All the disadvantages of filters mentioned above.
  • You can’t be spontaneous in your CSS and changes are difficult. Every time you want to use RGBA, you have to resort to some converter to create the png and it’s data:// URI. Unless you are some kind of a cyborg with an embedded base64 encoder/decoder in your head :P
  • Larger filesize (you have to use 4-5 declarations (the rgba() one, the data:// one, 2 filters, one for IE7- and one for IE8 and a zoom:1; to give the element “layout” so that filters can be applied) instead of 2, and the data:// URI has the same size as the png). Also, the data:// URI can not be cached so every time you use it, you increase the filesize even more.  Ok, you save an http request per use, but is it worth it?

and some advantages:

  • You will not see the site without a background for even a single millisecond. Since the png is embedded in the CSS, it’s loaded as soon as the CSS itself is loaded. If your site background is too dark and you rely on the RGBA background to make the content legible, you might want to consider this solution.
  • No external files, no extra http requests.
  • The filter method works in IE6- without the script for transparent PNGs.

Choose the method that fits your needs better. :)

RGBA is not only for backgrounds!

It’s also for every CSS property that accepts color values. However, backgrounds in most cases are the easiest to workaround. As for borders, if you want solid ones, you can simulate them sometimes by wrapping a padded container with an RGBA background around your actual one and giving it as much padding as your desired border-width. For text color, sometimes you can fake that with opacity. However, these “solutions” are definitely incomplete, so you’d probably have to wait for full RGBA support and provide solid color fallbacks for those (unless someone comes up with an ingenious solution in <canvas>, it’s common these days :P ).