Skip to content

Instantly share code, notes, and snippets.

@bizhe
Created Mar 29, 2021
Embed
What would you like to do?
////
/// 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');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment