Masken und Beschneidungen/Masken

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

In guten Bildbearbeitungsprogrammen kann man mit Ebenenmasken Teile des Bilds verdecken. Nur wo die Maske durchsichtig ist, wirkt sich die Bildbearbeitung aus.

Im Unterschied zu einer Beschneidung mit clip-path, bei der außerhalb der Beschneideform stehende Teile einfach abgeschnitten werden, sind Masken Grafiken, die Sie auch für teiltransparente Schablonen mit weichen Übergängen verwenden können. Unter den Masken befindliche Objekte sind nur in den transparenten Bereichen sichtbar. Dies können Sie z.B. durch Verläufe oder Filtereffekte erreichen.

Kurz: Masken sind Grafiken; Beschneidungen aber Pfade.

Funktionsweise

Luminanzmaske

Die Maske wird in eine nicht sichtbare Ebene mit transparent-schwarzem Hintergrund projiziert. Die Farbwerte werden wie im Filter feColorMatrix mit der Einstellung luminance-to-alpha in Graustufen umgewandelt. Weiße Flächen sind undurchsichtig, schwarz ist vollständig transparent. Diese Farbwerte werden dann mit der Alphamaske kombiniert.

Alphamaske

In der Alphamaske wird nur der Wert des s berücksichtigt. RGB-Werte ohne Werte im Alphakanal erhalten einen Wert von 1.

Beachten Sie:
In der Praxis ergibt
  • die Füllfarbe Weiß keine Transparenz;
  • die Füllfarbe Schwarz volle Transparenz.

Masken in CSS

Genau wie Beschneidungen waren Masken eine Domäne von SVG und wurden erst relativ spät in CSS implementiert.

Mit der CSS-Eigenschaft mask können Sie eine Schablone anlegen, die dann nur Teilbereiche einer beliebigen Form oder Grafik teilweise oder ganz sichtbar macht.[1]

Die Eigenschaft ist eine Zusammenfassung der möglichen Einzelangaben mask-image, mask-origin, mask-clip und mask-border.


mask-image

Die Eigenschaft mask-image referenziert die Grafik, die als Schablone oder Maske über ein HTML-Element gelegt wird. Wie bei background-image kann dies eine externe Gafik oder ein Verlauf sein.

Beispiele für maskierte Bilder ansehen …
.linear {
	-webkit-mask-image: linear-gradient(transparent, black); 
	mask-image: linear-gradient(transparent, black); 
}

.radial { 
	-webkit-mask: radial-gradient( black 40%, transparent 70%);
	mask: radial-gradient( black 40%, transparent 70%);
}

.radial2 {
  -webkit-mask-image: radial-gradient(circle at 50% 30%, black 50%, rgb(0 0 0 / 0.6) 50%);
  mask-image: radial-gradient(circle at 50% 37%, black 48%, rgb(0 0 0 / 0.6) 48%);
}

img:hover {
	-webkit-mask: none;
	mask: none;
}

Im ersten Beispiel wurde der lineare Verlauf mit mask-image, im zweiten mit der zusammenfassenden Eigenschaft mask notiert.

Achtung!

CSS-Maskierungen werden von allen modernen Browsern unterstützt, es muss jedoch für ältere Versionen (Stand: August 2024) zusätzlich noch der Browser-Präfix -webkit- verwendet werden. --Matthias Scharwies (Diskussion) 08:56, 20. Jul. 2024 (CEST)

mask-border

Die Eigenschaft mask-border ist eine Zusammenfassung der möglichen Einzelangaben mask-border-source, mask-border-slice, mask-border-width, mask-border-outset, mask-border-repeat und mask-border-mode.


mask-border vs. -webkit-box-image ansehen …
.stamptiles {
  mask: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg');
  -webkit-mask-box-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg') 30 repeat;
  mask-box-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg') 30 repeat;  
  mask-border: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg') 30 repeat;
}

.stamptiles2 {
  mask: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg');
  -webkit-mask-box-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg') 30 repeat;
  mask-box-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg') 30 repeat;  
  mask-border: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg') 30 repeat;
  webkit-mask-size:100%;
  mask-size:100%;
}

.perforated { /*works only in webkit-Browsers */
  -webkit-mask-box-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/stampTiles.svg') 30 repeat;
}

Dieses Beispiel vergleicht die mask-border-Eigenschaft mit der nicht-standardisierten -webkit-box-image-Eigenschaft. In den Webkit-Browsern wird der Rand durch die Maske perforiert. Im Firefox erstrecken sich die Perforationen über das gesamte Bild. Im mittleren Bild sorgt mask-size: 100% für Abhilfe – die Perforation ist im Firefox nun aber riesig!


mask-size

Sie können Masken mithilfe der Eigenschaft mask-size skalieren.

Erlaubt sind dabei die Schlüsselwörter:

  • auto, Voreinstellung übernimmt die Maße der Grafik, keine Skalierung
  • contain, passt unter Beibehaltung des Seitenverhältnisses die größere Seite der Grafik in den Anzeigebereich ein
  • cover, passt unter Beibehaltung des Seitenverhältnisses die kleinere Seite der Grafik in den Anzeigebereich ein, ergibt eine vollständige Füllung des Anzeigebereiches
  • ein Paar Längenangaben

Die erste Angabe spezifiziert die gewünschte Breite, die zweite entsprechend die Höhe der Maske. Ist nur ein Wert gegeben, so wird die Höhe unter Beibehaltung des Seitenverhältnisses skaliert.

Beispiele für maskierte Bilder ansehen …
.umriss {
	-webkit-mask: url(https://wiki.selfhtml.org/images/5/56/Deutschland-Umriss.svg#maskelement); 
	-webkit-mask-size: 95%; 
	-webkit-mask-repeat: no-repeat;
	mask-image: url(https://wiki.selfhtml.org/images/5/56/Deutschland-Umriss.svg#maskelement); 
	 mask-size: 50%;
	 mask-repeat: no-repeat;
}

Das Beispiel erhält eine Grafik mit einer Maske und einem Schieberegler input type="range". Mit ihm können Sie den Wert für mask-size und so die Größe der Schablone verändern.

Referenzieren einer SVG-Grafik in HTML

Das Referenzieren von externen Grafiken als Schablone hat Nachteile: neben der Dateigröße wird ein zusätzlicher HTTP-Request nötig. Besser wäre es wie bei den Verläufen im ersten Beispiel unsere Schablone mit SVG direkt im HTML-Dokument zu notieren:

Referenzieren eines SVG-Fragments als Schablone ansehen …
<style>
.bubbles1 {
  -webkit-mask-image: url(#mask1);
  mask-image: url(#mask1);
  mask-size:100%
}
</style>
...
<svg width="0" height="0" viewBox="0 0 450 450">
  <defs>
    <mask id="mask1">
      <rect fill="black" x="0" y="0" width="450" height="450" />
      <circle fill="#FFFFFF" r="50" />
      <circle fill="#FFFFFF" cx="125" cy="125" r="100" />
      <circle fill="#FFFFFF" cx="225" cy="300" r="100" />
      <circle fill="#FFFFFF" cx="350" cy="50" r="90" />
      <circle fill="#FFFFFF" cx="100" cy="400" r="100" />
      <circle fill="#FFFFFF" cx="400" cy="400" r="100" />	  	  
    </mask>
  </defs>
</svg>

Masken in SVG

Mit dem mask-Element können Sie eine Schablone anlegen, die dann nur Teilbereiche einer beliebigen Form oder Grafik sichtbar macht[2].

Die Maskenform wird im Definitionsabschnitt festgelegt und mit ihrer id dem zu maskierenden Element über das mask-Attribut zugeordnet.


Beispiel ansehen …
    <defs>
        <mask id="Maske" maskUnits="userSpaceOnUse"
              x="0" y="0" width="200" height="80">
            <rect x="0" y="0" width="100" height="80" fill="white"/>
        </mask>

        <text id="Text" x="84" y="48" 
              font-size="20" font-weight="bold" text-anchor="middle">
            schwarz &amp; weiß 
        </text>
    </defs>

    <rect x="100" y="10" width="95" height="60"  />
  
    <use xlink:href="#Text" fill="white"/>
    <use xlink:href="#Text" fill="black" mask="url(#Maske)"/>

Der Hintergrund besteht aus einem schwarzen Rechteck (Ohne Angabe einer Füllfarbe wird der Standardwert schwarz verwendet.).

Der Text wird als symbol definiert und mit use zweimal aufgerufen:

  1. als weiße Schrift und dann noch
  2. als schwarze Schrift mit der Maske:

Die Maske beinhaltet ein weißes Rechteck, das die linke Hälfte des Hintergrunds verdeckt.


Folgende Angaben sind möglich:

  • MaskUnits: absolute oder relative Koordinaten
    • userSpaceOnUse: (Standardwert) aktuelles Koordinatensystem soll verwendet werden
    • objectBoundingBox: Koordinaten passen sich an das zu beschneidende Element an
  • maskContentUnits: definiert das Koordinatensystem für den Inhalt des Maskierungs-Elements
    • userSpaceOnUse: übernimmt Werte aus dem existierenden Koordinatensystem, in das die Maskierung eingebunden ist.
    • objectBoundingBox: (Standardwert) Koordinatensystem beginnt in der linken oberen Ecke des Elements und erstreckt sich auf die BoundingBox

Koordinaten:

  • x: X-Wert der linken, oberen Ecke (Standardwert: -10%)
  • y: Y-Wert der linken, oberen Ecke (Standardwert: -10%)
  • width: Breite (Standardwert: 120%)
  • height: Höhe (Standardwert: 120%)

Mit diesen Attributen können Sie Position und Größe (Höhe und Breite) der Maske angeben. Nur innerhalb des Puffers gelegene Bereiche dienen auch als Maske.

Beachten Sie: Werden diese Attribut nicht angegeben, werden die Standardwerte angenommen, für x und y '-10%' und für width und height '120%'.

teiltransparente Bereiche

Die Füllfarbe der Maskenform bestimmt den Grad der Transparenz der Maske. Sie können mit Verläufen weiche Übergange der Transparenzen erreichen. Je näher der Farbwert bei Weiß (#ffffff) liegt, desto deckender ist die Maske, je näher bei Schwarz (#000000), desto transparenter.[3]

Beispiel ansehen …
<defs>
    <linearGradient id="Verlauf1"
                    x1="0%"   y1="0%"
                    x2="100%" y2="0%">
        <stop offset="0%"   stop-color="white"/>
        <stop offset="100%" stop-color="black"/>
    </linearGradient>

    <mask id="Maske3" x="0" y="0" width="800" height="120" >
        <rect x="0" y="0"  width="800" height="120"
            fill="url(#Verlauf1)"/>
    </mask>
</defs>

<text x="10" y="100" >
    Text im Hintergrund
</text>
<rect x="1" y="1" width="800" height="120"
    style="fill: #3983ab; mask: url(#Maske3)"/>
</main>

Über den Text wird eine Maske gelegt, die mit einem Verlauf gefüllt ist. Die weißen Bereiche geben keine Transparenz, so dass die blaue Farbe sichtbar bleibt, nach rechts werden die Schwarz-Anteile größer, so dass die Maske transparenter wird.

Bilder mit Masken einblenden

Beispiel ansehen …
  <defs>
    <lineargradient id="Verlauf1"
                    x1="0%"   y1="0%"
                    x2="100%" y2="0%">
        <stop offset="0%"  stop-color="white"/>
        <stop offset="80%" stop-color="black"/>
    </lineargradient>
	
	<radialGradient id="Verlauf2">
        <stop offset="90%"  stop-color="white"/>
        <stop offset="100%" stop-color="black"/>
    </radialGradient>

    <mask id="Maske4">
      <circle cx="200" cy="200" r="200"
            fill="url(#Verlauf1)" />
    </mask>

    <mask id="Maske5">
      <circle cx="200" cy="200" r="200"
            fill="url(#Verlauf2)" />
    </mask>
  </defs>

  <image x="0" y="0" width="400px" height="400px" transform="translate(50,0)"
    xlink:href="http://wiki.selfhtml.org/images/a/a6/Lauf-1.jpg"
	mask="url(#Maske4)">
    <title>Lauf an der Pegnitz - normal ohne Filter</title>
  </image>	

  <image x="0" y="0" width="400px" height="400px" transform="translate(500,0)"
    xlink:href="http://wiki.selfhtml.org/images/a/a6/Lauf-1.jpg"
	mask="url(#Maske5)">
    <title>Lauf an der Pegnitz - normal ohne Filter</title>
  </image>

In diesen Beispielen werden die Bilder durch Masken verdeckt. Während das linke Bild durch einen linearen Verlauf nach rechts hin ausgeblendet wird; wird das rechte Bild durch eine Maske mit einem radialen Verlauf verdeckt - die Außenbereiche werden verdeckt. Im Unterschied zu einer Beschneidung sorgt der Verlauf für weiche Kanten.


Bilder mit weichen Kanten

Weiche Kanten durch radiale Verläufe lassen sich nur bei kreisförmigen Elementen erzeugen. Bei anderen Formen kann man einen Filter verwenden:

Beispiel ansehen …
  <defs>
    <filter id="Filter1" x="-.33" y="-.33" width="1.5" height="1.5">
      <feGaussianBlur stdDeviation="15"/>
    </filter>

    <mask id="Maske6" x="0" y="0" width="400" height="400">
      <circle cx="200" cy="200" r="175" 
	        fill="white" filter="url(#Filter1)"/>
    </mask>

    <mask id="Maske7" x="0" y="0" width="400" height="400">
      <rect x="25" y="25" width="350" height="350" 
	        fill="white" filter="url(#Filter1)"/>
    </mask>
  </defs>

  <image x="0" y="0" width="400px" height="400px" transform="translate(50,0)"
    xlink:href="http://wiki.selfhtml.org/images/a/a6/Lauf-1.jpg"
	mask="url(#Maske6)">
    <title>Lauf an der Pegnitz - normal ohne Filter</title>
  </image>	

  <image x="0" y="0" width="400px" height="400px" transform="translate(500,0)"
    xlink:href="http://wiki.selfhtml.org/images/a/a6/Lauf-1.jpg"
	mask="url(#Maske7)">
    <title>Lauf an der Pegnitz - normal ohne Filter</title>
  </image>

Den Masken wurde ein Weichzeichnungsfilter feGaussianBlur zugeordnet. Da die Abmessungen des Filter größer als die der Grafik sind, wurden die Abmessungen der für die Masken benutzten Grundformen (Kreis links und Rechteck rechts) entsprechend verkleinert.


Weblinks

  1. W3C: Masking
  2. W3C: MaskElement
  3. http://tutorials.jenkov.com/svg/mask.html#mask-example