El modelo de objetos tipificados | Programar Plus

Ayudo a escribir documentación técnica y una característica sobre la que he estado escribiendo este año que realmente se ha destacado es el Modelo de objetos tipificados (o Typed OM). Si aún no lo ha encontrado, se le perdonará, ya que es bastante nuevo. Se incluye en el conjunto de API de CSS Houdini y, en la superficie, parece el menos emocionante. Sin embargo, los sustenta a todos y eventualmente cambiará la forma en que vemos CSS como lenguaje.

Permite escribir valores en CSS. Recuerda la sintaxis base de CSS:

selector {
  property: value;
}

Ese valor puede ser muchas cosas, colores, unidades, imágenes, palabras. Lo cual para CSS tiene sentido, pero para nosotros, cuando accedemos a él e intentamos cambiarlo por cualquier medio, aparece como una cadena.

Typed OM permite que se devuelva como un tipo en su lugar. Entonces, si tuviéramos que acceder, digamos 10px en JavaScript, en lugar de '10px' siendo devuelto, obtenemos el número 10 y la unidad 'px'. Lo cual es mucho más fácil de trabajar.

Es posible que hayas visto algunas de las increíbles demostraciones de Ana Tudor. En su ejemplo ‘Hueco’, registra propiedades personalizadas en JavaScript para usarlas en su CSS. Está utilizando la API de propiedades y valores y, por lo tanto, puede determinar los tipos de estas propiedades. Esto no sería posible si Typed OM no existiera.

¿Qué tal un ejemplo?

A primera vista, parece un poco más de trabajo que la forma en que estamos acostumbrados a acceder y configurar estilos en este momento, pero hay muchos beneficios. Si queremos, por ejemplo, obtener el ancho de un elemento, haríamos algo como esto:

const elementWidth = getComputedStyle(myElement).width;
// returns '300px'

No solo estamos accediendo a una cadena aquí, sino que getComputedStyle fuerza un rediseño. Es posible que no seamos conscientes de qué unidades se están utilizando, por lo que acceder a la parte numérica de la cadena se vuelve complicado, y si ejecutamos esto en nuestro código varias veces, podría dañar el rendimiento.

Si queremos usar Typed OM y devolver un valor escrito, tendríamos que acceder a las propiedades y valores a través de computedStyleMap() y es get() método:

const elementWidth = myElement.computedStyleMap().get('width');
// returns CSSUnitValue {value: 300, type: 'px'}

Ahora podemos acceder al valor y la unidad por separado, y el valor aquí se devuelve como un número entero.

elementWidth.value // 300
elementWidth.unit // 'px'

Tampoco hemos forzado un nuevo diseño, que es nada menos que una victoria. Apuesto a que ahora te estás preguntando y sí, no solo puedes acceder al valor CSS como un tipo, sino que también puedes crear valores unitarios con bastante facilidad, a través de la CSS objeto:

let newWidth = CSS.px(320);
// returns CSSUnitValue {value: 320, type: 'px'}

Ese es un pequeño ejemplo y uno que es fácil de mostrar, ya que la parte de las unidades de la especificación se ha desarrollado considerablemente para algunos otros tipos de valor. Pero independientemente, permite mucha menos coincidencia de cadenas y flexibilidad.

Otro conjunto de valores que está bien especificado son los valores de transformación: translate, rotate, scaleetc. Esto es genial porque si quisiéramos cambiar uno de estos valores en un elemento sin Typed OM, puede ser complicado, especialmente si hemos establecido más de uno.

.myElement {
  transform: rotate(10deg) scale(1.2);
}

Digamos que queríamos aumentar la rotación. Si accedemos a esta propiedad con getComputedStyle() se devuelve una matriz.

const transform = getComputedStyle(myElement).transform;
// returns matrix(0.984808, 0.173648, -0.173648, 0.984808, 0, 0)

Con las transformaciones que tenemos en el elemento, no podemos sacar un valor de la matriz. No voy a ir a todos los vectores, valores escalares y productos escalares aquí, pero basta con decir que no puede extraer un valor una vez que se ha formado la matriz. Definitivamente va a haber numerosas asignaciones.

Si solo tiene una transformación o escala, esto es posible mediante la coincidencia de cadenas donde se encuentra el valor en la matriz. Pero eso es información para otro día.

Podríamos usar propiedades personalizadas para establecer el valor de estas transformaciones y actualizarlas:

.myElement {
  --rotate: 10deg;
  transform: rotate(var(--rotate)) scale(1.2);
}
myElement.style.setProperty('--rotate', '15deg');

Sin embargo, necesitamos saber el nombre de la propiedad personalizada y todavía estamos pasando una cadena.

Ingrese el OM escrito. Echemos un vistazo a lo que se devuelve de la computedStyleMap:

myElement.computedStyleMap().get('transform');
/* returns
CSSTransformValue {
  0: CSSRotate {...}
  1: CSSScale {...}
} */

Cada valor de transformación tiene su propio tipo. hay CSSRotate y CSSScale para el código anterior. Así como todos los demás como sesgar y traducir. Entonces, en lugar de tratar con matriz, o seguir trabajando con cadenas, podemos crear estos tipos y aplicar un CSSTransformValue con ellos.

const newTransform = new CSSTransformValue([
  new CSSRotate(CSS.deg(15)),
  new CSSScale(CSS.number(1.2), CSS.number(1.2))
])
myElement.attributeStyleMap.set('transform', newTransform);

Observe cómo estamos creando los tipos de transformación con el método de clase y el new palabra clave, en lugar del método de fábrica utilizado con los valores numéricos.

Tenemos mucho más control sobre cada valor individual, algo muy necesario cuando declaramos múltiples valores en CSS.

Preparé un Pen con todo este código de ejemplo aquí.

son los cimientos

A medida que empecemos a familiarizarnos con otras API dentro de la suite Houdini, los beneficios de todo esto serán aún más evidentes. Cuando declaramos una nueva propiedad personalizada con la API de propiedades y valores, establecemos un tipo y obtenemos un manejo automático de errores, por ejemplo. Estos tipos de valores también se pasan a los worklets de Paint API y Layout API, por lo que también podemos usar el poder allí.

Hay más tipos que no he mencionado, más tipos por venir y realmente mucho más sobre lo que escribir. Si aún no lo ha sido, Typed OM se está implementando en todos los principales navegadores en este momento. Sin duda, despertó mi interés este año, ¡así que ten cuidado cuando llegue el 2020!