Search code examples
cssmixinsstylus

Add pseudo classes with Stylus CSS preprocessor


I am new to the Stylus CSS preprocessor, but what I have seen so far I really like. Anyway, I have the following css:

$link
    color #777
    display block

...
a.className, a.className:hover, a.className:visited
    @extends $link

$link is used elsewhere as well. This works just fine. However I am sure there must be some way to avoid having to repeatedly enter a.className in the line: 'a.className, a.className:hover, a.className:visited'. That is, what I would like to be able to do is something like:

a.className, &:hover, &:visited
    @extends $link

OR, say

anchor(className)
    @extends $link

where 'anchor' is a mixin that creates the selector. However my attempts at either approach haven't really been successful. The best I could come up with was:

a.className
    &:link
    &:hover
    &:visited
        @extends $link

While this works I am not sure it's any clearer than the original. Any guidance/help much appreciated!


Solution

  • In the interest of answering the question, you don't need a mixin here, since those generate attributes. You need a function that will a return a manipulated string, which can then be interpolated later:

    mono-link(className)
      states = 'link', 'hover', 'visited'
      parent = 'a.' + className
      retList = (parent)
      for state in states
        push(retList, parent + ':' + state)
      return join(',', retList)
    
    $link
      color #777
      display block
    
    {mono-link(someclass)}
      @extend $link
    

    yields

    a.someclass,
    a.someclass:link,
    a.someclass:hover,
    a.someclass:visited {
      color: #777;
      display: block;
    }
    

    Nevertheless, this really isn't CSS you should be writing, particularly the display: block part, since that would be inherited from the a.someclass selector.