search
HomeWeb Front-endCSS TutorialSelector Specificity with CSS Preprocessors

Selector Specificity with CSS Preprocessors

Key Points

  • Selector specificity is a recurring problem in medium and large projects that require careful management and understanding. Tools such as interactive calculator and Sass' mixin can help understand and manage specificity.
  • BEM (block, element, modifier) ​​method is a powerful tool for maintaining consistent specificity. By using class names for each styled element, the specificity of each selector remains the same, eliminating the problem of overly specific selectors. However, BEM may not be suitable for all types of projects, especially those that non-developers may need to write partial HTML.
  • CSS preprocessors such as LESS, Sass, and Stylus provide solutions to specific problems. One way is to add an existing selector with a class, attribute, ID, or type selector to improve its specificity. This method has limitations because once the heaviest selector is used, it cannot be overwritten unless a new, heavier selector is created.
  • Another approach is self-chain selector, which works with ID, class, and attribute selectors. This method provides an almost infinitely scalable way to override any selector, but does not work with type selectors. By using the parent reference selector, the same selector can be linked to itself multiple times, each time increasing its specificity.

Selector specificity is a real problem for most medium and large projects, and like any other frequently repeated coding issues, it needs to be handled carefully. Even CSS-Tricks has a recent article on how to keep CSS specificity low. Before you try to use !important, let me remind you: > CSS/Daily Tips: If everything is !important, nothing is !important. ——Tony Nelson (@tonynelson19) November 18, 2010

CSS specificity is not complicated, but the community has done a lot of work to make it as easy to understand as possible, writing guides by using analogies to Fish and Star Wars or using poker terms. There are interactive calculators available online, and even Sass' specific mixin, which allows you to check and output the exact specificity values ​​of the selector. In CSS-specific strategies, the simpler the better, the specific solution in this article (which may feel a little clumsy) is suitable for situations where the architecture does not allow for simple fixes. When deciding which approach is best for your project, apply your judgment and ultimately try to strike the perfect balance between a clean and easy-to-maintain CSS.

Method 0 – BEM

BEM is not just a naming convention, it is a front-end toolkit invented by Yandex, with the idea of ​​being closer to object-oriented programming. In practice, this means using the class name for everything you want to style. While “not casing in a cascading stylesheet” may sound ridiculous to some, avoid using type selectors when creating modules that should be easy to maintain, portable, self-sufficient, easy to modify and extensible And the idea of ​​avoiding nesting is very helpful. However, one of the main advantages of the BEM method is that it keeps the specificity of each selector unchanged, so there are almost no problems caused by overly specific selectors, which is why this method is the No. 0 method— If you adopt it, you actually eliminate any future issues with selector specificity in your project.

Specification of rules

Since you will only use a single class for everything you write, the specificity of each selector will be 0,1,0

BEM is not the answer

There are countless success stories about using BEM's front-end architecture, however, despite its popularity, BEM is not suitable for specific types of projects. It seems to be perfect for front-end developers to be the only project to write HTML. However, if you write content for a CMS for at least part of the content editor, BEM will be severely restricted. The pure form of BEM does not allow nesting and type selectors, such as .Section--dark > a (for example, to make it lighter), but instead requires you to invent a class for the anchor tag. This leads to a problem - the content editor will insert the default link through the graphical interface, which can cause the link to be nearly invisible. This may also apply to all paragraphs, lists, or images in a specific section. Sometimes it is necessary to be able to write pure HTML content without classes, in which case the solution is to have the parent styling it with a descendant selector. This use of cascading allows context flexibility—it has a custom style when something is in a different context. So we need a practical solution for situations where we cannot use pure BEM, which is quite common. CSS preprocessors can help us here, and all 3 popular preprocessors – LESS, Sass and Stylus – are able to simplify our work when we need to override the selector with a more specific selector.

Method 1 – Use the selector to add prefix

When you encounter specificity problems and want to make a selector heavier, you can add a class, attribute, ID, or type selector before an existing selector. In this way, you can slightly increase specificity. Although this feature is mainly used to locate IE using the conditional html tag, it has more features to be developed. Parent Reference Selector (&) in CSS Preprocessor allows us to easily add selector prefix to make it heavier, so we can do the following:

<code>.class {
  body & {
    foo: bar;
  }
}</code>

Created CSS:

<code>.class {
  body & {
    foo: bar;
  }
}</code>

You may want to use the html or body tag to prefix, but you can also use some more specific content that exists on the page, such as .page, #wrapper, html[lang], etc. Sass allows you to place prefixed selectors in variables when changes occur in the future. In addition, for large projects, it may be worth creating a set of prefixed selectors with different weights:

<code>body .class {
  foo: bar;
}</code>

This will generate:

<code>$prepend1: "html &";
$prepend2: "#wrapper &";

.selector {
  #{$prepend1} {
    background: #cacaca;
  }
  #{$prepend2} {
    background: #fefefe;
  }
}</code>

Other popular preprocessors such as LESS and Stylus also offer this feature.

Specification of rules

Adding prefixes our original class selector 0,1,0 with type selector will result in 0,1,1, and prefixes with ID – 1,1,0. The downside here is that once you add a selector prefix with the heaviest selector in your code (i.e. #wrapper), you can't override it anymore unless you invent a new, heavier selector, And this is not always possible.

Method 2 – Self-chain selector

Adding selector prefix is ​​useful, but it is not an infinitely scalable solution – you may have only limited ways to locate the parent. Additionally, once you prefix multiple selectors with the heaviest option in your code, you will limit options to resolve specificity issues later (especially if you use ID). The front-end community has recently been reminded of a very useful CSS feature – self-chain selectors to improve their specificity. Self-chain selectors are suitable for ID, class, and attribute selectors, but not for type selectors. However, if you mainly use classes to style content, the self-chain selector provides you with an infinitely scalable way to override any selector. With the parent reference selector, you can easily link the same selector to itself multiple times (this applies to ID, class, and attribute selectors, but not to type selectors). However, you need to insert each & after the first one, the minimum requirement is Sass 3.4:

<code>html .selector {
  background: #cacaca;
}
#wrapper .selector {
  background: #fefefe;
}</code>
<code>.selector {
  {&} {
    background: #cacaca;
  }
  {&}{&} {
    background: #fefefe;
  }
}</code>

Similarly, you can do this using LESS and Stylus. If this is too ugly for your taste, you can always create a mixin that iteratively improves the specificity of any single selector. This mixin uses some advanced features and also requires Sass 3.4:

<code>.selector.selector {
  background: #cacaca;
}
.selector.selector.selector {
  background: #fefefe;
}</code>

Created CSS:

<code>@mixin specificity($num: 1) {
  $selector: &;
  @if $num > 1 {
    @for $i from 1 to $num {
      $selector: $selector + &;
    }
    @at-root #{$selector} {
      @content;
    }
  } @else {
    @content;
  }
}

.selector {
  @include specificity(2) {
    background: #cacaca;
  }
  @include specificity(3) {
    background: #fefefe;
  }
}</code>

You can create the same mixin in Stylus, unfortunately there is no easy way to create such mixin in LESS.

Specification of rules

The self-chain increases the selector's specificity from 0,1,0 to 0,2,0, and so on, making it almost infinitely scalable.

Final Thoughts

The next natural step in dealing with specificity issues in our smarter CSS than ever is to create a way to identify conflicting statements, using something like David Khourshid's Sass mixin for each entity Specificity, then automatically use one of the above methods to improve specificity. Maybe I'm too optimistic about my dream of self-aware stylesheets, but I think the complex logic in our code will increase as CSS preprocessors develop. Which of the above methods will you use next time you need to deal with specificity issues? What other strategies do you use to solve your specificity problems?

FAQs about CSS preprocessor and selector specificity

What is the selector specificity in the CSS preprocessor?

Selector specificity is a concept in CSS that determines which styles are applied to elements when conflicting rules exist. It is a weight system assigned to different type selectors (such as IDs, classes, and type selectors). In CSS preprocessors such as Sass or Less, this concept remains the same. However, these preprocessors provide additional functionality such as nesting, which affects the specificity of the selector.

How does nesting affect selector specificity in CSS preprocessors?

Nesting is a feature in the CSS preprocessor that allows you to write more organized and easier to read code. However, it also increases selector specificity. Each nesting level adds specificity, making the nested selector more specific than the parent selector. This is useful for overwriting styles, but can also lead to unexpected consequences if not managed properly.

How to calculate the specificity of selectors in CSS preprocessors?

The specificity of the selector is calculated based on the type of selector used. Generally, ID selectors are most specific, followed by class selectors, and then type selectors. Each type of selector is assigned different weights, and the total specificity is the sum of these weights. Some CSS preprocessors, such as Sass, provide functions for calculating selector specificity.

What does "&" mean in CSS styles in preprocessors such as Sass?

The "&" symbol is used in CSS preprocessors such as Sass to reference the parent selector in nested rules. This is useful for creating more specific selectors or applying styles to different states of an element, such as hover or active states.

How to use a dual selector in Sass to increase specific weights?

In Sass, you can improve its specificity by copying the selector. This is called a link or a double selector. For example, the specificity of .class.class will be higher than .class. However, this method should be used with caution, as it will make your CSS more difficult to maintain and overwrite.

What are the potential problems with high specificity in CSS preprocessors?

High specificity will make your CSS more difficult to maintain and cover. It can lead to so-called specificity conflicts, and you have to constantly improve the specificity of the selector to cover the previous style. This can cause CSS to swell and complex.

How to manage specificity in CSS preprocessors?

There are several strategies to manage specificity in CSS preprocessors. One is to use low specificity selectors as much as possible. Another is to avoid unnecessary nesting, as this increases specificity. You can also use the BEM (block, element, modifier) ​​method to keep specificity low and consistent.

Can I use !important to override specificity in CSS preprocessor?

Yes, you can use the !important rule to override specificity in the CSS preprocessor. However, this should be a last resort, as it will make your CSS harder to maintain and can lead to specific conflicts.

How does the order of selectors affect specificity in CSS preprocessors?

The order of selectors affects specificity in the CSS preprocessor. If the specificity of the two selectors is the same, the last selector that appears in the CSS will be applied. This is called source order specificity.

Can I use inline styles to override specificity in CSS preprocessor?

Yes, inline styles have the highest specificity in CSS and can override other styles. However, use them with caution, as they can make your CSS more difficult to maintain and can lead to inconsistent styles.

The above is the detailed content of Selector Specificity with CSS Preprocessors. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
@keyframes vs CSS Transitions: What is the difference?@keyframes vs CSS Transitions: What is the difference?May 14, 2025 am 12:01 AM

@keyframesandCSSTransitionsdifferincomplexity:@keyframesallowsfordetailedanimationsequences,whileCSSTransitionshandlesimplestatechanges.UseCSSTransitionsforhovereffectslikebuttoncolorchanges,and@keyframesforintricateanimationslikerotatingspinners.

Using Pages CMS for Static Site Content ManagementUsing Pages CMS for Static Site Content ManagementMay 13, 2025 am 09:24 AM

I know, I know: there are a ton of content management system options available, and while I've tested several, none have really been the one, y'know? Weird pricing models, difficult customization, some even end up becoming a whole &

The Ultimate Guide to Linking CSS Files in HTMLThe Ultimate Guide to Linking CSS Files in HTMLMay 13, 2025 am 12:02 AM

Linking CSS files to HTML can be achieved by using elements in part of HTML. 1) Use tags to link local CSS files. 2) Multiple CSS files can be implemented by adding multiple tags. 3) External CSS files use absolute URL links, such as. 4) Ensure the correct use of file paths and CSS file loading order, and optimize performance can use CSS preprocessor to merge files.

CSS Flexbox vs Grid: a comprehensive reviewCSS Flexbox vs Grid: a comprehensive reviewMay 12, 2025 am 12:01 AM

Choosing Flexbox or Grid depends on the layout requirements: 1) Flexbox is suitable for one-dimensional layouts, such as navigation bar; 2) Grid is suitable for two-dimensional layouts, such as magazine layouts. The two can be used in the project to improve the layout effect.

How to Include CSS Files: Methods and Best PracticesHow to Include CSS Files: Methods and Best PracticesMay 11, 2025 am 12:02 AM

The best way to include CSS files is to use tags to introduce external CSS files in the HTML part. 1. Use tags to introduce external CSS files, such as. 2. For small adjustments, inline CSS can be used, but should be used with caution. 3. Large projects can use CSS preprocessors such as Sass or Less to import other CSS files through @import. 4. For performance, CSS files should be merged and CDN should be used, and compressed using tools such as CSSNano.

Flexbox vs Grid: should I learn them both?Flexbox vs Grid: should I learn them both?May 10, 2025 am 12:01 AM

Yes,youshouldlearnbothFlexboxandGrid.1)Flexboxisidealforone-dimensional,flexiblelayoutslikenavigationmenus.2)Gridexcelsintwo-dimensional,complexdesignssuchasmagazinelayouts.3)Combiningbothenhanceslayoutflexibilityandresponsiveness,allowingforstructur

Orbital Mechanics (or How I Optimized a CSS Keyframes Animation)Orbital Mechanics (or How I Optimized a CSS Keyframes Animation)May 09, 2025 am 09:57 AM

What does it look like to refactor your own code? John Rhea picks apart an old CSS animation he wrote and walks through the thought process of optimizing it.

CSS Animations: Is it hard to create them?CSS Animations: Is it hard to create them?May 09, 2025 am 12:03 AM

CSSanimationsarenotinherentlyhardbutrequirepracticeandunderstandingofCSSpropertiesandtimingfunctions.1)Startwithsimpleanimationslikescalingabuttononhoverusingkeyframes.2)Useeasingfunctionslikecubic-bezierfornaturaleffects,suchasabounceanimation.3)For

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor