Sunday, October 19, 2014

Quick Tip: Forcing a CSS override

If you are using OneUI in your XPages application, then you know sometimes it just doesn’t do what you want it to do. Trying to get it to behave can be frustrating, this tip will help when OneUI overides your custom style for reasons unknown.

The Problem

In my case, I was trying to make the labels of a radio button group appear disabled. Only the buttons themselves would look disabled, but the labels looked the same as when the control was enabled.
I don't feel that there is enough distinction between Enabled on the left, and Disabled on the right.
The radio button group control does attempt to make it easy by having a property to enter the styleClass for when the control is disabled or enabled.

XPages makes it easy for you to specify a disabled styleClass
This works fine for most of the CSS, except for some reason the color is overwritten as shown in the left picture below. I spent a lot of time playing with multiple CSS selectors with no success until I discovered how to force the CSS to override.
For some reason the "color" is overwritten by OneUI

The Solution

The way to override is to add “!important” after the attribute you don’t want to be overwritten. In my case, the only attribute that wasn’t behaving was the color. After I added !important, it worked exactly like I wanted. In the right picture above shows what this one change gives you.

Here is the Before code:

.radio-disabled {
font-size:14pt;
font-family:Calibri;
color: #AFAEB5;
}

Here is the After code:
.radio-disabled {
font-size:14pt;
font-family:Calibri;
color: #AFAEB5 !important;
}

The Finished Result

Enabled on the left, disabled on the right. It is easy to distinguish which is which.

Final Thoughts

Perhaps this is old news to some who read this. Though, in my office, none of the four XPages developers knew about this before. I hope that this helps other XPagers who wrestle with OneUI.

I will add that, this should be something that is used sparingly. In my case, only the specific class of “.radio-disabled” is using it. I can see that you could really mess your UI by overusing !important. Here is a related article called “Don’t Use !important” that explains some of the pitfalls.

4 comments:

  1. Brian Gleeson (IBM)October 20, 2014 at 3:26 AM

    The reason that color is getting over-ridden in this case, is due to CSS specificity rules. The more specific a CSS selector is, the more weight it has, and it will over-ride less specific CSS. In the example, the OneUI CSS uses 1 class selector + 2 element selectors, whilst yours only uses 1 class selector. Thus, the OneUI CSS has more weight, and overrides your CSS, with color being the only overlapping property. Using "!important" is a brute force method of overriding all CSS to make sure yours is applied. But as you have said, it's better to avoid using that. It would be better to use higher specificity to override the CSS, so in this example, define your CSS with something like ".lotusForm td label.radio-disabled". That has 2 class selectors and 2 element selectors, and will override the OneUI CSS without resorting to the use of !important. More info on css specificity: http://www.smashingmagazine.com/2010/04/07/css-specificity-and-inheritance/

    ReplyDelete
    Replies
    1. Brian, Thanks for your very informative comment. At first, I tried several combinations of defining the classes together and couldn't find the right combination apparently.

      Delete
    2. Brian Gleeson (IBM)October 20, 2014 at 7:34 AM

      No problem. Believe me when I say I've been in similar situations myself, and !important was the only way out

      Delete
  2. I'm not a fan of using !important but have also come across situations where i have had no choice.
    I've used it in the past style sheet to override some inline styling i had no control over.

    ReplyDelete