CSS Triangle Mixin

Avatar of Kitty Giraudel
Kitty Giraudel am

Es gibt einen ziemlich beliebten CSS-Hack, der transparente Ränder an einem Element mit 0 Breite / 0 Höhe verwendet, um Dreiecke zu imitieren. Hier auf CSS-Tricks gibt es einen CSS-Schnipsel, der dies darstellt.

Wenn Sie sich, wie ich, nie ganz daran erinnern, wie es funktioniert, können wir uns mit Sass helfen.

/// Triangle helper mixin
/// @param {Direction} $direction - Triangle direction, either `top`, `right`, `bottom` or `left`
/// @param {Color} $color [currentcolor] - Triangle color 
/// @param {Length} $size [1em] - Triangle size
@mixin triangle($direction, $color: currentcolor, $size: 1em) {
  @if not index(top right bottom left, $direction) {
    @error "Direction must be either `top`, `right`, `bottom` or `left`.";
  }

  width: 0;
  height: 0;
  content: '';
  z-index: 2;
  border-#{opposite-position($direction)}: ($size * 1.5) solid $color;
  
  $perpendicular-borders: $size solid transparent;
  
  @if $direction == top or $direction == bottom {
    border-left:   $perpendicular-borders;
    border-right:  $perpendicular-borders;
  } @else if $direction == right or $direction == left {
    border-bottom: $perpendicular-borders;
    border-top:    $perpendicular-borders;
  }
}

Zusätzliche Hinweise

* Die Funktion opposite-position stammt von Compass; wenn Sie Compass nicht verwenden, müssen Sie möglicherweise Ihre eigene haben;
* Das Mixin kümmert sich nicht um die Positionierung des Dreiecks; es ist jedoch durchaus möglich, es mit einem Positionierungs-Mixin zu kombinieren;
* Die Direktive content soll es ermöglichen, sie auf Pseudo-Elemente anzuwenden, was in den meisten Fällen tatsächlich der Fall ist.

Verwendung

.foo::before {
  @include triangle(bottom);
  position: absolute;
  left: 50%;
  bottom: 100%;
}
.foo::before {
  width: 0;
  height: 0;
  content: '';
  z-index: 2;
  border-top: 1.5em solid currentColor;
  border-left: 1em solid transparent;
  border-right: 1em solid transparent;
  position: absolute;
  left: 50%;
  bottom: 100%;
}