A couple of versions ago, WebKit implemented their own vendor-specific property for the CSS3 appearance. It is called -khtml-appearance.
According to the specifications of the World Wide Web Consortium:
“CSS appearance sets 'appearance' to the specified value and the other properties to their appropriate system value. 'normal' resets 'appearance' to 'normal' and the others to 'inherit'. The 'appearance' property does not affect the specified or computed values of any other properties.”
A little bit of vague explanation, however it is not the point of my blog post. Using this WebKit feature in RadFormDecorator was crucial, and let us drop the listening to the poorly supported onpropertychange event in Apple Safari and Google Chrome.
To clarify our new approach I will explain the technique for decorating checkboxes below. The approach is similar with radio button controls.
Unlike the FireFox –moz-appearance, -khtml-appearance implements a none value (a real none, unlike in FireFox, that implements none as “default”), that removes the default system appearance of the control it is applied to.
This will render the regular checkbox with a custom image. It is important to mention that –khtml-appearance: none works almost like visibility: hidden, with the difference that the element it is applied to loses its dimensions, and this is why we had to explicitly set width and height to it, along with an image sprite with the respective coordinates for the normal state of the control.
In order to style the checked state of the control, we simply use the :checked pseudo class with the same image sprite, only setting coordinates for the “checked” state image in the sprite:
To make things even more beautiful, we use the :hover pseudo class to toggle the images then the the mouse hovers the control. And again – we use the same image sprite:
Further, what we have to take care of is the disabled (both normal, checked and hover) states of the control. To target a disabled checkbox, we use the disabled HTML attribute as a selector. The standard approach to mark an element as disabled on the Web is to make it decrease its opacity, so:
Note that unlike [type=”checkbox”], we do not set [disabled=”disabled”], but [disabled] only because there is only one value for this attribute - disabled.
For aesthetic purposes, in order to disable the hover effect on the disabled checkboxes, we add another two selectors for checked:disabled:hover and normal:disabled:hover to the existing normal state selector properties, as shown below:
Finally, as this approach is proprietary, we used a browser-specific hack – a @media query selector combined with a proprietary WebKit property (-webkit-min-device-pixel-ratio) that wraps the new selectors:
This will ensure that our new rendering will not affect any other browser, but WebKit only.
Again, almost all of the new CSS is added to the base style sheet (Skins/FormDecorator.css). What is left now is to add references to the image sprites for radio buttons and checkboxes for the different skins in each skin style sheet (Skins/[SkinName]/FormDecorator.[SkinName].css). Again we shall use the WebKit hack. The new code should be added at the bottom of the style sheet.
Did you notice the .rfdCheckbox and .rfdRadio classes? In fact they are dummy classes, and are used only as pointers. They are set to the documentElement of the page or to the DecorationZoneID element when the DecoratedControls is “All”, “CheckBoxes” or “RadioButtons”. The idea is that if decoration of these is turned off, they do not get decorated, because the root element will not bear .rfdCheckbox or .rfdRadio.
Iana Tsolova is Product Manager at Telerik’s DevTools division. She joined the company back in the beginning of 2008 as a Support Officer and has since occupied various positions at Telerik, including Senior Support Officer, Team Lead at one of the ASP.NET AJAX teams and Technical Support Director. Iana’s main interests are web development, reading articles related to geography, wild nature and latest renewable energy technologies.