Reading List
The most recent articles from a list of feeds I subscribe to.
CMYK colors in CSS: Useful or useless?
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:
- A color system that’s easier for most people to understand and manipulate.
- 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.
- 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.
- 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
CMYK colors in CSS: Useful or useless?
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:
- A color system that’s easier for most people to understand and manipulate.
- 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.
- 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.
- 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
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! ;)
On native, single-input, multiple file uploads
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)
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:
- Get the
color(orbackgroundColor, orborderColoror any property that is widely supported and accepts color values) value of thestyleobject of any element that exists in the page for sure (for instance, the first script tag) and store it in a variable. - Assign an RGBA color to the
colorproperty of that element and catch any errors produced. - Assign to a variable whether the
colorof that element did change (booleantrueorfalse). - Restore the previous color to the
colorproperty, so that our script doesn’t interfere with the designer’s decisions. - 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!