
Presentando Constructor.css

Todo empezó, como muchas cosas, con una conversación tonta. En este caso, estaba hablando con nuestro Director de Competencia de Tecnología Front End (también conocido como “jefe”) Mundi Morgado.
Fue algo como esto…
Mundi MorgadoQuiero que construyas un lector de pantalla visual.
Natan Smith ¿Quién y ahora?
Mundi MorgadoQuiero una biblioteca CSS que te permita ver la estructura de un documento. No debería usarse class
para obligarte a concentrarte en la semántica. Además, hágalo compatible con temas.
Natan SmithClaro, déjame ver qué se me ocurre.
Avance rápido una semana y tenemos lo que ahora llamamos:
Construct.css: la biblioteca CSS disponible sin clase
¿Por qué desechable? Bueno, en realidad no pretende ser un marco de estilo completo y listo para producción. Más bien, es como ruedas de entrenamiento para la semántica de documentos, con algunas líneas parachoques (piense en los bolos) para mantenerlo en el camino correcto.
Es parte de nuestro esfuerzo continuo en TandemSeven para promover la alfabetización en códigos en toda nuestra organización. A medida que más de nuestros diseñadores de UX comienzan a compartir la responsabilidad de la accesibilidad y la semántica de un proyecto, tiene sentido que construyamos de tal manera que permita que la UX y el desarrollo sean más colaborativos.
Hay cuatro aspectos principales de Construct.
Construcción: “Básica”
Primero está el Construct.css
archivo base, que aplica una apariencia bastante básica a la mayoría de los elementos HTML comunes. Mira este ejemplo de una página básica.
Construir: “Cajas”
En segundo lugar, está construct.boxes.css
. Esto distingue visualmente elementos semánticos que de otro modo serían invisibles, como: header
, main
, nav
, etc. De esa manera, uno puede ver dónde están (o no) esos elementos mientras se crea una página. Aquí hay una página con cuadros semánticos delineados.
Construir: “Tema”
En tercer lugar, la tematización es posible mediante construct.theme.css
. Esto es principalmente solo un ejemplo (inspirado en PaperCSS) de cómo hacer que la interfaz de usuario parezca “dibujada a mano”, para evitar que los observadores se obsesionen demasiado con la apariencia, en lugar de con la semántica de un documento. Aquí está el tema de ejemplo en acción.
Construir: “Depurar”
Por último, hay un construct.debug.css
archivo que resalta y señala marcas no válidas y/o problemáticas. A continuación se muestra un ejemplo retorcido de cómo “todo” sale mal en una sola página HTML. Esto se inspiró en a11y.css, aunque diverge en lo que se considera digno de mención.
Por ejemplo, decimos “divi-itis” cuando varios div:only-child
se han anidado uno dentro del otro. También estamos obstinados en type="checkbox"
estar contenidos dentro de un archivo label
. Esto es para lograr la máxima capacidad de hacer clic dentro de un espacio en blanco que de otro modo estaría muerto, entre una casilla de verificación (o radio) y su etiqueta textual.
Cualquiera o todos estos archivos CSS se pueden aplicar individualmente o en conjunto entre sí. También hay un marcador (etiquetado “¡OBTENER Construct!”) en la página de inicio de Construct que puede utilizar para obtener resultados para cualquier página web.
El bookmarklet incorporará de forma remota:
sanitize.css
construct.css
construct.boxes.css
construct.debug.css
Nuestro “reinicio” – Sanitize.css
Unas breves palabras sobre Santitize.css: fue creado por mi compañero de trabajo Jonathan Neal (autor de Normalize.css) como una forma de tener un “reinicio” de CSS semi-opinionado. Es decir, incluye muchos valores predeterminados que de todos los modos escribimos como desarrollados, por lo que es un buen punto de partida.
Tecnicamente hablando
Bien, ahora que hemos cubierto el “por qué”, profundicemos en el “cómo”.
Básicamente, todo gira en torno al uso (¿abusar?) de los pseudoelementos ::before
y . ::after
Por ejemplo, para mostrar el nombre de una etiqueta a nivel de bloque, usamos este CSS.
Etiquetas semánticas (usando ::before)
Aquí hay una versión abreviada del construct.boxes.css
archivo, para mayor brevedad. Hace que la section
etiqueta tenga un borde discontinuo y que el nombre de su etiqueta se muestre en la esquina superior izquierda.
{ background: #fff; color: #f0f; content: "section"; font-family: "Courier", monospace; font-size: 1rem; /* 10px. */ letter-spacing: 0.1rem; /* 1px. */ line-height: 1.3; text-transform: uppercase; position: absolute; top: 0; left: 0.3rem; /* 3px. */}
Mensajes de advertencia (usando ::después)
Asimismo, aquí hay un fragmento de código del construct.debug.css
archivo que genera los mensajes de advertencia de marcado. Este ejemplo en particular hace que script
se muestren etiquetas, que pueden optimizarse aún más o necesitar la atención del desarrollador: JavaScript en línea y/o externo src
sin async
.
En el caso de JS en línea, lo configuramos font-size
y line-height
en 0
porque hacemos que el elemento sea visible. Quitamos el texto de la página text-indent: -99999px
solo para asegurarnos de que no aparezca. No queremos que ese código JS aleatorio se muestre junto con el contenido legítimo de la página.
(Por favor, nunca hagas esto con contenido “real”. Es solo un truco, ¿vale?)
Sin embargo, para que aparezca nuestro mensaje de error, debemos establecer font-size
y line-height
volver a valores distintos de cero y eliminar nuestro archivo text-indent
. Luego, con un posicionamiento un poco más absoluto, conseguimos que el mensaje sea visible. Esto nos permite ver, entre el resto del contenido de la página, dónde verificar (a través del inspector DOM) el script
punto de inserción.
script:not([src]),script[src]:not([async]),script[src^="http:"] { color: transparent; display: block; font-size: 0; height: 2rem; /* 20px. */ line-height: 0; margin-bottom: 2rem; /* 20px. */ position: relative; text-indent: -99999px; width: 100%;}script:not([src])::after,script[src]:not([async])::after,script[src^="http:"]::after { background: #f00; color: #fff; display: inline-block; font-family: Verdana, sans-serif; font-size: 1.1rem; /* 11px. */ font-weight: normal; left: 0; line-height: 1.5; padding-left: 0.5rem; /* 5px. */ padding-right: 0.5rem; /* 5px. */ pointer-events: none; position: absolute; text-decoration: none; text-indent: 0; top: 100%; white-space: nowrap; z-index: 1;}body script:not([src])::after,body script[src]:not([async])::after,body script[src^="http:"]::after { top: 0;}script:not([src])::after { content: 'Move inline script to external *.js file' ;}script[src]:not([async])::after { content: 'Consider [async] for script with [src="…"]' ;}script[src]:not([src=""]):not([async])::after { content: 'Consider [async] for script with [src="' attr(src) '"]' ;}script[src^="http:"]::after { content: 'Consider "https:" for script with [src="' attr(src) '"]' ;}
Nota: algunos scripts deben cargarse de forma sincrónica. No querrás que el código de tu “aplicación” se cargue antes que el código del “marco”. Diablos, algunos JS en línea probablemente también estén bien, especialmente si estás haciendo una optimización de súper velocidad para la ruta de renderizado crítico. Estas advertencias son “tontas” en el sentido de que coinciden sólo a través de selectores CSS. Tómelos con cautela, su kilometraje puede variar, etc.
marcador JS
El bookmarklet JS mencionado anteriormente encuentra todas las etiquetas link rel="stylesheet"
y style
en la página y hace que no sean efectivas. Esto nos permite agregar nuestro propio CSS para que tome el control, de modo que los únicos estilos aplicados sean los proporcionados directamente a través de Construct.
La magia se logra estableciendo rel="stylesheet"
. rel=""
Si una hoja de estilo externa no se identifica como tal, incluso si está almacenada en caché, el navegador no aplicará sus estilos a la página. De manera similar, destruimos el contenido de cualquier etiqueta en línea style
estableciendo .innerHTML
Esto nos deja con las etiquetas todavía intactas, porque aún queremos validar que no haya etiquetas link
o style
presentes dentro de body
.
También comprobamos que no style
se utilizan demasiadas etiquetas en el archivo head
. Permitimos uno, ya que podría usarse para la ruta de renderizado crítica. Si hay un proceso de compilación para generar una página con estilos en línea consolidados, entonces es probable que se emitan a través de una sola etiqueta.
a href="javascript:( function (d) { var f = Array.prototype.forEach; var linkTags = d.querySelectorAll('[rel='stylesheet']'); var styleTags = d.querySelectorAll('style'); f.call(linkTags, function (x) { x.rel = ''; }); f.call(styleTags, function (x) { x.innerHTML = ''; }); var newLink = d.createElement('link'); newLink.rel = 'stylesheet'; newLink.href = 'https://t7.github.io/construct.css/css/bookmarklet.css'; d.head.appendChild(newLink); })(document);" GET Construct!/a
¡Adelante, consigue Construct!
Obtener Construct
Eso lo cubre bastante. Es un sencillo complemento que le ayudará a visualizar la semántica de su documento y a depurar marcas posiblemente problemáticas.
También me ha parecido muy divertido de usar. Un clic rápido en el bookmarklet de cualquier sitio suele mostrar muchas cosas que se podrían mejorar.
Por ejemplo, así es como se ve el sitio de CNN con Construct aplicado…
PS ¡Llama seguridad!
Si intentas hacer esto con el sitio de Twitter, es posible que te preguntes por qué no funciona. Al principio, esto también nos dejó perplejos. Tiene que ver con la Política de seguridad de contenido (CSP) del sitio. Esta se puede utilizar para impedir que se carguen CSS o JavaScript de forma externa y para incluir en la lista blanca dominios seguros.
Esto se puede configurar a nivel del servidor o mediante una meta
etiqueta en el archivo head
.
meta http-equiv="Content-Security-Policy" content="…" /
Lea más sobre CSP aquí.
Sé lo que estás pensando…
¿No puedes simplemente destruir esa
meta
etiqueta con JS?
En el caso de Twitter, se emite desde el servidor. Incluso si estuviera en HTML, destruirlo no tiene ningún efecto en el comportamiento real del navegador. Está bloqueado.
Bueno entonces…
¿No puedes insertar tu propia
meta
etiqueta de seguridad y anularla?
Uno podría pensar que sí, pero, afortunadamente, no. Una vez que el navegador acepta un CSP para esa página, no se puede anular. Eso probablemente sea algo bueno, aunque arruine nuestra diversión.
Supongo que sería como desear más deseos. ¡Va en contra de las reglas de los genios!
Deja una respuesta