Clipping und Maskierung gibt es in CSS schon eine ganze Weile und sie haben eine ziemlich gute Browserunterstützung. Ich habe kürzlich an einem Projekt gearbeitet, bei dem eine Clipping-Technik für Tooltips über Links im Text verwendet werden musste.
Diese Tooltips haben zwei Designs, je nach Inhalt


Man könnte denken, dass der Text-Tooltip keinerlei Clipping erfordert. Ein Pseudo-Element kann am unteren Rand positioniert werden, um die kleine Kerbe hinzuzufügen, richtig? Du hast absolut Recht! Da der Hintergrund des Tooltips eine einfarbige Farbe hat, gibt es wirklich keinen Bedarf für CSS-Tricksereien und Ähnliches.
Aber das Clipping des Bildes im zweiten Design ist es, wo die Dinge interessant werden…
Hier ist der Denkprozess, der mir durch den Kopf ging, als ich mit der Aufgabe begann.
Idee 1: clip-path & polygon
Die CSS-Eigenschaft clip-path ermöglicht es uns, ein benutzerdefiniertes Polygon mit Prozentwerten zu definieren, um den gewünschten Pfad zu erstellen.
Diese Lösung ist oft ausreichend, wenn die Form deines Pfades einfach genug ist. Im untenstehenden Demo verwende ich calc()-Werte, um sicherzustellen, dass der Ausschnitt vollständig responsiv ist, während das kleine Dreieck dieselbe Größe behält, egal wie sehr das Elternelement gestreckt wird.
.tooltip {
clip-path: polygon(
0% 0%, // Top left point
100% 0%, // Top right point
100% calc(100% - 10px), // Bottom right point
calc(50% + 10px) calc(100% - 10px), // Center right of the triangle
50% 100%, // Tip of the triangle
calc(50% - 10px) calc(100% - 10px), // Center left of the triangle
0% calc(100% - 10px) // Bottom left point
);
}
Diese Lösung ist sehr sauber, aber in meinem Fall nicht gut genug, da ich keine gerade Dreiecks-Kerbe habe, sondern eine benutzerdefinierte Form.
Idee 2: clip-path und SVG
Die Verwendung eines SVG-Pfades schien eine gute Lösung zu sein. Zuerst exportierst du deinen SVG-Clipping-Pfad und verwendest ihn dann in deinem CSS mit dem Wert url(#clipPathId).
Schau dir das folgende Demo an. Siehst du ein Problem mit dem Pfad?
Der Pfeil wird basierend auf dem Seitenverhältnis des Bildes gestreckt. Da die kleine Kerbe Teil der gesamten Pfadform ist, wird sie genauso gestreckt wie der rechteckige Teil des Pfades in seiner Größe gestreckt wird.
Idee 3: mask-image
Nun, hier ist das, was ich mit der CSS-Eigenschaft mask-image in CSS entdeckt habe: Du kannst Maskenebenen kombinieren! Denk daran wie an ein background-image in CSS. Du kannst mehrere Farbverläufe oder Bilder auf ein einziges Element anwenden. Was wäre, wenn du all diese Ebenen kombinierst, um die endgültige Maske zu generieren, die du benötigst?
Das ist genau das, was wir hier mit zwei Ebenen tun werden:
- Ein großes Rechteck, das den gesamten Block außer einem Streifen unten bedeckt (in Grün dargestellt)
- Ein Bild des Pfeils (in Pink dargestellt)

Mit dieser Lösung kann sich das Rechteck entsprechend den Abmessungen unseres Tooltips dehnen, und der Pfeil behält immer seine feste Größe.
Der gesamte Code und die Demos unten sind prefix-frei und die Demos verwenden Autoprefixer. Zum Zeitpunkt des Schreibens dieses Artikels benötigen Edge, Chrome und Safari Präfixe.
Genau wie bei Hintergrund-Eigenschaften werden wir drei verschiedene Masken-Eigenschaften verwenden, um unsere beiden Ebenen zu definieren:
mask-image: Diese Eigenschaft erlaubt es uns, das Rechteck mit einem linearen Hintergrund und den Pfeil mit einem Inline-SVG zu zeichnen.mask-position: Das Rechteck benötigt keine Position (da es von links oben beginnt), aber der Pfeil muss unten in der Mitte positioniert werden.mask-repeat: Wir müssen beide Ebenen wiederholen vermeiden; andernfalls würde der lineare Farbverlauf das gesamte Element abdecken, wenn er wiederholt wird.
.tooltip {
mask-image:
linear-gradient(#fff, #fff), /* Rectangle */
url('data:image/svg+xml;utf8,'); /* Bottom arrow mask-position: */
0 0, /* Rectangle */
50% 100%; /* Bottom arrow */
mask-size:
100% calc(100% - 18px), /* Rectangle */
38px 18px; /* Bottom arrow */
mask-repeat: no-repeat;
}
Tada! Ändere die Abmessungen des Tooltips oder ersetze das Bild und der untere Pfeil behält sein ursprüngliches Verhältnis.
Komplexere Formen
Lass uns ein bisschen schick werden und tiefer in diese Technik eintauchen. Ich wurde von der iMessage-App auf iOS inspiriert und versuchte, dieselben Tooltips mit dieser Maskierungstechnik zu reproduzieren.

Ich musste mehr Ebenen zeichnen, damit meine Maske jede abgerundete Ecke rendert:
- vier Kreise, einer für jede Ecke (in Rot dargestellt)
- ein horizontales Rechteck (in Blau dargestellt)
- ein vertikales Rechteck (in Grün dargestellt)
- ein SVG für den Pfeil (in Gelb dargestellt)

Der vollständige Code wird etwas länger sein, da wir mehr Ebenen zeichnen müssen, aber die Logik bleibt dieselbe. Die Ecken werden mit vier radialen Farbverläufen gezeichnet. Um das Rechteck zu füllen, benötigen wir zwei Rechtecke (eins vertikal, eins horizontal), wie oben gezeigt. Und schließlich unser kleiner Pfeil, der ein Inline-SVG verwendet.
.tooltip {
--radius: 25px;
mask-image:
radial-gradient(#fff (var(--radius) - 1), #fff0 var(--radius)), /* Top left corner */
radial-gradient(#fff (var(--radius) - 1), #fff0 var(--radius)), /* Top right corner */
radial-gradient(#fff (var(--radius) - 1), #fff0 var(--radius)), /* Bottom left corner */
radial-gradient(#fff (var(--radius) - 1), #fff0 var(--radius)), /* Bottom right corner */
linear-gradient(#fff, #fff), /* Horizontal gradient */
linear-gradient(#fff, #fff), /* Vertical gradient */
url('data:image/svg+xml;utf8,'); /* Bottom right icon */
mask-position:
0 0, /* Top left corner */
100% 0, /* Top right corner */
0 100%, /* Bottom left corner */
100% 100%, /* Bottom right corner */
0 var(--radius), /* Horizontal gradient */
var(--radius) 0, /* Vertical gradient */
100% 100%; /* Bottom right icon */
mask-size:
(var(--radius) * 2) (var(--radius) * 2), /* Top left corner */
(var(--radius) * 2) (var(--radius) * 2), /* Top right corner */
(var(--radius) * 2) (var(--radius) * 2), /* Bottom left corner */
(var(--radius) * 2) (var(--radius) * 2), /* Bottom right corner */
100% calc(100% - #{var(--radius) * 2}), /* Horizontal gradient */
calc(100% - #{var(--radius) * 2}) 100%, /* Vertical gradient */
(39px / 2) (25px / 2); /* Bottom right icon */
mask-repeat: no-repeat;
}
Wie du siehst, können wir eine Version mit dem Pfeil links oder rechts erstellen, indem wir eine gespiegelte Version des Pfeils verwenden und ihn in einer anderen Ecke positionieren. Der Trick funktioniert auch gut bei Tooltips ohne Bilder. Aber wie ich am Anfang dieses Artikels sagte, brauchst du wahrscheinlich nicht so viel CSS, wenn du nur einen einfarbigen Hintergrund gestalten musst.
Wenn du mehr über Clipping und Maskierung in CSS erfahren möchtest, gibt es hier auf CSS-Tricks viele weitere großartige Artikel, die einen Blick wert sind.
Ich würde eine kleine Optimierung für dein letztes Demo vorschlagen, bei der du CSS-Variablen und auch "farthest-side" in Betracht ziehen kannst, was dir helfen wird, die Verwendung der Radius-Variable zu reduzieren: https://codepen.io/t_afif/pen/yLMwOGX
console.log('HTML + CSS +JS ROCKS');Liebe es
Ich habe diese Technik geliebt, aber bitte beachte, dass im Gegensatz zu
clip-pathmask-image, obwohl es Teile des Elements visuell abschneidet, diese für Hover-/Klickereignisse offen lässt.Tolle Idee, Louis. Bis jetzt habe ich hauptsächlich die Polygon- oder SVG-Methode verwendet, aber tatsächlich ist letztere sehr nützlich, wenn man die Größe des Elements ändern muss. Daumen hoch.
sieh https://codepen.io/xboxyan/pen/poeVrqB
Wenn du nur ein einfaches Dreieck erstellen möchtest, kannst du einfach die CSS-Borderrand-Eigenschaft verwenden (ja, das mag seltsam erscheinen, aber es ergibt Sinn).
HTML
CSS
Stell dir vor, jeder Rand muss die gleichen Abmessungen haben, damit er perfekt funktioniert.
https://codepen.io/stomperhk/pen/VwbLrbv
Ist das letzte Beispiel nicht der perfekte Anwendungsfall für die
mask-border-Eigenschaft, die die Verwendung eines einzelnen SVG-Bildes für alle 4 Ecken auf dieselbe Weise wieborder-imageerlaubt?