Oh, die vielen Wege, um dreieckige Breadcrumb-Bänder zu erstellen!

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Oh, die vielen Möglichkeiten, dreieckige Breadcrumb-Bänder zu erstellen

Schauen wir uns an, wie wir eine Reihe von Links erstellen können, die mit einer pfeilähnlichen Form und einer Einkerbung an jedem Block ineinander übergehen, wie man sie vielleicht in einer hierarchischen Breadcrumb-Navigation sieht.

Dieses Muster ist Ihnen wahrscheinlich schon oft aufgefallen. Es taucht häufig in Dingen wie mehrstufigen Formularen und Website-Breadcrumbs auf. Für unsere Zwecke nennen wir diese "Bänder", damit wir wissen, wovon wir sprechen, während wir weitermachen.

Wie viele Dinge im Web können wir solche Bänder auf vielfältige Weise erstellen! Ich habe eine Demo-Seite erstellt, die eine Vielzahl davon zusammenbringt, wie z. B. die Verwendung von CSS-Dreiecken, SVG-Hintergründen und der CSS-Eigenschaft clip-path.

Beginnen wir mit der HTML-Struktur

Für jede Demo ist die HTML-Struktur weitgehend dieselbe, wobei wir ein <nav> als Elternelement und dann Links als Kinder darin haben.

<nav class="ribbon ribbon--modifier" role="navigation" aria-label="breadcrumbs">
  <a class="ribbon__element" href="https://www.silvestar.codes/">Home</a>
  <a class="ribbon__element" href="https://www.silvestar.codes/categories/articles/">Blog</a>
  <a class="ribbon__element" href="https://www.silvestar.codes/articles/building-an-animated-sticky-header-with-custom-offset/" aria-current="page">Post</a>
</nav>

Beachten Sie, dass diese Elemente gemäß der A11y Style Guide Website barrierefrei sein sollten. Es ist eine gute Regel, Komponenten mit Blick auf Barrierefreiheit zu erstellen, und die Barrierefreiheit von Anfang an einzuführen, ist der beste Weg, die klassische Situation "Ich habe vergessen, es barrierefrei zu machen" zu vermeiden.

Lassen Sie uns einige Grundstile erstellen

Bei solchen Dingen möchten wir sicherstellen, dass die Größenbestimmung der Elemente korrekt erfolgt. Zu diesem Zweck definieren wir die Schriftgröße des .ribbon (so nennen wir diese Dinger) Wrapper-Elements und verwenden dann em-Einheiten für das Kindelement, das sind die Links selbst.

/* Define font size of the wrapper element */ 
.ribbon {
  font-size: 15px;
}

/* Use ems to define the size of the ribbon element */ 
.ribbon__element {
  font-size: 1.5em;
  letter-spacing: 0.01em;
  line-height: 1.333em;
  padding: 0.667em 0.667em 0.667em 1.333em;
}

Diese spezielle Technik wäre vorteilhaft für die Definition der Größe der Dreiecksform für jedes Band, da wir dieselben Größen verwenden würden, um das Dreieck zu berechnen. Und da wir em-Einheiten verwenden, um die Größe des Bandelements zu berechnen, könnten wir alle Elemente durch Neudefinition der font-size auf dem Wrapper-Element ändern.

Wir verwenden CSS Grid für das Layout, weil wir es können. Wir könnten dies auf eine Weise tun, die eine tiefere Browserunterstützung bietet, aber das überlassen wir Ihnen, basierend auf Ihren Support-Anforderungen.

Wir werden vier Spalten definieren

  • Drei für Bandelemente
  • Eine, um Abständigkeitsprobleme zu beheben. Wie es ist, würde die rechte Pfeilform *außerhalb* der Bandkomponente platziert werden, und das könnte das ursprüngliche Layout durcheinander bringen.
/* The wrapper element 
 * We're using CSS Grid, but ensure that meets your browser support requirements.
 * Assuming the use of autoprefixer for vendor prefixes and properties.
 */
  
.ribbon {
  display: grid;
  grid-gap: 1px;
  grid-template-columns: repeat(auto-fill, 1fr) 1em; /* Auto-fill the three ribbon elements plus one narrow column to fix the sizing issues */
}

Wenn Sie es vorziehen, die Bandelemente nicht zu strecken, könnte das Raster anders definiert werden. Zum Beispiel könnten wir max-content verwenden, um Spalten nach Inhalt zu skalieren. (Beachten Sie jedoch, dass max-content noch nicht sehr gut unterstützt wird in einigen wichtigen Browsern.)

/* Make ribbon columns adjust to the maximum content size */
.ribbon--auto {
  grid-template-columns: repeat(3, max-content) 1em;
}

Ich bin sicher, es gibt viele verschiedene Wege, wie wir das Layout gestalten könnten. Ich mag diesen, weil er den genauen Abstand zwischen den Bandelementen ohne komplizierte Berechnungen definiert.

Barrierefreiheit bedeutet nicht nur das Hinzufügen von Aria-Attributen. Sie umfasst auch Farbkontrast und Lesbarkeit sowie das Hinzufügen von Hover- und Fokus-Zuständen. Wenn Sie den outline-Stil nicht mögen, könnten Sie zum Beispiel andere CSS-Eigenschaften wie box-shadow verwenden.

/* Use current link color, but add underline on hover  */
.ribbon__element:hover, 
.ribbon__element:active {
  color: inherit;
  text-decoration: underline;
}

/* Clear default outline style and use inset box shadow for focus state */
.ribbon__element:focus {
  box-shadow: inset 0 -3px 0 0 #343435;
  outline: none;
}

Die einzigartige Dreiecksform erstellen

Wir haben mehr als eine Option, wenn es darum geht, das Dreieck am Ende jedes Bandes zu definieren. Wir könnten

  1. Wir könnten ein Dreieck mit Rändern mit Pseudoelementen erstellen
  2. Wir könnten ein SVG-Hintergrundbild auf Pseudoelementen verwenden
  3. Wir könnten Inline-SVG-Bilder verwenden
  4. Wir könnten einen clip-path mit der Funktion polygon() erstellen

Lassen Sie uns in jedes einzelne eintauchen.

Option 1: Der Randansatz

Zuerst sollten wir die Breite und Höhe des Elements auf Null setzen, damit es nicht im Weg der Pseudoelemente ist, die wir zum Zeichnen des Dreiecks mit Rändern verwenden. Dann sollten wir das Dreieck mit Rändern zeichnen, insbesondere indem wir einen durchgehenden linken Rand definieren, der der Hintergrundfarbe entspricht, um ihn mit dem Rest des Bandes zu verbinden. Von dort definieren wir obere und untere Ränder und machen sie transparent. Der Trick hier ist, die Größe des Randes zu berechnen.

Unser Bandelement hat eine Inhaltsgröße, die dem Wert der line-height plus den oberen und unteren Abständen entspricht.

1.333em + 0.667em + 0.667em = 2.667em

Das bedeutet, dass unsere oberen und unteren Ränder die halbe Größe davon haben sollten. Das Einzige, was noch zu tun ist, ist, die Elemente absolut an der richtigen Seite der Komponente zu positionieren.

/* The left arrow */
.ribbon--alpha .ribbon__element:before {
  /* Make the content size zero */
  content: '';  
  height: 0;  
  width: 0;

  /* Use borders to make the pseudo element fit the ribbon size */
  border-bottom: 1.333em solid transparent;
  border-left: 0.667em solid #fff;
  border-top: 1.333em solid transparent;

  /* Position the element absolutely on the left side of the ribbon element */
  position: absolute;
  top: 0;  
  bottom: 0;  
  left: 0;
}

/* The right arrow */
.ribbon--alpha .ribbon__element:after {
  /* Make the content size zero */
  content: '';  
  height: 0;  
  width: 0;

  /* Use borders to make the pseudo-element fit the ribbon size */
  border-bottom: 1.333em solid transparent;
  border-left: 0.667em solid;
  border-top: 1.333em solid transparent;

  /* Position the element absolutely on the right side of the ribbon element and push it outside */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  -webkit-transform: translateX(0.667em);
  transform: translateX(0.667em);
}

Da das rechte Dreieck der Hintergrundfarbe des Bandes entsprechen sollte, denken Sie daran, die richtige Randfarbe für das Pseudoelement jedes Bandes hinzuzufügen.

/* The right arrow of the first element */
.ribbon--alpha .ribbon__element:nth-child(1):after {
  border-left-color: #11d295;
}

/* The right arrow of the second element */
.ribbon--alpha .ribbon__element:nth-child(2):after {
  border-left-color: #ef3675;
}

/* The right arrow of the third element */
.ribbon--alpha .ribbon__element:nth-child(3):after {
  border-left-color: #4cd4e9;
}

Und da haben wir es!

Siehe den Pen
CSS Grid Ribbon – Alpha
von Silvestar Bistrović (@CiTA)
auf CodePen.

Option 2: Der Hintergrundbildansatz

Wir können auch ein Dreieck mit einem Hintergrundbild erstellen. Dies erfordert das Erstellen eines Bildes, das zum Design passt, was etwas umständlich ist, aber dennoch absolut möglich. Wir werden hier SVG verwenden, da es bei jeder Auflösung scharf ist.

Im Gegensatz zum Randdreiecksansatz möchten wir die Höhe unseres Pseudoelements an die Höhe des Bandelements anpassen, also 100 %. Die Breite der Komponente sollte der Breite des linken Randes des Randdreiecks entsprechen, die in unserem Fall 0,666666em beträgt. Dann sollten wir ein weißes Dreieck für das Hintergrundbild auf dem Dreieck der linken Seite verwenden und dann Dreiecksbilder mit Farbe für die Dreiecke auf der rechten Seite. Wiederum verwenden wir absolute Positionierung, um unsere Dreiecke an der richtigen Seite des Bandelements zu platzieren.

/* The left arrow */
.ribbon--beta .ribbon__element:before {
  /* Define the arrow size */
  content: '';  
  height: 100%;  
  width: 0.666666em;
  
  /* Define the background image that matches the background color */
  background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSIjZmZmIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=);
  background-position: center left;
  background-repeat: no-repeat;
  background-size: 100%;
  
  /* Position the element absolutely on the left side of the ribbon element */
  position: absolute;
  bottom: 0;
  top: 0;
  left: 0;
}

/* The right arrow */
.ribbon--beta .ribbon__element:after {
  /* Define the arrow size */
  content: '';  
  height: 100%;
  width: 0.667em;

  /* Define the background image attributes */
  background-position: center left;
  background-repeat: no-repeat;
  background-size: 100%;

  /* Position the element absolutely on the right side of the ribbon element and push it outside */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  -webkit-transform: translateX(0.667em);
  transform: translateX(0.667em);
}

/* Define the background image that matches the background color of the first element */
.ribbon--beta .ribbon__element:nth-child(1):after {
  background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjMTFkMjk1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=);
}

/* Define the background image that matches the background color of the second element */
.ribbon--beta .ribbon__element:nth-child(2):after {
  background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjZWYzNjc1IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=);
}

/* Define the background image that matches the background color of the third element */
.ribbon--beta .ribbon__element:nth-child(3):after {
  background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjQwIiB2aWV3Qm94PSIwIDAgMTAgNDAiIHdpZHRoPSIxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSAxNSAyMCAxMGgtNDB6IiBmaWxsPSIjNGNkNGU5IiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0ibWF0cml4KDAgLTEgLTEgMCAyNSAyNSkiLz48L3N2Zz4=);
}

Da haben wir es!

Siehe den Pen
CSS Grid Ribbon – Beta
von Silvestar Bistrović (@CiTA)
auf CodePen.

Option 3: Der Inline-SVG-Ansatz

Anstatt ein anderes SVG-Dreieck für jedes Hintergrundbild zu laden, könnten wir Inline-SVG direkt in HTML verwenden.

Dieser spezielle Ansatz ermöglicht es uns, die fill-Farbe jedes SVG-Pfeils mit CSS zu steuern. Die Pfeilgröße wird durch die Bandgröße bestimmt. Wiederum verwenden wir em-Einheiten, um die Größe zu definieren, und die Pfeile sind wie bei den anderen bisher gesehenen Ansätzen absolut positioniert.

/* Position arrows absolutely and set the correct size */
.ribbon--gamma .ribbon__element svg {
  height: 2.667em;
  position: absolute;
  top: 0;
  width: 0.667em;
}

/* The left arrow */
.ribbon--gamma .ribbon__element svg:first-child {
  fill: #fff; /* Define the background image that matches the background color */
  left: 0; /* Stick left arrows to the left side of the ribbon element */
}

/* The right arrow */
.ribbon--gamma .ribbon__element svg:last-child {
  left: 100%; /* Push right arrows outside of the ribbon element */
}

/* Define the fill color that matches the background color of the first element */
.ribbon--gamma .ribbon__element:nth-child(1) svg:last-child {
  fill: #11d295;
}

/* Define the fill color that matches the background color of the second element */
.ribbon--gamma .ribbon__element:nth-child(2) svg:last-child {
  fill: #ef3675;
}

/* Define the fill color that matches the background color of the third element */
.ribbon--gamma .ribbon__element:nth-child(3) svg:last-child {
  fill: #4cd4e9;
}

Siehe den Pen
CSS Grid Ribbon – Gamma
von Silvestar Bistrović (@CiTA)
auf CodePen.

Option 4: Der Clip-Path-Ansatz

Wir können die Banddreiecke mit einem Polygon erstellen, das den Hintergrund maskiert. Der Shape-Editor von Firefox ist ein fantastisches Werkzeug, um Formen direkt im Browser mit einer GUI zu zeichnen, ebenso wie Clippy.

Da Polygone mit Prozentwerten erstellt werden müssen, sollten wir unser Bestes tun, um die Größe der Randdreiecke anzupassen. Beachten Sie auch, dass prozentbasierte Polygone auf einigen Viewports vielleicht etwas seltsam aussehen, besonders wenn sich die Elementgrößen an ihre Umgebung anpassen, wie z. B. Wrapper-Elemente. Erwägen Sie, Polygone für verschiedene Viewports neu zu definieren.

.ribbon--delta .ribbon__element {
  clip-path: polygon(95% 0, 100% 50%, 95% 100%, 0% 100%, 5% 50%, 0% 0%);
}

Da wir unser Wrapper-Element mit CSS Grid definiert haben, sollten wir die Bandelemente erweitern, aber das letzte Element auf die Größe des Polygon-Dreiecks, also 5 %, belassen. Das letzte Bandelement sollte um die Größe der Randdreiecksbreite breiter sein, um mit den ersten beiden Beispielen übereinzustimmen.

/* Make all ribbon elements (except the last one) wider by the size of the polygon triangle */
.ribbon--delta .ribbon__element:not(:last-child) {
  width: 105%;
}

/* Make the last ribbon element wider by the size of the border triangle */
.ribbon--delta .ribbon__element:last-child {
  width: calc(100% + .667em);
}

Siehe den Pen
CSS Grid Ribbon – Delta
von Silvestar Bistrović (@CiTA)
auf CodePen.

Variationen dieser Optionen

Nachdem wir nun gelernt haben, wie man das Breadcrumb-Band auf verschiedene Arten erstellt, könnten wir damit spielen, z. B. Schatten oder Verläufe hinzufügen und verschiedene Größen verwenden.

Einen Schatten hinzufügen

Wir könnten den Schatten zu unseren Bandelementen hinzufügen. Achten Sie darauf, den Schatten auf der linken oder rechten Seite des Bandelements zu vermeiden.

/* Add shadow under each ribbon element */
.ribbon--shadow .ribbon__element {
  box-shadow: 1px 3px 3px -3px black;
}

Siehe den Pen
CSS Grid Ribbon – Shadow
von Silvestar Bistrović (@CiTA)
auf CodePen.

Verläufe für Farbe verwenden

Wir könnten Verläufe zu unserem Bandelement hinzufügen. Achten Sie darauf, die Farbe des rechten Dreiecks dabei anzupassen. Achten Sie außerdem darauf, die Zugänglichkeitsrichtlinien für Kontraste einzuhalten.

Wenn wir beispielsweise den Randansatz oder den Hintergrundbildansatz verwenden, sollten wir hauptsächlich horizontale (d. h. von links nach rechts) Verläufe verwenden (mit Ausnahmen einiger sorgfältig berechneter schräger Verläufe). Wenn wir den clip-path-Ansatz verwenden, können wir jede gewünschte Verlaufsversion verwenden.

/* Add gradient to the first ribbon element */
.ribbon--gradient .ribbon__element:nth-child(1) {
  background-image: linear-gradient(to right, #11ced2, #11d295);
}

/* Add gradient to the second ribbon element */
.ribbon--gradient .ribbon__element:nth-child(2) {
  background-image: linear-gradient(to right, #ef36b2, #ef3675);
}

/* Add gradient to the third ribbon element */
.ribbon--gradient .ribbon__element:nth-child(3) {
  background-image: linear-gradient(to right, #4c9fe9, #4cd4e9);
}

Siehe den Pen
CSS Grid Ribbon – Gradient
von Silvestar Bistrović (@CiTA)
auf CodePen.

Mit Größenvariationen arbeiten

Da die Größe unserer Bandelemente von der Schriftgröße des Wrapper-Elements abhängt, ist die Definition verschiedener Größen ziemlich einfach.

/* Small ribbons */
.ribbon--small {
  font-size: 10px;
}

/* Big ribbons */
.ribbon--big {
  font-size: 20px;
}

Hier ist ein kleineres Set von Bändern

Siehe den Pen
CSS Grid Ribbon – Small
von Silvestar Bistrović (@CiTA)
auf CodePen.

Und hier ist ein schönes Set von klobigen Bändern

Siehe den Pen
CSS Grid Ribbon – Big
von Silvestar Bistrović (@CiTA)
auf CodePen.

Kombinieren Sie alles!

Wir können auch verschiedene Modifikatorklassen kombinieren, um noch mehr Styling zu erreichen. Verwenden wir zum Beispiel Gradienten- und Schattenmodifikatoren zusammen

Siehe den Pen
CSS Grid Ribbon – Shadow Gradient
von Silvestar Bistrović (@CiTA)
auf CodePen.

Gibt es andere Winkel zu beachten?

Das Erstellen von benutzerdefinierten Elementen mit verschiedenen CSS-Techniken ist eine großartige Möglichkeit, wie jeder von uns sein Wissen verbessern oder auffrischen kann. Vor Beginn lohnt es sich, einige Gedanken über die Wartbarkeit und Modularität der zu erstellenden Komponente zu investieren. Eine konsistente Namenskonvention, wie BEM, ist sicherlich hilfreich. Barrierefreiheit ist ebenfalls ein wichtiges Thema, daher ist es von Vorteil, von Anfang an daran zu denken und Barrierefreiheitsmerkmale im Laufe der Zeit zu dokumentieren.

Wir haben uns vier verschiedene Ansätze zur Erstellung von Banddreiecken angesehen. Haben Sie einen anderen Ansatz verwendet oder kennen Sie einen, den wir hier noch nicht berücksichtigt haben? Lassen Sie es mich in den Kommentaren wissen!