Podcast Link to the Podcast
Notes CSS Typed Object Model (Typed OM) CSS Typed OM API allow manipulating CSS styles through a typed JS representation rather than a simple string. Provide performance win. Browser understands the structured JS representation and no longer needs to parse CSS string from scratch. const div = document . createElement ( ' div ' ); // browser needs to parse the string to understand and use it div . style . height = ' 5px ' ; // browser understands and use the value as 5px div . style . height = CSS . px ( 5 );
Enter fullscreen mode Exit fullscreen mode Built-in error handling. You can't provide invalid value to a type. div . attributeStyleMap . set ( ' color ' , CSS . px ( 10 )) // TypeError: Failed to set, invalid type for property
Enter fullscreen mode Exit fullscreen mode Rather than manipulating raw string, developer can create / transform CSS in a meaningful object const _5px = CSS . px ( 5 ); // 5px const _15px = _5px . add ( CSS . px ( 10 )); // 15px; const div = document . createElement ( ' div ' ); div . style . height = _15px ; // <div style="height: 15px;"></div>
Enter fullscreen mode Exit fullscreen mode API based on functional programming concept To check browser support Typed OM, currently (21 Nov 2020) supported in Safari Tech Preview & Chromium // checking browser support if ( window . CSS && CSS . number ) { // 😍 browser supports Typed OM! }
Enter fullscreen mode Exit fullscreen mode computedStyleMap <script> const element = document . querySelector ( ' #app ' ); console . log ( element . computedStyleMap (). get ( ' font-size ' )); // Specification: CSSUnitValue { value: 2, unit: 'rem' } // Chrome: CSSUnitValue { value: 32, unit: 'px' } console . log ( window . getComputedStyle ( element ). fontSize ); // "32px" </script> <div id= "app" style= "font-size: 2rem;" ></div>
Enter fullscreen mode Exit fullscreen mode attributeStyleMap parse, modify inline styles <script> const element = document . querySelector ( ' #app ' ); const inlineStyles = element . attributeStyleMap ; console . log ( inlineStyles . get ( ' font-size ' )); // CSSUnitValue { value: 2, unit: 'rem' } inlineStyles . set ( ' height ' , CSS . px ( 10 )); // < div id = " app " style = " font-size: 2rem; height: 10px; " >< /div > inlineStyles . clear (); // < div id = " app " style = "" >< /div > inlineStyles . append ( ' background-image ' , ' linear-gradient(yellow, green) ' ); inlineStyles . append ( ' background-image ' , ' linear-gradient(to bottom, blue, red) ' ); // < div id = " app " // style="background-image: linear-gradient(yellow, green), // linear-gradient(to bottom, blue, red)"> < /div > inlineStyles . delete ( ' background ' ); // < div id = " app " style = "" >< /div > inlineStyles . has ( ' opacity ' ); // false </script> <div id= "app" style= "font-size: 2rem;" ></div>
Enter fullscreen mode Exit fullscreen mode <script> // `attributeStyleMap` only gets inline style console . log ( element . attributeStyleMap . get ( ' color ' )); // null console . log ( element . computedStyleMap (). get ( ' color ' )); // CSSStyleValue { /* red */ } </script> <div id= "app" style= "font-size: 2rem;" ></div> <style> #app { color : red ; } </style>
Enter fullscreen mode Exit fullscreen mode Types of CSSStyleValue CSSImageValue CSSKeywordValue CSSNumericValue CSSPositionValue CSSTransformValue CSSUnparsedValue create CSSStyleValue CSSStyleValue . parse ( ' font-size ' , ' 32px ' ); // CSSUnitValue { value: 2, unit: 'px' } CSSStyleValue . parse ( ' transform ' , ' translate3d(10px, 20px, 30px) scale(1.5) ' ); /* CSSTransformValue { 0: CSSTranslate { is2D: false x: CSSUnitValue { value: 10, unit: 'px' } y: CSSUnitValue { value: 20, unit: 'px' } z: CSSUnitValue { value: 30, unit: 'px' } } 1: CSSScale { is2D: true x: CSSUnitValue { value: 1.5, unit: 'number' } y: CSSUnitValue { value: 1.5, unit: 'number' } z: CSSUnitValue { value: 1, unit: 'number' } } } */
Enter fullscreen mode Exit fullscreen mode CSSImageValue does not cover linear-gradient
CSSKeywordValue display: none
, none
is a CSSKeywordValue CSSStyleValue . parse ( ' display ' , ' none ' ); // CSSKeywordValue { value: 'none' } const keywordValue = new CSSKeywordValue ( ' flex ' ); // CSSKeywordValue { value: 'flex' } keywordValue . value ; // 'flex'
Enter fullscreen mode Exit fullscreen mode CSSNumericValue CSSNumericValue has a few subclasses, eg: CSSUnitValue, CSSMathValue // Convert units CSS . px ( 48 ). to ( ' in ' ) // CSSUnitValue { value: 0.5, unit: 'in' } CSS . px ( 48 ). to ( ' rem ' ) // Error // Cannot transform absolute unit to relative unit
Enter fullscreen mode Exit fullscreen mode CSSMathValue CSSMathNegate, CSSMathMin, CSSMathMax, CSSMathSum, CSSMathProduct, CSSMathInvert new CSSMathSum ( CSS . px ( 5 ), CSS . px ( 10 )); // 15px div . attributeStyleMap . set ( ' width ' , new CSSMathMax ( CSS . rem ( 10 ), CSS . px ( 30 ))); // <div style="width: max(10rem, 30px)"></div>
Enter fullscreen mode Exit fullscreen mode CSSPositionValue const position = new CSSPositionValue ( CSS . px ( 20 ), CSS . px ( 50 )) position . x ; // CSSUnitValue { value: 20, unit: 'px' } position . y ; // CSSUnitValue { value: 50, unit: 'px' }
Enter fullscreen mode Exit fullscreen mode CSSTransformValue CSSTranslate, CSSScale, CSSRotate, CSSSkew, CSSSkewX, CSSSkewY, CSSPerspective, CSSMatrixComponent const transformValue = CSSStyleValue . parse ( ' transform ' , ' translate3d(10px, 20px, 30px) scale(1.5) ' ); // iterate through each transformation for ( const transform of transformValue ) { console . log ( transform ); } // CSSTranslate { ... } // CSSScale { ... } // get DOMMatrix out of the transformValue transformValue . toMatrix (); // DOMMatrix { a: 1.5, b: 0, c: 0, ... }
Enter fullscreen mode Exit fullscreen mode CSSUnparsedValue CSSCustomProperty, that is not Houdini Property the value is parsed as string <script> const element = document . querySelector ( ' #app ' ); element . attributeStyleMap . get ( ' --length ' ); // CSSUnparsedValue { 0: 3px } </script> <div id= "app" style= "--length: 3px;" >
Enter fullscreen mode Exit fullscreen mode References
Top comments (1)
About 3 years since this post, this CSS Typed OM and other Houdini features like defining/declaring custom properties is still like an experimental. I mean, Firefox still does not support them, making me hesitate on using them.