<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Adrian Benavente</title>
    <description>The latest articles on DEV Community by Adrian Benavente (@adrianbenavente).</description>
    <link>https://dev.to/adrianbenavente</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F464701%2F90208464-d234-461d-9f77-891ae5a66435.jpg</url>
      <title>DEV Community: Adrian Benavente</title>
      <link>https://dev.to/adrianbenavente</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adrianbenavente"/>
    <language>en</language>
    <item>
      <title>Accesibilidad: desafíos en la era de la Inteligencia Artificial</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Fri, 22 Sep 2023 15:04:46 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/accesibilidad-desafios-en-la-era-de-la-inteligencia-artificial-57dh</link>
      <guid>https://dev.to/adrianbenavente/accesibilidad-desafios-en-la-era-de-la-inteligencia-artificial-57dh</guid>
      <description>&lt;p&gt;De algo no podemos dudar, la Inteligencia Artificial (IA) avanza a pasos agigantados y no parece que vaya a experimentar un retroceso en un futuro cercano -ni lejano-, más bien todo lo contrario.&lt;/p&gt;

&lt;p&gt;En lo personal, no puedo evitar medir la tecnología en función de lo que puede aportarle a la humanidad. Y al margen de ser un defensor de la IA como una herramienta de trabajo más, que nos aleja de roles utilitarios y redime de tareas repetitivas, permitiéndonos habitar más el plano de la abstracción y de las ideas, esa es para mí solo una de las tantas formas en que puede mejorar la calidad de vida de la gente.&lt;/p&gt;

&lt;p&gt;Resulta tentador pensar que el potencial está en la capacidad de integrarse a los productos de apoyo, y no estaríamos del todo errados. Por ejemplo, un software de asistencia podría ser capaz de generar textos alternativos o &lt;em&gt;captions&lt;/em&gt; de un video donde no hayan sido incluidos. Bien, esto ya ocurre, pero hoy uno de los principales problemas radica en la baja precisión de los resultados. Además, esto eleva su costo tanto económico como de recursos, ya que se necesita un poder de cómputo mayor.&lt;/p&gt;

&lt;p&gt;Y aquí se desprende una pregunta inevitable, ¿no deberíamos nosotros como desarrolladores tomar medidas para quitar esa carga de encima al usuario, sirviéndonos de la IA para proveer experiencias digitales accesibles e inclusivas más satisfactorias?&lt;/p&gt;

&lt;p&gt;Dado mi interés particular por la accesibilidad web, una de las primeras inquietudes que vinieron a mi mente fue acerca de cuán provechosa podría resultar la inteligencia artificial para generar descripciones automatizadas de imágenes. Para este artículo, elegí enfocarme en ese escenario en específico con el fin de intentar ilustrar, con un caso cotidiano, de qué manera podría representar un gran beneficio pero también profundizar aún más la brecha de inclusión y convertirse en un mecanismo silencioso de replicar y reforzar sesgos si no se toman las acciones adecuadas. Sobre el final veremos cómo este desafío también se traslada a otros terrenos.&lt;/p&gt;

&lt;p&gt;Aclaro de antemano que no soy un experto en Machine Learning ni Inteligencia Artificial, si no un desarrollador web volcado a la accesibilidad tratando de ver hacia dónde va el mundo digital, y qué o a quiénes podríamos estar dejándonos en el camino. Ahora sí, vamos a sumergirnos de lleno en este asunto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Descripción de imágenes
&lt;/h2&gt;

&lt;p&gt;Sabemos que las redes sociales ya desde hace bastante ofrecen la posibilidad de añadir manualmente texto alternativo a las imágenes, pero lamentablemente aun hoy es minoritaria la porción de gente que se toma ese trabajo, y aun son menos los que cuentan con conocimiento acerca de cuáles son las consideraciones y prácticas recomendadas a la hora de redactar un texto alternativo útil. Con lo cual ya vemos asomar aquí una necesidad. En tal caso, ¿podemos los autores de contenido simplemente delegar esta tarea en una herramienta automatizada y desentendernos por completo?&lt;/p&gt;

&lt;p&gt;La respuesta a priori pareciera ser un "no" rotundo si tenemos en cuenta que se requiere ciertos &lt;em&gt;datos periféricos&lt;/em&gt; para nutrir al modelo a entrenar y prevenir resultados sesgados. Estos datos deberían contemplar cosas tales como el entorno, expresiones, emociones, y sobre todo, que los mismos provengan de imágenes que reflejen variedad, y eso incluye a personas con diversidad funcional, de género, de etnia, etc.&lt;/p&gt;

&lt;p&gt;Existen herramientas online y plugins que permiten crear texto alternativo empleando inteligencia artificial, y de hecho es una funcionalidad implementada desde hace un buen tiempo en redes sociales como Instagram y Facebook, pero en todos los casos tienen bastantes limitaciones a la fecha de la redacción de este artículo. Suelen fallar en la mayoría de los aspectos que se mencionaron en el párrafo anterior, a menudo proporcionando información insuficiente, reducida a apenas una descripción superficial. Y ni hablar de los gráficos de representación de datos, quizás el apartado donde encontramos mayor déficit en lo que a alternativas textuales se refiere, a pesar de que está habiendo progresos.&lt;/p&gt;

&lt;p&gt;Más allá de si pueden o no brindar el contexto necesario para entender una imagen, el punto es que, por ahora, estas herramientas no predicen qué detalles son importantes para el usuario; y no se trata de algo menor. Claro que se espera que esto evolucione a futuro, pero aun no parece que se esté hablando lo suficiente del tema, y toda potencial barrera de acceso al contenido debería ser abordada desde la fase más temprana del desarrollo.&lt;/p&gt;

&lt;p&gt;Cuáles detalles serán más relevantes por sobre otros, dependerá de varios factores. Algo a valorar podría ser aquello que deseaba comunicar quien creó la imagen. Además, es fundamental conocer el tipo de contenido que consumen los usuarios según la plataforma y de qué manera lo hacen. Una imagen publicada en una red social requiere una descripción distinta a la de un sitio web portfolio para fotógrafos, o un portal sobre ciencia, porque los intereses de cada público no son los mismos.&lt;/p&gt;

&lt;p&gt;Por todo lo mencionado, en la actualidad todavía es indispensable la intervención humana en la revisión del &lt;em&gt;output&lt;/em&gt; antes de la publicación. Pero mientras tratamos de concientizar a los creadores de contenido sobre la importancia de involucrarse en ello, tenemos que estar preparados para encontrarnos con que, en un principio, una gran parte creerá que la generación automatizada será suficiente. Esto desemboca inevitablemente en la discusión acerca de la Inteligencia Artificial Explicable[¹] como parte de un derecho universal, el &lt;em&gt;derecho a la explicación&lt;/em&gt;, tal como se lo contempla en el Reglamento General de Protección de Datos (GDPR) de la Unión Europea. Al menos el usuario final debería poder conocer, de forma clara y transparente, el proceso de toma de decisiones que llevó a la IA al resultado que se le presenta, y así de paso ayudarlo a identificar posibles sesgos.&lt;/p&gt;

&lt;p&gt;Ahora bien, que sea posible automatizar por completo esta tarea a futuro es algo esperable, pero creo que nos encontramos en un momento crucial de la historia para garantizar que, cuando llegue ese futuro, su implementación realmente resulte un aporte valioso para la inclusión digital. &lt;/p&gt;

&lt;p&gt;Entonces, ¿además de evitar los sesgos durante la fase de entrenamiento, de qué otra forma podríamos garantizar descripciones relevantes? Una buena idea sería permitirle al usuario acceder a una descripción más amplia si así lo desea, mediante un enlace por ejemplo. O bien proporcionar filtros que le permitan refinar el nivel de detalle de los textos alternativos generados. También, una característica que poseen varias aplicaciones y sitios web es mostrar una advertencia cuando una descripción fue generada automáticamente; aunque esto sirva como medida adicional, por sí sola sigue siendo insuficiente. Por supuesto que, en los tiempos que corren, lo ideal sería que el software fuese capaz de reconocer y adaptarse a las preferencias del usuario a nivel de sistema o navegador, aun queda mucho camino por recorrer en ese sentido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Si bien elegí enfocarme en un caso típico, el problema de los sesgos introducidos en los modelos de Machine Learning genera una brecha de inclusión transversal a gran parte de las implementaciones de inteligencia artificial actuales. Por poner un ejemplo, tanto los asistentes de voz como los programas de speech-to-text (voz a texto), tienen problemas para reconocer correctamente el habla si esta no se ajusta a cierta "norma". Personas con Parkinson, tartamudos, sordos, personas con Síndrome de Down, ELA, o parálisis cerebral, encuentran una barrera a la hora utilizar estas tecnologías.&lt;/p&gt;

&lt;p&gt;Del lado de los desarrolladores de software nos encontramos con que asistentes de código basados en inteligencia artificial como GitHub Copilot, al usar como fuente de datos el código open source disponible en GitHub, arrastra consigo todas las malas prácticas de accesibilidad del pasado. Y este punto es importante: si la data que alimenta a las IA proviene del pasado, pertenece, por ende, a un pasado que -y aquí coincidiremos la mayoría- era menos inclusivo.&lt;/p&gt;

&lt;p&gt;Para muestra un botón. La organización WebAIM realiza anualmente un análisis de cerca de un millón de sitios web en busca de errores de accesibilidad[²]. En el último análisis de febrero de 2023, en el 96.3% de los casos se detectaron fallos de conformidad con las WCAG 2, siendo dos de los principales la falta de textos alternativos y de etiquetas de formulario. Esto representa un decremento del 1.5% en los últimos cuatro años[³].&lt;/p&gt;

&lt;p&gt;Por lo pronto, veo al menos dos caminos, generar modelos universales y diversos, o especializados para incluir a los grupos minoritarios. Lo que está claro es que si no tomamos una medida ya mismo al respecto, estaremos perpetuando y reforzando estos sesgos, provocando más y más exclusión.&lt;/p&gt;

&lt;p&gt;Por suerte, ya hay varios proyectos en marcha. En el área del reconocimiento de voz, cabe destacar Project Euphonia de Google[⁴] y el Speech Accessibility Project de la Universidad de Illionis[⁵].&lt;/p&gt;

&lt;p&gt;Es insoslayable que la inteligencia artificial está abriendo posibilidades que nos invitan a soñar con un mundo digital más inclusivo. Todavía estamos a tiempo, es solo una cuestión de aprender de los errores del pasado y poner las prioridades en su lugar, moviendo la accesibilidad al comienzo de nuestro flujo de trabajo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lectura adicional:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3.org/WAI/research/ai2023/"&gt;Artificial Intelligence (AI) and Accessibility Research Symposium 2023 | Web Accessibility Initiative (WAI) | W3C&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3.org/TR/webmachinelearning-ethics/#value-3-ensuring-diversity-and-inclusiveness"&gt;Ethical Principles for Web Machine Learning&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/-/es/Lisandra-Armas-Aguila-ebook/dp/B0C7LLXJ62/ref=sr_1_1?__mk_es_US=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=2O0XWVO9SQOP&amp;amp;keywords=moviendo+la+accesibilidad+a+la+izquierda&amp;amp;qid=1695360930&amp;amp;sprefix=moviendo+la+accesibilidad+a+la+izquierd%2Caps%2C227&amp;amp;sr=8-1"&gt;Libro "Moviendo la accesibilidad a la izquierda" de Lisandra Armas (formato eBook)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referencias:
&lt;/h2&gt;

&lt;p&gt;[¹]: &lt;a href="https://es.wikipedia.org/wiki/Inteligencia_artificial_explicable"&gt;Inteligencia artificial explicable - Wikipedia, la enciclopedia libre&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[²]: &lt;a href="https://webaim.org/projects/million/#errors"&gt;WebAIM: The WebAIM Million - The 2023 report on the accessibility of the top 1,000,000 home pages&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[³]: &lt;a href="https://webaim.org/projects/million/#wcag"&gt;WebAIM: The WebAIM Million - The 2023 report on the accessibility of the top 1,000,000 home pages&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[⁴]: &lt;a href="https://sites.research.google/euphonia/about/"&gt;Project Euphonia&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[⁵]: &lt;a href="https://speechaccessibilityproject.beckman.illinois.edu/"&gt;Speech Accessibility Project&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>accesibility</category>
      <category>ai</category>
    </item>
    <item>
      <title>La espera terminó: el elemento DIALOG alcanza pleno soporte</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Tue, 19 Apr 2022 14:12:10 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/la-espera-termino-el-elemento-alcanza-pleno-soporte-5de7</link>
      <guid>https://dev.to/adrianbenavente/la-espera-termino-el-elemento-alcanza-pleno-soporte-5de7</guid>
      <description>&lt;p&gt;Primero sería Firefox 98, en marzo de este año, quien se sumaría a darle soporte&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, y Safari haría lo propio al poco tiempo con su más reciente versión, la 15.4&lt;sup id="fnref2"&gt;2&lt;/sup&gt;, pasando así el elemento &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; de HTML5 a ser soportado por todos los navegadores modernos&lt;sup id="fnref3"&gt;3&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZOMRFTY_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/Gpea71M.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZOMRFTY_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/Gpea71M.png" alt="Tabla de compatibilidad de caniuse.com" width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Especificaciones principales
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Categoría a la que pertenece&lt;/strong&gt;: Contenido de flujo&lt;sup id="fnref4"&gt;4&lt;/sup&gt;, seccionado raíz&lt;sup id="fnref5"&gt;5&lt;/sup&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contenido permitido&lt;/strong&gt;: Contenido de flujo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interfaz de DOM&lt;/strong&gt;: &lt;code&gt;HTMLDialogElement&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Contexto de uso
&lt;/h2&gt;

&lt;p&gt;Se usa para representar un cuadro de diálogo o ventana modal, ya sea para informar algo importante al usuario, como para involucrarlo en alguna acción o toma de decisiones. Están inspirados en los que vemos comúnmente en todos los sistemas operativos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problemas que resuelve
&lt;/h2&gt;

&lt;p&gt;Las soluciones mágicas que nos trae, además de tener un impacto positivo del lado del usuario, mejoran también la experiencia de desarrollo. Veamos algunas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accesibilidad y experiencia de usuario
&lt;/h3&gt;

&lt;p&gt;El diálogo se cierra al presionar la tecla Esc, interacción que cualquier usuario, tenga una discapacidad o no, agradecerá siempre.&lt;/p&gt;

&lt;p&gt;Por defecto, el foco se coloca automáticamente sobre el primer elemento &lt;a href="https://html.spec.whatwg.org/multipage/interaction.html#focusable"&gt;enfocable&lt;/a&gt; que exista dentro, a no ser que se indique otro explícitamente usando el atributo &lt;code&gt;autofocus&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Al cerrarse el diálogo, el foco vuelve a donde se encontraba antes (típicamente el botón o elemento que disparó su apertura).&lt;/p&gt;

&lt;p&gt;Por otro lado, para que las tecnologías de apoyo, como los lectores de pantalla, comuniquen al usuario el propósito del diálogo, es suficiente con usar &lt;code&gt;aria-labelledby&lt;/code&gt; en el elemento, apuntando al &lt;code&gt;id&lt;/code&gt; del título del mismo, o sumistrar el texto directamente mediante &lt;code&gt;aria-label&lt;/code&gt;. Si este no fuese lo suficientemente descriptivo, se puede recurrir a &lt;code&gt;aria-describedby&lt;/code&gt;&lt;sup id="fnref6"&gt;6&lt;/sup&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt; &lt;span class="na"&gt;aria-labelledby=&lt;/span&gt;&lt;span class="s"&gt;"dialog-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dialog-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Agregar a la billetera&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dialog&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Agregar a la billetera"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;De esta forma, al abrirse el diálogo, se anunciará su título seguido de la palabra "diálogo" (si no se provee, se anuncia solamente "diálogo"). Además, huelga decir que ya nos podemos olvidar del uso de &lt;code&gt;role="dialog"&lt;/code&gt;, ya que, al ser una etiqueta semántica, su rol es implícito, pudiendo únicamente cambiarse por el más específico &lt;code&gt;role="alertdialog"&lt;/code&gt;&lt;sup id="fnref7"&gt;7&lt;/sup&gt; &lt;sup id="fnref8"&gt;8&lt;/sup&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interacción y estilos
&lt;/h3&gt;

&lt;p&gt;Invocando el método &lt;code&gt;show()&lt;/code&gt; del elemento, se muestra el diálogo sin impedir la navegación por el resto del documento, mientras que &lt;code&gt;showModal()&lt;/code&gt; confina al usuario, realizando &lt;a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/keyboard-operation-trapping.html"&gt;focus trap&lt;/a&gt;, hasta tanto se ejecute el método &lt;code&gt;close()&lt;/code&gt;; al accionarse un botón, por ejemplo, o si se pulsa Esc. Además, &lt;code&gt;showModal()&lt;/code&gt; agrega una capa de overlay para ocultar el contenido subyacente, la cual puede ser accedida por CSS para su personalización, mediante el pseudoelemento &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::backdrop"&gt;::backdrop&lt;/a&gt;&lt;sup id="fnref9"&gt;9&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Si se busca conocer el estado (abierto o cerrado) del diálogo, se puede consultar el atributo (implícito) &lt;code&gt;open&lt;/code&gt; del elemento, el cual retorna un &lt;em&gt;booleano&lt;/em&gt;. Una advertencia: ¡nunca se debería modificar el valor de este atributo o removerlo! En primer lugar, porque el navegador perdería por completo el rastro del estado, produciendo varios efectos no deseados&lt;sup id="fnref10"&gt;10&lt;/sup&gt;; y en segundo lugar, ¿por qué querrías hacerlo, si al final se controla "automágicamente"?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;A estas alturas, y si eres alguien con ciertos conocimientos de accesibilidad, te resultarán más que evidentes las ventajas que trae de serie este elemento. Hasta ahora, debíamos tener una serie de consideraciones que, si se descuidaban, fácilmente nuestras modales podían volverse una pesadilla para la accesibilidad. Otra opción era buscar una librería que proporcione diálogos accesibles, a cambio de ceder el control sobre nuestro markup, o terminar invirtiendo en personalización el tiempo que se pretendió ahorrar en un principio.&lt;br&gt;
En cualquier caso, había que cerciorarse de que se cumpla con lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Indicar el rol&lt;/strong&gt;: para que las tecnologías de apoyo puedan anunciar que se trata de un diálogo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atrapar el foco&lt;/strong&gt; -aplica para ventanas modales-: Se trata, hoy por hoy, de una labor prácticamente artesanal, y consiste en hacer que, al avanzar el foco con la tecla tabuladora (Tab), tras haber alcanzado el último elemento interactivo del diálogo, este vuelva a posarse sobre el primero; y a la inversa, al retroceder con Shift + Tab, impidiendo que el usuario navegue a otras partes del documento por fuera de la ventana modal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bloquear el resto del documento&lt;/strong&gt;: por la misma razón que en el caso anterior: en una ventana modal, queremos que el usuario se concentre en una acción específica. Para esto, la práctica más común es volver el resto del contenido invisible para los usuarios de tecnologías de asistencia cuando la modal está visible, añadiendo &lt;code&gt;aria-hidden="true"&lt;/code&gt; mediante JS a un contenedor principal, colocando por fuera al elemento que hace las veces de diálogo; además, conviene agregar a este último el atributo &lt;code&gt;aria-modal="true"&lt;/code&gt;, de esa forma los productos de apoyo avisarán que el resto del contenido está inactivo. Luego, hay que recordar cambiar a &lt;code&gt;aria-hidden="false"&lt;/code&gt; o remover el atributo por completo del nodo cuando la modal se cierre.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Controlar el estado abierto/cerrado&lt;/strong&gt;: para impedir la creación de  diálogos duplicados o permitir volver a abrir un diálogo cerrado; para lo mencionado en el punto anterior sobre el bloqueo del documento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conservar la referencia del elemento que abrió el diálogo&lt;/strong&gt;: para devolver el foco a su sitio original al cerrarlo. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Probablemente nos hayamos encontrado realizando estas tareas de manera repetitiva en el pasado. Bueno, se podría decir que ya no tendremos que preocuparnos más por ellas.&lt;/p&gt;

&lt;p&gt;Sin embargo, como sucede con toda nueva característica, conviene que sea usada con prudencia y proporcionando algún tipo de fallback para agentes de usuario más antiguos: versiones de navegadores aun vivas o tecnologías de apoyo cuyo ciclo de actualización es más lento. Una buena opción, bastante robusta, puede ser &lt;a href="https://a11y-dialog.netlify.app/"&gt;a11y-dialog&lt;/a&gt;. También existe un &lt;a href="https://github.com/GoogleChrome/dialog-polyfill"&gt;polyfill&lt;/a&gt; publicado por el equipo de Chrome. No nos olvidemos que la retrocompatibilidad también forma parte de la accesibilidad.&lt;/p&gt;

&lt;h2&gt;
  
  
  Donar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://buymeacoffee.com/fena"&gt;Buy Me a Coffee&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cafecito.app/fena"&gt;Invitame un café en cafecito.app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://www.mozilla.org/en-US/firefox/98.0/releasenotes/"&gt;Firefox 98 release notes&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://webkit.org/blog/12445/new-webkit-features-in-safari-15-4/"&gt;New WebKit Features in Safari 15.4&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://caniuse.com/dialog"&gt;Dialog element | Can I use... Support tables for HTML5, CSS3, etc&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#flow_content"&gt;Content categories - Developer guides | MDN&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="https://html.spec.whatwg.org/multipage/sections.html#sectioning-root"&gt;HTML Standard&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby"&gt;aria-describedby - Accessibility | MDN&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog"&gt;MDN: The Dialog element&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;&lt;a href="https://w3c.github.io/aria/#alertdialog"&gt;Accessible Rich Internet Applications (WAI-ARIA) 1.3&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn9"&gt;
&lt;p&gt;&lt;a href="https://webkit.org/blog/12209/introducing-the-dialog-element/"&gt;Introducing the Dialog Element | WebKit&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn10"&gt;
&lt;p&gt;&lt;a href="https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element"&gt;HTML Standard&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>html</category>
      <category>a11y</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>WCAG 3.0 (Silver), cocinando el futuro de la accesibilidad digital</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Wed, 10 Nov 2021 22:16:24 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/wcag-30-construyendo-el-futuro-de-la-accesibilidad-digital-2099</link>
      <guid>https://dev.to/adrianbenavente/wcag-30-construyendo-el-futuro-de-la-accesibilidad-digital-2099</guid>
      <description>&lt;p&gt;WCAG, por sus siglas &lt;u&gt;W&lt;/u&gt;eb &lt;u&gt;C&lt;/u&gt;ontent &lt;u&gt;A&lt;/u&gt;ccessibility &lt;u&gt;G&lt;/u&gt;uidelines (&lt;u&gt;W&lt;/u&gt;3&lt;u&gt;C&lt;/u&gt; &lt;u&gt;A&lt;/u&gt;ccessibility &lt;u&gt;G&lt;/u&gt;uidelines a partir de la versión 3.0), son una serie de recomendaciones (pautas) desarrolladas por el &lt;a href="https://www.w3.org/WAI/GL/"&gt;Accessibility Guidelines Working Group&lt;/a&gt;, que es, a su vez, miembro de la &lt;a href="https://www.w3.org/WAI/about/"&gt;WAI&lt;/a&gt;. No nos adentraremos en explicar qué es la WAI ya que no está dentro del alcance de este artículo. Dichas pautas adquirieron el estatus de &lt;a href="https://www.iso.org/standard/58625.html"&gt;Estándar ISO/IEC, registrado bajo el código 40500&lt;/a&gt; en 2012, y se han convertido una de las principales referencias a la hora de crear una experiencia satisfactoria para todos los usuarios de la web por igual, sin importar sus condiciones físicas o mentales.&lt;/p&gt;

&lt;p&gt;WCAG 2.0 vio la luz en 2008. La versión 2.1 (2018), adicionó algunos nuevos criterios. La 2.2 aun es borrador, se espera se convierta en recomendación para lo que resta de 2021.&lt;/p&gt;

&lt;h2&gt;
  
  
  Codename "Silver"
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pbmCScQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/21zhLKk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pbmCScQX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/21zhLKk.jpg" alt="" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La siguiente versión mayor, la 3.0, también se encuentra en borrador. El nombre en clave de este proyecto antes de ser publicado era &lt;a href="https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/#wcag-3-name-formerly-silver-project"&gt;Silver&lt;/a&gt;, ya que ese es el nombre del grupo de trabajo a cargo. Su fecha de lanzamiento está planificada para 2023, y tiene objetivos muy concretos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Abrazar nuevas tecnologías 🧑‍💻
&lt;/h3&gt;

&lt;p&gt;Se busca incorporar documentación para libros digitales, PDF, aplicaciones para teléfonos móviles, y tecnologías emergentes como la realidad virtual, la realidad aumentada y la &lt;a href="https://en.wikipedia.org/wiki/Web_of_Things"&gt;Web of Things&lt;/a&gt;. Muchas de las cuales no existían, o no estaban tan avanzadas cuando se redactó WCAG 2.0.&lt;/p&gt;

&lt;p&gt;De manera que, por cada error que arroje un test, se nos ofrecerá una serie de métodos distintos para resolverlo, dependiendo de a qué tecnología estemos apuntando.&lt;/p&gt;

&lt;p&gt;Se deja de utilizar el término &lt;a href="https://www.w3.org/TR/2006/WD-WCAG20-20060427/complete.html#webunitdef"&gt;web unit&lt;/a&gt;, que hace referencia a la URI específica de un documento, y en su lugar se introducen los conceptos de &lt;a href="https://www.w3.org/TR/wcag-3.0/#dfn-view"&gt;vistas&lt;/a&gt; y &lt;a href="https://www.w3.org/TR/wcag-3.0/#dfn-process"&gt;procesos&lt;/a&gt;; un proceso son los pasos secuenciales que tiene que completar el usuario para realizar una determinada tarea. Ajustándose así a la forma en que funcionan las aplicaciones en el presente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mayor inclusión 🫂
&lt;/h3&gt;

&lt;p&gt;La idea es atender a las necesidades de más grupos de diversidades funcionales en los que las pautas de WCAG 2 no están tan enfocadas. Por ejemplo, existe un gran número de criterios de conformidad para personas con discapacidad visual, pero menos de 10 para personas con discapacidad auditiva. &lt;/p&gt;

&lt;p&gt;Similar es el caso de las personas con discapacidad del habla, quienes han encontrado en los asistentes virtuales una nueva barrera tecnológica.&lt;/p&gt;

&lt;p&gt;También se pondrá un mayor enfásis en las personas con discapacidad cognitiva.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accesibilidad para todo el mundo 🌎
&lt;/h3&gt;

&lt;p&gt;La idea es que más individuos, empresas y organizaciones logren que sus productos, o el contenido que crean, sean accesibles. Para ello, se renovó el sitio web de la documentación con un formato más amigable y claro. Se evita abrumar al lector, utilizando acordeones, para que pueda concentrarse mejor, mostrando solo aquello que le interese. A esto se le suma el uso de iconografía mejorada acompañando los textos.&lt;/p&gt;

&lt;p&gt;Project managers, formuladores de políticas u otros puestos que no sean de ingeniería y desarrollo, se encontrarán con una versión en lenguaje de alto nivel, despojada de tecnicismos, para que puedan llevarse la información que necesiten para trabajar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Un feedback más útil 🛠️
&lt;/h3&gt;

&lt;p&gt;Los test se realizarán primero de manera atómica, a nivel de vistas, componentes o bloques de contenido. Cada uno de estos recibirá un puntaje de 0% a 100%.&lt;/p&gt;

&lt;p&gt;Estos resultados, junto con el número de errores críticos, arrojarán un puntaje final que va de 0 a 4. Se aprueba con un promedio total de 3.5 entre todas las categorías funcionales, siempre y cuando ninguna tenga una puntuación menor a 3.5; es decir, no se puede promediar 3.5 en el total pero que una de las categorías haya obtenido un score de 1. Esto significa que se aceptará un cierto número errores no críticos, brindando mayor flexibilidad que el actual "pasa" o "no pasa", todo esto sin sacrificar exigencia, ya que un solo error crítico arrojará un puntaje de 0 y no se podrá alcanzar la conformidad.&lt;/p&gt;

&lt;p&gt;Estos son los umbrales propuestos para los resultados de las pruebas (pueden cambiar):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Muy pobre (0): Cualquier error crítico o menos del 50% de las pruebas relacionadas pasan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deficiente (1): Sin errores críticos, aprox. del 50% al 79% de las pruebas relacionadas pasan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Regular (2): Sin errores críticos, aprox. pasan del 80% al 89% de las pruebas relacionadas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bueno (3): Sin errores críticos, aprox. pasan del 90% al 98% de las pruebas relacionadas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Excelente (4): Sin errores críticos, aprox. Pasan del 99% al 100% de las pruebas relacionadas&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Las pruebas holísticas, o sea, las que están centradas en la experiencia del usuario y no en la funcionalidad, aun no han sido claramente definidas en el borrador.&lt;/p&gt;

&lt;h3&gt;
  
  
  Niveles de conformidad menos ambigüos 🥇
&lt;/h3&gt;

&lt;p&gt;La forma de medir la conformidad ha sido reformulada, reemplazando los niveles &lt;strong&gt;A&lt;/strong&gt;, &lt;strong&gt;AA&lt;/strong&gt; y &lt;strong&gt;AAA&lt;/strong&gt; por &lt;strong&gt;Bronze&lt;/strong&gt;, &lt;strong&gt;Silver&lt;/strong&gt; y &lt;strong&gt;Gold&lt;/strong&gt;, ya que el sistema vigente ha demostrado no siempre ser confiable: hay usuarios que logran realizar sus tareas con éxito en sitios que no cumplen con el nivel AA, mientras que otros fracasan en utilizar sitios que lo hacen a rajatabla. De esta forma, se busca también utilizar un vocabulario más familiar para todo individuo, y alentar así a quienes hacen sitios web y producen contenido a querer superarse y hacerlo cada vez mejor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redes sociales 🗣️
&lt;/h3&gt;

&lt;p&gt;Mejorar la accesibilidad de las redes sociales, es otra de las metas. Cuando se publicó WCAG 2.0 en 2008, el contenido de la web no se actualizaba al ritmo de hoy en día. Resulta complicado para los administradores de este tipo de plataformas medir su nivel de accesibilidad. Se espera que el nuevo sistema de puntuación les brinde un panorama más claro para que puedan saber dónde están parados, dentro un un &lt;em&gt;espectro&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cambio de acrónimo
&lt;/h2&gt;

&lt;p&gt;Por último, cabe mencionar que se cambiará el acrónimo de &lt;u&gt;W&lt;/u&gt;eb &lt;u&gt;C&lt;/u&gt;ontent &lt;u&gt;A&lt;/u&gt;ccessibility &lt;u&gt;G&lt;/u&gt;uidelines, para pasar a ser &lt;u&gt;W&lt;/u&gt;3&lt;u&gt;C&lt;/u&gt; &lt;u&gt;A&lt;/u&gt;ccessibility &lt;u&gt;G&lt;/u&gt;uidelines. Esto se decidió, por un lado porque la mayoría de la gente tiene asociada mentalmente a la W3C con estas pautas, pero sobre todo para no limitarlas únicamente al contenido de la web, ampliando así su alcance a otras tecnologías, como ya mencionamos antes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3.org/TR/wcag-3.0/#scoring-atomic-tests"&gt;W3C Accessibility Guidelines (WCAG) 3.0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/"&gt;WCAG 3 Introduction | Web Accessibility Initiative (WAI) | W3C&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Colaborar
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://buymeacoffee.com/fena"&gt;Buy Me a Coffee&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cafecito.app/fena"&gt;Invitame un café en cafecito.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
    </item>
    <item>
      <title>El problema de las SPA y la accesibilidad... y cómo solucionarlo</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Sun, 07 Nov 2021 22:04:55 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/el-problema-de-las-spa-y-la-accesibilidad-54dk</link>
      <guid>https://dev.to/adrianbenavente/el-problema-de-las-spa-y-la-accesibilidad-54dk</guid>
      <description>&lt;p&gt;Las SPA son aplicaciones o sitios que, en lugar de hacer una petición al servidor cada vez que el usuario interactúa con la página, los contenidos se cargan una única vez y son mostrados de manera dinámica por JavaScript en el momento en que sean requeridos, ya sea en su totalidad o de manera parcial y asíncrona, sin necesidad de recargar toda la página. Esto permite una navegación más fluida, con menor consumo de recursos, similar a la de una aplicación nativa.&lt;/p&gt;

&lt;p&gt;A su vez, a los desarrolladores nos permitió granularizar mucho más nuestra arquitectura, dejando de pensar en páginas, para pasar a verlo todo en términos de &lt;em&gt;componentes&lt;/em&gt;. También facilitó la depuración de errores ya que todo lo que necesitamos es un navegador y las developer tools del framework o librería que estemos usando.&lt;/p&gt;

&lt;p&gt;Sin embargo, y a pesar de todas sus bondades, de las que solo nombré las más superficiales ya que este no es un artículo dedicado enteramente a las SPA, se podría decir que de cierto modo &lt;em&gt;hicieron la web menos accesible por defecto&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Claro que, echarle toda la culpa de esto a las SPA, no sería lo más razonable. Un cambio de paradigma no es más que una nueva manera de pensar y hacer las cosas. Por eso quiero compartir una serie de implementaciones que deberemos hacer desde el comienzo del proceso del desarrollo, que, junto con las &lt;a href="https://webaim.org/standards/wcag/checklist"&gt;verificaciones básicas&lt;/a&gt; de siempre, garantizarán que nuestras SPA cumplan con &lt;a href="https://www.w3.org/TR/WCAG21/#operable"&gt;el principio 2 de las WCAG 2.0&lt;/a&gt; que es ser &lt;strong&gt;operables&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manejo del foco
&lt;/h2&gt;

&lt;p&gt;Como la pestaña no se recarga al navegar entre vistas, el lector de pantalla no avisará de ningún cambio de contenido a no ser que se le indique explícitamente. Para ello, una técnica muy común es &lt;strong&gt;ubicar el foco en el primer encabezado&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onNavigate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;titulo-seccion&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pero las etiquetas de encabezado no son elementos enfocables, por lo que hay que otorgarles esta característica, colocándoles el atributo &lt;code&gt;tabindex&lt;/code&gt;. Le daremos un valor de &lt;code&gt;-1&lt;/code&gt;, para evitar que interfiera en el flujo de navegación de la tecla TAB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"titulo-seccion"&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Título de la sección&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Aquí el contenido...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo anterior también aplica a los casos en donde un botón o enlace realiza un scroll dentro de la vista, hasta otra parte de la misma. Siempre se debería poner el foco donde comienza el contenido al que llevaremos al usuario.&lt;/p&gt;

&lt;h2&gt;
  
  
  Título del documento
&lt;/h2&gt;

&lt;p&gt;Al existir un único documento HTML, este tendrá siempre el mismo título. El usuario podría no saber en qué pantalla se encuentra, en caso de irse a otra pestaña del navegador y luego volver. Por eso, debemos modificar el texto de la etiqueta &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; mediante JS, al cambiar de vista, para que refleje el contenido de esta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mi maravilloso sitio | Quiénes somos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Semántica HTML
&lt;/h2&gt;

&lt;p&gt;A veces, los frameworks de desarrollo de SPA, si no son bien utilizados, pueden forzar malas prácticas como el uso excesivo de etiquetas &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, lo que puede degradar o hasta arruinar por completo la experiencia de usuarios de tecnologías asistivas. &lt;strong&gt;Mantener siempre una correcta semántica HTML, resulta imprescindible.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Mi página&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Inicio&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/nosotros"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nosotros&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/portfolio"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Portfolio&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/contacto"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Contacto&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Nosotros&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Bla, bla...&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;@adrian.benavente.dev&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;La tecnología avanza y con ella las formas de desarrollar software, y las tecnologías de asistencia también hacen lo propio para acompañar esta evolución. Seguro que en un futuro próximo cada vez encontraremos un mejor soporte para SPA por parte de los distintos agentes de usuario que utilizan las personas con discapacidades, o, tal vez, las herramientas de desarrollo de SPA incorporen mejoras de accesibilidad. Mientras tanto, no podemos simplemente sentarnos a esperar que esto suceda, y mucho menos, cuando ocurra, dejar de lado la retrocompatibilidad.&lt;/p&gt;

&lt;p&gt;Por último, no olvidemos que, según las WCAG, en una &lt;a href="https://www.w3.org/TR/2006/WD-WCAG20-20060427/conformance.html#conformance-claims"&gt;declaración de conformidad&lt;/a&gt; un documento es o no es accesible, pero nunca puede ser parcialmente accesible; en ese caso se considera que no lo es, y se lo excluye. Ahora bien, una SPA consta de un solo documento. ¿Se va entendiendo el punto?&lt;/p&gt;

&lt;p&gt;ACTUALIZACIÓN: &lt;a href="https://www.w3.org/TR/wcag-3.0/"&gt;el borrador de WCAG 3.0&lt;/a&gt; ya incorpora los conceptos de &lt;em&gt;vistas&lt;/em&gt; y &lt;em&gt;estados&lt;/em&gt;, desprendiéndose de términos como página o documento, acortando así la brecha con el vocabulario actual y ajustándose para incluir a las SPA. Sin embargo, esta versión no verá la luz antes de 2023.&lt;/p&gt;

&lt;h2&gt;
  
  
  Colaborar
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://buymeacoffee.com/fena"&gt;Buy Me a Coffee&lt;/a&gt;&lt;br&gt;
&lt;a href="https://cafecito.app/fena"&gt;Invitame un café en cafecito.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>a11y</category>
    </item>
    <item>
      <title>CSS4 no existe, son tus padres disfrazados</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Fri, 05 Feb 2021 19:39:38 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/css4-no-existe-son-tus-padres-disfrazados-141o</link>
      <guid>https://dev.to/adrianbenavente/css4-no-existe-son-tus-padres-disfrazados-141o</guid>
      <description>&lt;p&gt;Nos encanta la reacción que nos produce oír hablar de CSS4, ¿qué bien suena, verdad?, es una buena forma de entusiasmar a quienes recién llegan al front o reniegan en las redes de CSS y sus limitaciones. Pero, en el fondo, a nuestro desarrollador web interior algo le hace ruido; el mismo que nos recuerda que los frameworks pasan pero la web es para siempre. ¿Qué sabe, entonces, esa voz interior que a nuestro orgulloso ego le gustaría silenciar? Que CSS4 no existe, son tus padres disfrazados...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bnQ57tuW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/VuwMPqL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bnQ57tuW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/VuwMPqL.png" alt="" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Un repaso
&lt;/h2&gt;

&lt;p&gt;Pensar siquiera en &lt;strong&gt;CSS4&lt;/strong&gt; va en contra de la dinámica de la web actual, ya que esta no evoluciona de manera lineal. Por ende, tampoco CSS. Repasemos cómo es que funciona la cosa...&lt;/p&gt;

&lt;p&gt;En los albores de la world wide web, el progreso de CSS no era muy vertiginoso que digamos, por lo cual la W3C podía darse el lujo de publicar documentos unitarios, es por eso que &lt;strong&gt;CSS1&lt;/strong&gt; y &lt;strong&gt;CSS2&lt;/strong&gt; sí existieron. Sin embargo, posteriormente a la versión 2.1, su desarrollo se estaba acelerando tanto que se decidió dividirlo en módulos, cada uno de estos en manos de un grupo de trabajo aparte&lt;sup id="fnref1"&gt;1&lt;/sup&gt;. Y es así como nace &lt;strong&gt;CSS3&lt;/strong&gt;. Ya no a partir de un documento concreto, si no más bien como la necesidad de fijar una versión sobre la cual cimentar este nuevo paradigma.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pcOK75EK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/LrlanJ2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pcOK75EK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/LrlanJ2.png" alt="" width="602" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lo largo de su desarrollo, dichos módulos van atravesando distintas etapas o niveles de maduración&lt;sup id="fnref2"&gt;2&lt;/sup&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Editor's Draft (ED)&lt;/strong&gt;: Primer borrador presentado por una o más personas. No necesariamente respaldado por la W3C.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Working Draft (WD)&lt;/strong&gt;: La W3C lo publica para revisión por la comunidad de desarrolladores, tanto interna como externa.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Candidate Recommendation (CR)&lt;/strong&gt;: Ha tenido la aceptación suficiente como para empezar a testearlo en entornos no productivos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Proposed Recommendation (PR)&lt;/strong&gt;: Ha madurado lo suficiente y ha sido debidamente testeado como para considerar su implementación definitiva.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Superado este último estadío, se convierte en &lt;strong&gt;Recomendación de la W3C (REC)&lt;/strong&gt;, y la pelota de ahí en más pasa a estar en el campo de los navegadores y cuán rápido le brinden soporte (teléfono para Safari). Al no haber una sincronicidad en el avance del desarrollo de los módulos, necesitaríamos que todos o la mayoría de ellos se encontrasen en el mismo nivel, para así poder hablar de una nueva versión de CSS, lo cual (spoiler alert) no va a ocurrir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mirando el vaso medio lleno
&lt;/h2&gt;

&lt;p&gt;Un momento, no todo es drama, mientras estábamos lamentándonos por la no llegada de CSS4, pasaron un montón de cosas emocionantes en CSS que no las supimos celebrar debidamente por estar esperando la tierra prometida. Pero todavía estamos con vida, tenemos una nueva oportunidad, hagamos una mirada retrospectiva de algunos de los hitos que ocurrieron desde el ya mentado CSS3 hasta acá:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Flexbox (sí, ya nos parece viejo, pero ocurrió durante este período)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Grid (el sueño de todo maquetador hecho realidad)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CSS Shapes (por fin superamos la era de los cuadrados)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Propiedad &lt;code&gt;gap&lt;/code&gt; para Flexbox&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nuevos modos de color (RGB para seres humanos)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom properties, que a su vez son variables (CSS no es un lenguaje de progr...)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detección de features y preferencias de usuario (golazo de la inclusión y la accesibilidad)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¡Y son solo algunos de una larga lista&lt;sup id="fnref3"&gt;3&lt;/sup&gt;! No voy a ahondar en cada una de estas features porque este artículo se volvería kilométrico, pero todas cuentan con suficiente documentación al alcance de una búsqueda desde nuestro navegador.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSSWhatever, una mirada al futuro
&lt;/h2&gt;

&lt;p&gt;Entonces, ¿qué podemos esperar, ahora que ya entendimos cómo va la cosa y estamos más relajados respecto de este tema? Bueno, acá una serie de novedades que están por venir en un futuro próximo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Propiedad &lt;code&gt;aspect-ratio&lt;/code&gt; (sí, basta de hacks horribles para mantener el aspect ratio de los iframes) (solo Chrome por ahora)&lt;sup id="fnref4"&gt;4&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Función de color &lt;code&gt;hwb()&lt;/code&gt; (ya hice &lt;a href="https://dev.to/adrianbenavente/hwb-un-mordisco-del-futuro-de-css-46j8"&gt;un post sobre esto&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anidación de selectores y selector de padre (sí, eso que actualmente hacemos con preprocesadores)&lt;sup id="fnref5"&gt;5&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subgrid (grillas que reconocen y heredan las propiedades de su grilla padre) (de momento solo en Firefox)&lt;sup id="fnref6"&gt;6&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pseudo-selector &lt;code&gt;:is()&lt;/code&gt; (se le puede pasar una lista de selectores separada por coma, sería como lo opuesto a &lt;code&gt;:not()&lt;/code&gt;)&lt;sup id="fnref7"&gt;7&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scroll snap (RIP Slick Carousel) (por ahora solo funciona en navegadores de la familia Chromium)&lt;sup id="fnref8"&gt;8&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Houdini (API de bajo nivel para meternos en las entrañas del motor de CSS y crear nuevas propiedades con un comportamiento totalmente definido por nosotros)&lt;sup id="fnref9"&gt;9&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;El desarrollo de CSS no es lineal y, en parte, está bien que así sea, porque nos permite ir implementando las nuevas características e ir mejorando progresivamente nuestras apps y sitios sin la necesidad de esperar la llegada de una gran especificación monolítica, algo que volvería mucho más lento el crecimiento de la web.&lt;/p&gt;

&lt;p&gt;Por último, te animo a dejar abajo en los comentarios qué otras features recientes pasé por alto que te hayan gustado y cuáles esperás ver en un futuro próximo. Gracias por leerme.&lt;/p&gt;

&lt;p&gt;Y si te agradan mis artículos, toda colaboración es un incentivo.&lt;br&gt;
&lt;a href="https://cafecito.app/fena"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bjlmcqJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.cafecito.app/imgs/buttons/button_1.svg" alt="Invitame un café en cafecito.app" width="192" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://www.w3.org/Style/CSS/current-work"&gt;Estado actual de los distintos módulos&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://www.w3.org/2005/10/Process-20051014/tr#maturity-levels"&gt;7 W3C Technical Report Development Process&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://css-tricks.com/css4/"&gt;https://css-tricks.com/css4/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio"&gt;aspect-ratio - CSS: Cascading Style Sheets | MDN&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;&lt;a href="https://tabatkins.github.io/specs/css-nesting/"&gt;CSS Nesting Module Level 3&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Subgrid"&gt;Subgrid - CSS: Cascading Style Sheets | MDN&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;&lt;a href="https://css-tricks.com/almanac/selectors/i/is/"&gt;https://css-tricks.com/almanac/selectors/i/is/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/docs/Web/CSS/scroll-snap-stop"&gt;https://developer.mozilla.org/docs/Web/CSS/scroll-snap-stop&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn9"&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Houdini"&gt;CSS Houdini | MDN&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>CSS Modules en Vue.js - ¿Qué son y por qué deberíamos empezar a usarlos?</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Tue, 29 Dec 2020 03:30:59 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/css-modules-en-vue-js-4h1b</link>
      <guid>https://dev.to/adrianbenavente/css-modules-en-vue-js-4h1b</guid>
      <description>&lt;h2&gt;
  
  
  En la teoría...
&lt;/h2&gt;

&lt;p&gt;Según su definición oficial&lt;sup id="fnref1"&gt;1&lt;/sup&gt;, los &lt;strong&gt;CSS Modules&lt;/strong&gt; son archivos CSS que, con la ayuda de bundlers como Webpack, Parcel o Browserify, nos permiten escribir estilos que luego se convertirán en nombres de clase únicos e irrepetibles, compuestos por nombre del archivo, class name y un hash aleatorio, en cuya generación no intervendremos ni nos interesa saber cómo ocurre, aunque, para quienes tengan curiosidad, les dejo la referencia: &lt;a href="https://github.com/css-modules/icss" rel="noopener noreferrer"&gt;GitHub - css-modules/icss: Interoperable CSS — a standard for loadable, linkable CSS&lt;/a&gt;. Cabe aclarar que no se trata de una especificación técnica dentro de CSS, si no de un paso en el "building" de nuestra aplicación.&lt;/p&gt;

&lt;h2&gt;
  
  
  En la práctica...
&lt;/h2&gt;

&lt;p&gt;Cuando estamos trabajando en Vue, al encontrarse con un módulo CSS, el bundler tomará los nombres de clase que hayamos declarado y les agregará el nombre del componente delante, y el ya mencionado hash al final, asegurando así un encapsulamiento de estilos completo, quedando de esta forma: &lt;code&gt;.{NombreDelComponente}_{nombreDeClase}_{hash}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Un ejemplo sencillo, con fines puramente ilustrativos, de cómo se implementa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- MiComponente.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"$style.container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"$style.title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Título&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"$style.subtitle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Subtítulo&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"$style.paragraph"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            Lorem ipsum dolor sit amet... etc...
        &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.subtitle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;darkgray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;italic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.paragraph&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;130%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El HTML final sería algo como esto...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"MiComponente_container_h342kj"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"MiComponente_title_g0921s"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Título&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"MiComponente_subtitle_a298vn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Subtítulo&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"MiComponente_paragraph_y030mw"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Lorem ipsum dolor sit amet... etc...
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y los estilos...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.MiComponente_container_h342kj&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.MiComponente_title_g0921s&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.MiComponente_subtitle_a298vn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;darkgray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;italic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.MiComponente_paragraph_y030mw&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;130%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí ya comienzan a asomar sus ventajas, permitiéndonos abstraernos por completo del resto de nuestra aplicación y empezar a pensar en cada componente como un universo aparte.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preprocesadores
&lt;/h3&gt;

&lt;p&gt;También se puede utilizar con preprocesadores (por ej.: &lt;code&gt;&amp;lt;style lang="scss" module&amp;gt;&lt;/code&gt;), en cuyo caso debemos tener en cuenta que la anidación está permitida siempre y cuando respetemos la sintáxis de Vue para CSS Modules a la hora de acceder a nuestras clases (&lt;code&gt;&amp;lt;h2 :class="$style.title"&amp;gt;&lt;/code&gt;).  De lo contrario, no funcionaría:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;:class=&lt;/span&gt;&lt;span class="s"&gt;"$style.container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Título&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"scss"&lt;/span&gt; &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1280px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="err"&gt;.title&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* ❌ ¡será ignorada! */&lt;/span&gt;
        &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Múltiples clases
&lt;/h3&gt;

&lt;p&gt;Siempre que estemos usando "binding" de clases en Vue y necesitemos asignar varias a un mismo elemento, debemos hacerlo en forma de &lt;em&gt;array&lt;/em&gt;. Pues bien, con CSS modules no es la excepción: &lt;code&gt;&amp;lt;button :class="[$style.clase1, $style.clase2, $style.clase3, ...]"&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  La propiedad 'composes'
&lt;/h3&gt;

&lt;p&gt;Sin duda una feature muy útil de los CSS Modules es la posibilidad de heredar reglas de otro selector, de manera muy similar al &lt;code&gt;@extend&lt;/code&gt; de Scss, utilizando la propiedad &lt;code&gt;composes&lt;/code&gt;&lt;sup id="fnref2"&gt;2&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.serifFont&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Georgia&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.display&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;composes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;serifFont&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;35px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuración de Webpack
&lt;/h2&gt;

&lt;p&gt;Si nuestro proyecto usa una configuración manual de Webpack, los CSS Modules se pueden habilitar simplemente añadiendo la siguiente regla:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="c1"&gt;// ... otras reglas&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;css$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-style-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-loader&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="na"&gt;localIdentName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[local]_[hash:base64:8]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En el caso de los frameworks más comunes, suelen venir habilitados por defecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Naming de clases
&lt;/h2&gt;

&lt;p&gt;Aunque nada nos impide definir clases en kebab case (&lt;code&gt;.mi-clase-kebab-case&lt;/code&gt;), por convención se recomienda utilizar siempre camel case (&lt;code&gt;.miClaseCamelCase&lt;/code&gt;), ya que esto permite acceder a la misma desde el template utilizando notación de puntos (&lt;code&gt;$style.miClaseCamelCase&lt;/code&gt;), de lo contrario deberíamos usar sintáxis de corchetes que es menos legible (&lt;code&gt;$style['mi-clase-kebab-case']&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  En el JS
&lt;/h2&gt;

&lt;p&gt;Como podemos intuir, cada vez que declaramos una clase, esta se convierte en una propiedad del objeto &lt;code&gt;$style&lt;/code&gt; que se añade al scope global al estar trabajando con CSS Modules. La misma guardará como valor el nombre único auto generado, de manera tal que si, por alguna razón, quisiéramos acceder a la misma desde el JS del componente, podríamos hacer lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nombreDeMiClase&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Diferencia con "Scoped"
&lt;/h2&gt;

&lt;p&gt;Si bien ambos cumplen la misma función, scoped tiene una serie de desventajas con respecto a CSS Modules:&lt;/p&gt;

&lt;h3&gt;
  
  
  Legibilidad
&lt;/h3&gt;

&lt;p&gt;Para encapsular, Vue utiliza el atributo &lt;code&gt;data&lt;/code&gt; seguido de &lt;code&gt;-v-&lt;/code&gt; y un hash único por componente en cada elemento, lo que ensucia mucho los HTML y CSS finales&lt;sup id="fnref3"&gt;3&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Title &lt;span class="nt"&gt;&amp;lt;small&amp;gt;&lt;/span&gt;(small)&lt;span class="nt"&gt;&amp;lt;/small&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Content 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Content 2&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.test&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  HTML generado
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-v-5b2d5ecc=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;data-v-5b2d5ecc=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Title &lt;span class="nt"&gt;&amp;lt;small&lt;/span&gt; &lt;span class="na"&gt;data-v-5b2d5ecc=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;(small)&lt;span class="nt"&gt;&amp;lt;/small&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-v-5b2d5ecc=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-v-5b2d5ecc=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;data-v-5b2d5ecc=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Content 1&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;data-v-5b2d5ecc=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Content 2&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como vemos, con esta estrategia se agregan los atributos &lt;code&gt;data&lt;/code&gt; incluso en aquellos elementos que no llevan CSS 👎.&lt;/p&gt;

&lt;h4&gt;
  
  
  CSS generado
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-v-5b2d5ecc&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.test&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-v-5b2d5ecc&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Especificidad
&lt;/h3&gt;

&lt;p&gt;Por más que, a nivel de componente, los estilos están encapsulados de forma segura, podrían existir, en el HTML final, nombres de clase repetidos, lo que puede resultar confuso de leer si no se sigue un patrón de class naming como puede ser BEM o SMACSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compatibilidad
&lt;/h3&gt;

&lt;p&gt;Por último, los estilos de tipo &lt;code&gt;scoped&lt;/code&gt; son específicos de Vue, mientras que &lt;strong&gt;CSS Modules&lt;/strong&gt; son un estándar y pueden ser utilizados en cualquier proyecto JS que use bundlers como Webpack, Parcel o Browserify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparativa con React
&lt;/h2&gt;

&lt;p&gt;Por último, solo a modo de comparación, un breve vistazo a su implementación en React, donde podemos ver que la misma es todavía más similar a la descrita en la documentación oficial&lt;sup id="fnref1"&gt;1&lt;/sup&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* MiComponente.module.css */&lt;/span&gt;
&lt;span class="nc"&gt;.title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;900&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-decoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;underline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.paragraph&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Roboto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Importante&lt;/strong&gt;: el archivo de estilos debe llevar .module antes de la extensión (por ej.: &lt;code&gt;MiComponente.module.css&lt;/code&gt; ó &lt;code&gt;MiComponente.module.scss&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  JSX
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MiComponente.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MiComponente.module.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MiComponente&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Título&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paragraph&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Lorem ipsum dolor sit amet...
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MiComponente&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;CSS Modules es una librería que ha estado adquiriendo mucha popularidad en los últimos tiempos&lt;sup id="fnref4"&gt;4&lt;/sup&gt; ya que integra CSS con Javascript como nunca antes se vió, y soluciona el problema del &lt;em&gt;specificity hell&lt;/em&gt;, haciendo nuestro flujo de trabajo mucho más productivo. &lt;/p&gt;

&lt;p&gt;Afortunadamente, su curva de aprendizaje es ínfima y, sin duda, es una herramienta que vale la pena añadir a nuestro stack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cafecito.app/fena" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.cafecito.app%2Fimgs%2Fbuttons%2Fbutton_1.svg" alt="Invitame un café en cafecito.app"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://github.com/css-modules/css-modules" rel="noopener noreferrer"&gt;GitHub - css-modules/css-modules: Documentation about css-modules&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;&lt;a href="https://css-tricks.com/css-modules-part-1-need/" rel="noopener noreferrer"&gt;What are CSS Modules and why do we need them?&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;&lt;a href="https://code.luasoftware.com/tutorials/vuejs/vuejs-css-styles-scoped-vs-module/" rel="noopener noreferrer"&gt;Vue.js CSS Styles Scoped vs Module | Lua Software Code&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;&lt;a href="https://2020.stateofcss.com/en-US/technologies/css-in-js/#css_in_js_experience_ranking" rel="noopener noreferrer"&gt;The State of CSS 2020: CSS-in-JS&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>css</category>
      <category>vue</category>
    </item>
    <item>
      <title>HWB, una mordida al futuro de CSS</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Sat, 17 Oct 2020 18:56:54 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/hwb-un-mordisco-del-futuro-de-css-46j8</link>
      <guid>https://dev.to/adrianbenavente/hwb-un-mordisco-del-futuro-de-css-46j8</guid>
      <description>&lt;p&gt;Se encuentra publicada en la &lt;a href="https://www.w3.org/TR/css-color-4/#the-hwb-notation"&gt;especificación de Color Nivel 4&lt;/a&gt; de CSS, una nueva función de color con una lógica más intuitiva para seres humanos: se trata de HWB (por las siglas Hue, Whiteness, Blackness). Esta forma de definir colores se asemeja más a lo que vemos en la rueda de color de un color picker, donde primero elegimos un tono de referencia y a partir de este nos movemos hacia el negro o el blanco, hasta lograr el color deseado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e2s3x9Hw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://framework7.io/i/docs/color-picker-wheel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e2s3x9Hw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://framework7.io/i/docs/color-picker-wheel.png" alt="Rueda de color" width="640" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Parece ser que, desde el equipo de Sass, están barajando la posibilidad de introducir su propia versión, como parte del módulo &lt;code&gt;color&lt;/code&gt;, lo que nos permitirá empezar a utilizar por adelantado una feature del futuro, creada respetando los &lt;a href="https://www.w3.org/TR/css-color-4/#the-hwb-notation"&gt;specs de CSS4&lt;/a&gt;, sumándole todas las ventajas de estar trabajando con este potente superset de CSS. Esta decisión de no incluirla en el scope global va en sintonía con la filosofía de Sass de nunca incorporar una sintáxis CSS que aún no esté soportada por todos los navegadores modernos. En los casos de &lt;code&gt;rgb()&lt;/code&gt;, &lt;code&gt;hsl()&lt;/code&gt;, y sus variantes &lt;code&gt;rgba()&lt;/code&gt; y &lt;code&gt;hsla()&lt;/code&gt;, estas pueden invocarse desde el ámbito global ya que cuentan con un soporte total.&lt;/p&gt;

&lt;p&gt;Entonces, ¿cómo será implementada? Veámoslo...&lt;/p&gt;

&lt;h2&gt;
  
  
  hwb()
&lt;/h2&gt;

&lt;p&gt;Al igual que el método &lt;code&gt;hsl()&lt;/code&gt;, recibe tres argumentos obligatorios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Un &lt;strong&gt;número&lt;/strong&gt; (de 0 a 360) que representa en grados la posición del tono en la rueda de color.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Un &lt;strong&gt;número&lt;/strong&gt; (0% - 100%), expresado en porcentaje, definiendo la cantidad de blanco.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;un &lt;strong&gt;número&lt;/strong&gt; (0% - 100%), expresado en porcentaje, definiendo la cantidad de negro.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...y un cuarto parmámetro opcional, siendo este un &lt;strong&gt;número&lt;/strong&gt; de 0 a 1 (aceptando decimales, obviamente) que corresponde al valor de &lt;code&gt;$alfa&lt;/code&gt;, es decir, la opacidad, donde 0 (cero) es transparencia total y 1 (uno) opacidad total; su valor por defecto es 1.&lt;/p&gt;

&lt;p&gt;Los parámetros los podemos pasar separados por comas o espacios, como sucede con &lt;code&gt;rgb()&lt;/code&gt; y &lt;code&gt;hsl()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"sass:color"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;selector&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hwb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;270&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;20%&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;40%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// esto es válido&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hwb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;270&lt;/span&gt; &lt;span class="m"&gt;20%&lt;/span&gt; &lt;span class="m"&gt;40%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// esto también&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sin embargo, si queremos pasarle el cuarto parámetro (valor de alfa), deberemos sí o sí separarlos con coma, de lo contrario veremos un error en el compilador. Esta función compila a &lt;code&gt;rgb()&lt;/code&gt; en el CSS resultante.&lt;/p&gt;

&lt;h2&gt;
  
  
  whiteness() y blackness()
&lt;/h2&gt;

&lt;p&gt;Funcionan igual que &lt;code&gt;saturation()&lt;/code&gt; y &lt;code&gt;lightness()&lt;/code&gt; si estuviésemos usando el modelo &lt;code&gt;hsl&lt;/code&gt;, es decir que: recibiendo cualquier &lt;a href="https://developer.mozilla.org/es/docs/Web/CSS/color_value"&gt;color CSS válido&lt;/a&gt; retornará su valor de &lt;strong&gt;blanco&lt;/strong&gt; o &lt;strong&gt;negro&lt;/strong&gt;, permitiendo recuperarlo. También forman parte del módulo &lt;code&gt;color&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  scale(), adjust() y change()
&lt;/h2&gt;

&lt;p&gt;Las funciones que modifican el color de manera directa, ahora además soportan &lt;code&gt;$whiteness&lt;/code&gt; y &lt;code&gt;$blackness&lt;/code&gt; como argumentos. Podremos, por ejemplo, hacer lo siguiente: &lt;code&gt;color.adjust(#d2e1dd, $blackness: 30%)&lt;/code&gt;; igual que &lt;code&gt;$saturation&lt;/code&gt; y &lt;code&gt;$lightness&lt;/code&gt;, aceptan valores negativos.&lt;/p&gt;

&lt;p&gt;Esta nueva característica es, de momento, &lt;a href="https://github.com/sass/sass/blob/master/proposal/color-4-hwb.md"&gt;una propuesta&lt;/a&gt; que podría volverse realidad y cualquiera puede &lt;a href="https://github.com/sass/sass/issues/new"&gt;sumarse a la discusión&lt;/a&gt; aportando ideas. ¿Qué opinás de esta nueva feature?&lt;/p&gt;

&lt;h3&gt;
  
  
  ACTUALIZACIÓN:
&lt;/h3&gt;

&lt;p&gt;Recientemente, esta propuesta fue aceptada como podemos ver en &lt;a href="https://github.com/sass/sass/commit/032bbcaabc733bb39d1a615d69bf7566e50211db"&gt;este commit&lt;/a&gt; así que podemos empezar a utilizar esta feature a partir de la última versión, la 1.29.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cafecito.app/fena"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bjlmcqJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.cafecito.app/imgs/buttons/button_1.svg" alt="Invitame un café en cafecito.app" width="192" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Sass 1.23 - La versión que cambió las reglas del juego</title>
      <dc:creator>Adrian Benavente</dc:creator>
      <pubDate>Mon, 07 Sep 2020 05:45:12 +0000</pubDate>
      <link>https://dev.to/adrianbenavente/sass-1-23-la-version-que-cambio-las-reglas-del-juego-3ekg</link>
      <guid>https://dev.to/adrianbenavente/sass-1-23-la-version-que-cambio-las-reglas-del-juego-3ekg</guid>
      <description>&lt;p&gt;Se está por cumplir un año ya desde el lanzamiento de la versión que quizás introdujo los cambios más significativos en Sass como lenguaje desde la migración de su compilador de Ruby a Dart, y he notado que, sin embargo, este suceso ha pasado bastante desapercibido. Fuera del sitio oficial de Sass, los posteos en internet hablando acerca de esto, así como los videos en YouTube, son escasos por no decir nulos, y ni hablemos de encontrar algo en español. Es por eso que decidí ordenar de la forma más prolija y detallada posible pero sin agobiar al lector, las features más trascendentales que introduce Sass 1.23, y que, según sus desarrolladores, llegaron para quedarse.&lt;/p&gt;

&lt;h2&gt;
  
  
  Démosle la bienvenida al Module System
&lt;/h2&gt;

&lt;p&gt;Sin lugar a dudas, el salto más importante que ha dado esta versión, y por el cual se la considera una versión bisagra es debido a la deprecación completa (aunque gradual) de la regla &lt;code&gt;@import&lt;/code&gt; para la carga de archivos, cediendo el paso al nuevo &lt;strong&gt;Module System&lt;/strong&gt;, cuya implementación gira en torno a la nueva at-rule &lt;code&gt;@use&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Previo a esta versión, cuando usábamos &lt;code&gt;@import&lt;/code&gt;, era imposible saber dónde habían sido definidas las funciones, mixins y variables (llamados "miembros" por convención, y así nos referiremos de ahora en adelante) que estábamos invocando dentro de un archivo (a los cuales a partir de ahora es correcto referirse como "namespaces"), ya que el solo hecho de hacer un &lt;code&gt;@import&lt;/code&gt; los volvía disponibles dentro de todos los archivos que fueran llamados a continuación. &lt;/p&gt;

&lt;p&gt;Esto era un dolor de cabeza para muchos desarrolladores, y un potencial problema en proyectos grandes donde podía llegar a ocurrir que se definieran dos miembros con el mismo nombre. Además, nos obligaba a prestar particular atención al orden de importación, cuando existían múltiples imports, si queríamos que determinados miembros estuvieran disponibles cuando los necesitábamos.&lt;/p&gt;

&lt;p&gt;Con esto, de paso, Sass se despega por completo de la colisión confusa con el &lt;code&gt;@import&lt;/code&gt; de CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cambios de la versión
&lt;/h2&gt;

&lt;p&gt;Estos son algunos de los pricipales cambios y mejoras que introdujo la versión 1.23:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Importación de archivos como módulos mediante la regla &lt;code&gt;@use&lt;/code&gt;. Mejora el encapsulamiento ya que los miembros de éste solo estarán disponibles dentro del archivo que los está usando, a diferencia de &lt;code&gt;@import&lt;/code&gt; que tenía un scope global.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// some-file.scss&lt;/span&gt;
  &lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;"some-module"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌ disponible dentro de este archivo&lt;/span&gt;
  &lt;span class="c1"&gt;// y de todos los que se importen después &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// some-file.scss&lt;/span&gt;
  &lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"some-module"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ✅ disponible solo dentro de este archivo &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Con la regla &lt;code&gt;@forward&lt;/code&gt;, se podrá hacer que los miembros de otro archivo estén disponibles cuando el archivo actual sea importado con &lt;code&gt;@use&lt;/code&gt;, creando de esta manera una API extendida. Sin embargo, el archivo que realiza el &lt;code&gt;@forward&lt;/code&gt; no podrá acceder a los miembros de éste, a diferencia de &lt;code&gt;@use&lt;/code&gt;, si no que actuará como un simple intermediario. Es decir que podemos hacer lo siguiente:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// mixins.scss&lt;/span&gt;
  &lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;expand&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// foo.scss&lt;/span&gt;
  &lt;span class="k"&gt;@forward&lt;/span&gt; &lt;span class="s2"&gt;"mixins"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;.foo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;peru&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column-reverse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// some-other-file.scss&lt;/span&gt;
  &lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;.expanded&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mientras que esto nos daría un error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// palette.scss&lt;/span&gt;
  &lt;span class="nv"&gt;$colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;primary&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#007BFF&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;secondary&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#6C757D&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#DC3545&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// functions.scss&lt;/span&gt;
  &lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"sass:map"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@forward&lt;/span&gt; &lt;span class="s2"&gt;"palette"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$prop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;palette&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$colors&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$prop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="c1"&gt;// =&amp;gt; Error: There is no module&lt;/span&gt;
      &lt;span class="c1"&gt;// with the namespace "palette".&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Es posible, de ser necesario, decidir de manera selectiva qué variables, mixins o funciones de determinado namespace estarán disponibles, de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// src/_list.scss&lt;/span&gt;
  &lt;span class="nv"&gt;$horizontal-list-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;list-reset&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;list-horizontal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-2px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$horizontal-list-gap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// bootstrap.scss&lt;/span&gt;
  &lt;span class="k"&gt;@forward&lt;/span&gt; &lt;span class="s2"&gt;"src/list"&lt;/span&gt; &lt;span class="nt"&gt;hide&lt;/span&gt; &lt;span class="nt"&gt;list-reset&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;horizontal-list-gap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...o de forma inversa con &lt;code&gt;show&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="k"&gt;@forward&lt;/span&gt; &lt;span class="s2"&gt;"src/list"&lt;/span&gt; &lt;span class="nt"&gt;show&lt;/span&gt; &lt;span class="nt"&gt;list-horizontal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y también algo que es muy interesante es que podemos agregar un prefijo para todos los miembros del namespace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// src/_list.scss&lt;/span&gt;
  &lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;reset&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// bootstrap.scss&lt;/span&gt;
  &lt;span class="k"&gt;@forward&lt;/span&gt; &lt;span class="s2"&gt;"src/list"&lt;/span&gt; &lt;span class="nt"&gt;as&lt;/span&gt; &lt;span class="nt"&gt;list-&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// styles.scss&lt;/span&gt;
  &lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"bootstrap"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;bootstrap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list-reset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;La at-rule &lt;code&gt;@extend&lt;/code&gt; se limita al scope del archivo actual cuando se utiliza &lt;code&gt;@use&lt;/code&gt;. A diferencia de antes, que al usar &lt;code&gt;@import&lt;/code&gt; el &lt;code&gt;@extend&lt;/code&gt; quedaba disponible globalmente, en ocasiones haciendo difícil predecir qué reglas estábamos extendiendo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Usando los &lt;strong&gt;modificadores de acceso&lt;/strong&gt; &lt;code&gt;-&lt;/code&gt; ó &lt;code&gt;_&lt;/code&gt; podemos hacer que un miembro sea privado, lo que significa que solo podrá ser utilizado dentro del propio archivo que lo define: &lt;code&gt;$_private-var: value&lt;/code&gt; ó &lt;code&gt;$-private-var: value&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Namespaces&lt;/strong&gt; personalizados mediante el uso de &lt;code&gt;as&lt;/code&gt;. Por ejemplo:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"functions"&lt;/span&gt; &lt;span class="nt"&gt;as&lt;/span&gt; &lt;span class="nt"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...o como &lt;strong&gt;top-level module&lt;/strong&gt; (usar con precaución):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"functions"&lt;/span&gt; &lt;span class="nt"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta última forma tiene la limitación de que, si usamos otro módulo como "top-level module" y este contiene, también, una función llamada &lt;code&gt;color()&lt;/code&gt;, el compilador arrojará un error.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;También podemos importar un módulo sobreescribiendo el valor de una o más de sus variables. Para ello, primero tenemos que asignarle un valor por defecto al momento de definirla:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// bootstrap.scss&lt;/span&gt;
  &lt;span class="nv"&gt;$paragraph-margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$paragraph-margin-bottom&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y luego llamar el archivo de esta manera, utilizando la cláusula &lt;code&gt;with&lt;/code&gt; que recibirá un &lt;a href="https://sass-lang.com/documentation/values/maps"&gt;mapa&lt;/a&gt; con las variables que queramos pisar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="k"&gt;@use&lt;/span&gt; &lt;span class="s2"&gt;"bootstrap"&lt;/span&gt; &lt;span class="nt"&gt;with&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;paragraph-margin-bottom&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="nc"&gt;.2rem&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Las &lt;strong&gt;funciones del core de Sass&lt;/strong&gt; ahora son accedidas a través de &lt;strong&gt;módulos nativos&lt;/strong&gt;: &lt;code&gt;sass:color&lt;/code&gt;, &lt;code&gt;sass:list&lt;/code&gt;, &lt;code&gt;sass:map&lt;/code&gt;, &lt;code&gt;sass:math&lt;/code&gt;, &lt;code&gt;sass:meta&lt;/code&gt;, &lt;code&gt;sass:selector&lt;/code&gt;, y &lt;code&gt;sass:string&lt;/code&gt;. Las cargaremos en nuestra hoja de estilos con &lt;code&gt;@use&lt;/code&gt; (por ej: &lt;code&gt;@use "sass:map"&lt;/code&gt;) y las usaremos como cualquier otro módulo, con la sintáxis &lt;code&gt;namespace.function()&lt;/code&gt;. Esto se hizo para evitar la colisión con funciones nativas de CSS, lo que les permitirá, en el futuro, agregar nuevas de manera segura.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se incorporaron, además, algunos &lt;strong&gt;mixins al core&lt;/strong&gt;, que vienen a solucionar algunas malas prácticas del pasado, como los &lt;code&gt;@import&lt;/code&gt; anidados, tal es el caso de &lt;code&gt;meta.load-css($url, $with: ())&lt;/code&gt; que sirve para cargar una hoja de estilos de manera dinámica, recibiendo dos parámetros, el primero &lt;code&gt;$url&lt;/code&gt; es un string con la url de dicho CSS, y el segundo &lt;code&gt;$with: ()&lt;/code&gt; es opcional y deberá ser un mapa con la configuración, igual al del ejemplo anterior solo que en este caso las variables no llevan $ adelante.  También tenemos &lt;code&gt;meta.module-variables()&lt;/code&gt; y &lt;code&gt;meta.module-functions()&lt;/code&gt; para acceder a las variables o funciones respectivamente de un determinado módulo. Están disponibles de la misma manera que las built-in functions: &lt;code&gt;@use "sass:meta"&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ¿Es seguro de usar?
&lt;/h2&gt;

&lt;p&gt;Desde el lanzamiento de esta versión, ya ha pasado casi un año y han salido 3 versiones menores posteriormente (actualmente se encuentra en la 1.26), por lo que es 100% seguro de utilizar en cualquier proyecto nuevo. Sin embargo, hemos de esperar que no nos funcionen las nuevas features en proyectos de más de un año de antigüedad.&lt;/p&gt;

&lt;p&gt;Si bien esta versión es completamente retro-compatible, los desarrolladores avisan que &lt;code&gt;@import&lt;/code&gt; será eventualmente removido por completo de Sass, pero que dejarán transcurrir un tiempo prudencial para que tengamos chance de migrar.&lt;/p&gt;

&lt;p&gt;Por suerte, Sass pone a nuestra disposición una &lt;strong&gt;herramienta de migración automatizada&lt;/strong&gt;, a través de línea de comandos: &lt;strong&gt;sass-migrator&lt;/strong&gt;. Existen varias formas de instalarla, las cuales &lt;a href="https://sass-lang.com/documentation/cli/migrator"&gt;se detallan aquí&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrando nuestro código
&lt;/h2&gt;

&lt;p&gt;Seguiremos las instrucciones para &lt;a href="https://sass-lang.com/documentation/cli/migrator"&gt;Sass: Migrator&lt;/a&gt; de la página oficial, y una vez que tengamos instalada la CLI, simplemente navegamos a la carpeta de nuestro proyecto y hacemos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sass-migrator module &lt;span class="nt"&gt;--migrate-deps&lt;/span&gt; &amp;lt;path/to/style.scss&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El flag &lt;code&gt;--migrate-deps&lt;/code&gt; lo que hace es decirle que migre no solo el archivo específico que le estamos indicando si no además todos los archivos que pudiera estar importando.&lt;/p&gt;

&lt;p&gt;Podemos pasarle el flag &lt;code&gt;--verbose&lt;/code&gt; para que la consola nos de output sobre los cambios que va realizando sobre los archivos, y el flag &lt;code&gt;--dry-run&lt;/code&gt; si queremos que corra el comando de manera "simulada" sin ejecutar realmente los cambios, lo cual tiene sentido usándolo en combinación con el anterior.&lt;/p&gt;

&lt;p&gt;Si bien lo anterior bastará para la mayoría de los casos, hay un último flag que puede llegar a ser muy útil para quienes desarrollen alguna biblioteca: &lt;code&gt;--forward&lt;/code&gt;, que acepta los valores &lt;code&gt;none&lt;/code&gt;(valor por defecto), &lt;code&gt;all&lt;/code&gt; y &lt;code&gt;prefixed&lt;/code&gt;. Si elegimos &lt;code&gt;--forward=all&lt;/code&gt; permitiremos que el usuario de nuestra biblioteca pueda acceder a toda la API (excepto miembros privados) con un solo &lt;code&gt;@use&lt;/code&gt;, ya que lo que hará es un &lt;code&gt;@forward&lt;/code&gt; de todos los archivos. En el caso de &lt;code&gt;prefixed&lt;/code&gt;, básicamente hace un &lt;code&gt;@forward&lt;/code&gt; únicamente de los miembros a los que hayamos puesto un prefijo, el cual debemos explicitar de manera obligatoria con el flag adicional &lt;code&gt;--remove-prefix&lt;/code&gt;; la herramienta eliminará automáticamente este prefijo. Antes de los módulos, se solía agregar estos prefijos para evitar colisiones de nombres. El ejemplo del sitio de Sass, lo grafica a la perfección:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;style.scss
@import &lt;span class="s2"&gt;"theme"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

@mixin app-inverted &lt;span class="o"&gt;{&lt;/span&gt;
  color: &lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="nt"&gt;-bg-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  background-color: &lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="nt"&gt;-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;sass-migrator &lt;span class="nt"&gt;--migrate-deps&lt;/span&gt; module &lt;span class="nt"&gt;--remove-prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;app- style.scss
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;style.scss
@use &lt;span class="s2"&gt;"theme"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

@mixin inverted &lt;span class="o"&gt;{&lt;/span&gt;
  color: theme.&lt;span class="nv"&gt;$bg&lt;/span&gt;&lt;span class="nt"&gt;-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  background-color: theme.&lt;span class="nv"&gt;$color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Debo decir que he realizado unas cuantas migraciones y, en todos los casos, la herramienta es bastante efectiva e inteligente al realizar su labor. En algúna ocasión he tenido que refactorizar un poco a mano pero han sido cosas mínimas que no me han llevado más de unos minutos. Aun así, es recomendable primero probar siempre con &lt;code&gt;--dry-run --verbose&lt;/code&gt;, para nuestra tranquilidad.&lt;/p&gt;

&lt;p&gt;Referencias: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sass-lang.com/blog/the-module-system-is-launched"&gt;https://sass-lang.com/blog/the-module-system-is-launched&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://css-tricks.com/introducing-sass-modules/"&gt;https://css-tricks.com/introducing-sass-modules/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://seesparkbox.com/foundry/dart_sass_update_version_1.23.0"&gt;https://seesparkbox.com/foundry/dart_sass_update_version_1.23.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://cafecito.app/fena"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bjlmcqJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.cafecito.app/imgs/buttons/button_1.svg" alt="Invitame un café en cafecito.app" width="192" height="40"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
    </item>
  </channel>
</rss>
