Title: CSS Masking Module Level 1 Status: ED Prepare for TR: no Work Status: Refining Implementation Report: https://test.csswg.org/harness/results/css-masking-1_dev/grouped/ ED: https://drafts.fxtf.org/css-masking-1/ TR: https://www.w3.org/TR/css-masking-1/ Previous Version: https://www.w3.org/TR/2021/CRD-css-masking-1-20210805/ Shortname: css-masking Level: 1 Group: csswg Issue Tracking: GitHub https://github.com/w3c/fxtf-drafts/labels/css-masking-1 Editor: Dirk Schulze, Adobe Inc., dschulze@adobe.com, w3cid 51803 Editor: Brian Birtles, Mozilla Japan, bbirtles@mozilla.com, w3cid 43194 Editor: Tab Atkins Jr., Google, https://www.xanthir.com/contact/, w3cid 42199 Abstract: CSS Masking provides two means for partially or fully hiding portions of visual elements: masking and clipping. Abstract: Abstract: Masking describes how to use another graphical element or image as a luminance or alpha mask. Typically, rendering an element via CSS or SVG can conceptually be described as if the element, including its children, are drawn into a buffer and then that buffer is composited into the element's parent. Luminance and alpha masks influence the transparency of this buffer before the compositing stage. Abstract: Abstract: Clipping describes the visible region of visual elements. The region can be described by using certain SVG graphics elements or basic shapes. Anything outside of this region is not rendered. Test Suite: https://test.csswg.org/suites/css-masking/nightly-unstable/ Ignored Vars: trapeze.svg
spec:fill-stroke-3; type:value; text:square spec:svg2; type:property text:fill text:fill-rule text:fill-opacity text:stroke text:stroke-dashoffset text:stroke-dasharray text:stroke-opacity text:stroke-linecap text:stroke-miterlimit text:stroke-linejoin text:stroke-width spec:svg2; type:element text:a text:title text:script text:style spec:svg; type:element; text:font spec:css-color-4; type:property text:color spec:css-fonts-4; type:property; text:font-family text:font-stretch text:font-weight text:font-style spec:filter-effects-1; type:property; text:flood-color text:flood-opacity text:lighting-color text:color-interpolation-filters text:filter spec:filter-effects-1; type:element; text:fecolormatrix text:filter spec:css-transforms-1; type:dfn; text:user coordinate system spec:css-overflow-3; type:value; for:overflow; text:visible
spec:svg2; url:https://svgwg.org/svg2-draft/coords.html#ViewBoxAttribute; type:element-attr; for:svg; text:viewBox spec:svg2; url:https://svgwg.org/svg2-draft/text.html#TermTextContentElement; type:dfn; text:text content element spec:svg2; url:https://svgwg.org/svg2-draft/render.html#TermNeverRenderedElement; type:dfn; text:never-rendered element# Introduction # {#intro} This section is not normative. This specification defines two different graphical operations which both fully or partly hide portions of an object: clipping and masking. ## Clipping ## {#clipping} A closed vector path, shape or polygon defines a so called clipping path. This clipping path is a region (in the absence of anti-aliasing) where everything on the “inside” of this region is allowed to show through but everything on the outside is “clipped out” and does not appear on the canvas.
Term in CSS Masking | Term in [[!CSS3BG]] |
---|---|
mask layer image | background images |
mask painting area | background painting area |
mask-size | background-size |
mask-position | background-position |
mask positioning area | background positioning area |
mask border image | border-image |
mask border image area | border image area |
<g clip-path="circle()">
<path id="shape" d="M0,0 L10,10, L 20,0 z"/>
</g>
The shape is referenced by a use element:
<use xlink:href="#shape"/>
The geometry of the shape is not influenced by the circular clipping path.
Name: clip-path Value: <Specifies a basic shape or references a clipPath element to create a clipping path.> | [ < > || < > ] | none Initial: none Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: as specified, but with < > values made absolute Media: visual Animation type: by computed value
<clip-source> = <>
<geometry-box> = <> | fill-box | stroke-box | view-box
clip-path: polygon(15px 99px, 30px 87px, 65px 99px, 85px 55px,
122px 57px, 184px 73px, 198px 105px, 199px 150px,
145px 159px, 155px 139px, 126px 120px, 112px 138px,
80px 128px, 39px 126px, 24px 104px);
clip-path: url("#clip1");
<clipPath id="clip1">
<polygon points="15,99 30,87 65,99 85,55 122,57 184,73 198,105
199,150 145,159 155,139 126,120 112,138 80,128 39,126 24,104"/>
</clipPath>
Name: | clipPath |
---|---|
Categories: | container elements, never-rendered element |
Content model: | Any number of the following elements, in any order: |
Attributes: | |
DOM Interfaces: | SVGClipPathElement |
Name: clip-rule Value: nonzero | evenodd Initial: nonzero Applies to: Applies to SVG graphics elements Inherited: yes Percentages: n/a Computed value: as specified Media: visual Animation type: discreteThe 'clip-rule' property indicates the algorithm which is to be used to determine whether a given point is inside a shape for a clipping region created with a graphics element. The definition of the algorithms and the 'clip-rule' values follows the definition of the 'fill-rule' property. See section “Fill Properties” in SVG 1.1 [[!SVG11]].
The following drawing illustrates the nonzero rule:
The following drawing illustrates the evenodd rule:
<g clip-rule="nonzero">
<clipPath id="MyClip">
<path d="..." clip-rule="evenodd" />
</clipPath>
<rect clip-path="url(#MyClip)" ... />
</g>
whereas the following fragment of code will not cause an evenodd clipping rule to be applied because the 'clip-rule' is specified on the referencing element, not on the object defining the clipping shape:
<g clip-rule="nonzero">
<clipPath id="MyClip">
<path d="..." />
</clipPath>
<rect clip-path="url(#MyClip)" clip-rule="evenodd" ... />
</g>
Name: mask-image Value: <This property sets the mask layer image of an element. Where:># Initial: none Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: the keyword ''mask-image/none'', a computed < >, or a computed < > Media: visual Animation type: discrete
<mask-reference> = none | <> | < >
<mask-source> = <>
body { mask-image: linear-gradient(black 0%, transparent 100%) }
p { mask-image: none }
div { mask-image: url(resources.svg#mask2) }
Name: mask-mode Value: <The 'mask-mode' property indicates whether the <># Initial: match-source Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: discrete
<masking-mode> = alpha | luminance | match-sourceValues have the following meanings:
<mask id="SVGMask" mask-type="alpha" maskContentUnits="objectBoundingBox">
<radialGradient id="radialFill">
<stop stop-color="white" offset="0"/>
<stop stop-color="black" offset="1"/>
</radialGradient>
<circle fill="url(#radialFill)" cx="0.5" cy="0.5" r="0.5"/>
</mask>
<style>
rect {
mask-image: url(#SVGMask);
mask-mode: luminance;
}
</style>
<rect width="200" height="200" fill="green"/>
Name: mask-repeat Value: <Specifies how mask layer images are tiled after they have been sized and positioned. See 'background-repeat' property [[!CSS3BG]] for the definitions of the property values.># Initial: repeat Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: Consists of: two keywords, one per dimension Media: visual Animation type: discrete
body {
background-color: blue;
mask-image: url(dot-mask.png) luminance;
mask-repeat: space;
}
Name: mask-position Value: <See the 'background-position' property [[!CSS3BG]] for the definitions of the property values.># Initial: 0% 0% Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: refer to size of mask painting area minus size of mask layer image; see text 'background-position' [[!CSS3BG]] Computed value: Consisting of: two keywords representing the origin and two offsets from that origin, each given as an absolute length (if given a < >), otherwise as a percentage. Media: visual Animation type: repeatable list
body {
mask-image: url("logo.png");
mask-position: 100% 100%;
mask-repeat: no-repeat;
}
mask-position: right 3em bottom 10px
Name: mask-clip Value: [ <For mask layer images that do not reference a mask element, 'mask-clip' determines the mask painting area, which determines the area that is affected by the mask. The painted content of an element must be restricted to this area. The 'mask-clip' property has no affect on a mask layer image that references a mask element. The x, y, width, height and maskUnits attributes on the mask element determine the mask painting area for mask references. Values have the following meanings:> | no-clip ]# Initial: border-box Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: discrete
Name: mask-origin Value: <For elements rendered as a single box, specifies the mask positioning area. For elements rendered as multiple boxes (e.g., inline boxes on several lines, boxes on several pages) specifies which boxes 'box-decoration-break' operates on to determine the mask positioning area.># Initial: border-box Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: discrete
Name: mask-size Value: <Specifies the size of the mask layer images. See 'background-size' property [[!CSS3BG]] for the definitions of the property values. See the section “Layering multiple mask layer images” for how 'mask-size' interacts with other comma-separated mask properties to form each mask layer. ## Compositing mask layers: the 'mask-composite' property ## {#the-mask-composite}># Initial: auto Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: as specified, but with lengths made absolute Media: visual Animation type: repeatable list
Name: mask-composite Value: <># Initial: add Applies to: All elements. In SVG, it applies to container elements without the defs element and all graphics elements Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: discrete
<compositing-operator> = add | subtract | intersect | excludeEach keyword represents a Porter-Duff compositing operator [[!COMPOSITING-1]] which defines the compositing operation used on the current mask layer with the mask layers below it. In the following, the current mask layer is referred to source, all mask layers below it (with the corresponding compositing operators applied) are referred to destination.
mask-image: circle.svg, rect.svg;
The mask layer with rect.svg is below the mask layer with circle.svg. That means circle.svg is closer to the user than rect.svg.
With the property 'mask-composite' the author may choose different ways to combine multiple mask layers.
* ''mask-composite/add'' paints the circle.svg on top of rect.svg. The behavior is described by the compositing operator source over.
mask-composite: add;
mask-composite: subtract;
mask-composite: intersect;
mask-composite: exclude;
mask-image: rect.svg, circle.svg;
mask-composite: add, exclude;
rect.svg and circle.svg make use of the ''mask-composite/add'' compositing operator. There is no further mask layer to use ''mask-composite/exclude'' and therefore, ''mask-composite/exclude'' is ignored.
mask-image: trapeze.svg, circle.svg, rect.svg;
mask-composite: subtract, add;
First, circle.svg is “added” to rect.svg. In a second step, only portions of trapeze.svg that are not overlapping the compositing result of the previous two layers is visible.
Name: mask Value: <># Initial: see individual properties Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: see individual properties Computed value: see individual properties Media: visual Animation type: see individual properties
<mask-layer> = <If one <> || < > [ / < > ]? || < > || < > || [ < > | no-clip ] || < > || < >
div {
background: linear-gradient(bottom, #F27BAA 0%, #FCC8AD 100%);
mask-border-slice: 25 fill;
mask-border-repeat: stretch;
mask-border-source: url(mask.png);
}
Name: mask-border-source Value: none | <Specifies an image to be used as mask border image. An image that is an empty image (zero width or zero height), that fails to download, is non-existent, or that cannot be displayed (e.g. because it is not in a supported image format) is ignored. It still counts as an mask border image but does not mask the element. See “Mask processing” on how to process the mask border image. A computed value of other than ''mask-border-source/none'' results in the creation of a stacking context [[!CSS21]] the same way that CSS 'opacity' [[CSS3COLOR]] does for values other than ''1''. 'mask-border-source' and 'mask-image' can be specified independent of each other. If both properties have a value other than ''mask-border-source/none'', the element is masked by both masking operations one after the other. Note: It does not matter if 'mask-image' is applied to the element before or after 'mask-border-source'. Both operation orders result in the same rendering. ## Mask Border Image Interpretation: the 'mask-border-mode' property ## {#the-mask-border-mode}> Initial: none Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: they keyword ''mask-border-source/none'' or the computed < > Media: visual Animation type: discrete
Name: mask-border-mode Value: luminance | alpha Initial: alpha Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: discreteThe 'mask-border-mode' property indicates whether the <
Name: mask-border-slice Value: [ <This property specifies inward offsets from the top, right, bottom, and left edges of the mask border image, dividing it into nine regions: four corners, four edges and a middle. The middle image part is discarded and treated as fully opaque white (the content covered by the middle part is not masked and shines through) unless the fill keyword is present. See the 'border-image-slice' property [[!CSS3BG]] for the definitions of the property values. ## Masking Areas: the 'mask-border-width' property ## {#the-mask-border-width}> | < > ]{1,4} fill? Initial: 0 Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: refer to size of the mask border image Computed value: as specified Media: visual Animation type: discrete
Name: mask-border-width Value: [ <The mask border image is drawn inside an area called the mask border image area. This is an area whose boundaries by default correspond to the border box, see 'mask-border-outset'. See the 'border-image-width' property [[!CSS3BG]] for the definitions of the property values. Note: For SVG elements without an associated layout box the 'border-width' is considered to be ''0''. ## Edge Overhang: the 'mask-border-outset' property ## {#the-mask-border-outset}> | < > | auto ]{1,4} Initial: auto Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: relative to width/height of the mask border image area Computed value: all < >s made absolute, otherwise as specified Media: visual Animation type: discrete
Name: mask-border-outset Value: [ <The values specify the amount by which the mask border image area extends beyond the border box. If it has four values, they set the outsets on the top, right, bottom and left sides in that order. If the left is missing, it is the same as the right; if the bottom is missing, it is the same as the top; if the right is missing, it is the same as the top. As with 'mask-border-width', a <> | < > ]{1,4} Initial: 0 Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: all < >s made absolute, otherwise as specified Media: visual Animation type: discrete
Name: mask-border-repeat Value: [ stretch | repeat | round | space ]{1,2} Initial: stretch Applies to: All elements. In SVG, it applies to container elements excluding the defs element, all graphics elements and the use element Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: discreteThis property specifies how the images for the sides and the middle part of the mask border image are scaled and tiled. The first keyword applies to the horizontal sides, the second to the vertical ones. If the second keyword is absent, it is assumed to be the same as the first. See the 'border-image-repeat' property [[!CSS3BG]] for the definitions of the property values. The exact process for scaling and tiling the mask border image parts is given in the section Masking with the mask border image ## Mask Border Image Shorthand: the 'mask-border' property ## {#the-mask-border}
Name: mask-border Value: <<'mask-border-source'>> || <<'mask-border-slice'>> [ / <<'mask-border-width'>>? [ / <<'mask-border-outset'>> ]? ]? || <<'mask-border-repeat'>> || <<'mask-border-mode'>> Initial: See individual properties Applies to: See individual properties Inherited: no Percentages: n/a Computed value: See individual properties Media: visual Animation type: See individual propertiesThis is a shorthand property for setting 'mask-border-source', 'mask-border-slice', 'mask-border-width', 'mask-border-outset', 'mask-border-repeat' and 'mask-border-mode'. Omitted values are set to their initial values. Note: The 'mask' shorthand resets the properties 'mask-border', 'mask-border-source', 'mask-border-slice', 'mask-border-width', 'mask-border-outset', 'mask-border-repeat' and 'mask-border-mode'. ## Masking with the mask border image ## {#masking-with-the-mask-border-image} After the mask border image given by 'mask-border-source' is sliced by the 'mask-border-slice' values, the resulting nine images are scaled, positioned, and tiled into their corresponding mask border image regions in four steps as described in the section Drawing the Border Image [[!CSS3BG]]. The application of the 'mask-border-source' property to an element formatted with the CSS box model establishes a stacking context in the same way that CSS 'opacity' [[CSS3COLOR]] does, and all the element's descendants are rendered together as a group with the masking applied to the group as a whole. The 'mask-border-source' property has no effect on the geometry or hit-testing of any element's CSS boxes. # SVG Mask Sources # {#svg-masks} ## The mask element ## {#MaskElement}
Name: | mask |
---|---|
Categories: | container elements, never-rendered element |
Content model: | Any number of the following elements, in any order: |
Attributes: | |
DOM Interfaces: | SVGMaskElement |
Name: mask-type Value: luminance | alpha Initial: luminance Applies to: mask elements Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: discreteThe 'mask-type' property defines whether the content of the mask element is treated as as luminance mask or alpha mask, as described in Calculating mask values. Values have the following meanings:
<svg>
<mask style="mask-type: luminance;" id="mask">
...
</mask>
</svg>
<p style="mask-image: url(#mask); mask-mode: auto;">
This is the masked content.
</p>
In the next example the computed value of 'mask-mode' is ''mask-mode/alpha'' and overrides the preference on the mask element that is computed to ''mask-type/luminance''. The mask layer image is used as an alpha mask.
lt;svg>
<mask style="mask-type: luminance;" id="mask2">
...
</mask>
lt;/svg>
lt;p style="mask-image: url(#mask2); mask-mode: alpha;">
This is the masked content.
lt;/p>
Name: clip Value: <With this specification the 'clip' property is deprecated. Authors are encouraged to use the 'clip-path' property instead. UAs must support the 'clip' property. The 'clip' property applies only to absolutely positioned elements. In SVG, it applies to elements which establish a new viewport, pattern elements and mask elements. Values have the following meanings:> | ''clip/auto'' Initial: auto Applies to: Absolutely positioned elements. In SVG, it applies to elements which establish a new viewport, pattern elements and mask elements. Inherited: no Percentages: n/a Computed value: as specified Media: visual Animation type: by computed value
p#one { clip: rect(5px, 40px, 45px, 5px); }
p#two { clip: rect(5px, 55px, 45px, 5px); }
and assuming both Ps are 50 by 55 pixel, will create, respectively, the rectangular clipping regions delimited by the dashed lines in the following illustrations:
[Exposed=Window] interface SVGClipPathElement : SVGElement { readonly attribute SVGAnimatedEnumeration clipPathUnits; readonly attribute SVGAnimatedTransformList transform; };
[Exposed=Window] interface SVGMaskElement : SVGElement { readonly attribute SVGAnimatedEnumeration maskUnits; readonly attribute SVGAnimatedEnumeration maskContentUnits; readonly attribute SVGAnimatedLength x; readonly attribute SVGAnimatedLength y; readonly attribute SVGAnimatedLength width; readonly attribute SVGAnimatedLength height; };