typeplate / starter-kit

Typeplate is a “Typographic Starter Kit.” We don’t make aesthetic design choices, but define proper markup with extensible styling for common typographic patterns. A stripped-down Sass library concerned with the appropriate technical implementation of design patterns—not how they look.
http://typeplate.com
Other
653 stars 60 forks source link

Unable to extend classes inside media queries #27

Closed craigmdennis closed 10 years ago

craigmdennis commented 10 years ago

Sometimes you want to be able to use a smaller font for a heading on a small screen and a larger on on large screens while still keeping body copy relatively stable.

Currently you are unable to @extend the classes within a new media query context.

Is there some way we can use @mixins instead and bypass this issue?

.heading {
  @extend .alpha;
}

@media( min-width: 768px; ) {
  .heading {
    @extend .giga; // Currently not allowed
  }
}
.heading {
  @include alpha;
}

@media( min-width: 768px; ) {
  .heading {
    @include giga; // Works fine
  }
}

The only downside I can see is overriding styles from the previous media context, but I think that's ok.

grayghostvisuals commented 10 years ago

I'm still mulling this over. Not sure how I feel about it just yet. Any other options or suggestions you might have besides a mixin were not thinking of still?

mistergraphx commented 10 years ago

Hi, this is a Sass known issue @extend and placeholders don't work as expected in media-queries : http://www.sitepoint.com/cross-media-query-extend-sass/ Hugo Giraudel point a hack to this in this article ...

in my projects i use @mixin and no hacks if possible ... and i've stop to over used placeholders.

grayghostvisuals commented 10 years ago

@mistergraphx Yeah, I'm aware of the faults with Sass extends. I'm just talking out loud to figure out any other options we're not thinking of ATM.

craigmdennis commented 10 years ago

The only way I have got this to work in an acceptable way for me is to use SASS maps.

The implementation is a different as I have taken the core principles and created my own typography kit.

$scale: (
  tera: 91,
  giga: 72,
  mega: 60,
  alpha: 48,
  bravo: 40,
  charlie: 32,
  delta: 24,
  echo: 21,
  foxtrot: 18,
  golf: 14,
  hotel: 12
);
h1 {
  @extend .charlie;

  @media( min-width: 768px; ) {
    font-size: rem( map-get($scale, mega) );
  }
}

Where rem() is a simple conversion utility.

This doesn't account for margins or line-height and I could be completely wrong but hey, call it a work-in-progress.

Hopefully this might spark some ideas for a way forward; some kind of reusable utility that's used in the initial creation of the classes but also can be called independently.

grayghostvisuals commented 10 years ago

@craigmdennis I really like the path you're on. Code below is pretty close to what I might integrate into the starter kit. It is the progress I have currently for the namespacing branch. Demo http://codepen.io/grayghostvisuals/full/33b5ba511ab59981b83e34261b9d9bce

$typl8-serif-boolean: true !default;
$typl8-custom-font: false !default;
$typl8-font-family: if($typl8-serif-boolean, serif, sans-serif) !default;
$typl8-font-weight: normal !default;
$typl8-line-height: 1.65 !default;
$typl8-font-size: 112.5 !default;
$typl8-font-base: 16 * ($typl8-font-size/100) !default;
$typl8-measure: $typl8-font-base * $typl8-line-height;
$typl8-prefixes: -webkit-, -moz-, -ms-, '';

// Use modularscale.com to generate a list of font-sizes
$typl8-scale: (
  tera: 91,
  giga: 72,
  mega: 60,
  alpha: 48,
  bravo: 40,
  charlie: 32,
  delta: 24,
  echo: 21,
  foxtrot: 18,
  golf: 14,
  hotel: 12
);

// Assign sizes to elements
$typl8-headings: (
  h1: mega,
  h2: alpha,
  h3: bravo,
  h4: charlie,
  h5: delta,
  h6: echo
);

$typl8-typescale-unit: rem !default;

@function context-calc($scale, $base, $value) {
    @return ($scale/$base)#{$value};
}

@function measure-margin($scale, $measure, $value) {
    $pixelValue: $measure/$scale;
    $remValue: $pixelValue * $typl8-font-base;

    @if $value == rem {
        @return $pixelValue#{$value};
    } @else if $value == em {
        @return ($remValue/$scale)#{$value};
    } @else {
        @return $remValue#{$value};
    }
}

%hN {
    text-rendering: optimizeLegibility; // voodoo to enable ligatures and kerning
    line-height: 1; // this fixes huge spaces when a heading wraps onto two lines
    margin-top: 0;
}

@mixin type-scale($scale, $base, $value, $measure:"") {
    @if $value == rem {
        font-size: $scale#{px};
        font-size: context-calc($scale, $base, $value);
    } @else if $value == em {
        font-size: context-calc($scale, $base, $value);
    } @else {
        font-size: $scale#{px};
    }

    @if $measure != "" {
        @if $value == rem {
            margin-bottom: measure-margin($scale, $measure, $value: px);
            margin-bottom: measure-margin($scale, $measure, $value);
        } @else if $value == em {
            margin-bottom: measure-margin($scale, $measure, $value: em);
        } @else {
            margin-bottom: measure-margin($scale, $measure, $value);
        }
    }
}

@mixin scale() {
  @each $name, $size in $typl8-scale {
    .#{$name} {
      @extend %hN;
      @include type-scale(
        $size,
        $typl8-font-base,
        '#{$typl8-typescale-unit}',
        $typl8-measure
      );
    }
  }
}

@mixin headings() {
  @each $h, $size in $typl8-headings {
    #{$h} {
      @extend .#{$size};
    }
  }
}

@include headings;
@include scale;

.title {
  @extend .bravo;

  @media( min-width: 768px ) {
    @include type-scale(
        map-get($typl8-scale, tera),
        $typl8-font-base,
        '#{$typl8-typescale-unit}',
        $typl8-measure
      );
  }
}

.sub-title {
  @extend .charlie;

  @media( min-width: 768px ) {
    @include type-scale(
        map-get($typl8-scale, mega),
        $typl8-font-base,
        '#{$typl8-typescale-unit}',
        $typl8-measure
      );
  }
}
grayghostvisuals commented 10 years ago

This is now integrated in the namespacing branch. Thanks for the idea to use maps. Works out quite well.