5

I have clickable elements which I am giving the pointer cursor to with a class. Someone hovers over, they see the pointer cursor as a visual cue that it's clickable. They click which performs an Ajax call. Since the Ajax call is an indeterminate length, I'm attempting to set it up so that the cursor becomes a "wait" cursor on Ajax start, and then reverts on Ajax stop.

HOWEVER... it seems that despite an "!important" declaration on the "wait" class, the pointer still has priority. The net result is that when someone clicks the item, they're not likely to move away from it. They'll just keep the mouse where it is and will wait. So the cursor doesn't get updated.

I have created some straight CSS to show that when you move into an element with pointer, even when it is NOT the "important" declaration, the pointer is taking precedence. Tested in Chrome and Firefox for Windows:

Here's the fiddle: http://jsfiddle.net/3NdYP/

And the relevant code contained therein (CSS truncated):

HTML:

<div id="fakeBody" class="wait">
    <table>
        <tr class="pointer">
            <td>Yup, a pointer row normally...</td>
        </tr>
    </table>            
</div>

CSS:

.pointer {
    cursor: pointer;
}

.wait {
    cursor: wait !important;
}

The "fakeBody" is just for the fiddle. In the real world scenario, it is the body element itself.

Greg Pettit
  • 10,749
  • 5
  • 53
  • 72
  • 4
    That is how it normally works. The `.pointer` is more specific to the element. You can instead make it as `.wait, .wait *` which would make it apply for all child elements of `.wait` also when the parent div has `class='wait'`. – Harry Jul 22 '14 at 15:51
  • 1
    You might benefit from the answer in this [Stackoverflow question](http://stackoverflow.com/questions/5805040/relationship-between-important-and-css-specificity). – Jmh2013 Jul 22 '14 at 15:52

3 Answers3

7

try this

   $(document).ajaxStart(function(){
    $('.pointer').addClass("wait");
}).ajaxComplete(function(){
    $('.pointer').removeClass("wait");
});
Deathmras
  • 312
  • 1
  • 9
7

Because .pointer is nested inside .wait, so its cursor declaration takes precedence. The same thing would happen for any other CSS declaration: background-color, for instance. If you're explicitly telling the child to have a different rule, that will override any inherited styles, even when defined with !important.

Ben Dyer
  • 1,656
  • 1
  • 12
  • 23
  • Thanks, Ben. Super useful to at least know what I did wrong. – Greg Pettit Jul 22 '14 at 15:54
  • That makes sense. I just came to this while wondering why when I had `body { font-size: '15px' !important }` specified, my user agent stylesheet kept changing it to 16px on tables. Your post explains why. Easy enough to fix by changing the selector to `body, body table`, but also very good to keep this point in mind as my application grows. – BobRodes Jun 21 '16 at 22:39
2

If the CSS engine encounters multiple styles that apply for the same element it tries to find out which one should apply. It follows specific rules, but most importantly tries to find the selector with the highest specificity and it looks for inheritance.

The specificity is the "weight" of the selector. Most important is the category of the selectors, inline styles have highest priority then come id, class and last type and some pseudo selectors. It counts the number of statements in each group, #id will have specificity 0-1-0-0 and .class span.other-class will have specificity 0-0-2-1 if the element is a span, has class .other-class and is wrapped by an element with class .class.

For your example both selector have the same specificity (0-0-1-0) in this case the inheritance aspect comes in place. The style of the innermost html element overrides all styles of elements above it.

So to fix this you can add a statement with higher specificity than .pointer for the tr element.

.wait, .wait .pointer {
    cursor: wait;
}

Or you can make sure that the innermost element will override the styles above. The * in the following css will ensure that the innermost td will be matched by the selector:

.wait, .wait * {
  cursor: wait;
}

The universal selector * does not have any specificity weight and should not yield any performance impact here (See https://stackoverflow.com/a/13432169/3778409).

Simon Zyx
  • 6,503
  • 1
  • 25
  • 37