Die CSS-Eigenschaft clip-path ist eine der am wenigsten genutzten und doch interessantesten Eigenschaften in CSS. Sie kann in Verbindung mit CSS Shapes verwendet werden, um interessante Layouts zu erstellen, und kann bis zum Extrem getrieben werden, um unglaublich beeindruckende Layouts und Animationen wie das Species in Pieces-Projekt zu schaffen.
Bei der Erforschung der Erstellung beliebig geformter UI-Komponenten mit CSS und SVG stellte ich fest, dass die clip-path-Eigenschaft in Kombination mit SVG-Pfaden relativ einfach zur Erstellung kreisförmiger Menüs verwendet werden kann, insbesondere angesichts des (erwarteten) Browserverhaltens bei der Handhabung von Zeigerereignissen auf zugeschnittenen Bereichen gemäß der Spezifikation. Lassen Sie uns diese Idee etwas genauer untersuchen.
Einige Hintergründe
Vor ein paar Jahren habe ich einen Artikel für Codrops über die Verwendung von CSS-Transforms und ein wenig CSS-Tricksen zur Erstellung von kreisförmigen Menüs nur mit CSS geschrieben. Diese Technik ist alles andere als optimal oder intuitiv und erfordert viele Workarounds und Hacks, um den gewünschten Effekt zu erzielen.
Um ein Menü mit dieser Technik zu erstellen, simuliert man eine Sektorform, indem man die Menüelemente verzerrt und sie dann sozusagen durch Verbergen des Überlaufs auf ihrem Container ausschneidet. Und da man mit dem Verzerren der Menüelemente beginnt, muss man anschließend den Inhalt "entzerren", der nach dem Verzerren des Containers verzerrt wäre.
Das resultierende Menü ist nicht flexibel, erfordert viele Hacks und der Inhalt ist meist auf Icons beschränkt, da anderer Inhalt in den verzerrten Elementen schwer zu positionieren und zu gestalten wäre. Alle Details dieser Technik erfahren Sie im Artikel.
Heute kann die CSS-Eigenschaft clip-path – kombiniert mit SVG-Pfaden – auch zur Erstellung kreisförmiger Menüs in CSS verwendet werden. Die Technik ist nicht hacky, erfordert keine seltsamen Transformations-Workarounds und funktioniert genau wie erwartet. Es gibt ein paar Einschränkungen und zum Zeitpunkt der Erstellung dieses Artikels einen Browserfehler (siehe nächster Abschnitt), aber der erforderliche Code zur Erstellung des Menüs ist überraschend kurz, sauber und leicht verständlich.
Aber bevor wir uns mit dem Code befassen, und auch wenn der Code geradlinig und leicht verständlich ist, möchten Sie vielleicht zuerst mehr über Clipping-Pfade erfahren, wenn Sie noch nicht wissen, was sie sind, was sie tun und wie sie funktionieren. Alles darüber erfahren Sie in einem Artikel auf meinem Blog.
Wir müssen uns auch mit einigen Hinweisen zur Browserunterstützung befassen, bevor wir zum Code und zu den Live-Demos kommen.
Browserunterstützung (und Fehler)
- Wir werden die CSS-Eigenschaft
clip-pathverwenden. Das Erste, was man beachten sollte, ist die Browserunterstützung. Wie die Support-Tabelle von CanIUse unten zeigt, ist die Unterstützung der Eigenschaft nicht optimal, insbesondere da keine Version von IE sie unterstützt, nicht einmal MS Edge. - IE unterstützt Clip-Pfade in CSS noch nicht, aber es ist derzeit „in Erwägung gezogen“.
- Wenn Sie eine einfache CSS-Formfunktion zur Definition eines Clipping-Pfads verwenden, wird Firefox diesen Clipping-Pfad nicht anwenden, da er derzeit nur Clipping-Pfad-Werte unterstützt, die auf ein SVG
<clipPath>-Element verweisen. Firefox unterstützt die einfachen CSS-Formfunktionen noch nicht. (Siehe Ende dieses Abschnitts für einen Fallback-Tipp.) - WebKit/Blink-basierte Browser handhaben Zeigerereignisse nicht korrekt, wenn der verwendete Clipping-Pfad in SVG definiert ist. Dies ist ein Fehler. Standardmäßig sollten Zeigerereignisse außerhalb des sichtbaren Bereichs des zugeschnittenen Elements nicht ausgelöst werden; dies ist das erwartete Verhalten gemäß der Spezifikation. Wenn Sie eine einfache CSS-Formfunktion zur Definition des Clipping-Pfads verwenden, handhaben diese Browser Zeigerereignisse korrekt. Wenn Sie jedoch ein SVG
clipPathüber dieclip-path-Eigenschaft anwenden, werden Zeigerereignisse immer noch außerhalb des sichtbaren Bereichs ausgelöst, was Zeigerereignisse auf jedem darunterliegenden Element beeinträchtigt und blockiert. Ich habe diesbezüglich einen Fehlerbericht eingereicht, während ich an diesem Artikel gearbeitet habe. Hoffen wir, dass er bald behoben wird. Dieser Fehler bedeutet, dass die Demo in diesem Artikel derzeit in WebKit/Blink-basierten Browsern nicht funktioniert. (Entschuldigung.) - Es gibt auch einen weiteren Fehler in Blink-basierten Browsern, der ein extrem seltsames Rendering-Problem (es ist ein Kompositionsfehler) verursacht, das auch die Anwendung von Transformationseffekten auf zugeschnittene Elemente beim Hovern praktisch unmöglich macht. Daher verursacht das Skalieren des Menüs beim Klicken beispielsweise mit CSS-Skalierungstransformationen ein großes Problem, sodass wir den Öffnungs-/Schließeffekt überspringen werden. Ich habe auch einen Fehlerbericht für dieses Problem eingereicht.
Kurz gesagt: Die Demo für diesen Artikel funktioniert zum Zeitpunkt der Veröffentlichung derzeit nur wie erwartet in Firefox.
Wenn Sie den in diesem Artikel verwendeten Clipping-Pfad ändern und durch eine einfache CSS-Form ersetzen, funktioniert die Demo in anderen Browsern (außer IE/Edge), aber nicht in Firefox.
Wenn Sie eine einfache CSS-Formfunktion zur Definition eines Clipping-Pfads verwenden möchten und dass er in Firefox funktioniert, können Sie immer die gleiche Form mit einem SVG <clipPath>-Element erstellen und diese als Fallback für Firefox anwenden.
Zum Beispiel:
.element {
clip-path: url(#SVGPolygonShape); /* For Firefox */
clip-path: polygon(...); /* For other browsers */
}
Das Letzte, was hier zu beachten ist, ist, dass nur Firefox derzeit das Referenzieren eines clipPath-Elements unterstützt, das in einer externen SVG-Datei definiert ist; alle anderen Browser erfordern, dass der definierte SVG-Pfad im Dokument inline ist. Es gibt einen Thread zur Verfolgung dieses Problems im Chromium-Projekt.
Nachdem die Browserfehler und die Unterstützung klar sind, tauchen wir in den Code ein. Wir beginnen mit dem Markup für das Menü.
Markup erstellen
Das Markup ist ziemlich einfach: Das Menü ist eine ungeordnete Liste von Elementen, die in Links eingeschlossen sind und irgendeine Art von Inhalt wie Text oder ein Symbol enthalten. Ich verwende zur Demonstration ein einfaches "Icon"-Label.
<ul class="menu">
<li class="one">
<a href="#">
<span class="icon">icon-1</span>
</a>
</li>
<li class="two">
<a href="#">
<span class="icon">icon-2</span>
</a>
</li>
<li class="three">
<a href="#">
<span class="icon">icon-3</span>
</a>
</li>
<li class="four">
<a href="#">
<span class="icon">icon-4</span>
</a>
</li>
<li class="five">
<a href="#">
<span class="icon">icon-5</span>
</a>
</li>
<li class="six">
<a href="#">
<span class="icon">icon-6</span>
</a>
</li>
</ul>
Das ist alles Markup, was wir brauchen.
Den Clipping-Pfad definieren (die Sektorform)
Um eine Sektorform zu erstellen, müssen wir in der Lage sein, einen Bogen von einem Punkt zum anderen in der Mitte eines Pfades zu zeichnen, und das ist derzeit in CSS mit den einfachen CSS-Formfunktionen: circle(), ellipse(), inset() oder polygon() nicht möglich. (Das heißt, es sei denn, Sie möchten die polygon()-Funktion mit einer sehr großen Anzahl von Punkten verwenden, die so nah beieinander liegen, dass sie wie ein Bogen aussehen. Aber wer möchte das schon?)
Wir brauchen also eine direktere Methode, um die Sektorform zu zeichnen. Und glücklicherweise gibt uns die clip-path-Eigenschaft die Möglichkeit dazu, indem sie eine Referenz auf einen SVG-Pfad als Wert für den Clipping-Pfad akzeptiert.
Mit anderen Worten, Sie können die gewünschte Clipping-Pfad-Form definieren (sie kann sogar aus mehreren getrennten Pfaden bestehen) in SVG, diese Form in einem SVG <clipPath>-Element mit einer ID umschließen und dann diesen Pfad in CSS über die URL-Syntax referenzieren.
clip-path: url(#clipPathID);
Somit wird die Definition unserer Sektorform in SVG sehr einfach. Es sind jedoch einige mathematische und positionelle Überlegungen zu berücksichtigen.
Zuerst müssen Sie die Anzahl der Elemente bestimmen, die das Menü haben soll; dies bestimmt den Wert des Zentralwinkels für die Sektoren.
Als Nächstes müssen Sie die Sektorform mit einem SVG <path>-Element zeichnen. Die in SVG verfügbaren Pfadbefehle ermöglichen es Ihnen, den Pfad nach einigen einfachen Zeichenregeln zu zeichnen.
Wir werden vier Pfadbefehle verwenden, um die Sektorform zu zeichnen: M, l (kleines L), A und z. Aber bevor wir mit dem Zeichnen beginnen, müssen wir bestimmen, wo genau der Sektor die Elemente abschneiden wird, und dazu müssen wir das Konzept vor der Ausführung planen.
Die Position des Clipping-Pfads auf den Menüelementen bestimmen
Die Menüelemente müssen absolut übereinander positioniert und dann in Sektorformen zugeschnitten werden, die alle die Gesamtform des Menüs bilden.
Um dies zu tun, müssen wir diese Elemente als eine Reihe von Ebenen betrachten (was sie buchstäblich sind) und dann Teile dieser Ebenen abschneiden, so dass am Ende nur die Sektorformen dieser Ebenen sichtbar sind. Das folgende Bild zeigt die Ebenen für vier der sechs Elemente des Menüs, das wir erstellen.

Die transluzenten schwarzen Boxen dienen nur zur Veranschaulichung. Was wirklich passiert, ist, dass die Elemente rotiert werden, nicht die Clipping-Pfade. Das heißt, für jedes Element (rechteckige Box) wird das Element auf exakt die gleiche Sektorform zugeschnitten (so dass alle Elemente identisch sind), dann wird jedes Element um den notwendigen Winkel rotiert, damit ihre zugeschnittenen Bereiche nicht mehr überlappen und stattdessen das kreisförmige Menü bilden. Das folgende Bild verdeutlicht dies.

Wenn Sie den zweiten Sektor im obigen Bild betrachten (versuchen Sie, Ihren Kopf leicht zu neigen, damit der schwarze Rand oben ist) (Ja, ich habe meinen Kopf geneigt, als ich an diesen Illustrationen gearbeitet habe), können Sie die Position des Sektors innerhalb des Elements klarer erkennen: Sie ist exakt die gleiche wie die Position des Sektors im ersten Element, außer dass das erste Element nach dem Zuschneiden nicht rotiert wurde.
Beachten Sie, dass im zweiten Bild oben die schwarzen Boxen tatsächlich die Listenelemente darstellen, wie sie auf der Seite positioniert wären, da der Clipping-Pfad den sichtbaren/gemalten Bereich des Elements beeinflusst, es aber praktisch immer noch ein Rechteck ist, auch wenn nur ein kleiner Teil davon durch seinen neuen nicht-rechteckigen Viewport sichtbar ist.
Bevor wir weitermachen, hier ist eine animierte Version, die zeigt, wie die Elemente positioniert, zugeschnitten und rotiert werden, um das gesamte Menü mit den zugeschnittenen Elementen zu erhalten. Ziel dieses GIFs ist es zu zeigen, dass sie alle identisch zugeschnitten werden, bevor sie rotiert werden.

Auch wenn die Elemente zugeschnitten sind, sind sie prinzipiell immer noch rechteckig. Denken Sie also bei der Visualisierung ihrer Rotation daran, dass ein rechteckiges Element rotiert wird, aber nur die nicht-rechteckige Form darin sichtbar ist.
Die Punktkoordinaten des Clipping-Pfads bei Anwendung auf die Menüelemente bestimmen
Da wir nun wissen, wie die Elemente rotiert werden, wissen wir, dass die anfängliche Sektorform für alle Elemente identisch sein wird. Alles, was wir als Nächstes brauchen, ist die Zeichnung der Sektorform in SVG. Und dazu müssen wir sehen, wie die Koordinaten der Punkte bestimmt werden, die den Sektor definieren.
Werfen wir einen Blick auf den Code für die Sektorform, bevor wir ihn sezieren; das folgende <svg> wird auf der Seite platziert, damit der Clipping-Pfad in CSS referenziert werden kann.
<svg height="0" width="0">
<defs>
<clipPath clipPathUnits="objectBoundingBox" id="sector">
<path fill="none" stroke="#111" stroke-width="1" class="sector" d="M0.5,0.5 l0.5,0 A0.5,0.5 0 0,0 0.75,.066987298 z"></path>
</clipPath>
</defs>
</svg>
Der wichtigste Teil im obigen Code ist die Deklaration clipPathUnits="objectBoundingBox". Das Attribut clipPathUnits akzeptiert zwei Werte: userSpaceOnUse und objectBoundingBox. Ersteres zeichnet den Pfad mit dem Koordinatensystem der gesamten Seite, letzteres verwendet das Koordinatensystem des Elements – was wir wollen.
Wenn Sie objectBoundingBox verwenden, werden die Koordinaten der Punkte, die zum Zeichnen des Sektorpfads verwendet werden, mit relativen Werten im Bereich [0, 1] festgelegt. Diese Werte sind prinzipiell den Prozentwerten sehr ähnlich und werden relativ zur Bounding Box des Elements berechnet; d.h. zur Breite und Höhe des Elements, in unserem Fall. Deshalb sind die Werte im obigen Ausschnitt alle kleiner als 1.
Wenn Sie stattdessen den Wert userSpaceOnUse anstelle von objectBoundingBox verwenden, verwendet der Browser das Koordinatensystem auf der Seite (im Falle von HTML) oder das aktuell verwendete Benutzerkoordinatensystem (das der Leinwand im Falle von SVG) bei der Positionierung Ihres Clipping-Pfads, was bedeutet, dass er je nach Position des Elements auf der Seite oder Leinwand möglicherweise wirklich auf Ihr Element angewendet wird oder auch nicht. Mehr dazu können Sie in meinem Artikel zu diesem Thema lesen.
Da wir wissen, wie der Sektor innerhalb des Menüelements (Quadrat) positioniert wird (siehe vorheriger Abschnitt), können wir die Position und die relativen Punktkoordinaten veranschaulichen.

Diese Koordinaten, zusammen mit dem relativen Kreisradius für den Sektor, werden von den Pfadbefehlen verwendet, um die Sektorform zu zeichnen.
Angesichts der Art und Weise, wie wir ihn auf unseren Menüelementen positionieren wollen, können die Koordinaten der Punkte, die den Clipping-Pfad definieren, wie im Bild gezeigt ermittelt werden. Drei Punkte sind erforderlich, um die Sektorform zu zeichnen, und wir benötigen auch den Radius des Kreises für diesen Sektor.
Der Radius des Kreises ist 0,5, was der halben Breite des Elements entspricht. Das Zentrum dieses Kreises liegt ebenfalls bei (0,5, 0,5). Der zweite Punkt auf dem Sektor, der die Basis bildet, befindet sich bei (1, 0,5). Die Koordinaten des dritten Punktes sind durch einfache Mathematik bei (0,75, 0,066987298) angesiedelt. Dann wird der Pfad unter Verwendung von SVG-Bogen- (A) und Linienbefehlen (l) gezeichnet. Wir werden nicht auf die Details des Zeichenvorgangs eingehen, da dies außerhalb des Rahmens dieses Tutorials liegt, aber hier ist eine interaktive Demo, die dieses Zeichnen in Aktion zeigt. Klicken Sie auf die Schaltfläche, um es abzuspielen.
Siehe den Stift Building A Circular Menu With SVG — #1 von Sara Soueidan (@SaraSoueidan) auf CodePen.
Um zu lernen, wie die Pfadbefehle zum Zeichnen der Sektorform verwendet werden, siehe diesen Artikel auf meinem Blog.
Mit diesen Daten kann der <path>, der unseren <clipPath> definiert, erstellt und zur Anwendung auf unsere Menüelemente bereit gemacht werden.
Die Menüelemente zuschneiden
Mit dem fertigen SVG-Clipping-Pfad können wir nun die Menüelemente mit der clip-path-Eigenschaft zuschneiden.
Zuerst werden die Elemente absolut übereinander im Menü positioniert. Wir beginnen mit der Erstellung eines Positionskontextes.
.menu {
position: relative;
list-style: none;
margin: 30px auto;
/* padding trick for maintaining aspect ratio */
height: 0;
padding: 0;
padding-top: 70%;
width: 70%;
}
Um sicherzustellen, dass das Menü quadratische Abmessungen hat, verwende ich den Padding-Hack, um sicherzustellen, dass es ein 1:1-Seitenverhältnis beibehält. Da wir es flüssig haben wollen, verwende ich Prozentwerte für die Breite. Mit Media Queries können Sie die minimalen und maximalen Abmessungen angeben, die Sie wünschen, und das Padding (für den Hack) entsprechend anpassen. Die Live-Demo unten enthält diesen Teil, sodass Sie mit diesen Werten spielen und sie nach Belieben anpassen können.
Positionieren Sie als Nächstes die Elemente innerhalb des Menüs und schneiden Sie sie auf die Sektorform zu.
.menu li {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
clip-path: url(#sector)
}
.menu li a {
display: block;
width: 100%;
height: 100%;
}
.menu li:hover {
background-color: gold;
}
Dadurch werden alle Elemente auf die Sektorform zugeschnitten, und es wird nur ein Element angezeigt (das letzte, über allen anderen), mit den restlichen "dahinter". Die verbleibenden Elemente sind nicht sichtbar, da sie alle im gleichen Bereich zugeschnitten sind und somit vom letzten Element überdeckt werden.
Um die restlichen Elemente anzuzeigen und unser kreisförmiges Menü zu bilden, müssen wir die Elemente um die notwendigen Winkel drehen. Element Nr. 1, das den Index 0 hat, wird um 0 * Winkel = 0 * 60 = 0deg gedreht.
Element Nr. 2 wird um 1 * 60 = 60deg gedreht; Element Nr. 3 wird um 2 * 60 = 120deg gedreht. Und so weiter.
.one {
background-color: $base;
transform: rotate(0deg);
}
.two {
background-color: darken($base, 7%);
transform: rotate(-60deg);
}
.three {
background-color: darken($base, 14%);
transform: rotate(-120deg);
}
.four {
background-color: darken($base, 21%);
transform: rotate(-180deg);
}
.five {
background-color: darken($base, 28%);
transform: rotate(-240deg);
}
.six {
background-color: darken($base, 35%);
transform: rotate(-300deg);
}
Wir hätten eine Sass-Schleife verwenden können, um dies zu automatisieren, aber lassen wir uns nicht zu weit vom Thema abweichen.
Und das ist alles, was nötig ist, um die kreisförmigen Menüelemente mit CSS-Clipping-Pfaden zu erstellen. Hier ist die Live-Demo.
Siehe den Stift Circular Menu using CSS clip-path von Sara Soueidan (@SaraSoueidan) auf CodePen.
Beachten Sie, dass Sie aufgrund des Fehlers bei Zeigerereignissen in Chrome zum Zeitpunkt der Erstellung dieses Artikels den SVG-Clipping-Pfad-Verweis durch diesen ersetzen können:
clip-path: polygon(50% 50%, 100% 50%, 75% 6.6%);
um eine Vorstellung davon zu bekommen, wie das Menü mit korrekten Zeigerereignissen funktioniert. Fahren Sie mit der Maus über die Elemente, um zu sehen, wie sich ihre Hintergrundfarbe ändert. Denken Sie daran, dass der neue Clipping-Pfad in Firefox jedoch nicht funktioniert. Daher können Sie vorerst die obige Zeile nach der clip-path URL-Syntax hinzufügen, damit Firefox letztere verwenden kann.
So wird das Menü mit dem polygon() Clipping-Pfad aussehen.

Ich habe diese CSS-Zeile zum obigen Menü hinzugefügt, damit Sie sie auskommentieren können, wenn Sie möchten.
Icons/Inhalte zu den Menüelementen hinzufügen
... ist einfach. Alles, was Sie tun müssen, ist sicherzustellen, dass die Icons/Texte/was auch immer innerhalb des sichtbaren Bereichs des Elements (der Sektorform) sichtbar sind. Wiederum, anhand des durch die Höhe und Breite des Elements definierten Koordinatensystems können Sie die Position der Elemente schätzen, damit sie im neuen Sektor-förmigen Viewport angezeigt werden.

Es kann einige Experimente erfordern, um die genaue Ausrichtung zu erreichen, die Sie wünschen, abhängig vom Inhalt der Elemente.
Für unsere Demo verwende ich Text. Die Positionierung dieses Textes 30% vom oberen Rand des Elements und 15% vom rechten Rand war ein guter Ausgangspunkt.
Nachdem wir die Position für den Text in unserem Beispiel festgelegt haben, müssen wir den Text um den gleichen Winkel wie den Sektor drehen, um sicherzustellen, dass er richtig aussieht, sonst würden Sie das hier bekommen.

statt dessen

Und die Stile für den Text innerhalb der Elemente sind.
.icon {
position: absolute;
/* exact values here depend on what you are placing inside the items (icon, image, text, etc.) */
right: 15%;
top: 30%;
/* angle of rotation = angle of the sector itself */
transform: rotate(60deg);
/* style further as needed */
}
Ein anderer Weg
Die obige Technik ist der einfachste Weg, dieses kreisförmige Menü mit CSS-Clipping-Pfaden zu realisieren.
Anstatt die gleiche Sektorform zum Zuschneiden aller Elemente zu verwenden und diese Elemente dann in CSS zu drehen, hätten Sie die Elemente nicht drehen und stattdessen eine rotierte Sektorform verwenden können, so dass jedes Menüelement so zugeschnitten wird, dass die resultierenden Sektoren bereits zum Bilden der kreisförmigen Form gedreht sind.
Diese Technik ist jedoch komplizierter, da Sie die Punktkoordinaten sowie die Rotation für jeden SVG <path> angeben müssen, ganz zu schweigen davon, dass es mehr Arbeit erfordern würde, die Position für den Inhalt jedes Elements so zu erhalten, dass er durch jeden dieser Sektoren sichtbar wird. Es ist komplizierter und zeitaufwendiger, also definitiv nicht besser als die obige Technik.
Dennoch möchte ich Ihnen zeigen, wie der Code für die Clipping-Pfade in diesem Fall aussehen würde.
<svg height="0" width="0">
<defs>
<clipPath clipPathUnits="userSpaceOnUse" transform="matrix(1,0,0,1,0,0)" id="one-2">
<path fill="none" stroke="#111" stroke-width="1" class="sector" d="M250,250 l250,0 A250,250 0 0,0 375,33.49364905389035 z"></path>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" transform="matrix(0.5,-0.86602,0.86602,0.5,-91.5063509461097,341.5063509461096)" id="two-2">
<path fill="none" stroke="#111" stroke-width="1" class="sector" d="M250,250 l250,0 A250,250 0 0,0 375,33.49364905389035 z"></path>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" transform="matrix(-0.49999,-0.86602,0.86602,-0.49999,158.49364905389024,591.5063509461097)" id="three-2">
<path fill="none" stroke="#111" stroke-width="1" class="sector" d="M250,250 l250,0 A250,250 0 0,0 375,33.49364905389035 z"></path>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" transform="matrix(-1,0,0,-1,500,500)" id="four-2">
<path fill="none" stroke="#111" stroke-width="1" class="sector" d="M250,250 l250,0 A250,250 0 0,0 375,33.49364905389035 z"></path>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" transform="matrix(-0.5,0.86602,-0.86602,-0.5,591.5063509461097,158.4936490538905)" id="five-2">
<path fill="none" stroke="#111" stroke-width="1" class="sector" d="M250,250 l250,0 A250,250 0 0,0 375,33.49364905389035 z"></path>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" transform="matrix(0.5,0.86602,-0.86602,0.5,341.5063509461096,-91.5063509461097)" id="six-2">
<path fill="none" stroke="#111" stroke-width="1" class="sector" d="M250,250 l250,0 A250,250 0 0,0 375,33.49364905389035 z"></path>
</clipPath>
</defs>
</svg>
Das ist ziemlich viel SVG-Code im Vergleich zu den wenigen Zeilen aus den vorherigen Abschnitten.
Der obige Ausschnitt enthält einen Clipping-Pfad für jeden Sektor, der entsprechend gedreht ist, und ohne die Koordinaten in relative Werte im Bereich [0, 1] umgewandelt zu haben; Sie müssten diese Koordinaten ebenfalls umwandeln. Jeder der obigen Sektoren kann dann als Clipping-Pfad für sein jeweiliges Element im Menü verwendet werden. Nicht sehr optimal, oder?
Beachten Sie, dass der obige Code von einem Generator für kreisförmige Menüs generiert wurde, den ich vor einiger Zeit erstellt habe, also nein, ich habe das nicht von Hand programmiert. (Mehr dazu im nächsten Abschnitt.)
SVG-Kreismenüs
Die clip-path-Technik ist großartig und funktioniert konzeptionell gut; aber die aktuellen Browser-Fehler machen das resultierende Menü heute praktisch unbrauchbar.
Vor einigen Monaten habe ich die Idee untersucht, SVG und SVG-Pfade zur Erstellung von kreisförmigen Menüs zu verwenden, da SVG generell gut für die Erstellung nicht-rechteckiger Formen ausgestattet ist. Mit SVG-Pfaden würden die Sektorformen gezeichnet und in einen Link <a> eingeschlossen. Das Erstellen der Sektoren ist unkompliziert und erfordert die gleichen Überlegungen und Schritte wie zuvor, außer dass Sie bei den absoluten Werten für die Punktkoordinaten bleiben können, anstatt relative Werte zu verwenden, da die gesamte SVG-Leinwand das Koordinatensystem ist, in dem die Sektoren gezeichnet werden. Sie müssen die Sektorformen nicht auf ein Element anwenden – die Form paths selbst werden die Menüelemente sein.
Wenn Sie also heute ein kreisförmiges Menü für Ihre Benutzeroberflächen benötigen, ist SVG derzeit Ihre beste Option. Die Unterstützung ist großartig (IE9+ und alle modernen Browser) und funktioniert genau wie erwartet. Außerdem erhalten Sie die Flexibilität von SVG, insbesondere dass Sie SVG-Icons anstelle von Icon-Fonts im Menü verwenden können. Wenn Sie interessiert sind, können Sie den Artikel, der erklärt, wie das geht, hier finden.
Da die Erstellung eines kreisförmigen Menüs in SVG ziemlich viel Zeit in Anspruch nimmt, habe ich auch einen Generator erstellt, mit dem Sie die definierenden Merkmale des Menüs visuell anpassen und dann den Code für dieses Menü generieren lassen können, bereit zum Einbetten. Das Tool enthält auch eine ausführliche Anleitung zum generierten Code, zum Einbetten, zum Animieren des Menüs beim Öffnen/Schließen und sogar einige UX-Überlegungen, wenn Sie kreisförmige Menüs verwenden möchten.

Den Generator finden Sie hier.
Abschließende Worte
Verwenden Sie nicht die alte Technik mit CSS-Transforms zur Erstellung von kreisförmigen Menüs. Clipping-Pfade in CSS sind ziemlich fantastisch und sehr mächtig, aber bis die Unterstützung besser wird, sind sie nicht immer eine gute Wahl. SVG ist auch genauso fantastisch und eignet sich derzeit besser für die Erstellung von kreisförmigen Menüs, zumindest bis die Unterstützung für CSS-Clipping-Pfade besser wird.
Ich hoffe, Ihnen hat dieser Artikel gefallen und Sie fanden ihn nützlich. Danke fürs Lesen!
Großartig! Eine sehr nützliche Eigenschaft. Danke für den Artikel.
Bis die Unterstützung für
pointer-eventsfür externe SVG-Clipping-Pfade verbessert ist, könnten Sie den einzelnen Element-Clip aufclip-path: polygon(50% 50%, 100% 50%, 100% 0, 77% 0%);erweitern, damit ihre Hintergrundfarbe nach außen reicht, und einen kreisförmigenclip-pathauf das Haupt.menuwieclip-path: circle(35% at 50% 50%);anwenden, um die Elemente rundlich abzuschneiden.Ich konnte Ihre CodePen-Demo nicht direkt forken, aber ich habe sie hier neu erstellt: http://codepen.io/shshaw/pen/zGQwbq?editors=010
Stimmt, das funktioniert, aber das ist ein Hack, den ich vermeiden wollte. Die ganze Idee dahinter ist, nicht um den heißen Brei herumreden zu müssen. Erstellen Sie einfach die Form und wenden Sie sie an. Das "Zuschneiden von Elementen durch Zuschneiden ihres Elternteils" ist einer der Workarounds der vorherigen CSS-Technik, und die ganze Idee war, dies zu vermeiden. Ich empfehle immer noch, SVG vorerst zu verwenden, bis die Unterstützung besser wird, da
clip-pathin IE/Edge leider gar nicht funktioniert, also war dies ein Proof of Concept.Außerdem sind großartige Neuigkeiten, dass der von mir eingereichte Fehler bereits in Arbeit ist, also könnten wir ihn in der nächsten Version von Chrome sehen (hurra!)... hoffe ich. =)
Vielen Dank für den exzellenten Artikel (Artikel)! Ihre verwandten Links bieten eine wertvolle Grundlage.
Das Informationsvolumen, das Sie jemandem in weniger als einer Stunde vermitteln können (ich schätze, Sie haben wahrscheinlich mehr als eine Ihrer Stunden dafür aufgewendet), ist ziemlich beeindruckend!
Nochmals vielen Dank.
Vielen Dank, Max! Ich freue mich, dass Sie es nützlich fanden! ^^