clip-path shape(): kurvige Pfade direkt in CSS statt SVG-Pfad-Strings
AI generated
{ }
@
CSS · Formen · Layout · Grafik
clip-path: shape()
Kurvige Pfade direkt in CSS, ohne einen einzigen SVG-Pfad-String zu schreiben

Die shape()-Funktion erweitert clip-path um echte Kurvenbefehle wie curve to, arc to und smooth to, direkt in lesbarer CSS-Syntax. Wo bisher nur ein externes SVG oder eine grobe Polygon-Annäherung half, entstehen jetzt organische, kurvige Formen ohne Build-Step und ohne Pfad-Editor.

13 Min. Lesezeit shape() · curve to · arc to Chrome · Edge · Firefox (aktuell)

1. Was die shape()-Funktion ist und welches Problem sie löst

Bis vor kurzem kannte clip-path im Wesentlichen zwei Wege, um eine Form zu beschreiben: gerade Linien über polygon() oder eine komplette, extern eingebundene SVG-Datei mit einem <clipPath>-Element. Für alles, was Kurven, Bögen oder weiche Übergänge braucht, blieb bisher nur der Umweg über SVG, oft erzeugt in einem Grafikprogramm und dann als Pfad-String kopiert, der für Menschen kaum lesbar und noch schwerer von Hand anzupassen war.

shape() schließt genau diese Lücke, indem es echte Kurvenbefehle direkt als CSS-Funktionswert einführt. Statt eines kryptischen SVG-d-Attributs wie M10 10 C 20 20, 40 20, 50 10 steht jetzt eine sprechende Syntax wie curve to 50px 10px with 20px 20px zur Verfügung, die sich direkt im Stylesheet liest, versteht und mit CSS-Werten wie calc() oder Custom Properties kombinieren lässt, was bei einem SVG-Pfad-String schlicht nicht möglich ist.

2. Grundsyntax: from, line to, curve to und close

Eine shape()-Deklaration beginnt immer mit from <startpunkt> und listet danach eine Folge von Befehlen auf, die von diesem Punkt aus einen Pfad zeichnen. line to zeichnet eine gerade Linie zum angegebenen Punkt, genau wie ein Eckpunkt in polygon(), während curve to <zielpunkt> with <kontrollpunkt> eine quadratische oder mit zwei Kontrollpunkten eine kubische Bézierkurve zeichnet. Der Befehl close am Ende schließt den Pfad zurück zum Startpunkt, exakt wie Z in SVG.

Alle Koordinaten akzeptieren die üblichen CSS-Längeneinheiten, Prozentwerte relativ zur Referenzbox des Elements und sogar calc()-Ausdrücke, wodurch sich eine Form mit einer festen Randbreite von zum Beispiel 20 Pixel unabhängig von der tatsächlichen Elementgröße beschreiben lässt. Das ist ein Vorteil, den ein statischer SVG-Pfad-String von Natur aus nicht bietet, weil dessen Koordinaten beim Export fest eingebrannt werden.


/* Ein Dreieck mit einer abgerundeten Spitze */
.rounded-triangle {
  clip-path: shape(
    from 50% 0%,
    line to 100% 100%,
    curve to 0% 100% with 50% 130%,
    close
  );
}

3. shape() vs. polygon(): wann welches Werkzeug

polygon() bleibt die richtige Wahl für alles, was tatsächlich aus geraden Kanten besteht, etwa ein Chevron, ein Pfeil oder ein schräg abgeschnittener Hero-Bereich. Die Syntax ist kompakt, jeder Punkt ist eine simple Koordinate, und es gibt keinen Grund, dafür Kurvenbefehle zu bemühen, die am Ende doch nur eine Gerade beschreiben würden.

Sobald aber eine Kante tatsächlich rund oder organisch wirken soll, zeigt sich der Unterschied deutlich: Eine runde Form mit polygon() nachzubilden bedeutet, sie in viele kleine gerade Segmente zu zerlegen, was entweder kantig aussieht oder eine große Zahl an Koordinatenpaaren erfordert, die kaum noch von Hand zu pflegen sind. shape() beschreibt dieselbe Rundung mit einem einzigen curve to- oder arc to-Befehl, bei exakt gleichem Rendering-Ergebnis, aber lesbarer Quelle.

4. Organische Formen bauen: mehrere curve-to-Befehle kombinieren

Für eine frei geformte, blob-artige Fläche reihen sich mehrere curve to-Befehle aneinander, wobei jeder Kontrollpunkt bestimmt, wie stark die Kurve in diesem Abschnitt nach außen oder innen ausbaucht. Der praktische Arbeitsablauf ist meist iterativ: grobe Eckpunkte wie bei einem Polygon festlegen, dann Stück für Stück line to durch curve to ersetzen und die Kontrollpunkte im Browser-DevTools-Formen-Editor live verschieben, bis die Silhouette organisch wirkt.

Ein Vorteil gegenüber einem SVG-Export aus einem Design-Tool ist, dass jeder einzelne Punkt und jede Kurve im Quellcode benannt und nachvollziehbar bleibt. Wer später nur die obere Kante anpassen will, ändert genau den betroffenen curve to-Befehl, statt einen kompletten, maschinengenerierten Pfad-String zu durchsuchen und das richtige Zahlenpaar darin zu erraten.


/* Organische Blob-Form aus vier Kurvensegmenten */
.blob {
  clip-path: shape(
    from 20% 0%,
    curve to 100% 35% with 70% 0%,
    curve to 75% 100% with 100% 70%,
    curve to 0% 65% with 30% 100%,
    curve to 20% 0% with 0% 30%,
    close
  );
}

5. arc to: echte Kreisbögen ohne Bézier-Annäherung

Neben curve to für Bézierkurven bietet shape() mit arc to einen eigenen Befehl für echte Kreis- und Ellipsenbögen, angegeben über Zielpunkt, Radius und Richtung (cw für im Uhrzeigersinn, ccw für gegen den Uhrzeigersinn). Das ist der entscheidende Unterschied zu einer Bézierkurve, die einen Kreis immer nur annähert: Ein arc to-Bogen ist geometrisch exakt, was bei abgerundeten Ecken oder kreisförmigen Aussparungen sichtbar glattere Ergebnisse liefert als eine grob abgeschätzte Kurve.

Damit lassen sich zum Beispiel abgerundete Rechtecke mit exakt definiertem Eckenradius bauen, ganz ohne border-radius, was immer dann nützlich ist, wenn die Form Teil eines größeren clip-path-Konstrukts ist und border-radius allein nicht ausreicht, weil zusätzlich eine gerade Kante an anderer Stelle abgeschnitten werden muss.


/* Abgerundetes Rechteck ueber vier arc-to-Befehle */
.rounded-cutout {
  clip-path: shape(
    from 0 20px,
    arc to 20px 0 of 20px cw,
    line to calc(100% - 20px) 0,
    arc to 100% 20px of 20px cw,
    line to 100% calc(100% - 20px),
    arc to calc(100% - 20px) 100% of 20px cw,
    line to 20px 100%,
    arc to 0 calc(100% - 20px) of 20px cw,
    close
  );
}

6. shape() animieren: weiche Formübergänge ohne JavaScript

Weil zwei shape()-Werte mit der gleichen Anzahl und Reihenfolge an Befehlen interpolierbar sind, kann der Browser zwischen ihnen sauber animieren, etwa bei einem Hover-Zustand, der eine Blob-Form leicht verzerrt, oder einem Scroll-getriebenen Übergang von einer runden zu einer eckigen Silhouette. Vorausgesetzt ist lediglich, dass Start- und Zielform strukturell zueinander passen, also dieselbe Zahl an curve to- oder arc to-Befehlen in derselben Reihenfolge verwenden.

Das ist ein klarer Vorteil gegenüber der Animation eines SVG-path-Attributs, das ohne zusätzliche JavaScript-Bibliothek wie GSAP kaum sinnvoll interpolierbar ist, weil der Browser zwei beliebige Pfad-Strings nicht automatisch aufeinander abbildet. Mit shape() reicht eine einfache CSS-transition-Deklaration auf clip-path, und der Browser übernimmt die komplette Interpolation der einzelnen Koordinaten.


.blob-interactive {
  clip-path: shape(from 20% 0%, curve to 100% 35% with 70% 0%,
    curve to 75% 100% with 100% 70%, curve to 0% 65% with 30% 100%,
    curve to 20% 0% with 0% 30%, close);
  transition: clip-path 0.4s ease;
}

.blob-interactive:hover {
  clip-path: shape(from 15% 0%, curve to 100% 25% with 80% 0%,
    curve to 80% 100% with 100% 80%, curve to 0% 75% with 20% 100%,
    curve to 15% 0% with 0% 20%, close);
}

7. Browser-Unterstützung und Fallback auf polygon()

shape() ist neuer als polygon() und die Unterstützung in aktuellen Browsern wächst, ist aber noch nicht so flächendeckend wie bei den etablierten clip-path-Funktionen. Der pragmatische Umgang damit ist ein zweistufiges Fallback: Zunächst eine grobe polygon()-Näherung deklarieren, die in jedem Browser funktioniert, und direkt danach die feinere shape()-Version, die in Browsern mit Unterstützung die vorherige Deklaration überschreibt.

Eine @supports-Abfrage macht diese Absicherung explizit und verhindert, dass in älteren Browsern eine komplett eckige oder gar keine Form angezeigt wird. Wichtig ist dabei, dass die polygon()-Näherung optisch nah genug an der Zielform liegt, damit der Unterschied für Nutzer ohne shape()-Unterstützung nicht als Bruch wahrgenommen wird, sondern höchstens als etwas kantigere Variante derselben Form.


.blob {
  /* Fallback: grobe Polygon-Naeherung fuer aeltere Browser */
  clip-path: polygon(20% 0%, 65% 5%, 100% 35%, 90% 70%, 75% 100%, 35% 95%, 0% 65%, 5% 25%);
}

@supports (clip-path: shape(from 0 0, line to 100% 100%)) {
  .blob {
    clip-path: shape(from 20% 0%, curve to 100% 35% with 70% 0%,
      curve to 75% 100% with 100% 70%, curve to 0% 65% with 30% 100%,
      curve to 20% 0% with 0% 30%, close);
  }
}

8. Praktischer Workflow: DevTools-Editor, Design-Tools und Wartbarkeit

Aktuelle Browser-DevTools bieten mittlerweile einen visuellen Editor für clip-path-Werte, der auch shape()-Pfade direkt im Canvas anfasst und verschiebt, ähnlich wie ein Vektor-Werkzeug in einem Design-Programm. Das beschleunigt die Feinabstimmung erheblich, weil Kontrollpunkte per Maus statt durch wiederholtes Ändern von Zahlenwerten im Editor angepasst werden können, während das Ergebnis sofort als lesbarer CSS-Wert im Stylesheet landet.

Gegenüber einem in Figma oder Illustrator exportierten SVG-Pfad bleibt shape() außerdem Teil des CSS-Build-Prozesses, ohne zusätzliche Asset-Datei, zusätzlichen HTTP-Request oder eine separate Pflege zwischen Design-Tool und Repository. Für ein Team, das Formen häufiger anpasst, etwa bei saisonalen Kampagnenseiten, reduziert das die Reibung zwischen Design und Umsetzung spürbar.

9. Praxis-Einsatz: Kampagnenflächen, Badges und dekorative Trenner

Im Shop-Kontext eignet sich shape() besonders für saisonale Kampagnenflächen mit organischer Silhouette, für Badge- und Sticker-Elemente mit weichen statt scharfen Ecken, und für dekorative Section-Trenner, die einen sanften Wellenverlauf statt einer harten Kante zwischen zwei Bereichen zeichnen. In allen drei Fällen ersetzt eine einzige shape()-Deklaration ein zusätzliches SVG-Asset, das sonst separat gehostet, geladen und bei jeder Design-Anpassung neu exportiert werden müsste.

Wichtig bleibt auch hier, die Form als rein dekoratives Element zu behandeln: Interaktive Bereiche wie Buttons oder Links sollten niemals ausschließlich über eine shape()-Kontur klickbar gemacht werden, ohne die zugrunde liegende Klickfläche für Tastatur- und Screenreader-Nutzung ausreichend groß zu halten.

Funktion Kurven möglich Lesbarkeit Typischer Einsatz
polygon() Nein, nur gerade Kanten Hoch, einfache Koordinaten Chevrons, Pfeile, schräge Sections
shape() mit curve to Ja, Bézierkurven Hoch, benannte Befehle Organische Blobs, weiche Kanten
shape() mit arc to Ja, echte Kreisbögen Hoch, benannte Befehle Präzise Rundungen, Kreisausschnitte
Externes SVG clipPath Ja, beliebig komplex Niedrig, generierter Pfad-String Sehr komplexe, statische Illustrationen

Mironsoft

Modernes CSS, Layout-Architektur und Rendering-Performance

CSS, das wartbar bleibt statt mit jeder Änderung zu brechen?

Wir prüfen bestehende Stylesheets auf Spezifitäts-Chaos und Layout-Thrashing und bauen daraus eine CSS-Architektur mit Cascade Layers, Custom Properties und modernen Layout-Primitiven, die auch nach dem zehnten Feature noch verständlich ist.

CSS-Audit

Spezifität, Cascade-Konflikte und ungenutzte Selektoren systematisch aufdecken.

Architektur-Refactoring

Cascade Layers, Custom Properties und Design Tokens sauber einführen.

Performance-Tuning

Layout-Thrashing, teure Selektoren und Rendering-Engpässe gezielt beheben.

10. Zusammenfassung

clip-path shape() in CSS: Das Wichtigste auf einen Blick

Grundprinzip

shape() bringt echte Kurvenbefehle wie curve to und arc to direkt in clip-path, ohne Umweg über einen externen SVG-Pfad-String.

Vs. polygon()

polygon() bleibt für gerade Kanten die einfachere Wahl, shape() lohnt sich, sobald eine Kante tatsächlich rund oder organisch wirken soll.

Animierbar

Zwei strukturell gleiche shape()-Werte interpolieren der Browser automatisch, eine reine CSS-transition genügt für weiche Formübergänge.

Fallback

Eine polygon()-Näherung vor der shape()-Deklaration und eine @supports-Abfrage sichern ältere Browser sauber ab.

11. FAQ: clip-path shape() in CSS: Das Wichtigste auf einen Blick

1Was macht die shape()-Funktion in clip-path?
shape() erweitert clip-path um echte Kurvenbefehle wie curve to, arc to und smooth to, die direkt als lesbare CSS-Syntax geschrieben werden, statt einen SVG-Pfad-String einzubinden.
2Worin unterscheidet sich shape() von polygon()?
polygon() kennt nur gerade Linien zwischen Eckpunkten. shape() kann zusätzlich echte Kurven und Kreisbögen zeichnen und eignet sich deshalb für organische, runde Formen, die polygon() nur grob annähern könnte.
3Kann ich shape()-Werte animieren?
Ja, solange Start- und Zielform dieselbe Anzahl und Reihenfolge an Befehlen verwenden. Eine einfache CSS-transition auf clip-path reicht dann für einen weichen Formübergang aus.
4Was ist der Unterschied zwischen curve to und arc to?
curve to zeichnet eine Bézierkurve über einen oder zwei Kontrollpunkte, arc to zeichnet einen geometrisch exakten Kreis- oder Ellipsenbogen über Zielpunkt, Radius und Richtung.
5Brauche ich für shape() ein Design-Tool wie Figma?
Nein, shape()-Pfade lassen sich direkt im Stylesheet schreiben und im visuellen clip-path-Editor der Browser-DevTools per Maus anpassen, ganz ohne externes Grafikprogramm.
6Wie sichere ich shape() für ältere Browser ab?
Zuerst eine grobe polygon()-Näherung deklarieren, die überall funktioniert, danach die feinere shape()-Version, optional zusätzlich abgesichert über eine @supports-Abfrage.
7Ersetzt shape() komplett den Einsatz von SVG?
Nein. Für sehr komplexe, statische Illustrationen bleibt eine externe SVG-Datei sinnvoll. shape() ersetzt vor allem die Fälle, in denen bisher eine einfache Kurve oder ein Bogen ein ganzes SVG-Asset gerechtfertigt hat.
8Funktionieren calc()-Ausdrücke in shape()-Koordinaten?
Ja, alle Koordinaten akzeptieren normale CSS-Längeneinheiten, Prozentwerte und calc()-Ausdrücke, wodurch sich Formen mit fester Randbreite unabhängig von der Elementgröße beschreiben lassen.
9Ist eine shape()-Form performant im Rendering?
Ja, der Browser rendert shape() wie jeden anderen clip-path-Wert über eine Pfadberechnung, ohne die pixelweise Deckkraftberechnung, die eine Maske erfordert. Das ist rechnerisch günstiger als mask-image.
10Darf eine per shape() geformte Fläche interaktiv sein?
Ja, aber die klickbare Fläche sollte trotz der visuellen Kontur ausreichend groß bleiben, damit Tastatur- und Screenreader-Nutzung sowie Touch-Bedienung nicht eingeschränkt werden.