So erstellen Sie ein Flächendiagramm mit CSS

Avatar of Rami Yushuvaev
Rami Yushuvaev am

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

Sie kennen vielleicht ein paar Möglichkeiten, Diagramme mit reinem CSS zu erstellen. Einige davon werden hier auf CSS-Tricks behandelt und viele andere finden Sie auf CodePen, aber ich habe nicht viele Beispiele für „Flächendiagramme“ (stellen Sie sich ein Liniendiagramm mit gefüllter unterer Fläche vor) gesehen, insbesondere keine nur in HTML und CSS. In diesem Artikel werden wir genau das tun und dabei eine semantische und zugängliche HTML-Grundlage verwenden.

A red area chart against a dark gray background.

Beginnen wir mit dem HTML

Um die Dinge zu vereinfachen, verwenden wir `<ul>-Tags als Container und `<li>-Elemente für einzelne Datenelemente. Sie können je nach Bedarf beliebige andere HTML-Tags in Ihrem Projekt verwenden.

<ul class="area-chart">
  <li> 40% </li>
  <li> 80% </li>
  <li> 60% </li>
  <li> 100% </li>
  <li> 30% </li>
</ul>

CSS kann den inneren HTML-Text nicht abrufen, deshalb verwenden wir CSS-Custom-Properties, um Daten an unser CSS zu übergeben. Jedes Datenelement hat die benutzerdefinierten Eigenschaften `--start` und `--end`.

<ul class="area-chart">
  <li style="--start: 0.1; --end: 0.4;"> 40% </li>
  <li style="--start: 0.4; --end: 0.8;"> 80% </li>
  <li style="--start: 0.8; --end: 0.6;"> 60% </li>
  <li style="--start: 0.6; --end: 1.0;"> 100% </li>
  <li style="--start: 1.0; --end: 0.3;"> 30% </li>
</ul>

Was wir berücksichtigen müssen...

Es gibt mehrere Designprinzipien, die wir vor dem Styling berücksichtigen sollten

  • Dateneinheiten: Wir verwenden einheitenlose Daten in unserem HTML (d. h. keine `px`, `em`, `rem`, `%` oder andere Einheiten). Die benutzerdefinierten Eigenschaften `--start` und `--end` sind Zahlen zwischen 0 und 1.
  • Spaltenbreite: Wir werden keine feste `width` für jedes `<li>-Element festlegen. Wir werden auch keine `%` verwenden, da wir nicht wissen, wie viele Elemente vorhanden sind. Jede Spaltenbreite basiert auf der Breite des Hauptcontainers, geteilt durch die Gesamtzahl der Datenelemente. In unserem Fall ist das die Breite des `<ul>-Elements geteilt durch die Anzahl der `<li>-Elemente.
  • Barrierefreiheit: Die Werte in jedem `<li>` sind optional und nur die benutzerdefinierten Eigenschaften `--start` und `--end` sind erforderlich. Dennoch ist es am besten, eine Art Text oder Wert für Screenreader und andere assistive Technologien einzuschließen, um den Inhalt zu beschreiben.

Jetzt fangen wir mit dem Styling an!

Beginnen wir zuerst mit dem allgemeinen Layout-Styling. Das Diagramm-Wrapper-Element ist ein Flex-Container, der Elemente in einer Reihe anzeigt und jedes Kindelement streckt, sodass der gesamte Bereich gefüllt ist.

.area-chart {
  /* Reset */
  margin: 0;
  padding: 0;
  border: 0;

  /* Dimensions */
  width: 100%;
  max-width: var(--chart-width, 100%);
  height: var(--chart-height, 300px);

  /* Layout */
  display: flex;
  justify-content: stretch;
  align-items: stretch;
  flex-direction: row;
}

Wenn der Flächen-Diagramm-Wrapper eine Liste ist, sollten wir den Listenstil entfernen, um mehr Styling-Flexibilität zu erhalten.

ul.area-chart,
ol.area-chart {
  list-style: none;
}

Dieser Code stylt alle Spalten im gesamten Diagramm. Bei **Balkendiagrammen** ist es einfach: Wir verwenden `background-color` und `height` für jede Spalte. Bei **Flächendiagrammen** werden wir die `clip-path`-Eigenschaft verwenden, um den anzuzeigenden Bereich festzulegen.

Zuerst richten wir jede Spalte ein

.area-chart > * {
  /* Even size items */
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;

  /* Color */
  background: var(--color, rgba(240, 50, 50, .75));
}

Um ein Rechteck zu erstellen, das den *gesamten* Bereich abdeckt, greifen wir zur `clip-path`-Eigenschaft und verwenden ihre `polygon()`-Funktion, die die Koordinaten des Bereichs enthält. Dies tut im Moment im Grunde nichts, da das Polygon alles abdeckt

.area-chart > * {
  clip-path: polygon(
    0% 0%,     /* top left */
    100% 0%,   /* top right */
    100% 100%, /* bottom right */
    0% 100%    /* bottom left */
  );
}

Jetzt zum besten Teil!

Um nur einen Teil der Spalte anzuzeigen, schneiden wir sie zu, um diesen flächendiagrammähnlichen Effekt zu erzielen. Um nur den gewünschten Bereich anzuzeigen, verwenden wir die benutzerdefinierten Eigenschaften `--start` und `--end` innerhalb des `clip-path`-Polygons

.area-chart > * {
  clip-path: polygon(
    0% calc(100% * (1 - var(--start))),
    100% calc(100% * (1 - var(--end))),
    100% 100%,
    0% 100%
  );
}

Ernsthaft, dieses eine Stück CSS erledigt *die gesamte* Arbeit. Hier ist, was wir bekommen

Arbeiten mit mehreren Datensätzen

Nachdem wir nun die Grundlagen kennen, erstellen wir ein Flächendiagramm mit mehreren Datensätzen. Flächendiagramme messen oft mehr als eine Datenmenge und der Effekt ist ein geschichteter Vergleich der Daten.

Diese Art von Diagramm erfordert mehrere Kindelemente, daher ersetzen wir unseren `<ul>-Ansatz durch eine `<table>`.

<table class="area-chart">
  <tbody>
    <tr>
      <td> 40% </td>
      <td> 80% </td>
    </tr>
    <tr>
      <td> 60% </td>
      <td> 100% </td>
    </tr>
  </tbody>
</table>

Tabellen sind barrierefrei und suchmaschinenfreundlich. Und wenn das Stylesheet aus irgendeinem Grund nicht geladen wird, sind alle Daten immer noch in der Markup sichtbar.

Auch hier verwenden wir die benutzerdefinierten Eigenschaften `--start` und `--end` mit Zahlen zwischen 0 und 1.

<table class="area-chart">
  <tbody>
    <tr>
      <td style="--start: 0; --end: 0.4;"> 40% </td>
      <td style="--start: 0; --end: 0.8;"> 80% </td>
    </tr>
    <tr>
      <td style="--start: 0.4; --end: 0.6;"> 60% </td>
      <td style="--start: 0.8; --end: 1.0;"> 100% </td>
    </tr>
  </tbody>
</table>

Zuerst stylen wir das allgemeine Layout für das Wrapper-Element, unsere Tabelle, der wir die Klasse `.area-chart` gegeben haben

.area-chart {
  /* Reset */
  margin: 0;
  padding: 0;
  border: 0;

  /* Dimensions */
  width: 100%;
  max-width: var(--chart-width, 600px);
  height: var(--chart-height, 300px);
}

Als Nächstes machen wir das `<tbody>-Element zu einem Flex-Container, der die `<tr>-Elemente in einer Reihe und gleichmäßig groß anzeigt

.area-chart tbody {
  width: 100%;
  height: var(--chart-height, 300px);

  /* Layout */
  display: flex;
  justify-content: stretch;
  align-items: stretch;
  flex-direction: row;
}
.area-chart tr {
  /* Even size items */
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

Jetzt müssen wir dafür sorgen, dass sich die `<td>-Elemente überlappen, wobei ein Element über dem anderen liegt, damit wir diesen geschichteten Effekt erzielen. Jedes `<td>` deckt den gesamten Bereich des `<tr>-Elements ab, das es enthält.

.area-chart tr {
  position: relative;
}
.area-chart td {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

Nutzen wir die magischen Kräfte von `clip-path: polygon()`! Wir zeigen nur den Bereich zwischen den benutzerdefinierten Eigenschaften `--start` und `--end`, die wiederum Werte zwischen 0 und 1 sind

.area-chart td {
  clip-path: polygon(
    0% calc(100% * (1 - var(--start))),
    100% calc(100% * (1 - var(--end))),
    100% 100%,
    0% 100%
  );
}

Fügen wir nun Farbe zu jedem hinzu

.area-chart td {
  background: var(--color);
}
.area-chart td:nth-of-type(1) {
  --color: rgba(240, 50, 50, 0.75);
}
.area-chart td:nth-of-type(2) {
  --color: rgba(255, 180, 50, 0.75);
}
.area-chart td:nth-of-type(3) {
  --color: rgba(255, 220, 90, 0.75);
}

Es ist wichtig, Farben mit Deckkraft zu verwenden, um einen schöneren Effekt zu erzielen, deshalb verwenden wir `rgba()`-Werte. Sie könnten hier auch `hsla()` verwenden, wenn das Ihr Ding ist.

Und schon ist es fertig

Zusammenfassung

Es spielt keine Rolle, wie viele HTML-Elemente wir unserem Diagramm hinzufügen, das **Flex-basierte Layout** sorgt dafür, dass alle Elemente gleich groß sind. Auf diese Weise müssen wir nur die Breite des Diagramm-Wrapper-Elements festlegen und die Elemente passen sich entsprechend für ein responsives Layout an.

Wir haben eine Technik zur Erstellung von Flächendiagrammen mit reinem CSS behandelt. Für fortgeschrittene Anwendungsfälle können Sie sich mein neues Open-Source-Framework für Datenvisualisierung ansehen, ChartsCSS.org. Sehen Sie sich den Abschnitt Area Chart an, um zu sehen, wie Flächendiagramme mit Dingen wie verschiedenen Ausrichtungen, Achsen und sogar einer umgekehrten Reihenfolge ohne Änderung des HTML-Markups und vielem mehr angepasst werden können!