//// /// Andy.SCSS: Open-Source Collection of Useful SASS Mixins Library. /// URL: http://gillesbertaux.com/andy$ /// Repository: https://github.com/gillesbertaux/andy /// By: Gilles Bertaux | http://gillesbertaux.com | @gillesbertaux /// The purpose of Andy is to gather useful mixins and avoid endless research /// or heavy framework use. Feel free to fork it on Github and add your own mixins: //// /// Base font size setting for Andy /// @access public /// @type Length $base-font-size: 16px !default; /// Mixin helper to output vendor-prefixed CSS /// @access private /// @author HugoGiraudel /// @param {String} $property - Unprefixed CSS property /// @param {*} $value - Raw CSS value /// @param {List} $prefixes [()] - List of prefixes to output @mixin prefix($property, $value, $prefixes: ()) { @each $prefix in $prefixes { -#{$prefix}-#{$property}: $value; } #{$property}: $value; } /// Mixin helper to prefix `@keyframes` /// @access private /// @param {String} $name - Animation name @mixin keyframes($name) { @-webkit-keyframes #{$name} { @content; } @keyframes #{$name} { @content; } } /// Function helper to strip a single character from a string; by default, simply removes the character. /// @access private /// @param {String} $string - The string to alter. /// @param {String} $to-replace - The character to check for. /// @param {String} $replacement [''] - The character to replace the removed character with. /// @example scss - Usage { /// .foo:after { /// content: str-replace('Hello.', '.', '!'); /// } /// @example css - Result /// .foo:after { /// content: 'Hello!' /// } @function str-replace($string, $to-replace, $replacement:'') { $target-location: str-index($string, $to-replace); @if $target-location == null { @return $string; } $string-without-target: str-slice($string, 1, $target-location - 1) + str-slice($string, $target-location + 1); $string: str-insert($string-without-target, $replacement, $target-location); @return $string; } /// Background gradient helper /// @access public /// @param {Color} $start-color - Start color /// @param {Color} $end-color - End color /// @param {String} $orientation - Type of gradient, either `vertical`, `horizontal` or `radial` /// @example scss - Usage /// .foo { /// @include background-gradient(red, black, 'vertical'); /// } /// @example css - Result /// .foo { /// background: -webkit-linear-gradient(top, red, black); /// background: linear-gradient(to bottom, red, black); /// } @mixin background-gradient($start-color, $end-color, $orientation) { background: $start-color; @if $orientation == 'vertical' { background: -webkit-linear-gradient(top, $start-color, $end-color); background: linear-gradient(to bottom, $start-color, $end-color); } @else if $orientation == 'horizontal' { background: -webkit-linear-gradient(left, $start-color, $end-color); background: linear-gradient(to right, $start-color, $end-color); } @else { background: -webkit-radial-gradient(center, ellipse cover, $start-color, $end-color); background: radial-gradient(ellipse at center, $start-color, $end-color); } } /// Background size helper /// @access public /// @param {Length} $width - Background width /// @param {Length} $height [$width] - Background height /// @example scss - Usage /// .foo { /// @include background-size(100%); /// } /// @example scss - Result /// .foo { /// -webkit-background-size: 100% 100%; /// -moz-background-size: 100% 100%; /// background-size: 100% 100%; /// } @mixin background-size($width, $height: $width) { @include prefix(background-size, $width $height, 'webkit' 'moz'); } /// Separated border-radius helpers /// @access public /// @param {Length} $top-left-radius - Top left radius /// @param {Length} $top-right-radius - Top right radius /// @param {Length} $bottom-right-radius - Bottom right radius /// @param {Length} $bottom-left-radius - Bottom left radius /// @example scss - Usage /// .foo { /// @include border-radius-separate(1px, 2px, 3px, 4px); /// } /// @example css - Result /// .foo { /// -webkit-border-top-left-radius: 1px; /// -moz-border-top-left-radius: 1px; /// border-top-left-radius: 1px; /// -webkit-border-top-right-radius: 2px; /// -moz-border-top-right-radius: 2px; /// border-top-right-radius: 2px; /// -webkit-border-bottom-right-radius: 3px; /// -moz-border-bottom-right-radius: 3px; /// border-bottom-right-radius: 3px; /// -webkit-border-bottom-left-radius: 4px; /// -moz-border-bottom-left-radius: 4px; /// border-bottom-left-radius: 4px; /// } @mixin border-radius-separate($top-left-radius, $top-right-radius, $bottom-right-radius, $bottom-left-radius) { @include prefix(border-top-left-radius, $top-left-radius, 'webkit' 'moz'); @include prefix(border-top-right-radius, $top-right-radius, 'webkit' 'moz'); @include prefix(border-bottom-right-radius, $bottom-right-radius, 'webkit' 'moz'); @include prefix(border-bottom-left-radius, $bottom-left-radius, 'webkit' 'moz'); } /// Box-sizing helper /// @access public /// @param {String} $type - Either `border-box`, `padding-box` or `content-box` /// @example scss - Usage /// .foo { /// @include box-sizing(border-box); /// } /// @example css - Result /// .foo { /// -moz-box-sizing: border-box; /// box-sizing: border-box; /// } @mixin box-sizing($type) { @include prefix(box-sizing, $type, 'moz'); } /// Horizontally centers block elements /// @access public /// @example scss - Usage /// .foo { /// @include center-block; /// } /// @example css - Result /// .foo { /// display: block; /// margin-left: auto; /// margin-right: auto; /// } @mixin center-block { display: block; margin-left: auto; margin-right: auto; } /// Horizontally and vertically centers block elements /// Important: you must have a parent element with `position: relative`. /// @access public /// @example scss - Usage /// .foo { /// @include center-both; /// } /// @example css - Result /// .foo { /// position: absolute; /// top: 50%; /// left: 50%; /// -webkit-transform: translate(-50%, -50%); /// -ms-transform: translate(-50%, -50%); /// transform: translate(-50%, -50%); /// } @mixin center-both { position: absolute; top: 50%; left: 50%; @include prefix(transform, translate(-50%, -50%), 'webkit' 'ms'); } /// Vertically centers block elements with known height. /// @access public /// @param {Length} $height - Element's height /// @example scss - Usage /// .foo { /// @include center-h(42px); /// } /// @example css - Result /// .foo { /// position: absolute; /// top: 50%; /// height: 42px; /// margin-top: -21px; /// } @mixin center-h($height) { position: absolute; top: 50%; height: $height; margin-top: -($height / 2); } /// Vertically centers block elements with unknown height. /// @access public /// @example scss - Usage /// .foo { /// @include center-h--unk; /// } /// @example css - Result /// .foo { /// position: relative; /// top: 50%; /// -webkit-transform: translateY(-50%); /// -ms-transform: translateY(-50%); /// transform: translateY(-50%); /// } @mixin center-h--unk { position: relative; top: 50%; @include prefix(transform, translateY(-50%), 'webkit' 'ms'); } /// Clearfix extend /// @access public /// @example scss - Usage /// .foo { /// @extend %clearfix; /// } %clearfix { *zoom: 1; &:before, &:after { content: ' '; display: table; } &:after { clear: both; } } /// Adds a thin black line above the element, and a thin gray line below the element, creating an inlay effect. /// @access public /// @example scss - Usage /// .foo { /// @include outline; /// } /// @example css - Result /// .foo { /// box-shadow: rgba(255, 255, 255, 0.5) 0 1px 0, inset rgba(0, 0, 0, 0.75) 0 1px 0; /// } @mixin outline { box-shadow: rgba(255, 255, 255, 0.5) 0 1px 0, inset rgba(0, 0, 0, 0.75) 0 1px 0; } /// Given the location of a webfont, will generate a font-face declaration with multiple file formats. /// @access public /// @param {String} $font-name - Font family name /// @param {String} $file-name - File name (no extension) /// @param {String | Number} $weight [normal] - Font weight /// @param {String} $style [normal] - Font style /// @example scss - Usage /// @include font-face('gotham', '/fonts/gotham'); @mixin font-face($font-name, $file-name, $weight: normal, $style: normal) { @font-face { font-family: quote($font-name); src: url($file-name + '.eot'); src: url($file-name + '.eot?#iefix') format('embedded-opentype'), url($file-name + '.woff') format('woff'), url($file-name + '.ttf') format('truetype'), url($file-name + '.svg##{$font-name}') format('svg'); font-weight: $weight; font-style: $style; } } /// Given a font size in pixels, reproduces that font size in rems. /// @access public /// @param {Length} $size - Font size /// @example scss - Usage /// .foo { /// @include font-size(16px); /// } /// @example css - Result /// .foo { /// font-size: 16px; /// font-size: 1rem; /// } @mixin font-size($size) { @if unitless($size) { $size: $size * 1px; } font-size: $size; font-size: ($size / $base-font-size) * 1rem; } /// Forces browsers to use hardware acceleration for transforms /// @access public /// @example scss - Usage /// .foo { /// @include ha; /// } /// @example css - Result /// .foo { /// -webkit-transform: translate3d(0, 0, 0); /// -moz-transform: translate3d(0, 0, 0); /// transform: translate3d(0, 0, 0); /// } @mixin ha { @include prefix(transform, translate3d(0, 0, 0), 'webkit' 'ms'); } /// Retina image media query helper; given an image path with a 2x-sized version of an image, will load that image as a background-image on high-resolution devices. /// @access public /// @param {String} $image - Image path /// @param {Length} $width - Image width /// @param {Height} $height - Image height /// @example scss - Usage /// .foo { /// @include image-2x('../images/image.png', 100%, auto); /// } @mixin image-2x($image, $width, $height) { @media (-webkit-min-device-pixel-ratio: 1.3), (min-resolution: 124dpi), (min-resolution: 1.3dppx) { /* on retina, use image that's scaled by 2 */ background-image: url($image); background-size: $width $height; } } /// Generates line-height values in both pixels and rems. /// @access public /// @param {Number} $height-value [12] - Height value /// @example scss - Usage /// .foo { /// @include line-height(16); /// } /// @example css - Result /// .foo { /// line-height: 16px; /// line-height: 1rem; /// } @mixin line-height($height-value: 12) { line-height: $height-value * 1px; //fallback for old browsers line-height: (1 / ($base-font-size / ($base-font-size * 0 + 1)) * $height-value * 1rem); } /// Media query helper for declaring media queries by width, and, optionally, ratio. /// @access public /// @param {Length} $width - Max-width /// @param {Number | False} $ratio [false] - Min device pixel ratio /// @example scss - Usage /// .foo { /// @include mquery(350px, 2) { /// width: 100%; /// } /// } @mixin mquery($width, $ratio: false) { @if $ratio { @media only screen and (max-width: $width) and (min--moz-device-pixel-ratio: $ratio), only screen and (max-width: $width) and (-webkit-min-device-pixel-ratio: $ratio), only screen and (max-width: $width) and (min-device-pixel-ratio: $ratio) { @content; } } @else { @media only screen and (max-width: $width) { @content; } } } /// Media query helper for declaring media queries by device pixel ratio. /// @access public /// @param {Number} $ratio - Min device pixel ratio /// @example scss - Usage /// .foo { /// @include mquery-r(2) { /// width: 100%; /// } /// } @mixin mquery-r($ratio) { @media only screen and (-webkit-min-device-pixel-ratio: $ratio), only screen and (min--moz-device-pixel-ratio: $ratio), only screen and (-o-min-device-pixel-ratio: $ratio), only screen and (min-device-pixel-ratio: $ratio) { @content; } } /// Given an opacity value, generates that value as well as a way to display that opacity value in Internet Explorer 8 and 9. /// @access public /// @param {Float} $opacity - Opacity /// @example scss - Usage /// .foo { /// @include opacity(0.5); /// } /// @example css - Result /// .foo { /// opacity: 0.5; /// filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=#50)"; /// } @mixin opacity($opacity) { opacity: $opacity; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=#{$opacity * 100})"; } /// Generates the color black, with, optionally, a set opacity. /// @access public /// @param {Float} $opacity - Opacity /// @example scss - Usage /// .foo { /// border-color: black(0.1); /// } /// @example css - Result /// .foo { /// border-color: rgba(0, 0, 0, 0.1); /// } @function black($opacity) { @return rgba(0, 0, 0, $opacity); } /// Generates the color white, with, optionally, a set opacity. /// @access public /// @param {Float} $opacity - Opacity /// @example scss - Usage /// .foo { /// border-color: white(0.1); /// } /// @example css - Result /// .foo { /// border-color: rgba(255, 255, 255, 0.1); /// } @function white($opacity) { @return rgba(255, 255, 255, $opacity); } /// Shorthandizes position declarations. /// @access public /// @param {String} $type - Either `relative`, `absolute` or `fixed` /// @param {Length} $left [null] - Left offset /// @param {Length} $right [null] - Right offset /// @param {Length} $top [null] - Top offset /// @param {Length} $bottom [null] - Bottom offset /// @example scss - Usage /// .foo { /// @include position(absolute, $top: 10px, $left: 10px); /// } /// @example css - Result /// .foo { /// position: absolute; /// left: 10px; /// top: 10px; /// } @mixin position($type, $top: null, $right: null, $bottom: null, $left: null) { position: $type; top: $top; right: $right; bottom: $bottom; left: $left; } /// Sizing helper /// @access public /// @param {Length} $width - Width /// @param {Length} $height [$width] - Height /// @example scss - Usage /// .foo { /// @include size(350px); /// } /// @example css - Result /// .foo { /// width: 350px; /// height: 350px; /// } @mixin size($width, $height: $width) { width: $width; height: $height; } /// Embossing text shadow /// @access public /// @param {Float} $value - Opacity value /// @example scss - Usage /// .foo { /// @include text-shadow(0.5); /// } /// @example css - Result /// .foo { /// text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0; /// } @mixin text-shadow($value) { text-shadow: rgba(255, 255, 255, $value) 0 1px 0; } /// Automatically prefix any transform /// @access public /// @param {String} $transformation - The transform to apply /// @example scss - Usage /// .foo { /// @include transform(translateX(10px)); /// } /// @example css - Result /// .foo { /// -webkit-transform: translateX(10px); /// -ms-transform: translateX(10px); /// transform: translateX(10px); /// } @mixin transform($transformation){ @include prefix(transform, $transformation, 'webkit' 'ms'); } /// Transition helper /// @param {Time} $time [1s] - Duration /// @param {String} $timing-function [ease-in-out] - Timing function or cubic bezier curve /// @example scss - Usage /// .foo { /// @include transition(0.3s, ease-in); /// } /// @example css - Result /// .foo { /// -webkit-transition: all 0.3s ease-in; /// transition: all 0.3s ease-in; /// } @mixin transition($time: 1s, $timing-function: ease-in-out) { @include prefix(transition, all $time $timing-function, 'webkit'); } /// Generates a grow-then-shrink (or shrink-then-grow) animation using transform(scale). /// @access public /// @param {Number} $scale-change [1.1] - The amount to scale by. /// @param {List} $animation-properties - Animation properties to apply. /// @example scss - Usage /// .foo { /// @include scale(0.5, 3s ease infinite alternate); /// } /// @example css - Result /// .foo { /// -webkit-animation: "scale-0-5" 3s ease infinite alternate; /// animation: "scale-0-5" 3s ease infinite alternate; /// } /// // -webkit- prefixed @keyframes are also generated /// @keyframes scale-0-5 { /// from, to { /// -webkit-transform: scale(1); /// -ms-transform: scale(1); /// transform: scale(1); /// } /// 50% { /// -webkit-transform: scale(0.5); /// -ms-transform: scale(0.5); /// transform: scale(0.5); /// } /// } @mixin scale($scale-change:1.1, $animation-properties: 1s ease-in-out) { $alias: 'scale-' + str-replace($scale-change + '', '.', '-'); @include keyframes($alias){ 0%, 100% { @include transform(scale(1)); } 50% { @include transform(scale($scale-change)); } } @include prefix(animation, $alias $animation-properties, 'webkit'); } /// Given two opacity values, animates an element between those opacity values. /// @access public /// @param {Number} $fade-from [0] - The beginning opacity value. /// @param {Number} $fade-to [1] - The final opacity value. /// @param {List} $animation-properties [1s ease] - The animation properties to apply. /// @example scss - Usage /// .foo { /// @include fade(.8, .2, 3s linear); /// } /// @example css - Result /// .foo { /// -webkit-animation: fade-0-8-0-2 3s linear; /// animation: fade-0-8-0-2 3s linear; /// } /// // (the @keyframes are also generated with a -webkit- vendor prefix) /// @keyframes fade-0-8-0-2 { /// from { /// opacity: 0.8; /// -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; /// } /// to { /// opacity: 0.2; /// -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)"; /// } /// } @mixin fade($fade-from: 0, $fade-to: 1, $animation-properties: 1s ease) { $alias: fade- + str-replace($fade-from + '', '.', '-') + '-' + str-replace($fade-to + '', '.', '-'); @include keyframes($alias){ from { @include opacity($fade-from); } to { @include opacity($fade-to); } } @include prefix(animation, $alias $animation-properties, 'webkit'); } /// Slide-in-from creates and calls an animation that slides an element on a given axis for a given amount of space. The offset is measured in the distance from the location the element would naturally fall in, were transforms not applied to it. /// @access public /// @param {String} $slide-axis [x] - The axis on which to slide; 'x' or 'y'. /// @param {Length} $slide-offset [-100px] - The offset from the natural element position from which to begin the animation. /// @param {List} $animation-properties [3s ease-out] - Any animation properties to be included. /// @example scss - Usage /// .foo { /// @include slide-in-from(y, -200px, 3s ease alternate infinite); /// } /// @example css - Result /// .foo { /// -webkit-animation: slide-in-y--200px 3s linear infinite alternate; /// animation: slide-in-y--200px 3s linear infinite alternate; /// } /// /// // (the @keyframes are also generated with a -webkit- vendor prefix) /// @keyframes slide-in-y--200px { /// 0% { /// opacity: 0; /// -webkit-transform: translateY(-200px); /// -ms-transform: translateY(-200px); /// transform: translateY(-200px); /// } /// 75% { /// -webkit-transform: translateY(0); /// -ms-transform: translateY(0); /// transform: translateY(0); /// } /// 100% { /// opacity: 1; /// } /// } @mixin slide-in-from($slide-axis: x, $slide-offset: -100px, $animation-properties: 3s ease-out) { $slide-start: if($slide-axis == x, translateX($slide-offset), translateY($slide-offset)); $slide-end: if($slide-axis == x, translateX(0), translateY(0)); @include keyframes(slide-in-#{$slide-axis}-#{$slide-offset}){ 0% { @include opacity(0); @include transform($slide-start); } 75% { @include transform($slide-end); } 100% { @include opacity(1); } } @include prefix(animation, slide-in-#{$slide-axis}-#{$slide-offset} $animation-properties, 'webkit'); }