CHS
CHS

Reputation: 965

Why does jQuery UI use nested css classes?

Why does jQuery UI write CSS like this:

.ui-dialog .ui-dialog-titlebar-close {}
.ui-dialog .ui-dialog-content {}

Since their class names are so descriptive I would think it faster and just as unlikely to have any collisions if they did this:

.ui-dialog-titlebar-close {}
.ui-dialog-content {}

It seems to me they are nesting classes unnecessarily and causing the browser to do more work but I wonder if there's a good reason for it that I'm not aware of. Does anyone know why they nest the classes as they do?

Upvotes: 3

Views: 293

Answers (3)

Oleg
Oleg

Reputation: 24988

You're correct about the fact that shallow, preferrably one-level selectors are preferable - at least from the performance perspective, at least in theory. However in most cases rendering engine optimizations offset the otherwise miniscule performance overhead.

This is when ease of maintenance, readability and size of the stylesheet kicks in. Reduced specificity allows to recycle "partial" classes - if you look at the rendered markup, .ui-dialog will have a whole bunch of other classes applied to it:

ui-dialog ui-widget ui-widget-content ui-corner-all ui-front ui-draggable ui-resizable

Would it have been preferable to instead have all the properties applied in one rule? Definitely not from the developer point of view, that approach would have made it into a maintenance nightmare. Imagine changing a single presentational property and then having to backdate it to all "specific" rules like in your example!

The reasoning for qualifying the ansector selector (e.g. .ui-dialog .ui-dialog-content) is a lot more trivial, if not immediately obvious - to increase specificity of these selectors. For instance, .ui-helper-reset class basically anulls any previously set style since the rule is declared at the bottom of the css file:

.ui-helper-reset {
    border: 0 none;
    font-size: 100%;
    line-height: 1.3;
    list-style: none outside none;
    margin: 0;
    outline: 0 none;
    padding: 0;
    text-decoration: none;
}

To override any of those properties, a higher-specificity selector has to be used.

Personally I dislike this pattern - and I hope that code consistency contributed more to the reasoning behind such class structure.

Upvotes: 1

Jared
Jared

Reputation: 12524

They do this to be specific.

The element with the class .ui-dialog-content also has several other classes such as .ui-widget-content.

<div id="dialog" class="ui-dialog-content ui-widget-content">

To ensure that the rules of .ui-dialog-content trump those of the other classes they add .ui-dialog infront.

This is evident when you inspect the element. The background and border rules of .ui-widget-content will be overridden.

.ui-dialog .ui-dialog-content {
    background: none repeat scroll 0 0 transparent;
    border: 0 none;
    overflow: auto;
    padding: 0.5em 1em;
    position: relative;
}

.ui-widget-content {
    background: url("images/ui-bg_highlight-hard_100_f2f5f7_1x100.png") repeat-x scroll 50% top #F2F5F7; /* Overridden */
    border: 1px solid #DDDDDD; /*Overridden*/
    color: #362B36;
}

Upvotes: 1

khollenbeck
khollenbeck

Reputation: 16157

Most likely because the CSS for .ui-dialog-titlebar-close and .ui-dialog-content is reusable. So basically they are ensuring these classes will only inherit specific styles to the dialog when they are children of .ui-dialog

Upvotes: 2

Related Questions