Skip to content

Instantly share code, notes, and snippets.

@erin-dot-io
Last active December 15, 2015 10:39
Show Gist options
  • Save erin-dot-io/5247046 to your computer and use it in GitHub Desktop.
Save erin-dot-io/5247046 to your computer and use it in GitHub Desktop.
A little mixin I built for easily creating css arrows in sass/scss using psuedo-classes. Demo: http://codepen.io/erinautomatic/pen/BLFqe
// The mixin
@mixin css-arrow($box-edge : bottom,
$edge-side : center,
$arrow-size : 10px,
$edge-side-offset : 0,
$fill-color : black,
$border-color : none,
$border-style : border) {
$box-edge-inverse: bottom;
$edge-side-pos: $edge-side;
$edge-side-pos-value: 0;
@if $box-edge == top { $box-edge-inverse: bottom; }
@else if $box-edge == right { $box-edge-inverse: left; }
@else if $box-edge == bottom { $box-edge-inverse: top; }
@else if $box-edge == left { $box-edge-inverse: right; }
@if ($box-edge == 'top' or
$box-edge == 'bottom') {
@if $edge-side == center {
$edge-side-pos: left;
$edge-side-pos-value: 50%;
$edge-side-offset: (-$arrow-size);
}
}
@if ($box-edge == 'left' or
$box-edge == 'right') {
@if $edge-side == center {
$edge-side-pos: top;
$edge-side-pos-value: 50%;
$edge-side-offset: (-$arrow-size);
}
}
&:after, &:before {
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border: solid rgba(#fff, 0);
}
&:after {
border-color: rgba(#fff, 0);
border-width: $arrow-size - 1;
#{$box-edge}: (-$arrow-size) - $arrow-size + 2;
border-#{$box-edge-inverse}-color: $fill-color;
#{$edge-side-pos}: $edge-side-pos-value;
margin-#{$edge-side-pos}: $edge-side-offset + 1;
}
@if $border-style == flag {
@include border-radius(2px);
&:before {
border-color: rgba(#fff, 0);
border-width: $arrow-size - 1;
#{$box-edge}: (-$arrow-size) - $arrow-size + 2;
border-#{$box-edge-inverse}-color: $border-color;
#{$edge-side-pos}: $edge-side-pos-value;
margin-#{$edge-side-pos}: $edge-side-offset + 2;
}
} @else {
&:before {
border-color: rgba(#fff, 0);
border-width: $arrow-size;
#{$box-edge}: (-$arrow-size) - $arrow-size;
border-#{$box-edge-inverse}-color: $border-color;
#{$edge-side-pos}: $edge-side-pos-value;
margin-#{$edge-side-pos}: $edge-side-offset;
}
}
}
// Example uses
// @include css-arrow([$box-edge], [$edge-side], [$arrow-size], [$edge-side-offset], [$fill-color], [$border-color], [$border-style])
// $box-edge accepts 'top', 'bottom', 'left', or 'right'
// $edge-side accepts 'left', 'right', or 'center' if $box-edge is 'top' or 'bottom', or:
// $edge-side accepts 'top', 'bottom', or 'center', if $box-edge is 'left' or 'right'
// $arrow-size accepts any standard unit size for css border attribute
// $edge-side-offset accepts any standard unit size for css margin attribute
// NOTE: $edge-side-offset will be ignored if $edge-side is 'center'. It can also be set to the default of 0 in this case.
// $fill-color and $border-color take any color value or variable containing a color
// $border-style accepts 'default' or 'flag' - more options are planned, including border width
.default { @include css-arrow; }
// If $edge-side is not 'center', use $edge-side-offset to offset the arrow from the top, right, bottom, or left side of the parent container
.offset { @include css-arrow(bottom, right, 14px, 15px, #ddd); }
// Add a second color to create a 1px border effect
.border-style { @include css-arrow(top, center, 18px, 0, #ddd, #aaa); }
// Adding 'flag' to the end of the mxin drops the :before arrow by 1 pixel to create a shadow effect instead of 1px border effect
.flag-style { @include css-arrow(right, center, 20px, 0, #ddd, #aaa, flag); }
@erin-dot-io
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment