Skip to content

Instantly share code, notes, and snippets.

@romellem
Last active March 17, 2016 19:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romellem/d1a2bcb506812fda831e to your computer and use it in GitHub Desktop.
Save romellem/d1a2bcb506812fda831e to your computer and use it in GitHub Desktop.
Sass mixin for creating multi-borders on boxes using box-shadows.
// See `http://codepen.io/romellem/pen/QyXJrZ` for some examples
@mixin multi-border($num, $style: 'all', $width: 1px, $colors: #000, $lock-inner: true, $add-margin: true, $inset: false) {
// define all styles
//$styles: ("top": "top", "right": "right", "bottom": "bottom", "left": "left", "top-left": "top-left", "top-bottom": "top-bottom", "top-right": "top-right", "bottom-left": "bottom-left", "bottom-right": "bottom-right", "top-left-right": "top-left-right", "bottom-left-right": "bottom-left-right", "all": "all");
// Only supports top, right, bottom, left, and all, for now.
$styles: ("top": true, "right": true, "bottom": true, "left": true, "all": true);
// If we try to use an un-named style, send a warning message and use 'all' instead
@if (map_has_key($styles, $style)) {
// Do nothing
} @else {
@warn '$style #{$style} was not in our list, using "all" instead.';
$style: 'all';
}
$shadows: ();
@if (length($colors) == 1) {
// If we only have one color, use its invert as the second color
$colors: append($colors, invert(nth($colors, 1)));
}
$num-colors: length($colors);
$invert-list: ();
@for $i from (-1 * $num) through -1 {
// Use abs() to have a decrement loop
$invert-list: append($invert-list, abs($i));
}
@for $i from 1 through $num {
$inset-text: '';
$inset-xy-switch: 1;
@if ($inset) {
$inset-text: 'inset ';
$inset-xy-switch: -1;
}
$x-pos: '0';
$y-pos: '0';
$blur: '0';
$spread: '0';
@if ($style == 'top') {
$y-pos: '#{$width * $i * -1 * $inset-xy-switch}';
} @else if ($style == 'right') {
$x-pos: '#{$width * $i * $inset-xy-switch}';
} @else if ($style == 'bottom') {
$y-pos: '#{$width * $i * $inset-xy-switch}';
} @else if ($style == 'left') {
$x-pos: '#{$width * $i * -1 * $inset-xy-switch}';
} @else if ($style == 'all') {
$spread: '#{$width * $i}';
} @else {
@error 'Somehow $style is unsupported';
}
// If $colors is a list of (A, B, C),
// and $lock-inner is true, our border will look like:
//
// | | | | |
// B A C B A
// | | | | |
//
// With the first color, A, staying on the inside and looping outwards
//
// If $lock-inner is false, our border will lock to the outside, like this:
//
// | | | | |
// A B C A B
// | | | | |
//
// With the first color, A, staying on the outside and looping inwards
$color-n: null;
@if ($lock-inner) {
$color-n: (($i - 1) % $num-colors) + 1;
} @else {
$color-n: ((nth($invert-list, $i) - 1) % $num-colors) + 1;
}
$temp-color: nth($colors, $color-n);
// Build our shadow string
$single-shadow: "#{$inset-text}#{$x-pos} #{$y-pos} #{$blur} #{$spread} #{$temp-color}";
// Build our shadows-list
$shadows: join($shadows, $single-shadow, comma);
}
// Apply the shadows
-webkit-box-shadow: #{$shadows};
-moz-box-shadow: #{$shadows};
box-shadow: #{$shadows};
// Add margins (if needed)
@if ($add-margin == true) {
@if ($inset == true) {
@if ($style == 'top') {
padding-top: $width * $num;
} @else if ($style == 'right') {
padding-right: $width * $num;
} @else if ($style == 'bottom') {
padding-bottom: $width * $num;
} @else if ($style == 'left') {
padding-left: $width * $num;
} @else if ($style == 'all') {
padding: $width * $num;
} @else {
@error 'Somehow $style is unsupported';
}
} @else {
@if ($style == 'top') {
margin-top: $width * $num;
} @else if ($style == 'right') {
margin-right: $width * $num;
} @else if ($style == 'bottom') {
margin-bottom: $width * $num;
} @else if ($style == 'left') {
margin-left: $width * $num;
} @else if ($style == 'all') {
margin: $width * $num;
} @else {
@error 'Somehow $style is unsupported';
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment