Archive for the ‘CSS’ Category
Posted in 'CSS, JavaScript' by James on May 11th, 2009
This started out as a little experiment and eventually turned into quite an endeavor. The task was simple enough; to emulate Internet Explorer’s ‘grayscale‘ filter in all non-IE browsers. The solution, much to my initial surprise, is not as tricky as you would think.
The ‘grayscale‘ filter in IE can be applied to any element and visually transforms the element itself into grayscale. You can apply the filter using one line of messy proprietary CSS:
elem.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)';
This can also be defined in your StyleSheet:
elem {
filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
/* Element must "hasLayout"! */
zoom: 1;
}
As shown, getting this to work in IE is a piece of cake; other browsers, however, require much more attention!
There are two things to consider; images and everything else. “Everything else” is quite simple; loop through all elements within the document and look for colour properties such as ‘backgroundColor’ and ‘color’, then convert their RGB values to grayscale. There are a few ways of doing this; note that we’re not talking about desaturating a photo; “grayscaling” is slightly different (as I understand it):
Posted in 'CSS, Code Snippets, JavaScript' by James on April 16th, 2009
Currently, Internet Explorer doesn’t support ‘:focus‘ within CSS selectors, a dynamic pseudo-class implemented in CSS2. The Anchor and most form elements (input, textarea etc.) support this psuedo class. It’s normally used to make it obvious to the user where ‘focus’ currently is. This can be especially useful for users who browse without a mouse (just using a keyboard).
It’s easy enough to fix with JavaScript; you can just apply the styles on the ‘focus’ and ‘blur’ events. The problem with this is that you’ll also be affecting browsers that already have support for ‘:focus’. So you need a reliable way (no browser sniffing) of determining whether or not it’s supported. Also, manually adding these event handlers where needed is a bit of a pain… something we could certainly do without.
‘pseudoFocus’ is a jQuery plugin that fixes the ‘focus’ pseudo class in all browsers that don’t support it. It doesn’t use browser sniffing to determine support, but instead performs a check to determine whether the browser in question supports the specific feature:
var focusIsSupported = (function(){
// Create an anchor + some styles including ':focus'.
// Focus the anchor, test if style was applied,
// if it was then we know ':focus' is supported.
var ud = 't' + +new Date(),
anchor = $('<a id="' + ud + '" href="#"/>').css({top:'-999px',position:'absolute'}).appendTo('body'),
style = $('<style>#'+ud+'{font-size:10px;}#'+ud+':focus{font-size:1px !important;}</style>').appendTo('head'),
supported = anchor.focus().css('fontSize') !== '10px';
anchor.add(style).remove();
return supported;
})();
Once it has performed the check it will then run through all the StyleSheets looking for selectors with the ‘focus’ psuedo class (or ‘:unknown’ in IE6) and then automatically attaches the ‘focus’ and ‘blur’ handlers to whatever elements are targeted by each of those selectors.
Note that this will only work if your rules are defined in an external StyleSheet, the plugin won’t check for styles within <style/> tags.
A quick demo is available here: /demos/plugins/jQuery/pseudofocus/, and you can download the entire plugin here: /demos/plugins/jQuery/pseudofocus/pseudofocus.js
Another note: If you need to support more than just anchors, buttons, inputs and textareas then you can add to the isAcceptable variable within the plugin. It’s a comma separated list that defines “focusable” elements. The reason for this list is to ensure that all selectors containing ‘:focus’ work, even including the following:
#nav a:focus span.whatever {}
#nav a:focus {}
#go-button:focus img {}
Be aware that you can’t add any element to this list and expect it to work; the list is only there to provide a primitive check – elements that have no ‘focus’/'blur’ events will not be effected.
Posted in 'CSS, Usability' by James on March 20th, 2009
In CSS, the “!important” suffix was originally intended to provide a method of overriding author stylesheets. Users could define their own “user stylesheets” and could use this suffix to give their rules precedence over the author’s (website creator’s) styles.
Unfortunately, and quite predictably, its usage has spread massively, but not in the right direction. Nowadays, it’s used to counteract the pain of having to deal with CSS specificity, otherwise known as the set of rules which dictate that “div h1 a” is more specific selector than “div a”. Most people that use CSS on a daily basis don’t know enough about CSS specificity to solve their problems without using the “!important” suffix.
For reference, “specificity” is the name given to signify the precedence of a particular CSS selector. Here’s a quick rundown:
* {} /* a=0 b=0 c=0 -> specificity = 0 */
LI {} /* a=0 b=0 c=1 -> specificity = 1 */
UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */
UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */
H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */
UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */
LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */
#x34y {} /* a=1 b=0 c=0 -> specificity = 100 */
/* Source: http://www.w3.org/TR/CSS2/cascade.html */
The specificity is calculated as follows:
- count the number of ID attributes in the selector (= a)
- count the number of other attributes and pseudo-classes in the selector (= b)
- count the number of element names in the selector (= c)
- ignore pseudo-elements.
(read more about it: http://www.w3.org/TR/CSS2/cascade.html#important-rules)
The power of CSS and its cascading nature, in my opinion, is only fully appreciated when one understands specificity. A lack of understanding only leads to bad practices, such as using the “!important” suffix. Of course, it’s not always a bad idea, sometimes it’s necessary; for example, the Google toolbar in browsers always insists on colouring certain input fields yellow to signify that an ‘autocomplete’ feature is available. To be blunt, this can make your design look crap! The only way to counteract this is to define an “!important” style, i.e. the only thing more specific than inline styles.
Apart from a few edge cases its use is, in my opinion, unfounded and mostly unnecessary. Not to mention the fact of how annoying it is for a user when they want to apply their own styles or enhancements; you better have a damn good reason for relinquishing such a rudimentary level of control!
The only thing that can override an “!important” rule is another one, which must be specified lower down and its selector must have the same (or a higher) level of specificity. You can also specify “!important” styles inline. Another method would be to remove the rule entirely, this can be achieved with JavaScript, by accessing and manually removing the rule in question: http://dev.opera.com/articles/view/dynamic-style-css-javascript/#addingandremovingrules.
Even though there are solutions, it is still a massive pain for users, so please, don’t use “!important” unless you have no other option!