En los siguientes puntos se destacan algunas de las implementaciones más destacables en este sitio web.
Para crear este sitio web desde cero se han utilizado los lenguajes de programación HTML, CSS y Javascript.
Además de eso se han utilizado varias librerías para simplificar ciertos trabajos que hubieran sido bastante tediosos y también algunas integraciones. Las librerias de código abierto e integraciones que se han utilizado son Normalize, HTML5 Boilerplate, Font Awesome, Webpack, Modernizr y ChartJS. Lo que han aportado estas librerías a la web está mencionado en apartados posteriores.
De entre todas las propiedades de los lenguajes de programación que se han utilizado en esta página podemos destacar las que más impacto tienen. En concreto destaca el uso de dos CSS layouts.
"Flexbox es un método de diseño de página unidimensional para compaginar elementos en filas o columnas. Los elementos de contenido se ensanchan para rellenar el espacio adicional y se encogen para caber en espacios más pequeños." - referencia en MDN.
Las propiedades de Flexbox facilitan mucho el hecho de que las páginas web sean compatibles con cualquier dispositivo, además de sustituir a otras propiedades más problemáticas que podrían causar problemas en distintos dispositivos (como CSS float). De esta manera, los elementos de la página que estás viendo ahora mismo están hechos a medida para tu dispositivo. ¡Flexbox es tan útil que incluso en las aplicaciones móviles se utiliza! Puedes ver cómo se integra en aplicaciones nativas de Android aquí.
Observa los siguientes ejemplos:
En los dos ejemplos de arriba hay 4 cajas dentro de un contenedor, en el primer caso las cajas están en un contenedor Flexbox y en el segundo caso (derecha) están en un contenedor sin especificar la propiedad "display: flex", por tanto tomará el valor por defecto "display: block". Si redimensionas la ventana del navegador podrás comprobar que en ambos ejemplos las cajas de colores cambian su tamaño, aunque no de la misma manera.
Esto sería lo que define el ancho de las cajas de colores en el primer ejemplo:
div div{
flex: 20%;
}
Podemos usar esta propiedad ya que el contenedor padre es flexible (Flexbox). Las cajas que hay en su interior pueden redimensionarse usando como referencia el ancho del contenedor que antecede al contenedor padre, en este caso la página entera (body). Además si estableciésemos otras propiedades también podríamos determinar en las proporciones en la que crecen por lo que tenemos total control sobre ello.
Por otro lado, esta es la propiedad que define el ancho de las cajas de colores en el segundo ejemplo:
div div{
width: 20%;
}
Se toma como referencia el ancho del contenedor padre. Si quisiéramos conseguir el mismo tamaño que en el primer ejemplo, tendríamos que añadir más ancho a cada contenedor y se descuadrarían las medidas dando problemas de desborde de página en ciertos anchos de pantalla (sobre todo en móviles). Por supuesto sería aún mucho más complicado que la página se adaptase a todos los dispositivos si las cajas tuviesen un ancho fijo.
Flexbox cuenta con varias propiedades bastante útiles para reducir errores en las páginas y conseguir ahorrar líneas de código, sobre todo en proyectos más complejos. Aunque el funcionamiento de sus propiedades puede llegar a resultar más confuso que otras propiedades como CSS float o margin, sus resultados merecen la pena.
En el ejemplo del contenedor flexible también se puede observar como las cajas se distribuyen uniformemente ocupando todo el espacio disponible. Es más, si redimensionaste la ventana habrás comprobado que la colocación de las mismas varía según el ancho de pantalla. Los dos ejemplos que están más abajo tienen exactamente el mismo código, solo varía el ancho del contenedor padre:
Al redimensionar la ventana, las cajas van cambiando de posición para no colapsar el contenedor padre. Esto se debe a la propiedad "flex-wrap: wrap;". Este es el código CSS (relacionado con Flexbox) de cada una de las cajas en el primer ejemplo:
div div{
display: flex;
justify-content: center;
align-items: center;
flex: 10%;
}
Y el código de los contenedores padre (relacionado con Flexbox):
div{
display: flex;
justify-content: space-between;
flex-direction: row;
flex-wrap: wrap;
}
Todas estas propiedades se usan constantemente en este proyecto. Puedes consultar todas las propiedades del layout de CSS Flexbox en W3schools o con más detalle en la última especificación hasta la fecha de W3C.
Flexbox es muy ventajoso en la mayoría de ocasiones, pero a veces puede llegar a resultar tedioso, sobre todo cuando tenemos un archivo HTML con demasiados elementos que funcionen como contenedores. En esos casos CSS grid es muy conveniente.
"CSS Grid layout contiene funciones de diseño dirigidas a los desarrolladores de aplicaciones web. El CSS grid se puede utilizar para lograr muchos diseños diferentes. También se destaca por permitir dividir una página en áreas o regiones principales, por definir la relación en términos de tamaño, posición y capas entre partes de un control construido a partir de primitivas HTML. Al igual que las tablas, el grid layout permite a un autor alinear elementos en columnas y filas. Sin embargo, con CSS grid son posibles muchos más diseños y de forma más sencilla que con las tablas. Por ejemplo, los elementos secundarios de un contenedor de cuadrícula podrían posicionarse para que se solapen y se superpongan, de forma similar a los elementos posicionados en CSS." - referencia en MDN.
Para ver cómo CSS grid facilita el trabajo vamos a ver un ejemplo más abajo. Pongamos que necesitamos crear un contenedor principal que contenga 6 contenedores hijos en su interior (todos siendo elementos div). De entre los elementos hijos, queremos que la primera caja ocupe todo el ancho disponible (100% del contenedor padre), la segunda y la tercera caja que ocupen la mitad del ancho disponible (50% del contenedor padre cada una) y las 3 cajas restantes deben ocupar 50%, 25% y 25% respectivamente y en su misma fila. Además queremos que queden distribuidas verticalmente así: 1 div-2 div-3 div. Si lo hiciérmos con Flexbox no habría una manera de que estos elementos ocuparan siempre la posición que le corresponde sin escribir mucho más código y sin crear cajas adicionales para cada fila dentro del grid. Observa el ejemplo abajo:
Primero creamos los divs con texto en su interior. Aún no hemos escrito el CSS que va a posicionar los elementos. Ten en cuenta que cada caja es independiente pero no existe ningún margen entre ellas.
Esto sucedería si hiciésemos el grid usando Flexbox:
Como se ve en el ejemplo, no hemos obtenido el resultado deseado. Los elementos no se encuentran distribuidos verticalmente quedando en cada línea 1, 2 y 3 elementos respectivamente. Además de eso, podríamos pensar que en las últimas 3 cajas podemos utilizar un ancho porcentual que utilice como referencia el ancho de la página, pero este tomará como referencia el ancho del contenedor padre, y es con Flexbox no se puede redimensionar un elemento nada más que utilizando como referencia al elemento padre, tampoco las propiedades de float con display:block. Volviendo al ejemplo, el efecto que queremos conseguir se puede lograr o bien creando más cajas con display: flex (sería una por cada línea o fila de la "tabla") o utilizando CSS grid. Además hay que tener en cuenta que no llegaremos a conseguir un ancho exacto a menos que utilicemos Javascript, por lo que en realidad ninguna propiedad de CSS puede hacer esto de manera fácil aunque CSS grid se le acerca mucho (más detalles en dev.to).
Vamos a usar CSS grid para posicionar los elementos. Primero vamos a definir nuestro grid (distribución parecida a una tabla). Tendrá 3 filas y 4 columnas (aunque luego solo aparecerán 3 columnas en la última fila). Usamos las siguientes propiedades de CSS para el contenedor padre:
div{
display: grid;
grid-template-columns: repeat(4, 25%);
grid-template-rows: 20vh auto auto;
}
Aunque hemos definido que hay 3 filas y 4 columnas, solamente se llenan 2 filas. ¿Por qué sucede esto? Porque las cajas en el interior por defecto solo ocupan 1 cuadrícula de la tabla y no tenemos más elementos para llenar las dos últimas filas. Vamos a cambiar esto definiendo la posición de cada caja. No estamos definiendo el ancho de los contenedores hijos solo su posición en el contenedor padre. Esto también es una ventaja con respecto a Flexbox u otros layouts, ya que podemos reordenar las cajas usando CSS a nuestro antojo y es más útil aún cuando utilizamos Javascript, ya que solo habría que inyectar código CSS para cambiar la posición de los elementos como queramos.
A continuación se muestran como ejemplos el CSS de la caja 1, la caja 3 y la caja 6:
div div.caja-1{
grid-row: 1 / 2;
grid-column: 1 / 5;
}
div div.caja-3{
grid-row: 2 / 3;
grid-column: 3 / 5;
}
div div.caja-6{
}
La caja 1 toma todas las posiciones en las columnas y la primera fila. La caja 3 toma 2 posiciones en las columnas y una en las filas. La caja 6 toma una posición en las columnas y otra en las filas. Observa como en la caja 6 no ha hecho falta escribir código para posicionarla en el grid, y es por que no hace falta que le demos los valores que ya tienen por defecto (ocupar una "celda" en el grid). Así es como se vería:
Acabamos de obtener una plantilla muy sencilla de programar y que además se va a adaptar a cualquier dispositivo sin perder la posición de sus elementos. Prueba a redimensionar la ventana del navegador para comprobarlo. Es más, acabamos de construir una plantilla básica para un sitio web en la que solo faltaría añadir el contenido:
En esta página web se han utilizado propiedades de reciente incorporación y también experimentales. Por eso a día de hoy muchas de ellas no son compatibles con todos los navegadores o dispositivos, es por eso que además se han tenido que utilizar otras técnicas para evitar que los dispositivos no compatibles con estas características puedan seguir viendo la web correctamente (esto se trata más adelante en el apartado 5). Algunas de las propiedades nuevas (en el momento de escribir esta página) son subgrid, el atributo srcset, @page size, Flexbox gap property o ciertas funciones matemáticas para tamaños. Otras no son compatibles aún con ningún navegador al estar en fase experimental, como @media scan. Además en la página se incorporan formatos de última generación para las imágenes (ver apartado 4).
Pese a que es bastante fácil acceder a cualquier contenido en la red, no es tan fácil encontrar algo entre la inmensidad de contenidos que hay en internet y es por eso que siempre solemos recurrir a un motor de búsqueda (como Google o Bing). Los motores de búsqueda indexarán todo el contenido que esté en internet a menos que manualmente se indique lo contrario. Sin embargo, los resultados de búsqueda se ordenan siguiendo una serie de parámetros que seleccionan resultados de calidad y adecuados a cada usuario. Es más, existe toda una profesión dedicada a estudiar cómo mejorar los resultados de búsqueda de los sitios web en los buscadores: especialistas en SEO.
Sobre todo a la hora de crear una web para una empresa, sería beneficioso que apareciese en las primeras páginas de los resultados de Google para atraer a más visitas y por tanto a mas clientes. De entre los aspectos que la inteligencia artificial del buscador de Google tiene en cuenta algunos de ellos son la estructura y el contenido de la página, la velocidad de carga, la adaptación del contenido a las palabras clave, etc (más información sobre cómo funciona la búsqueda de Google en su guía de SEO). Por eso, además de utilizar algunas metaetiquetas (apartado 6) también debemos mejorar el rendimiento de la página lo máximo posible para que Google la considere óptima.
Es recomendable seguir las directrices de contenido de Google para ganar tráfico al sitio web. Además, entre estas directrices se encuentran algunas que premian a los sitios web que utilizan las funcionalidades más nuevas de los distintos lenguajes de programación, nuevos formatos de archivo, compatibilidad con nuevos estándares (como los asistentes por voz) o lo que tienen compatibilidad con los resultados de búsqueda enriquecidos, funciones de accesibilidad, integraciones nativas en dispositivos móviles, etc.
Para comprobar el rendimiento del sitio como si lo revisara un robot de Google se ha utilizado la API de PageSpeed Insights integrada en Lighthouse. Después de haber subido todos los archivos del sitio web a un servidor de prueba, se procedió a utilizar Lighthouse. Estos son los resultados de que se obtuvieron a partir de la página principal:
Pese a que la puntuación podría mejorar, es óptima para los usuarios con los dispositivos creados hasta la fecha en la que se hizo la consulta.
Las incorporaciones al sitio web que fueron necesarias para mejorar este resultado se encuentran descritas en las secciones posteriores a esta.
Los archivos multimedia están presente en la mayoría de sitios web. Hay que tener en cuenta que representan un peso importante en el tiempo total de carga de cualquier sitio web. Es por eso que hay que optimizarlos al máximo para hacer que la web cargue lo antes posible, sin perder calidad. Además estos archivos deben ser compatibles con todos los dispositivos desde los que se visualicen y el formato en el que se guarden es crucial para ello. En este sitio web solamente se han utilizado imágenes y para optimizarlas se han tratado tres aspectos:
En el código HTML y CSS se han utilizado propiedades específicamente dedicadas a maximizar la compatibilidad de las imágenes y también reducir la velocidad de carga. Además, algunos aspectos básicos como el tamaño que se defina en el código CSS o las políticas de caché eficientes también influyen. Dos propiedades destacadas son el atributo srcet y la etiqueta picture, ambas de HTML.
El atributo srcset es bastante útil y se puede utilizar de distintas maneras según la etiqueta a la que complemente o el valor que se le de (más allá de las rutas de imagen). Por ejemplo, se puede utilizar como atributo en las etiquetas img para enlazar imágenes de distintos tamaños que se cargarán en función del tamaño y resolución de pantalla ahorrando así recursos. Si lo usamos de la manera anteriormente mencionada, también se podrá especificar de dos formas distintas, ya sea indicando el ancho o las ampliaciones de una imagen con respecto a la original (Ejemplo 1 // Ejemplo 2).
Por otro lado el atributo srcet también se utiliza dentro de las etiquetas picture. Las etiquetas picture están solamente dedicadas a servir una imagen en distintos formatos para maximizar la compatibilidad. En muchas ocasiones el atributo srcet ese mucho más práctico, ya que también puede proporcionar las imágenes según la compatiblidad del navegador con el formato (además de según el ancho de pantalla).
El uso de estos atributos es una de las tantas cosas que un usuario común no aprecia a simple vista, pese a que son pequeños granos de arena que contribuyen a optimizar el rendimiento de la página que finalmente se aprecia. Puedes comprobar en las imágenes que hay en esta misma página cómo si la abres en una pestaña nueva aparece la imagen en el formato más conveniente que soporta tu dispositivo y navegador.
Las imágenes suelen ser bastante pesadas en multitud de ocasiones. Esto puede afectar a la velocidad de carga de una página web, siendo uno de los principales factores por los que una página web carga lentamente. A esto se le suma la gran cantidad de imágenes que pueden llegar a coexistir en una misma página. Es por eso que es muy conveniente comprimir las imágenes pesadas en formatos que no tengan una compresión óptima por si mismos.
Las imágenes de esta página web en formatos jpg, png, jpeg 2000 y gif se han comprimido aproximadamente un 60% produciéndose una mejora significativa en la velocidad de carga de la pagina.
Pese a que en el apartado anterior se menciona que las imágenes en los formatos más convencionales se han comprimido para mejorar la velocidad es carga, es muy probable que las imágenes que estés viendo ahora mismo en tu navegador no sean las extensiones de imagen que se han comprimido.
Como ya se ha mencionado, todas las imágenes de esta página contienen fuentes alternativas para cada imagen única utilizando el atributo srcset o la etiqueta picture. Esto significa que por cada imagen que existe en la página existen al menos 2 copias idénticas pero con distintas extensiones de imagen. ¿Y por qué hacer eso cuando sería mucho más fácil subir el formato más óptimo? La respuesta tiene que ver con la compatibilidad entre dispositivos y navegadores. Las extensiones de imagen están ordenadas por orden de prioridad y el navegador va a mostrar la extensión de imagen que se encuentre más arriba en ese orden de prioridad y que a la vez sea compatible con el dispositivo y/o navegador.
Las extensiones clásicas como los jpg o png comunes no darán problemas, pero sí podrán dar problemas otros formatos de imagen como WebP, AVIF o Jpeg XL. Utilizamos estas extensiones de última generación porque tienen mejores perfiles de compresión, así la misma imagen con la misma calidad ocupará mucho menos en WebP que en jpg.
Las imágenes del sitio tienen este orden jerárquico:
De esta manera el 100% de usuarios a esta web verán todas las imágenes correctamente, el 90% verá imágenes optimizadas en WebP y el 63% verá imágenes en AVIF de última generación.
En la actualidad la mayoría del tráfico web pasa por un dispositivo móvil. Es más, existen multitud de dispositivos con características muy diversas (dimensiones de pantalla, dispositivos de entrada, resolución, sistemas operativos, velocidad de acceso a internet...). Por esta razón es fundamental adaptar un sitio o aplicación web para que funcione correctamente en cualquier dispositivo y/o navegador. Para logralo, en este sitio web se han utilizado las siguientes propiedades:
Ya se ha hablado de flexbox en apartados anteriores. Son precisamente las facilidades que este layout da a la hora de cambiar la distribución de los elementos y redimensionarlos las principales ventajas en cuanto a adaptación a dispositivos de cualquier tipo.
"Las media queries le permiten adaptar su sitio o aplicación dependiendo de la presencia o el valor de varias características y parámetros del dispositivo. Son un componente clave del responsive design. Por ejemplo, una consulta de medios puede reducir el tamaño de la fuente en dispositivos pequeños, aumentar el relleno entre párrafos cuando se ve una página en modo vertical, o aumentar el tamaño de los botones en las pantallas táctiles." - referencia en MDN.
Se han utilizado una gran cantidad de media queries en este sitio web. Esencialmente, las propiedades CSS que van definidas entre media queries solo se van a aplicar a los dispositivos que cumplan con los requisitos que se definen. Estos requisitos pueden ser un ancho determinado, la disponibilidad de un ratón, la orientación de un dispositivo móvil, la resolución, el color, etc.
Las propiedades que suceden a esta at-rule van a afectar solamente a los dispositivos que tengan un ancho definido en el rango que se establece en esta media query. Son las más comunes ya que conociendo el ancho de pantalla podemos programar propiedades distintas para dispositivos móviles. Los teléfonos móviles tendrán un ancho mucho menor que el de una pantalla de escritorio.
Puedes observar el ejemplo de abajo. En este caso aparece desde que dispositivo estás viendo esta página basándose en el ancho de la pantalla del navegador. Si estás en un ordenador minimiza la pantalla del navegador y observa como el texto cambia al alcanzar cierto ancho de ventana.
Con @media print podemos cambiar la apariencia de la página para adaptarla al formato de impresión. Esto es, al hacer clic en imprimir desde el navegador la página que aparecerá en formato impresión estará condicionada por las propiedades que sucedan a @media print. Además también se pueden complementar estas propiedades con las más recientes bajo la @page at-rule (con compatibilidad limitada en estos momentos).
Detecta la orientación del dispositivo en función de la relación de píxeles entre ancho y alto. Es decir: si se detecta por ejemplo unas medidas de 500px (w) x 1000px (h) (ratio 1:2) entonces se determinará que el dispositivo tiene una orientación vertical. Si se quiere obtener la información exacta de la orientación de un dispositivo móvil sería necesario utilizar javascript u otros lenguajes de programación.
Detecta la presencia de un ratón o cursor, su ausencia o si este cursor es de precisión limitada. Esto es de mucha utilidad por ejemplo a la hora de hacer botones que se puedan pulsar con facilidad en las pantallas táctiles.
Detecta si el dispositivo es compatible con los efectos hover.
"@supports otorga la habilidad de realizar consultas que comprueben si ciertas funcionalidades están disponibles (feature query)." - referencia en MDN.
El navegador devuelve datos sobre si soporta determinada propiedad de CSS o no y podemos definir acciones para adaptar el contenido en consecuencia.
Al diseñar para todos los dispositivos es muy importante tener en cuenta que hay que utilizar tamaños relativos para que la página web se visualice correctamente y la experiencia de usuario sea óptima. Generalmente esto se puede conseguir con valores porcentuales (%), valores con respecto al ancho o alto de la ventana (vh, vw) o variables de CSS (--var).
Sin embargo, a veces puede resultar complicado, ya que aunque los tamaños son relativos es probable que no deseemos que, por ejemplo, los márgenes de la página tomen el valor de 5% en todos los dispositivos (porque sería un gran espacio para las pantallas 4K y un espacio mínimo para los dispositivos móviles). Es por eso que existen funciones matemáticas que podemos utilizar al definir el tamaño de los elementos.
En esta página web se han utilizado bastante, empezando por los propios márgenes de la página que ahora mismo estás viendo. Si estás en un ordenador redimensiona la pantalla para comprobar que los márgenes no se adaptan de manera consistente. Eso es porque el tamaño de los márgenes está condicionado por una función clamp(). Más información sobre estas funciones en web.dev.
Modernizr es una de las librerías que se han utilizado para este proyecto y tiene un funcionamiento similar al de @supports en CSS, con la diferencia de que también funciona para Javascript y además tiene una compatibilidad del 100% con todos los dispositivos (es paradójico que @supports no funcione en algunos navegadores cuando es una propiedad diseñada para aumentar la compatibilidad).
Ya se ha mencionado la importancia del SEO, por eso es necesario facilitar el trabajo a los buscadores como Google para aportar la mayor información posible y aparecer en los resultados de búsqueda (incluyendo los de búsqueda enriquecida).
Los artículos científicos se han marcado con microdatos siguiendo las indicaciones para publicaciones académicas de schema.org.
En algunas páginas se han utilizado las etiquetas de Open Graph para modificar los metadatos que aparecen al compartir alguna de las páginas en redes sociales. Más información sobre el protocolo Open Graph creado por Facebook.
Se han seguido varias indicaciones de web.dev para mejorar la velocidad de carga de la página hasta llegar al tiempo recomendado. Más información sobre la velocidad de carga en web.dev.