CSS typed object model
The CSSStyleValue and its subclasses represent CSS values as distinct types instead of only strings. Also known as typed OM. It is most useful when native HTML semantics or browser capabilities can replace custom implementation work.
Overview
The CSSStyleValue and its subclasses represent CSS values as distinct types instead of only strings. Also known as typed OM. It is most useful when native HTML semantics or browser capabilities can replace custom implementation work.
Browser support
| Feature | Desktop | Mobile | ||||
|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Safari | Chrome Android | Safari iOS | |
| 66 | 79 | | 16.4 | 66 | 16.4 | |
| The CSSKeywordValue interface of the CSS Typed Object Model API creates an object to represent CSS keywords and other identifiers. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSKeywordValue() constructor creates a new CSSKeywordValue object which represents CSS keywords and other identifiers. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The value property of the CSSKeywordValue interface returns or sets the value of the CSSKeywordValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
CSSMathClamp | 100 | 100 | | 16.4 | 100 | 16.4 |
CSSMathClamp `CSSMathClamp()` constructor | 100 | 100 | | 16.4 | 100 | 16.4 |
lower | 100 | 100 | | 16.4 | 100 | 16.4 |
upper | 100 | 100 | | 16.4 | 100 | 16.4 |
value | 100 | 100 | | 16.4 | 100 | 16.4 |
| The CSSMathInvert interface of the CSS Typed Object Model API represents a CSS calc used as calc(1 / ). It inherits properties and methods from its parent CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathInvert() constructor creates a new CSSMathInvert object which represents a CSS calc used as calc(1 / value) | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathInvert.value read-only property of the CSSMathInvert interface returns a CSSNumericValue object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathMax interface of the CSS Typed Object Model API represents the CSS max function. It inherits properties and methods from its parent CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
CSSMathMax Experimental The CSSMathMax() constructor creates a new CSSMathMax object which represents the CSS max function. | 66 | 79 | | | 66 | |
| The CSSMathMax.values read-only property of the CSSMathMax interface returns a CSSNumericArray object which contains one or more CSSNumericValue objects. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathMin interface of the CSS Typed Object Model API represents the CSS min function. It inherits properties and methods from its parent CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
CSSMathMin Experimental The CSSMathMin() constructor creates a new CSSMathMin object which represents the CSS min function. | 66 | 79 | | | 66 | |
| The CSSMathMin.values read-only property of the CSSMathMin interface returns a CSSNumericArray object which contains one or more CSSNumericValue objects. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathNegate interface of the CSS Typed Object Model API negates the value passed into it. It inherits properties and methods from its parent CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathNegate() constructor creates a new CSSMathNegate object which negates the value passed into it. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathNegate.value read-only property of the CSSMathNegate interface returns a CSSNumericValue object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathProduct interface of the CSS Typed Object Model API represents the result obtained by calling CSSNumericValue.add, CSSNumericValue.sub, or CSSNumericValue.toSum on CSSNumericValue. It inherits properties and methods from its parent CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
CSSMathProduct Experimental The CSSMathProduct() constructor creates a new CSSMathProduct object which creates a new CSSMathProduct object which multiplies the arguments passed into it. | 66 | 79 | | | 66 | |
| The CSSMathProduct.values read-only property of the CSSMathProduct interface returns a CSSNumericArray object which contains one or more CSSNumericValue objects. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathSum interface of the CSS Typed Object Model API represents the result obtained by calling CSSNumericValue.add, CSSNumericValue.sub, or CSSNumericValue.toSum on CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
CSSMathSum Experimental The CSSMathSum() constructor creates a new CSSMathSum object which creates a new CSSKeywordValue object which represents the result obtained by calling CSSNumericValue.add, CSSNumericValue.sub, or CSSNumericValue.toSum on CSSNumericValue. | 66 | 79 | | | 66 | |
| The CSSMathSum.values read-only property of the CSSMathSum interface returns a CSSNumericArray object which contains one or more CSSNumericValue objects. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathValue interface of the CSS Typed Object Model API a base class for classes representing complex numeric values. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMathValue.operator read-only property of the CSSMathValue interface indicates the operator that the current subtype represents. For example, if the current CSSMathValue subtype is CSSMathSum, this property will return the string "sum". | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMatrixComponent interface of the CSS Typed Object Model API represents the transform-function/matrix and transform-function/matrix3d values of the individual transform property in CSS. It inherits properties and methods from its parent CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSMatrixComponent() constructor creates a new CSSMatrixComponent object representing the transform-function/matrix and transform-function/matrix3d values of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The matrix property of the CSSMatrixComponent interface gets and sets a 2d or 3d matrix. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSNumericArray interface of the CSS Typed Object Model API contains a list of CSSNumericValue objects. | 66 | 79 | | 16.4 | 66 | 16.4 |
@@iterator [Symbol.iterator] | 66 | 79 | | 16.4 | 66 | 16.4 |
entries | 66 | 79 | | 16.4 | 66 | 16.4 |
forEach | 66 | 79 | | 16.4 | 66 | 16.4 |
keys | 66 | 79 | | 16.4 | 66 | 16.4 |
| The read-only length property of the CSSNumericArray interface returns the number of CSSNumericValue objects in the list. | 66 | 79 | | 16.4 | 66 | 16.4 |
values | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSNumericValue interface of the CSS Typed Object Model API represents operations that all numeric values can perform. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The add() method of the CSSNumericValue interface adds a supplied number to the CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The div() method of the CSSNumericValue interface divides the CSSNumericValue by the supplied value. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The equals() method of the CSSNumericValue interface returns a boolean indicating whether the passed value are strictly equal. To return a value of true, all passed values must be of the same type and value and must be in the same order. This allows structural equality to be tested quickly. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The max() method of the CSSNumericValue interface returns the highest value from among the values passed. The passed values must be of the same type. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The min() method of the CSSNumericValue interface returns the lowest value from among those values passed. The passed values must be of the same type. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The mul() method of the CSSNumericValue interface multiplies the CSSNumericValue by the supplied value. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The parse() static method of the CSSNumericValue interface converts a value string into an object whose members are value and the units. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The sub() method of the CSSNumericValue interface subtracts a supplied number from the CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The to() method of the CSSNumericValue interface converts a numeric value from one unit to another. | 66 | 79 | 149 | 16.4 | 66 | 16.4 |
| The toSum() method of the CSSNumericValue interface converts the object's value to a CSSMathSum object to values of the specified unit. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The type() method of the CSSNumericValue interface returns the type of CSSNumericValue, one of angle, flex, frequency, length, resolution, percent, percentHint, or time. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSPerspective interface of the CSS Typed Object Model API represents the transform-function/perspective value of the individual transform property in CSS. It inherits properties and methods from its parent CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSPerspective() constructor creates a new CSSPerspective object representing the transform-function/perspective value of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The length property of the CSSPerspective interface sets the distance from z=0. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSRotate interface of the CSS Typed Object Model API represents the rotate value of the individual transform property in CSS. It inherits properties and methods from its parent CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The angle property of the CSSRotate interface gets and sets the angle of rotation. A positive angle denotes a clockwise rotation, a negative angle a counter-clockwise one. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSRotate() constructor creates a new CSSRotate object representing the transform-function/rotate value of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The x property of the CSSRotate interface gets and sets the abscissa or x-axis of the translating vector. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The y property of the CSSRotate interface gets and sets the ordinate or y-axis of the translating vector. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The z property of the CSSRotate interface representing the z-component of the translating vector. A positive value moves the element towards the viewer, and a negative value farther away. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSScale interface of the CSS Typed Object Model API represents the transform-function/scale and transform-function/scale3d values of the individual transform property in CSS. It inherits properties and methods from its parent CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSScale() constructor creates a new CSSScale object representing the transform-function/scale and transform-function/scale3d values of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The x property of the CSSScale interface gets and sets the abscissa or x-axis of the translating vector. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The y property of the CSSScale interface gets and sets the ordinate or y-axis of the translating vector. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The z property of the CSSScale interface representing the z-component of the translating vector. A positive value moves the element towards the viewer, and a negative value farther away. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSSkew interface of the CSS Typed Object Model API is part of the CSSTransformValue interface. It represents the transform-function/skew value of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The ax property of the CSSSkew interface gets and sets the angle used to distort the element along the x-axis (or abscissa). | 66 | 79 | | 16.4 | 66 | 16.4 |
| The ay property of the CSSSkew interface gets and sets the angle used to distort the element along the y-axis (or ordinate). | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSSkew() constructor creates a new CSSSkew object which represents the transform-function/skew value of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSSkewX interface of the CSS Typed Object Model API represents the transform-function/skewX value of the individual transform property in CSS. It inherits properties and methods from its parent CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The ax property of the CSSSkewX interface gets and sets the angle used to distort the element along the x-axis (or abscissa). | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSSkewX() constructor creates a new CSSSkewX object which represents the value of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSSkewY interface of the CSS Typed Object Model API represents the transform-function/skewY value of the individual transform property in CSS. It inherits properties and methods from its parent CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The ay property of the CSSSkewY interface gets and sets the angle used to distort the element along the y-axis (or ordinate). | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSSkewY() constructor creates a new CSSSkewY object which represents the transform-function/skewY value of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The styleMap read-only property of the CSSStyleRule interface returns a StylePropertyMap object which provides access to the rule's property-value pairs. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSStyleValue interface of the CSS Typed Object Model API is the base class of all CSS values accessible through the Typed OM API. An instance of this class may be used anywhere a string is expected. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The parse() static method of the CSSStyleValue interface sets a specific CSS property to the specified values and returns the first value as a CSSStyleValue object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The parseAll() static method of the CSSStyleValue interface sets all occurrences of a specific CSS property to the specified value and returns an array of CSSStyleValue objects, each containing one of the supplied values. | 66 | 79 | | 16.4 | 66 | 16.4 |
toString | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTransformComponent interface of the CSS Typed Object Model API is part of the CSSTransformValue interface. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The is2D read-only property of the CSSTransformComponent interface indicates where the transform is 2D or 3D. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The toMatrix() method of the CSSTransformComponent interface returns a DOMMatrix object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The toString() method of the CSSTransformComponent interface is a stringifier returning a CSS Transforms function. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTransformValue interface of the CSS Typed Object Model API represents transform-list values as used by the CSS transform property. | 66 | 79 | | 16.4 | 66 | 16.4 |
@@iterator [Symbol.iterator] | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTransformValue() constructor creates a new CSSTransformValue object which represents a list of individual transform objects. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTransformValue.entries() method returns an array of a given object's own enumerable property [key, value] pairs in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well). | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTransformValue.forEach() method executes a provided function once for each element of the CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The read-only is2D property of the CSSTransformValue interface returns whether the transform is 2D or 3D. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTransformValue.keys() method returns a new array iterator object that contains the keys for each index in the array. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The read-only length property of the CSSTransformValue interface returns the number of transform components in the list. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The toMatrix() method of the CSSTransformValue interface returns a DOMMatrix object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTransformValue.values() returns a new array iterator object that contains the values for each index in the CSSTransformValue object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTranslate interface of the CSS Typed Object Model API represents the transform-function/translate value of the individual transform property in CSS. It inherits properties and methods from its parent CSSTransformValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSTranslate() constructor creates a new CSSTranslate object representing the transform-function/translate value of the individual transform property in CSS. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The x property of the CSSTranslate interface gets and sets the abscissa or x-axis of the translating vector. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The y property of the CSSTranslate interface gets and sets the ordinate or y-axis of the translating vector. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The z property of the CSSTranslate interface representing the z-component of the translating vector. A positive value moves the element towards the viewer, and a negative value farther away. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnitValue interface of the CSS Typed Object Model API represents values that contain a single unit type. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnitValue() constructor creates a new CSSUnitValue object which returns a new CSSUnitValue object which represents values that contain a single unit type. For example, "42px" would be represented by a CSSNumericValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnitValue.unit read-only property of the CSSUnitValue interface returns a string indicating the unit type. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnitValue.value property of the CSSUnitValue interface returns a double indicating the number of units. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnparsedValue interface of the CSS Typed Object Model API represents property values that reference custom properties. It consists of a list of string fragments and variable references. | 66 | 79 | | 16.4 | 66 | 16.4 |
@@iterator [Symbol.iterator] | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnparsedValue() constructor creates a new CSSUnparsedValue object which represents property values that reference custom properties. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnparsedValue.entries() method returns an array of a given object's own enumerable property [key, value] pairs in the same order as that provided by a Statements/for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well). | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnparsedValue.forEach() method executes a provided function once for each element of the CSSUnparsedValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnparsedValue.keys() method returns a new array iterator object that contains the keys for each index in the array. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The length read-only property of the CSSUnparsedValue interface returns the number of items in the object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSUnparsedValue.values() method returns a new array iterator object that contains the values for each index in the CSSUnparsedValue object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The CSSVariableReferenceValue interface of the CSS Typed Object Model API allows you to create a custom name for a built-in CSS value. This object functionality is sometimes called a "CSS variable" and serves the same purpose as the var function. The custom name must begin with two dashes. | 66 | 79 | | 16.4 | 66 | 16.4 |
| Creates a new CSSVariableReferenceValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The fallback read-only property of the CSSVariableReferenceValue interface returns the custom property fallback value of the CSSVariableReferenceValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The variable property of the CSSVariableReferenceValue interface returns the custom property name of the CSSVariableReferenceValue. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The computedStyleMap() method of the Element interface returns a StylePropertyMapReadOnly interface which provides a read-only representation of a CSS declaration block that is an alternative to CSSStyleDeclaration. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The attributeStyleMap read-only property of the HTMLElement interface returns a live StylePropertyMap object that contains a list of style properties of the element that are defined in the element's inline style attribute, or assigned using the HTMLElement.style property of the HTMLElement interface via script. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The StylePropertyMap interface of the CSS Typed Object Model API provides a representation of a CSS declaration block that is an alternative to CSSStyleDeclaration. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The append() method of the StylePropertyMap interface adds the passed CSS value to the StylePropertyMap with the given property. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The clear() method of the StylePropertyMap interface removes all declarations in the StylePropertyMap. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The delete() method of the StylePropertyMap interface removes the CSS declaration with the given property. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The set() method of the StylePropertyMap interface changes the CSS declaration with the given property. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The StylePropertyMapReadOnly interface of the CSS Typed Object Model API provides a read-only representation of a CSS declaration block that is an alternative to CSSStyleDeclaration. Retrieve an instance of this interface using Element.computedStyleMap. | 66 | 79 | | 16.4 | 66 | 16.4 |
@@iterator [Symbol.iterator] | 66 | 79 | | 16.4 | 66 | 16.4 |
| The StylePropertyMapReadOnly.entries() method returns an array of a given object's own enumerable property [key, value] pairs, in the same order as that provided by a Statements/for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well). | 66 | 79 | | 16.4 | 66 | 16.4 |
| The StylePropertyMapReadOnly.forEach() method executes a provided function once for each element of StylePropertyMapReadOnly. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The get() method of the StylePropertyMapReadOnly interface returns a CSSStyleValue object for the first value of the specified property. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The getAll() method of the StylePropertyMapReadOnly interface returns an array of CSSStyleValue objects containing the values for the provided property. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The has() method of the StylePropertyMapReadOnly interface indicates whether the specified property is in the StylePropertyMapReadOnly object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The StylePropertyMapReadOnly.keys() method returns a new array iterator containing the keys for each item in StylePropertyMapReadOnly | 66 | 79 | | 16.4 | 66 | 16.4 |
| The size read-only property of the StylePropertyMapReadOnly interface returns an unsigned long integer containing the size of the StylePropertyMapReadOnly object. | 66 | 79 | | 16.4 | 66 | 16.4 |
| The StylePropertyMapReadOnly.values() method returns a new array iterator containing the values for each index in the StylePropertyMapReadOnly object. | 66 | 79 | | 16.4 | 66 | 16.4 |
- Not exposed to PaintWorklet.
- Not exposed to PaintWorklet.
- Not exposed to PaintWorklet.
- Requires an experimental browser flag to be enabled
Syntax
// Retrieving a value (with type)
const width = el.computedStyleMap().get('width');
console.log(width.value, width.unit); // 100, 'px'
// Setting a value
el.attributeStyleMap.set('height', CSS.px(200)); Live demo
Set width with CSSUnitValue
Use attributeStyleMap and CSS.px when the typed OM API is available.
Computed style note
Read from computedStyleMap when available and show a safe fallback otherwise.
Use cases
Use CSS typed object model
Use CSS typed object model when standard HTML needs a more specific platform feature, semantic signal, or browser capability.
Handle edge cases
Apply CSS typed object model to solve a focused requirement without redesigning the whole page architecture.
Cautions
- Test CSS typed object model in your target browsers and input environments before depending on it as a primary behavior.
- Provide a fallback path or acceptable degradation strategy when support is still limited.
Accessibility
- Make sure CSS typed object model supports the intended task without making the page harder to perceive, understand, or operate.
Related links
Powered by web-features