In the era of the "classic" RadControls for ASP.NET modifying a skin required opening
~ / RadControls / [ControlName] / Skins / [SkinName] / styles.css
and making the necessary changes. The new
RadControls for ASP.NET AJAX (formerly known as "
Prometheus") by default use skins, which are embedded in the assembly. This simplifies deployment but sacrifices customization. Or does it?
Actually, making a change to an embedded skin of a RadControl for ASP.NET AJAX is quite easy, given that one keeps in mind a couple of notable things. Namely:
(1) Since the embedded skin cannot be modified, the custom styles need to be placed elsewhere. For example in a <style> tag in the <head> section of the page or in an external CSS file (no matter whether in a АSP.NET theme or not). Using external CSS stylesheets is highly recommended, so that structure and content are properly separated from presentation.
(2) The embedded skins are registered automatically on the web page using <link> tags, which are appended at the end of the <head> section of the web page source HTML. In other words, the embedded skins are always applied last by the browser.
Why does (2) matter? Browsers adhere to certain rules, when deciding which one of two (or more) conflicting CSS style declarations to apply. Simply put, if two CSS rules have the same specificity, the latter specified wins. (Very roughly stated, specificity is the number of HTML elements, CSS classes and Client IDs, which take part in a CSS selector. In turn, a selector is a single comma-separated chunk before the opening bracket "{" of a CSS rule. If there is only one chunk, there are no commas.)
So, since RadControls' embedded skins are always the last stylesheets to be appended, you must supply a rule with greater specificity in order to override an embedded skin style. Supplying a CSS rule with the same level of specificity will not work. Here is an example:
In the Default RadGrid skin there is a CSS rule:
| |
| .RadGrid_Default |
| { |
| background: #d4d0c8; |
| color: #333; |
| } |
The specificity of the CSS selector is
10 points (one CSS class is worth 10 points). If we want to override this CSS rule, we should use for example:
| |
| div.RadGrid_Default |
| { |
| background: yellow; |
| color: blue; |
| } |
The above selector has a specificity of
11 points (1 + 10) and this is enough to override the skin. Adding "div" to the selector is just a small trick - the RadGrid_Skin CSS class is always applied to divs, so the CSS selector will select the same HTML elements, but now the CSS rule has higher weight than the skin's rule.
Some people are aware that by using the !important clause one can a CSS rule of random specificity. For example:
| |
| .RadGrid_Default |
| { |
| background: yellow !important ; |
| color: blue !important ; |
| } |
However, using !important is not recommended, firstly because it is not needed, and secondly, because further overriding it later may become rather hard in certain occasions.
Here is another example, which discusses a slightly different aspect of skin overriding. We will use again RadGrid's Default skin:
| |
| .SelectedRow_Default |
| { |
| background: #4c4c4c ; |
| color: #fff ; |
| } |
(specificity 10)
As we mentioned earlier, we can override the above CSS rule by adding an appropriate HTML element to the selector:
| |
| tr.SelectedRow_Default |
| { |
| background: black ; |
| color: yellow ; |
| } |
(specificity 11)
However, this will influence all RadGrids with the Default skin in our web application. We might want to override only several instances of RadGrid.
In this case the smart thing to do is assign a custom CSS class to all RadGrids to be modified:
| <telerik:RadGrid CssClass="MyCustomClass" /> |
Now this CSS class can be used to create a custom CSS rule with a higher specificity:
| |
| .MyCustomClass tr.SelectedRow_Default |
| { |
| background: black ; |
| color: yellow ; |
| } |
(specificity 21)
Finally, here are some CSS specificity-related articles worth reading:
CSS Specificity Things You Should Know About
Cascading Order (W3C CSS Standard)
CSS: What Happens When a Conflict Occurs