Diseñar en Shadow DOM con CSS Shadow Parts
Safari 13.1 acaba de enviar soporte para CSS Shadow Parts . Eso significa que el ::part()
selector ahora es compatible con Chrome, Edge, Opera, Safari y Firefox. Veremos por qué es útil, pero primero un resumen de la encapsulación de DOM en la sombra…
Los beneficios de la encapsulación DOM en la sombra
Trabajo en giffgaff, donde tenemos una amplia variedad de código CSS que ha sido escrito por muchas personas diferentes de diferentes maneras a lo largo de los años. Consideremos cómo esto podría ser problemático.
Colisiones de nombres
Las colisiones de nombres entre clases pueden surgir fácilmente en CSS. Un desarrollador podría crear un nombre de clase como .price. Otro desarrollador (o incluso el mismo) podría usar el mismo nombre de clase sin saberlo.
CSS no le alertará sobre ningún error aquí. Ahora, cualquier elemento HTML con esta clase recibirá el estilo destinado a dos cosas completamente diferentes.
Shadow DOM soluciona este problema. Las bibliotecas CSS-in-JS, como Emotion y styled-components , también resuelven este problema de una manera diferente al generar nombres de clases aleatorios, como .bwzfXH
. ¡Eso ciertamente ayuda a evitar conflictos! Sin embargo, CSS-in-JS no impide que nadie rompa su componente de otras maneras. Por ejemplo…
Estilos base y restablecimientos de CSS
Los estilos se pueden aplicar usando selectores de elementos HTML como button
y div
. Estos estilos podrían romper un componente. Shadow DOM es lo único que ofrece ( casi ) encapsulación completa: puede estar seguro de que su componente se verá igual, incluso en una base de código desordenada e importante porque cada componente está encapsulado.
/* This will have no effect on buttons inside shadow DOM */button { background-color: lime !important; }
No diría que sea una buena práctica diseñar elementos de esta manera, pero sucede. Incluso así, esos estilos no tendrán ningún efecto en el DOM de sombra.
Vale la pena señalar que los estilos heredables como color
y font
todavía line-height
se heredan en un DOM oculto. Para evitarlo, utilice all: initial
o, preferiblemente, all: revert
una vez que tenga un mejor soporte para navegadores.
Veamos un ejemplo común de CSS aplicado directamente a elementos HTML. Considere este código del reinicio de Eric Meyer :
html, body, div, span, applet, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, big, cite, code,del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var,b, u, i, center,dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td,article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline;}
¿Qué pasa si el componente con el que estamos trabajando utiliza los valores predeterminados del agente de usuario para margen y relleno? Este reinicio puede hacer que parezca roto, ya que esos valores predeterminados se eliminan de manera efectiva.
Shadow DOM es una forma de evitar estos problemas. Shadow DOM nos permite sentirnos plenamente seguros de que un componente se procesará como se espera, independientemente de en qué base de código termine. Del mismo modo, ninguno de los códigos destinados únicamente a un componente puede afectar inadvertidamente a cualquier otra cosa, todo sin recurrir a onerosas convenciones de nomenclatura de clases. . Shadow DOM ofrece un nivel de encapsulación que no se puede lograr de ninguna otra manera.
La encapsulación es excelente, pero también queremos que nuestros componentes sean temáticos y personalizables. Esto se ha hecho mucho más fácil con el ::part
selector.
Diseñar sombra DOM con ::part()
Hasta ahora, la única forma en que CSS modificaba el estilo de un elemento personalizado desde fuera del DOM oculto era utilizar propiedades personalizadas de CSS. En un sistema de diseño estricto en el que solo desea permitir cambios limitados, eso podría ser ideal. Si quieres que tu componente sea más versátil, crea un problema. Cada propiedad CSS que desee ofrecer para el estilo debe definirse mediante una propiedad personalizada. Sólo el sonido de eso parece tedioso.
La situación se complica aún más si queremos darle estilo a un componente de manera diferente según pseudoclases, como :hover
. Básicamente, terminamos con un montón de propiedades personalizadas. Veamos un ejemplo de Ionic , un conjunto de componentes web de código abierto. Basta con mirar todas las propiedades personalizadas definidas en el componente del botón Ionic .
Adelante, te esperaré.
Conté 23 propiedades personalizadas. No hace falta decir que eso no es lo ideal.
A continuación se muestra un ejemplo que se utiliza ::part()
para aplicar estilo al elemento.
En este Pen, simplemente estoy cambiando las propiedades color
y , pero podría usar lo que quiera sin estar limitado por las propiedades personalizadas que se han definido border
. background-color
Tenga en cuenta que también puedo diseñar diferentes estados de la pieza utilizando pseudoclases, como :hover
y :focus
.
Todo el componente en este ejemplo de botón se expone para darle estilo, pero si su componente web consta de varios elementos HTML, puede exponer solo partes seleccionadas del componente a este tipo de estilo, de ahí el nombre ::part
. Esto evita que los usuarios del componente apliquen estilo a cualquier elemento arbitrario dentro del árbol de sombras. Depende del autor del componente exponer las partes del componente que desean explícitamente. Otras partes del componente se pueden mantener visualmente uniformes o utilizar propiedades personalizadas para una personalización mínima.
Entonces, ¿cómo configuramos esto para nuestros propios componentes? Veamos el uso ::part
para hacer que ciertos elementos de un componente web sean elegibles para diseñar. Todo lo que hacemos es agregar un atributo de pieza al elemento que queremos exponer.
div part="box".../div buttonClick me/button
En este ejemplo, el div se puede personalizar con toda la gama de CSS; se puede cambiar cualquier propiedad de CSS. El botón, sin embargo, está bloqueado: nadie excepto el autor del componente puede cambiarlo visualmente.
Y de la misma manera que un elemento HTML puede tener múltiples clases, un elemento puede tener múltiples nombres de partes:
div part="box thing".../div
Eso es lo que conseguimos ::part
: al exponer “partes” de un elemento podemos proporcionar cierta flexibilidad en cómo se utiliza un componente web mientras ejercemos protección en otras áreas. Ya sea su sistema de diseño, una biblioteca de componentes o lo que sea, el hecho de que CSS Shadow Parts se esté volviendo común nos brinda otra herramienta interesante con la que trabajar.
Deja un comentario