Unable to extend classes inside media queries
Closed this issue · 6 comments
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.
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?
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.
@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.
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.
@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
);
}
}
This is now integrated in the namespacing branch. Thanks for the idea to use maps. Works out quite well.