Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
894 views
in Technique[技术] by (71.8m points)

css - How can I add additional information to an attribute selector via nesting in Sass?

I'm trying to avoid "class'itis" and leverage SASS nesting to achieve the following CSS output:

a[class^="utility-button"], a[class*=" utility-button"] { //some shared css rules}
.utility-button-one {//some unique css rules}
.utility-button-two {//some unique css rules}

This is what i'd like to be able to do (what i've currently tried):

a[class^="utility-button"], a[class*=" utility-button"] {
    //some shared css rules

    &-one {
        //some unique css rules
    }
    &-two {
        //some unique css rules
    }
}

Now I know that what that would output if it compiled would technically be:

a[class^="utility-button"], a[class*=" utility-button"] { //some shared css rules}
a[class^="utility-button"]-one {//some unique css rules}
a[class^="utility-button"]-two {//some unique css rules}
a[class*=" utility-button"]-one {//some unique css rules}
a[class*=" utility-button"]-two {//some unique css rules}

Which clearly won't work.

Is there any way round this - it would be awesome not to have to add two classes to every <a> tag i wish to inherit the utility button styles depending on a second class.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The parent selector cannot be used that way, it only contains a reference to the previous selector. Sass has no way of targeting the contents of an attribute selector (at least, not outside of whatever string manipulation functions are currently available).

The best you can do is either write a custom function or use a content aware mixin to do the dirty work for you with variables. Here's what a mixin version might look like (assuming you want to keep using nesting):

@mixin my-sel($append: false) {
    $class: if($append, selector-append(&, $append), &);
    @at-root a[class^="#{$class}"], a[class*=" #{$class}"] {
        @content;
    }
}


utility-button {
    @include my-sel {
        /* some shared css rules */
    }

    @include my-sel(-one) {
        /* some unique css rules */
    }
    @include my-sel(-two) {
        /* some unique css rules */
    }
}

Output:

a[class^="utility-button"], a[class*=" utility-button"] {
  /* some shared css rules */
}
a[class^="utility-button-one"], a[class*=" utility-button-one"] {
  /* some unique css rules */
}
a[class^="utility-button-two"], a[class*=" utility-button-two"] {
  /* some unique css rules */
}

If you need to be able to nest this into other selectors, then it gets quite a lot more complicated:

@function class-to-attribute-selector($class) {
    // the following line is completely optional, but you definitely need the @return
    $class: if(str-index($class, '.') == 1, str-slice($class, 2), $class);
    @return #{'[class^="#{$class}"]'}, #{'[class*=" #{$class}"]'};
}

@mixin class-sel {
    $sel-list: &;

    $new-sel: ();
    @each $sel in $sel-list {
        @if length($sel) > 1 {
            $s: ();
            @for $i from 1 to length($sel) {
                $s: append($s, nth($sel, $i));
            }
            $class: nth($sel, length($sel));
            $new-sel: append($new-sel, selector-nest($s, class-to-attribute-selector($class)));
        } @else {
            $new-sel: join($new-sel, class-to-attribute-selector(nth($sel, 1)));
        }
    }

    @at-root #{$new-sel} {
        @content;
    }
}

.foo {
    .utility-button {
        @include class-sel {
            /* some shared css rules */
        }

        &-one {
            @include class-sel {
                /* some unique css rules */
            }
        }
        &-two {
            @include class-sel {
                /* some unique css rules */
            }
        }
    }
}

.bar {
    @include class-sel {
        /* other rules */
    }
}

Output:

.foo [class^="utility-button"], .foo [class*=" utility-button"] {
  /* some shared css rules */
}
.foo [class^="utility-button-one"], .foo [class*=" utility-button-one"] {
  /* some unique css rules */
}
.foo [class^="utility-button-two"], .foo [class*=" utility-button-two"] {
  /* some unique css rules */
}

[class^="bar"], [class*=" bar"] {
  /* other rules */
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...