preface
While we’ve been styling DOM elements for a long time, we’re actually manipulating the CSS object model CSSOM. Houdini promotes another set of CSS object model Typed OM. What benefits does this standard bring to us?
CSSOM
What does CSSOM do?
In simple terms, CSSOM is a set of apis that allow JS to manipulate element CSS. It plays a very important role in the process of page rendering by the browser. The rendering steps of the browser roughly include:
- Parsing the HTML content and building it into A DOM object
- Parses the CSS content and builds it into CSSOM objects
- The browser combines the DOM and CSSOM into a render tree
- Eventually the browser renders the result
Problems faced
In normal development, we use the style object on the element to get the style of the element:
const cover = document.getElementById('cover');
cover.style.opacity; // Suppose it is 0.5
Copy the code
Then we reduce the transparency a little bit based on this:
cover.style.opacity += 0.3;
Copy the code
So, what’s wrong with that? First let’s look at the types of values:
typeof cover.style.opacity; // string
Copy the code
What a suprise! , so in fact, the operation above to reduce transparency actually produces a value of 0.50.3, which is clearly a problematic operation. Similarly, 200px strings are returned for attributes such as height, and getComputedStyles returns the same value. If you want to fit these values into a series of mathematical calculations, you must first convert them to numeric objects. To solve these problems, Typed OM emerged.
Typed OM
The appearance of Typed OM adds a new way for us to read and set values. Different from CSSOM, the Typed OM shows CSSOM values as a map in the attributeStyleMap of elements. The values of the rules are more useable JavaScript objects.
Benefits brought about
- Fewer bugs, as shown earlier, and operations via TypedOM to reduce this type of problem;
- The simple arithmetic operation method can be called on the numerical object, and the unit conversion can be done easily between the absolute units.
- CSSOM performance has been further improved due to the reduction of string operations. Tests provided by Tab Akins show that Typed OM operations are about 30% faster than CSSOM strings.
- Error handling, which throws an error for the wrong CSS value;
- Keep the key names consistent with the normal CSS style, and do not test the edge of backgroundColor and background-color.
- Due to the
attributeStyleMap
As well ascomputedStyleMap
Object is amap
That means we can use standardsmap
All methods provided in.
Browser Support
Current implementation of major browser vendors:
Intent to Implement: Intent to implement
Shipped: has been published
No signal: indicates No intention
Google Chrome and Opera were implemented in version 66 and 53, respectively.
Availability detection methods
You can check whether it is available by:
window.CSS && CSS.number
Copy the code
use
Basic read and assign methods
In Typed OM, the number and the unit of the number are separated. It gets a CSSUnitValue object with two internal keys: value and unit.
To assign a style to an element, you can also accept strings in addition to using css.px constructs
el.attributeStyleMap.set('height', CSS.px(10));
el.attributeStyleMap.set('height'.'10px');
// For fetch, return the CSSUnitValue object, whose value property is accessed to obtain a numeric value
el.attributeStyleMap.get('height').value; / / 10
el.attributeStyleMap.get('height').unit; // 'px'
Copy the code
CSS Numeric types
Typed OM, we have two basic numeric types. One is the simple numeric plus unit numbers mentioned in the example above. They belong to the CSSUnitValue type. For expressions that are more than a single number plus units or are evaluated using CALC, they are of type CSSMathValue.
CSSUnitValue
As mentioned above, CSSUnitValue represents a simple CSS value of number plus unit, but you can also construct one by using new on it. In most cases, you can also construct it directly from the CSS object’s method of the same name:
const num = CSS.number('10');
// num.value -> 10 num.unit -> 'number'
const px = CSS.px(42);
// px.value -> 42 px.unit -> 'px'
// We can also construct one using the new method
const deg = new CSSUnitValue(45.'deg');
// deg.value -> 45 deg.unit -> 'deg'
Copy the code
For a complete list of methods, you can view the contents of CSS Typed OM drafts.
CSSMathValue
If you want to express values that involve more than one value and use calC to evaluate the expression, use CSSMathValue. It should be noted that after calc is evaluated by the browser in actual use, it gets the calculation result, namely a CSSUnitValue value.
Since expressions are involved, operators are necessary. CSSMathValue also provides basic mathematical operators:
Calc (100vw + -10px)
new CSSMathSum(CSS.vw(100), CSS.px(- 10));
Calc (45deg * 3.1415926)
new CSSMathProduct(CSS.deg(45), CSS.number(Math.PI));
Calc (-10px)
new CSSMathNegate(CSS.px(10));
// Take the reciprocal: calc(1/10px);
new CSSMathInvert(CSS.px(10));
// Scope limit: calc(1px);
// The first parameter is the minimum value, the third parameter is the maximum value, and the middle value is the value to be clamped
new CSSMathClamp(1.- 1.3);
// Max: Max (10%, 10px)
new CSSMathMax(CSS.percent(10), CSS.px(10));
// 最小值: min(10%, 10px)
new CSSMathMin(CSS.percent(10), CSS.px(10));
Copy the code
What if the expression needs to be more complicated?
For example, if you want to build an expression: calc(1px * (3px + 2em)), you can do the following nesting:
new CSSMathProduct(CSS.px(1), new CSSMathSum(CSS.px(3), CSS.em(2)));
Copy the code
Mathematical operation method
CSSMathValue and CSSUnitValue both inherit from CSSNumericValue, and naturally inherit from CSSNumericValue’s mathematical operations, which are convenient to use:
// Add 1px + 1px
CSS.px(1).add(1);
// Subtract: 1px - 1px
CSS.px(1).sub(1);
// Multiply: 1px by 3px
CSS.px(1).mul(3);
// Divide: 1px into 3px
CSS.px(1).div(3);
// Compare the maximum value: Max (50%, 50vw);
CSS.percent(50).max(CSS.vw(50));
// Minimum value: min(50vh, 50vw);
CSS.vh(50).min(CSS.vw(50));
// The equality comparison method returns a Boolean value true
CSS.px(200).equals(CSS.px(200));
Copy the code
The addition, subtraction, multiplication and division operations also support multiple parameters
// Add calc(10px + 10vw + 10%)
CSS.px(10).add(CSS.vw(10), CSS.percent(10));
Copy the code
In addition, absolute units can be interchangeable:
CSS.in(9).to('cm').value;
/ / 22.860000000000003
Copy the code
CSS Transform Value type
For the Transform property of CSSTransform, the above basic value expression cannot be satisfied, so we need to use CSSTransformValue. To build CSSTransformValue, we can pass in the following parameters:
CSSRotate
Rotation:CSSScale
: zoomCSSSkew
Tilt:CSSSkewX
: X axis tiltCSSSkewY
: The Y-axis is tiltedCSSTranslate
: transformCSSPerspective
Perspective:
Note that skew(x, y) and skewX(x) skewY(y) have different results as usual
It’s just as easy to use:
Transform: rotateX(45deg) Scale (0.5) translate3D (10px, 10px, 10px);
new CSSTransformValue([
new CSSRotate(CSS.deg(45)),
new CSSScale(CSS.number(0.5), CSS.number(0.5)),
new CSSTranslate(CSS.px(10), CSS.px(10), CSS.px(10)));Copy the code
For the CSSTranslate type, you can also access the is2D method on the object to see if the current translate is2D or 3D. At the same time, the toMatrix method can be called to obtain the DOMMatrix matrix object.
CSS position value type
For properties that need to describe x/y positions, such as object-position, the CSSPositionValue type is used.
const pos = new CSSPositionValue(CSS.px(5), CSS.px(10));
// pos.y.value -> 10 pos.x.value -> 10
Copy the code
Numerical analysis
Since we can get string rules on objects of Type OM using the toString() method, can we use the API to parse string rules into types of Type OM? The answer is yes. Use the parse method in CSSStyleValue:
CSSStyleValue.parse('transform'.'translate (10 px) scale (0.5)');
// Will parse into a CSSTransformValue object
CSSStyleValue.parse('height'.'2px');
// The CSSUnitValue type will be resolved
Copy the code
computedStyleMap
The computedStyleMap method on the element returns all of the calculated attribute values, just like the traditional call to the window.getComputedStyle method. But there are still some small differences. Window.getcomputedstyle still returns string values; For the computedStyleMap method, the value returned is converted to the Type OM value Type.
document.body.attributeStyleMap.set('opacity'.1);
document.body.computedStyleMap().get('opacity').value;
/ / 1
window.getComputedStyle(document.body).opacity;
/ / '1'
Copy the code
Typed OM role in Other Houdini standards
Since Typed OM refers to the numbers of CSSOM, then the numbers in the standards related to it will all be related to it. The Typed values Typed by the CSS Paint API are also numeric types Typed in CSS Typed OM.
In addition, the use of Typed OM is laying the foundation for the more efficient development of various Houdini standards (including custom attributes, layout and drawing standards).
conclusion
CSS Typed OM solves the problem of modifying values at development time. It also increases the overall performance by reducing the number of string operations, making CSSOM easy and efficient to manipulate. RequestAnimationFrame can also produce custom animations with better performance.
Refer to the link
Drafts.css-houdini.org/css-typed-o…
Developers.google.com/web/updates…
Rocks1635.rssing.com/chan-409413…
Thank you
Thanks to Teacher An Jia for her suggestions on this paper