Skip to content

Instantly share code, notes, and snippets.

@JawsomeJason
Last active August 29, 2019 07:12
Show Gist options
  • Save JawsomeJason/d2107285b6e10315dd6bc055115647fe to your computer and use it in GitHub Desktop.
Save JawsomeJason/d2107285b6e10315dd6bc055115647fe to your computer and use it in GitHub Desktop.
Sass Mixin to generate `@element` EQCSS Element Queries
/// Helper for EQCSS Element Queries `@element`
///
/// @author Jason Featheringham
/// @link https://gist.github.com/thejase/d2107285b6e10315dd6bc055115647fe Code source
/// @link http://elementqueries.com/ Plugin to parse EQCSS
/// @link https://gist.github.com/tomhodgins/6237039fa07c2e4b7acd1c8b0f9549a9 EQCSS syntax
///
/// @param {String} $scope (&) - Optional scope. Defaults to current context
/// @param {List} $conditions (()) - 1+ of Maps of EQCSS conditions
/// @content rules to enclose in element query
///
/// @output rules wrapped by `@element` query
///
/// @example replicate multiple scoped query example from http://elementqueries.com/#scoped-queries-and-multiple-conditions
/// .scoped-multiple {
/// @include element((min-width: 350px), (max-width: 450px)) {
/// eq_this { // current context
/// background: gold;
///
/// > b {
/// color: red;
/// }
///
/// &:hover {
/// background: orange;
/// }
/// }
/// }
/// }
/// // => @element ".scoped-multiple" and (min-width: 350px) and (max-width: 450px) {
/// // eq_this {
/// // background: gold;
/// // }
/// // eq_this > b {
/// // color: red
/// // }
/// // eq_this:hover {
/// // background: orange;
/// // }
/// // }
@mixin element($conditions...) {
$selector: &;
$joined-conditions: ();
// at least one EQCSS condition is required
@if length($conditions) < 1 or type-of(nth($conditions, length($conditions))) != map {
@error 'element query must include at least one condition';
}
// flatten and join conditions into single string
@for $i from 1 through length($conditions) {
$condition: nth($conditions, $i);
// if a selector (string) wasn't specified at the beginning of the arguments, this will be the current context
@if $i == 1 and type-of($condition) == string {
$selector: $condition;
}
@else if type-of($condition) == map {
// join each with ' and '
@each $key, $value in $condition {
$joined-conditions: $joined-conditions + if(length($joined-conditions) > 0, ' and ', '');
$joined-conditions: $joined-conditions + '(#{$key}: #{$value})';
}
}
@else { @error 'element query conditions must be a map'; }
}
$element-query: unquote("'#{$selector}' and #{$joined-conditions}");
// Needs to be placed outside of current context to work
@at-root {
// @element syntax doesn't parse with sass, so send as raw string
@include _raw("@element #{inspect($element-query)} {");
@content;
@include _raw("}");
}
}
/// Insert unparsed string
/// @author Bill Criswell
/// @link http://stackoverflow.com/a/24085750/641553
///
/// @param {strong} $string - String to include
///
/// @output Unparsed string
///
/// @example Insert non-standard CSS include
/// @include raw('{% include "hubspot/styles/responsive/required_base.css" %}');
/// // => /**/{% include "hubspot/styles/responsive/required_base.css" %}/**/
@mixin _raw ($string) {
$string: '*/#{$string}/*';
/*#{$string}*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment