Mixin to Qualify a Selector

There is no easy way of qualifying a selector from within its associated ruleset. By qualifying I mean prepending an element name (e.g. a) to a class (e.g. .btn) so that a ruleset gets specific to a combination of an element selector and a class selector (e.g. a.btn) for instance.

As of today, the best (and so far only valid way) to do so is as follow:

.button {
  @at-root a#{&} {
    // Specific styles for `a.button`
  }
}

Wow, definitely not really elegant, is it? Ideally, you might want to hide this kind of horrific syntax behind a mixin so that you keep a clean and friendly API, especially if you have rookie developers in your team.

Doing so is extremely simple of course:

/// Since the current way to qualify a class from within its ruleset is quite
/// ugly, here is a mixin providing a friendly API to do so.
/// @author Hugo Giraudel
/// @param {String} $element-selector - Element selector
@mixin qualify($element-selector) {
  @at-root #{$element-selector + &} {
    @content;
  }
}

Now, rewriting our previous snippet:

.button {
  @include qualify(a) {
    // Specific styles for `a.button`
  }
}

Much better, right? Still, qualify can sound a bit tricky for inexperienced Sass tinkerers. You could provide an alias when a more descriptive name, such as when-is.

/// @alias qualify
@mixin when-is($args...) {
  @include qualify($args...) {
    @content;
  }
}

One final example:

.button {
  border: none;
  
  // Qualify `.button` with `button`
  @include qualify(button) {
    -webkit-appearance: none;
  }
  
  // Qualify `.button` with `a`
  @include when-is(a) {
    text-decoration: none;
  }
}

Comments

  1. User Avatar
    Dominick
    Permalink to comment#

    Can’t you just use a trailing ampersand after the a?

    • User Avatar
      Benjamin Reid
      Permalink to comment#

      Do you mean like?

      .button {
      
        a & {
        }
      }
      

      That’d produce:

      a .button { }
      
    • User Avatar
      Hugo Giraudel
      Permalink to comment#

      If you mean a&, it produces an error:

      Invalid CSS after “a”: expected “{“, was “&”
      “&” may only be used at the beginning of a compound selector.

      It will probably be fixed at some point but right now it doesn’t work.

  2. User Avatar
    AlienSKP
    Permalink to comment#

    You should end the internship of the guy who wrote that article.
    Don’t use mixin, use trailing ampersand as stated by previous 2 guys.
    CSS Tricks used to post serious articles..

    • User Avatar
      AlienSKP
      Permalink to comment#

      Goddamit I’m not woke up this morning lol

    • User Avatar
      AlienSKP
      Permalink to comment#

      discard this evil post of mine. It’s been written by the sleepy part of my brain

    • User Avatar
      Hugo Giraudel
      Permalink to comment#

      I am the so called “internship” by the way. :)

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag