Skip to content

Instantly share code, notes, and snippets.

@jakob-e
Created August 22, 2014 11:32
Show Gist options
  • Save jakob-e/c6739b61a4df0f6c1062 to your computer and use it in GitHub Desktop.
Save jakob-e/c6739b61a4df0f6c1062 to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
// ----
// Sass (v3.3.14)
// Compass (v1.0.0)
// ----
// ===========================================
//
// Extending Within Media Queries Revisited
// http://sassmeister.com/gist/e61a7e0cf08c82c1ad2a
//
// ===========================================
// External
// The content in this section is ment
// to be added in an external scss file
// ===========================================
// Define a global variable to keep the current
// breakpoint context
// Not ment to be manually edited.
// You could change it to something unlikely
// to be overridden like $_A2dklj_wdsd--dx
$_current-breakpoint-context : '' !global;
// Media - just my name for breakpoint
// @media is after all what is returned :)
@mixin media($breakpointlabels...){
// Loop thru passed breakpoint keys
@each $key in $breakpointlabels {
// Set the global flag to hold the label (eg. mobile).
// We need this to let the extend mixins know wich
// prefix to use.
//
// Because of the way Sass render CSS output all includes
// passed as @content will render inside the loop and
// hereby in the right context.
$_current-breakpoint-context:$key !global;
// Build media query
// Note! to enable breakpoints in em or other units
// include unit conversion https://github.com/jakob-e/unitconversion
// at the top of this page and shift to the outcommented lines.
$value:map-get($breakpoints,$key);
$min:if(length($value)>0, nth($value,1), null);
$max:if(length($value)>1, nth($value,2), null);
$mq :' all';
$mq : $mq + if($min>0 or $max>0,' and ','');
$mq : $mq + if($min>0,'(min-width:'+ $min+')','');
// $mq : $mq + if($min>0,'(min-width:'+ convert($breakpoints-units,$min)+')','');
$mq : $mq + if($min>0 and $max>0,' and ','');
$mq : $mq + if($max>0,'(max-width:'+$max+')','');
// $mq : $mq + if($max>0,'(max-width:'+convert($breakpoints-units,$max)+')','');
$mq : unquote($mq);
// Print media query
@media #{$mq} {
@content;
}
// Reset flag
$_current-breakpoint-context:'' !global;
}
}
// Mixin to create extends based on $name and context.
// We need the context to create unique extend names
// to avoid compile error.
@mixin new-extend($name){
%#{$_current-breakpoint-context + $name}{ @content; }
}
// Mixin to render the extends - like @extend %foo
// The ampersand hooks the extend to the parent
// selector(s)
@mixin extend($name){
& { @extend %#{$_current-breakpoint-context + $name}; }
}
// Mixin to handle extend creation loop and making sure
// we are also providing a root version of each extend
@mixin extends(){
@content;
@each $key, $value in $breakpoints {
@include media($key){
@content;
}
}
}
// ==============================================
// Local SCSS
// ==============================================
// Define breakpoints
// I like to work with no overlaps as they tend
// to cause errors. Zeros will be omitted
$breakpoints:(
//Label : Min Max
all : 0 0,
mobile : 0px 640px,
tablet : 641px 960px,
desktop: 961px 1200px,
large : 1201px 0
);
$breakpoints-units:'em'; // not implemented in this example
// ==============================================
// Create extends
// To reduce the number of media query outputted
// in the CSS we make sure all of our extends
// are created at once and as a bundle in each
// media query.
//
// Note! as we are not using a list we are not
// limited to one instance of each extend as in
// normal extend behaviour...
// Can't see why you would do that though ;)
// ==============================================
@include extends(){
};
// This will add a extra set of media queries
// compared to the outcommented examble above
// Overhead:
// @media all and (max-width: 640px) { }
// @media all and (min-width: 961px) and (max-width: 1200px) { }
// Not good if creating grid systems etc!
//
@include extends(){
@include new-extend(almostforgotthisone) { content:'almostforgotthisone'; }
}
// At root level you can use normal extend
// or the include syntax
#test_a1 {
@extend %one;
@include extend(two);
}
#test_a2 {
@extend %one;
@include extend(two);
}
// Multiple nested extends
#test_b1 {
@include media(mobile){
@include extend(one);
@include extend(two);
@include extend(three);
}
}
// Multiple nested extends on multiple
// breakpoints
#test_b2 {
@include media(mobile,tablet){
@include extend(one);
@include extend(two);
@include extend(three);
}
}
#test_b3 {
@include media(tablet,desktop){
@include extend(one);
@include extend(two);
@include extend(three);
}
}
// Nested context and outside
#test_b4 {
&.foo{
@include media(all){ @include extend(two);}
}
@include media(mobile){ @include extend(two); content:'Not extended content';}
@include media(all){
@include extend(one);
@include extend(two);
@include extend(three);
}
content:'Regular content';
}
// Multiple wrapped extends
@include media(desktop, mobile){
#test_c1 { @include extend(one);
@include extend(two);
@include extend(three);
content:'Regular content';
}
#test_c2 { @include extend(one);
@include extend(two);
@include extend(almostforgotthisone); }
}
"#test_a1" failed to @extend "%one".
The selector "%one" was not found.
Use "@extend %one !optional" if the extend should be able to fail.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment