/** * @name Base API * This are all the base API mixins that are exposed by gridle. */ /** * Specify a layout using a single call like in the example bellow * @param {Map} $layout The map layout wanted * @param {Map|List|String} [$context=null] The context in which to apply the layout * @example scss * body { * \@include g-layout(( * '#header' : 12, * '#sidebar' : 4 mobile 12, * '#content' : 8 mobile 12, * '#footer' : 12 * )); * } * * @author Olivier Bossel */ @mixin g-layout( $layout, $context : null ) { @include g-state($context) { @include g-row(); @each $sel, $l in $layout { > #{$sel} { @include gridle($l); } } } } /** * Apply some styling in a passed state * @param {Map|List|String} $states The states to apply the css for. Can be a state map, a list of states or a state name * @example scss * .my-cool-element { * // specify a register state name * \@include g-state(mobile) { * // your css code here... * } * // specify more than one register states * \@include g-state(mobile tablet) { * // your css code here... * } * // specify a min and max width * \@include g-state(200px, 500px) { * // your css code here... * } * // passing a state map (complexe usage) * \@include g-state(( * query : 'print only' * )) { * // your code here... * } * } * * @author Olivier Bossel */ @mixin g-state( $states, $has-parent : true ) { // check if is a min-max witdh query (compatibility layer) @if type-of($states) == number and type-of($has-parent) == number { // get a new state from settings passed $state : g-get-state(( min-width : $states, max-width : $has-parent )); // make a query @include g-state($state) { @content; } } @elseif type-of($states) == list or type-of($states) == string { // loop on each states : @each $state in $states { // make sure we have the state object $state : g-get-state($state); // make gridle state @include _g-state($state, $has-parent, true) { @content; } } } @elseif type-of($states) == map { // get a state from the passed one $state : g-get-state($states); // make gridle state @include _g-state($state, $has-parent, true) { @content; } } @else { @content; } } /** * Apply some css depending on the element size (element queries) * **Using this mixin requires that you import the ```gridle-eq.js``` file into your javascript code** * @param {Number} $size The size to take care of. If negative, mean lower than, if positive, mean greater than. * @param {Boolean} [$height=false] Set to true to handle height instead of width * @example scss * .my-cool-element { * \@include g-eq(-400px) { * // your css that will be applied when element * // is between 0 and 399px wide * } * } * * @author Olivier Bossel */ @mixin g-eq( $size, $height : false ) { $op : "min-width"; @if $height { @if $size < 0 { $op : "max-height"; $size : $size * -1; } @else { $op : "min-height"; } } @else { @if $size < 0 { $op : "max-width"; $size : $size * -1; } } &[#{$op}~="#{$size}"] { @content; } } /** * Basically, this is the same as the ```g-state``` mixin, with the difference that it will not print any media queries. It will just create a state context in which your inside code will refer. * @param {Map|List|String} $states The states to apply the css for. Can be a state map, a list of states or a state name * @example scss * @warn(g-get-state-var(min-width)); // will output the min-width of the default state * \@include g-state-context(mobile) { * @warn(g-get-state-var(min-width)); // will output the min-width of the mobile state * } * * @author Olivier Bossel */ @mixin g-state-context( $state ) { // get the state $state : g-get-state($state); $stateName : g-get-state-var(name, $state); // save the current state $savedState : $_g-current_state; $savedStateName : $_g-current_stateName; // set the current state $_g-current_state : $state !global; $_g-current_stateName : $stateName !global; // generate content @content; // reset the state $_g-current_state : $savedState !global; $_g-current_stateName : $savedStateName !global; } /** * Will print the generated selector depending on the "package" wanted, the state and some optional values that might be needed by the package (like for row-align that need a "side" value) * @param {String} $package The package to generate the selector for (see _settings.scss file) * @param {String|List */ @mixin g-selector( $package, $states : null, $value : null ) { #{g-selector($package, $states, $value)} { @content; } } /** * Helper gridle mixin that let you specify the grid properties through ```g-set``` map, or a list of properties like "8 push 2 mobile 12 push 0" * @param {Map|List} $properties The grid properties to apply * @example scss * #content { * // using list * \@include gridle(8 mobile 12); * // using a map * \@include gridle(( * grid : 8, * mobile : ( * grid : 12 * ) * )); * } * * @author Olivier Bossel */ @mixin gridle($properties) { @if type-of($properties) == map { @include g-set($map); } @else if type-of($properties) == list or type-of($properties) == number or type-of($properties) == string { $map : _g-get-gridle-set-map-from-list($properties); @if type-of($map) == map { @include g-set($map); } } @else { @error("The passed layout #{inspect($properties)} is not a valid layout list or map..."); } } /** * Helper mixin that let you specify the grid properties through map formated like in the example bellow. * Here's the possible properties: * * - ```grid``` {Integer} : The grid column count * - ```container``` {Boolean} : Set the element as container * - ```grid-grow``` {Boolean} : Set the element a grid column that grow * - ```grid-adapt``` {Boolean} : Set the element a grid column that adapt * - ```grid-table``` {Boolean} : Set the element a grid column of type table * - ```push``` {Integer} : Set the push count * - ```pull``` {Integer} : Set the pull count * - ```prefix``` {Integer} : Set the prefix count * - ```suffix``` {Integer} : Set the suffix count * - ```clear-each``` {Integer} : Set the clear each count * - ```grid-centered``` {Boolean} : Set the grid column as centered * - ```row``` {Boolean} : Set the element as a grid row * - ```row-full``` {Boolean} : Set the element as a grid row full * - ```col``` {Boolean} : Set the element as a grid column (vertical) * - ```row-align``` {String} : Set the row alignement * - ```row-no-gutter``` {Boolean} : Remove the gutters on columns inside this row * - ```nowrap``` {Boolean} : Set a nowrap on the row * - ```wrap``` {Boolean} : Reset the wrap property on the row * - ```order``` {Integer} : Set the order of the column (flex driver) * - ```hide``` {Boolean} : Hide the element * - ```show``` {Boolean} : Show the element * - ```visible``` {Boolean} : Set the visibility of the element to visible * - ```not-visible``` {Boolean} : Set the visibility of the element to hidden * - ```invisible``` {Boolean} : Set the visibility of the element to hidden * - ```show-inline``` {Boolean} : Set the display of the element to inline-block * - ```float``` {String} : Set the specified float of the element * - ```clear``` {String} : Clear the specified float of the element * - ```no-gutter``` {Boolean|String|List} : Remove the specified gutters * - ```gutter``` {Boolean|String|List} : Apply the specified gutters * * @param {Map} $properties The grid map properties to apply * @example scss * #content { * // using a map * \@include gridle(( * grid : 8, * push : 2 * mobile : ( * grid : 12 * ), * {stateName} : {mapProperties} * )); * } * * @author Olivier Bossel */ @mixin g-set( $propertiesMap, $state : current ) { // init if needed @include g-init(); // wrap in media query @include g-state($state) { @include _g-set($propertiesMap); } } @mixin _g-set( $propertiesMap ) { // loop on each settings @each $propertyName, $propertyValue in $propertiesMap { $sn : unquote("#{$propertyName}"); $sv : $propertyValue; // check if setting name is a state : @if g-has-state($sn) { // process the state @include g-set($sv, $sn); } @else { @if $sn == container { @if $sv == true { @include g-container(); } } @else if $sn == grid { @if length($sv) == 2 { @include g-grid(nth($sv,1), nth($sv,2)); } @else if type-of($sv) == list and length($sv) == 1 { @include g-grid(nth($sv,1)); } @else { @include g-grid($sv); } } @else if $sn == grid-grow { @if $sv == true { @include g-grid-grow(); } } @else if $sn == grid-adapt { @if $sv == true { @include g-grid-adapt(); } } @else if $sn == grid-table { @if $sv == true { @include g-grid-table(); } } @else if $sn == push { @if length($sv) == 2 { @include g-push(nth($sv,1), nth($sv,2)); } @else { @include g-push($sv); } } @else if $sn == pull { @if length($sv) == 2 { @include g-pull(nth($sv,1), nth($sv,2)); } @else { @include g-pull($sv); } } @else if $sn == prefix { @if length($sv) == 2 { @include g-prefix(nth($sv,1), nth($sv,2)); } @else { @include g-prefix($sv); } } @else if $sn == suffix { @if length($sv) == 2 { @include g-suffix(nth($sv,1), nth($sv,2)); } @else { @include g-suffix($sv); } } @else if $sn == clear-each { @if length($sv) == 2 { @include g-clear-each(nth($sv,1), nth($sv,2)); } @else { @include g-clear-each($sv); } } @else if $sn == grid-centered and $sv == true { @include g-grid-centered(); } @else if $sn == row and $sv == true { @include g-row(); } @else if $sn == row-full and $sv == true { @include g-row-full(); } @else if $sn == col and $sv == true { @include g-col(); } @else if $sn == row-align { @include g-row-align($sv); } @else if $sn == row-no-gutter { @include g-row-no-gutter($sv); } @else if $sn == nowrap { @if $sv == true { @include g-nowrap(); } @else { @include g-wrap(); } } @else if $sn == wrap { @if $sv == true { @include g-wrap(); } @else { @include g-nowrap(); } } @else if $sn == order { @include g-order($sv); } @else if $sn == hide { @if $sv == true { @include g-hide(); } @else { @include g-show(); } } @else if $sn == show { @if $sv == true { @include g-show(); } @else { @include g-hide(); } } @else if $sn == visible { @if $sv == true { @include g-visible(); } @else { @include g-not-visible(); } } @else if $sn == not-visible or $sn == invisible { @if $sv == true { @include g-not-visible(); } @else { @include g-visible(); } } @else if $sn == show-inline { @if $sv == true { @include g-show-inline(); } @else { @include g-hide(); } } @else if $sn == float { @include g-float($sv); } @else if $sn == clear { @if $sv == true { @include g-clear(); } @else { @include g-clear($sv); } } @else if $sn == no-gutter { @if $sv == true { @include g-no-gutter(); } @else { @include g-no-gutter($sv); } } @else if $sn == gutter or $sn == gutter-width { @if $sv == true { @include g-gutter(); } @else { @include g-gutter($sv); } } @else { // we do nothing } } } } @mixin _g-common-push( $state : default ) { // css position:relative; // handle direction attribute @if g-get-state-var(dir-attribute, $state) { [dir="rtl"] & { left: auto; } [dir="ltr"] & { right: auto; } } } /** * Set the push count for the column * @param {Integer} $columns The number of columns to push this column * @param {Integer} [$context=null] The context on which to calculate the push value. By default, it is the default context setted with ```g-setup```. * @example scss * .my-cool-column { * \@include g-push(2); * } * * @author Olivier Bossel */ @mixin g-push( $columns, $context : null ) { @include _g-call(push) { // variables : @if type-of($context) != number { $context : g-get-state-var(context); } $direction : g-get-state-var(direction); $name-multiplicator : g-get-state-var(name-multiplicator); $column-width : g-get-state-var(column-width); // vars : $width : 0; @if $column-width { $width : $column-width * ($columns / $name-multiplicator); } @else { $width : percentage(1 / $context) * ($columns / $name-multiplicator); } // @if $direction == rtl { $width : $width*-1; } // left:$width; // @if $direction == ltr { // [dir="rtl"] & { // left: $width * -1; // } // } // set value : @if $direction == rtl { right:$width;left:auto; } @else { left:$width;right:auto; } // handle direction attribute @if g-get-state-var(dir-attribute) { [dir="rtl"] & { right: $width; } [dir="ltr"] & { left: $width; } } } } @mixin _g-common-pull( $state : default ) { // css position:relative; // handle direction attribute @if g-get-state-var(dir-attribute, $state) { [dir="rtl"] & { right: auto; } [dir="ltr"] & { left: auto; } } } /** * Set the pull count for the column * @param {Integer} $columns The number of columns to pull this column * @param {Integer} [$context=null] The context on which to calculate the pull value. By default, it is the default context setted with ```g-setup```. * @example scss * .my-cool-column { * \@include g-pull(2); * } * * @author Olivier Bossel */ @mixin g-pull( $columns, $context : null ) { @include _g-call(pull) { // variables : @if type-of($context) != number { $context : g-get-state-var(context); } $direction : g-get-state-var(direction); $name-multiplicator : g-get-state-var(name-multiplicator); $column-width : g-get-state-var(column-width); // vars : $width : 0; @if $column-width { $width : $column-width * ($columns / $name-multiplicator); } @else { $width : percentage(1 / $context) * ($columns / $name-multiplicator); } // @if $direction == rtl { $width : $width*-1; } // right:$width; // @if $direction == ltr { // [dir="rtl"] & { // left: $width * -1; // } // } // set value : @if $direction == rtl { left:$width;right:auto; } @else { right:$width;left:auto; } // handle direction attribute @if g-get-state-var(dir-attribute) { [dir="rtl"] & { left: $width; } [dir="ltr"] & { right: $width; } } } } @mixin _g-common-prefix( $state : default ) { // handle direction attribute @if g-get-state-var(dir-attribute, $state) { [dir="rtl"] & { margin-left: auto; } [dir="ltr"] & { margin-right: auto; } } } /** * Set the prefix count for the column * @param {Integer} $columns The number of columns to prefix this column * @param {Integer} [$context=null] The context on which to calculate the prefix value. By default, it is the default context setted with ```g-setup```. * @example scss * .my-cool-column { * \@include g-prefix(2); * } * * @author Olivier Bossel */ @mixin g-prefix( $columns, $context : null ) { @include _g-call(prefix) { // vars : @if type-of($context) != number { $context : g-get-state-var(context); } $direction : g-get-state-var(direction); $name-multiplicator : g-get-state-var(name-multiplicator); $column-width : g-get-state-var(column-width); // vars : $width : 0; @if $column-width { $width : $column-width * ($columns / $name-multiplicator); } @else { $width : percentage(1 / $context) * ($columns / $name-multiplicator); } // set value : @if $direction == rtl { margin-right:$width; } @else { margin-left:$width; } // handle direction attribute @if g-get-state-var(dir-attribute) { [dir="rtl"] & { margin-right: $width; } [dir="ltr"] & { margin-left: $width; } } } } @mixin _g-common-suffix( $state : default ) { @if g-get-state-var(dir-attribute, $state) { [dir="rtl"] & { margin-right: auto; } [dir="ltr"] & { margin-left: auto; } } } /** * Set the suffix count for the column * @param {Integer} $columns The number of columns to suffix this column * @param {Integer} [$context=null] The context on which to calculate the suffix value. By default, it is the default context setted with ```g-setup```. * @example scss * .my-cool-column { * \@include g-suffix(2); * } * * @author Olivier Bossel */ @mixin g-suffix( $columns, $context : null ) { @include _g-call(suffix) { // vars : @if type-of($context) != number { $context : g-get-state-var(context); } $direction : g-get-state-var(direction); $name-multiplicator : g-get-state-var(name-multiplicator); $column-width : g-get-state-var(column-width); // vars : $width : 0; @if $column-width { $width : $column-width * ($columns / $name-multiplicator); } @else { $width : percentage(1 / $context) * ($columns / $name-multiplicator); } // set value : @if $direction == rtl { margin-left:$width; } @else { margin-right:$width; } // handle direction attribute @if g-get-state-var(dir-attribute) { [dir="rtl"] & { margin-left: $width; } [dir="ltr"] & { margin-right: $width; } } } } // // Row debug // @mixin _g-common-row-debug( $state : default ) { } /** * Display a debug grid on top of the row * @example scss * .my-row { * \@include g-row-debug(); * } * * @author Olivier Bossel */ @mixin g-row-debug() { @include _g-call(row-debug) { // variables : $context : g-get-state-var(context); position:relative; z-index:99999; overflow:hidden; &:before { pointer-events: none; content:''; position:absolute; top:0; left:0; width:100%; height:99999px; // vars : $width : percentage(1 / $context); background: linear-gradient(to right, rgba(0,0,0,0) 50% , rgba(0,0,0,.02) 50%); // Standard syntax background-size:($width*2) 100%; z-index:99999; } } } @mixin _g-common-container( $state : default ) { &:after { content: ""; display: table; clear: both; } } /** * Make the element a grid container * @example scss * .my-cool-container { * \@include g-container(); * } * * @author Olivier Bossel */ @mixin g-container( ) { @include _g-call(container) { } } // // Row no gutter // @mixin _g-common-row-no-gutter( $state : default ) { } /** * Remove the gutters on each columns inside the row * @param {String|List} [$sides=top right bottom left] The sides to clear * @example scss * .my-cool-row { * \@include g-row-no-gutter(left right); * } * * @author Olivier Bossel */ @mixin g-row-no-gutter( $sides : top right bottom left ) { @include _g-call(row-no-gutter) { margin-left: 0; margin-right: 0; > #{_g-get-generic-selector('grid')} { @include g-no-gutter($sides); } } } @mixin _g-common-grid-centered( $state : default ) { display:block !important; float:none !important; margin-left:auto !important; margin-right:auto !important; clear:both !important; } /** * Make a column centered * @example scss * .my-cool-column { * \@include g-grid-centered(); * } * * @author Olivier Bossel */ @mixin g-grid-centered( ) { @include _g-call(grid-centered) { } } @mixin _g-common-hide( $state : default ) { } /** * Hide an element * @example scss * .my-cool-element { * \@include g-hide(); * } * * @author Olivier Bossel */ @mixin g-hide( ) { @include _g-call(hide) { display:none !important; } } // // Not visible on // @mixin _g-common-not-visible( $state : default ) { } /** * Set the visibility of an element to hidden * @example scss * .my-cool-element { * \@include g-not-visible(); * } * * @author Olivier Bossel */ @mixin g-not-visible( ) { @include _g-call(not-visible) { visibility:hidden; } } /** * Set the visibility of an element to hidden * @example scss * .my-cool-element { * \@include g-invisible(); * } * * @author Olivier Bossel */ @mixin g-invisible( ) { @include _g-call(not-visible) { visibility:hidden; } } @mixin _g-common-show( $state : default ) { } /** * Set the display of an element to block * @example scss * .my-cool-element { * \@include g-show(); * } * * @author Olivier Bossel */ @mixin g-show( ) { @include _g-call(show) { display:block !important; } } @mixin _g-common-show-inline( $state : default ) { } /** * Set the display of an element to inline-block * @example scss * .my-cool-element { * \@include g-show(); * } * * @author Olivier Bossel */ @mixin g-show-inline( ) { @include _g-call(show-inline) { display:inline-block !important; } } @mixin _g-common-visible( $state : default ) { } /** * Set the visibility of an element to visible * @example scss * .my-cool-element { * \@include g-show(); * } * * @author Olivier Bossel */ @mixin g-visible( ) { @include _g-call(visible) { visibility:visible; } } @mixin _g-common-float( $state : default ) { } /** * Set the float property of the element to the specified direction * @param {String} [$float=left] The float direction to set * @example scss * .my-cool-element { * \@include g-float(right); * } * * @author Olivier Bossel */ @mixin g-float( $float-direction : left ) { @include _g-call(float) { float:#{$float-direction}; } } @mixin _g-common-clear( $state : default ) { } /** * Clear the float property of the element to the specified direction * @param {String} [$float=left] The float direction to clear * @example scss * .my-cool-element { * \@include g-clear(right); * } * * @author Olivier Bossel */ @mixin g-clear( $clear-direction : both ) { @include _g-call(clear) { clear:#{$clear-direction}; } } @mixin _g-common-no-gutter( $state : default ) { } /** * Remove the gutters on the column * @param {String|List} [$sides=top right bottom left] The sides to clear * @example scss * .my-cool-column { * \@include g-no-gutter(left right); * } * * @author Olivier Bossel */ @mixin g-no-gutter( $side : top right bottom left ) { @include _g-call(no-gutter) { @each $s in $side { padding-#{$s} : 0; } } } @mixin _g-common-gutter( $state : default ) { } /** * Set the gutters on the column * @param {String|List} [$sides=top right bottom left] The sides to apply gutters on * @example scss * .my-cool-column { * \@include g-gutter(left right); * } * * @author Olivier Bossel */ @mixin g-gutter( $side-or-size : right left ) { @include _g-call(gutter) { // get a gutter map $gutters : _g-forge-gutters-map($side-or-size); // check that we have a gutter map @each $side, $value in $gutters { @if $value and $value > 0 { padding-#{$side} : $value; } } } }