CSS clip-path

clip-path ist eine neue CSS-Eigenschaft, die wie viele andere CSS3-Eigenschaften ebenfalls den Ursprung in SVG hat. Wie bei shapes-outside kann man clip-path über Pfadfunktionen wie circle(), ellipse(), inset() oder polygon() eine Form zuweisen, die dann das Bild oder den Container in der jeweiligen Form beschneiden. Alles, was außerhalb der definierten Form ist, wird entfernt und der Hintergrund des Elternelements erscheint.

Die alte Eigenschaft clip gibt es zwar schon länger in CSS, wurde jetzt aber überarbeitet spezifiziert. Der aktuelle Einsatz von clip ist sicherlich ein anderer als ursprünglich angedacht. Meist nutzen Webworker clip für barrierefreies Verstecken von Elementen wie <input type="radio" /> um ein Custom-Design zu integrieren und gleichzeitig die Browser-Funktionen zu erhalten. Die HTML-Boilerplate nutzt dies in der .visuallyhidden Definition. Ein Beispiel: http://codepen.io/maddesigns/pen/jbiDn

Die alte Clip-Eigenschaft:

.clip-me {
  /* old:  absolute or fixed positioning required */
  position: absolute;  
  /* deprecated version */
  clip: rect(110px, 160px, 170px, 60px);
  /* reset/default on deprecated version */
  clip: auto;
}

Diese neuen hilfreiche Funktionen sind nun hinzu gekommen:

.clip-me {
  /* reset/default on current version */
  clip-path: none;
  /* current version */
  clip-path: rect(110px, 160px, 170px, 60px);
  /* rounded rectangle */
  clip-path: inset(10% 10% 10% 10% round 20%, 20%);
  /* circle */
  clip-path: circle(30px at 35px 35px);
  /* ellipse */
  clip-path: ellipse(65px 30px at 125px 40px);
  /* polygon */
  clip-path: polygon(0% 0%, 100% 50%, 0% 100%, 0% 0%);
}

Beispiel:

See the Pen Simple CSS Shapes demo by Sven Wolfermann (@maddesigns) on CodePen.

Zudem können auch die bereits vorhandenen Formenausmaße als Clip-Path verwendet werden.

clip-path: fill-box | stroke-box | view-box

clip-path: url() – SVG-Vorlage mit <clipPath>

Neben den einfachen Clip-Formen kann man auch umfangreiche Clip-Pfade, die in SVG definiert sind, verwenden. So können auch Bézierkurven verwendet werden, ganze Formen-Gruppen (<rect>, <circle>, <path> etc.) oder auch Texte.

SVG clipPath MDN-Referenz

Diese definierten Formen können im Anschluss in CSS als URL referenziert werden.

.element {

  /* referencing path from (inline SVG) <clipPath> */
  clip-path: url(#clipPath);

  /* referencing path from external SVG */
  clip-path: url(img/path.svg#clipPath);

}

Beispiel:

See the Pen CSS Shapes & responsive clipPath SVG image by Sven Wolfermann (@maddesigns) on CodePen.

Wenn sich die beschnittenen HTML-Elemente responsive verhalten sollen, muss man auf das in SVG angewendete Koordinatensystem acht geben. Gewöhnlicher Weise wird hier mit absoluten Pixelwerten gearbeitet, so dass sich Schnittmaske nicht mit skaliert. Durch clipPathUnits="objectBoundingBox" wird das Koordinatensystem so umgestellt, dass es sich relative zur viewBox verhält. Es ist also ratsam das Bild über <image> in SVG zu definieren und das komplette SVG inline in HTML zu integrieren.

SVG mit Text

Wie schon kurz erwähnt kann auch Text in SVG als Pfad- bzw. Beschnittform dienen. Über CSS @font-face ist es dann natürlich auch möglich den gewünschte Webfont nutzen. Die Positionierung kann manchmal etwas hakelig sein.

Beispiel:

See the Pen SVG clipPath text by Sven Wolfermann (@maddesigns) on CodePen.

Animated clip-path

Die Beschnittpfade können auch animiert sein, bzw. auf Mouse-Aktionen Transitions durchführen. Wichtig ist dabei, dass die Knotenanzahl des Pfades gleich bleibt, sonst funktioniert die Animation nicht. Es ist also nicht möglich von einem Stern-Polygon zu einem Viereck zu animieren, die Knoten müssen alle erhalten bleiben und dementsprechend positioniert werden, dann geht’s.

img {
    clip-path: polygon(0% 0%, 100% 50%, 0% 100%, 0% 0%);
    transition: clip-path 0.3s 0.1s;

    &:hover {
        clip-path: polygon(0% 0%, 100% 0%, 0% 100%, 0% 0%);
    }
}

Eine Animation kann auch direkt in SVG definiert sein. Es gibt aber teilweise große Performance-Unterschiede in den verschiedenen Browsern, also vorsichtig damit experimentieren.

Tools

Um clip-path zu experimentieren, hat Bennett Feely ein tolles Online-Tool entwickelt. Dort sind mehrere Formen bereits vordefiniert. Die Veränderung der Formen und die Auswirkung auf den CSS-Code ist schön umgesetzt. Ein weiteres Tool stammt von Alex Bylim – der Clip-Path-Generator.

Wie für CSS-Shapes, kann man auch für clip-path die Chrome-Browser-Erweiterung nutzen, um in den Dev-Tools Formen hinzuzufügen oder zu verändern.

Browser-Support

Der Browser-Support sieht grundsätzlich, mit Abstrichen, ganz gut aus. Aber der aktuelle Standard ist noch nicht in allen Browsern verfügbar. Chrome/Opera und Safari unterstützen die erwähnten Form-Funktionen in clip-path, allerdings mit -webkit-Präfix. Firefox unterstützt die Form-Funktionen leider noch nicht, aber die Variante mit url(#clipPath). Der Internet-Explorer unterstützt leider gar nichts davon. Hier müsste man das zu beschneidende Element (z.B. Bild) direkt in SVG einbinden, darauf anwenden und diesen SVG-Code inline ins HTML einfügen (Beipiel: http://codepen.io/maddesigns/pen/kbqzu). Dann funktioniert es auch dort.

Der komplette Browser-Support:

caniuse-clip-path

Empfohlene Blog Posts:

Das Schöne ist, das clip-path auf alle möglichen Elemente angewandt werden kann, z.B. auch Videos oder Textblöcke, nicht nur Bilder. Zudem sind die Beschnittpfade animierbar und können dynamisch über JavaScript generiert werden. Mit den zusätzlichen Möglichkeiten von SVG, bleibt kaum ein Wunsch an Gestaltungsmöglichkeiten offen. Wenn jetzt nur noch der Browser-Support insgesamt besser würde…

Bonus: Mask

Eine ähnliche Eigenschaft wie clip-path ist mask, was ebenfalls aus der SVG-Spezifikation her rührt. Neu ist die CSS-Eigenschaft ja eigentlich nicht, Safari (WebKit) hat mask bereits 2008 in einem Blog-Post beschrieben und Christian @derSchepp Schaefer beschrieb in seinem Blog-Post wie man die mask-Eigenschaft auch in alten IEs umsetzen kann. mask kann man (halb-)transparente URLs zuweisen, wie bei shape-outside. Im Unterschied zu clip-path kann <mask> auch halbtransparente Flächen beinhalten und somit das zu maskierende Element auch nur halbtransparent „beschneiden“.

Einen Maske kann direkt in SVG definiert werden und dort natürlich alle Möglichkeiten nutzen. Unter Anderem könnte man auch Text als Maske benutzen, hier ein Beispiel:

Beispiel:

See the Pen SVG text mask by Sven Wolfermann (@maddesigns) on CodePen.

Allerdings ist hier der Browser-Support nicht ganz so einfach zu lesen http://caniuse.com/#feat=css-mask da hier verschiedene Stufen der Spezifikation integriert sind.