Creates a triangle with fill and stroke on any side(s) you want.
@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);
}
}
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.