whizark
10/12/2014 - 10:09 AM

Sass: Placeholder Factory(Mixin) based on the argumetns #sass

Sass: Placeholder Factory(Mixin) based on the argumetns #sass

<a class="button">A button</a>
<button class="button">Button button</button>
<a class="button-large">A button</a>
<button class="button-large">Button button</button>
a.button, a.button-large, button.button, button.button-large {
  display: inline-block;
  background: #f00;
  color: #fff;
}

a.button, a.button-large {
  text-decoration: none;
}

button.button, button.button-large {
  border: none;
}

a.button, button.button {
  padding: 6.5px;
  font-size: 13px;
}

a.button-large, button.button-large {
  padding: 14px;
  font-size: 28px;
}

a.button, button.button {
  padding: 6.5px;
  font-size: 13px;
}

a.button-large, button.button-large {
  padding: 14px;
  font-size: 28px;
}
// ----
// Sass (v3.4.5)
// Compass (v1.0.1)
// ----

// Sass: Flexible/Reusable Component Definition with clean output
//
// Other ideas: https://github.com/whizark/xass#ideas

// Component Definitions
// The base style for all elements
%button {
  display: inline-block;
  background: #f00;
  color: #fff;
}

// The base style for `a` element
a%button {
  text-decoration: none;
}

// The base style for `button` element
button%button {
  border: none;
}

// The Mixin for variable styles
@mixin button($font-size) {
  // Generate $id by the arguments.
  // Serializing arguments is more better way.
  $id: $font-size;

  // Dynamically define placeholder.
  // There is an issue that THE PLACEHOLDER IS DEFINED MORE THAN TWICE.
  // @if not placeholder-defined(button-#{$id}) {
  @at-root %button-#{$id} {
    padding: $font-size * .5;
    font-size: $font-size;
  }
  // }
  //
  // placeholder-defined() won't be implemented.
  // https://github.com/sass/sass/issues/901
  //
  // So we need to try to find other ways.
  // For example, store generated id into Map and check it.
  //
  // Or @buffer/@append might be help us.
  // https://github.com/sass/sass/issues/116

  // Extend base styles by the element type.
  @extend %button;

  // Extend the arguments-specific styles.
  @extend %button-#{$id};
}

// Use case
a.button {
  @include button(13px);
}

a.button-large {
  @include button(28px);
}

button.button {
  @include button(13px);
}

button.button-large {
  @include button(28px);
}
<a class="button">A button</a>
<button class="button">Button button</button>
<a class="button-large">A button</a>
<button class="button-large">Button button</button>