Skip to content

Instantly share code, notes, and snippets.

@mindfullsilence
Last active October 4, 2017 22:56
Show Gist options
  • Save mindfullsilence/29d5078041047bf9cf277a05a90ec1af to your computer and use it in GitHub Desktop.
Save mindfullsilence/29d5078041047bf9cf277a05a90ec1af to your computer and use it in GitHub Desktop.
Creates a triangle with fill and stroke on any side(s) you want.

Use the mixin inside of a ::before or ::after pseudo element.

E.g.:

div::before {
  @include svg-triangle(
    $width: 30px, // any unit
    $height: 20px, // any unit
    $borders: left right, // left, right, bottom, or any combination of the 3
    $border-color: #cccccc, // hex
    $border-width: 2, // no unit
    $fill: #000000, // hex
    $direction: left // left, right, up, or down
  );
}

Note that the starting direction is up, and the borders will be applied to the sides corresponding to that orientation before $direction is applied.

@function -svg-triangle(
$width: 10,
$height: 10,
$border-color: transparent,
$borders: left bottom,
$border-width: 0,
$fill: #000000
) {
$canvas: '';
$triangle: '';
$stroke: '';
$width: strip-unit($width);
$height: strip-unit($height);
$canvas: $canvas + '<svg width="#{$width}" height="#{$height}" viewBox="-#{$border-width} -#{$border-width} #{$width + ($border-width * 2)} #{$height + ($border-width * 2)}" xmlns="http://www.w3.org/2000/svg">';
$top-point: "M #{$width / 2} 0";
$bottom-left: "L 0 #{$height}";
$bottom-right: "L #{$width} #{$height} z";
$triangle: $triangle + '<path d="#{$top-point} #{$bottom-left} #{$bottom-right}" fill="#{$fill}" />';
@if $borders != false {
$stroke: $stroke + '<path fill="none" stroke="#{$border-color}" stroke-width="#{$border-width}" d="';
$stroke-top: '#{$width / 2} 0';
$stroke-right: '#{$width} #{$height}';
$stroke-left: '0 #{$height}';
@if -contains($borders, right) and -contains($borders, bottom) and -contains($borders, left) {
$stroke: $stroke + 'M#{$stroke-top} L #{$stroke-right} L #{$stroke-left} Z';
} @else if -contains($borders, right) and -contains($borders, bottom) {
$stroke: $stroke + 'M#{$stroke-top} L #{$stroke-right} L #{$stroke-left}';
} @else if -contains($borders, bottom) and -contains($borders, left) {
$stroke: $stroke + 'M#{$stroke-right} L #{$stroke-left} L #{$stroke-top}';
} @else if -contains($borders, left) and -contains($borders, right) {
$stroke: $stroke + 'M#{$stroke-left} L #{$stroke-top} L #{$stroke-right}';
}
$stroke: $stroke + '" />';
}
$canvas: $canvas + $stroke + $triangle + '</svg>';
@return $canvas;
}
@mixin svg-triangle(
$width: 10px,
$height: 10px,
$borders: left bottom right,
$border-color: transparent,
$border-width: 0,
$fill: #000000,
$direction: up
) {
width: $width;
height: $height;
content: '';
display: block;
$triangle: -svg-triangle(
$width,
$height,
$border-color,
$borders,
$border-width,
$fill);
background-image: url('data:image/svg+xml,' + $triangle);
background-size: 100% 100%;
background-repeat: no-repeat;
background-position: center center;
@if $direction == left {
transform: rotate(-90deg);
} @else if $direction == right {
transform: rotate(90deg);
} @else if $direction == down {
transform: rotate(180deg);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment