Adrian P Adrian P - 1 month ago 7
Sass (Sass) Question

In SASS is there any way to reference the selectors value inside an extendable selector?

In SASS I want to set hover and focus pseudo classes for a button to use the normal color of the button inside the selector that extends %mybutton - that way I don't have to declare it for every type of button. Basically I want to know some way to refer to the 'child' selector that will inherit this selector in an abstract way.

For example:

%mybutton {
padding: 6px 20px;
border-radius: 2px;

&:hover, &:focus {
color: <use selectors color>;
outline: none;
}
}

button.btn-white {
@extend: %mybutton;
background-color: white;
color: black;
}

button.btn-blue {
@extend: %mybutton;
background-color: blue;
color: white;
}


Is this possible at all?

Answer

yes, this should be possible though @mixin function of Sass. [Sass Documentation #mixin] I am using a similar construct to build my classes and extend them by e.g. transitions-prefixes. The same rules/construct can be take to build your "own" Rule with Variable implementation.

I've always a "core" folder and including my mixin functions and variables in. In this example I show you the function "vendor-prefix" and "placeholder". For your solution look further below.

My Examples

/* Vendor Prefixes */
@mixin vendor-prefix($name, $argument) {
  -webkit-#{$name}: #{$argument};
  -ms-#{$name}: #{$argument};
  -moz-#{$name}: #{$argument};
  -o-#{$name}: #{$argument};
  #{$name}: #{$argument};
}


/* Placeholder */
@mixin placeholder {
  &::-webkit-input-placeholder {@content}
  &:-moz-placeholder           {@content}
  &::-moz-placeholder          {@content}
  &:-ms-input-placeholder      {@content}
}

/* Your new Function to extend the hover, focus statements */
@mixin button-effects($color_on_hover){
     &:hover, &:focus {
         color: #{$color_on_hover);  
     }
}


To use them in a class, you can do the following.
.your_class {
   display:block; width:20px; height:20px;
   @include('transition', 'all .3s');
}

Solution for your case

I've edited a little bit, so the function provides 3 Parameters for default color, hover color and the background-color. I Think this can be usefull in most of the use cases you try to accomplish.

// Your Mixin function for extension
// @param   $color_default      Default Color state of your Button
// @param   $color_on_hover     Color on hovering your element
// @param   $background_color   Background Color of your Button element (in case of you need)
@mixin btn_build($color_default, $color_on_hover, $background_color){
    padding: 6px 20px;
    border-radius: 2px;
    color: #{$color_default};
    background-color: #{$background_color};

    &:hover, &:focus {
      color: #{$color_on_hover};
      outline: none;
    }
}


// Button base class
.button {
   display:inline-block;
   height:34px; line-height:34px;
}

// Button white
.button.btn-white {
    @include btn_build('black', 'red', 'white');
}

// Button blue
.button.btn-blue {
    @include btn_build('black', 'white', 'blue');
}

Compiled example code

Actually without compressing, to make it a little bit readable. By default if you compile you may use compression on. E.g. with ruby sass compiler I use this:

sass --watch source:dist --style=compressed

.button {
  display: inline-block;
  height: 34px;
  line-height: 34px; }

.button.btn-white {
  padding: 6px 20px;
  border-radius: 2px;
  color: black;
  background-color: white; }
  .button.btn-white:hover, .button.btn-white:focus {
    color: red;
    outline: none; }

.button.btn-blue {
  padding: 6px 20px;
  border-radius: 2px;
  color: black;
  background-color: blue; }
  .button.btn-blue:hover, .button.btn-blue:focus {
    color: white;
    outline: none; }
Comments