Wextensible

Introducción

La resolución de los monitores se mide en píxeles de tal forma que los monitores usualmente vienen con una configuración mínima determinada. Inicialmente eran de 640x480 y actualmente uno típico de 19 pulgadas puede alcanzar desde un mínimo de 800x600 hasta los 1280x1024 píxeles. A más resolución más "cosas" podremos meter en pantalla pero más pequeñas se verán. Los sistemas operativos como Windows disponen de la posibilidad de cambiar la resolución para adaptarse a las necesidades visuales de los usuarios. Por lo tanto cuando se diseña la estructura de una página web hay que tener en cuenta que no puede ir dirigida a ninguna resolución particular y que, en la medida de lo posible, debería ser capaz de adaptarse a todas, al menos de las más modernas con un mínimo de 800x600 píxeles.

Una mayor complejidad sería plantearse terminales de mano donde el área de visualización es muy pequeña en comparación con un monitor de por ejemplo 19 pulgadas. Pero también existe la posibilidad de contemplar estilos específicos para estos soportes. En nuestro glosario XHTML+CSS expusimos la regla de estilo @media que nos permite configurar estilo para monitores (screen), terminales de mano (handheld), impresora (print), etc. Esto no lo contemplo actualmente en este sitio web y por tanto espero implementarlo y explicarlo en un futuro próximo.

Por lo tanto controlar como se especifican las medidas de los distintos marcos es una decisión importante que se ha de tomar antes de empezar a dotar de estilo a la estructura de la página. Usualmente se habla de tres posibilidades: medidas fijas, líquidas o elásticas. En definitiva el marco al que se debe prestar especial atención es el de contenido, que será el lugar donde el usuario tendrá que pasar mayor parte del tiempo leyendo texto o interaccionando con ese contenido. Así lo ideal sería que toda la estructura fuese capaz de adaptarse a diferentes soportes visuales sin que la apariencia de la página no se deforme en exceso.

Ejemplo de una estructura fija para una página web

En las estructuras fijas las dimensiones de los marcos, especialmente el ancho, se expresan en valores absolutos como píxeles de monitor. Realmente no son del todo absolutos sino relativos a la resolución que el usuario haya efectuado en el monitor tal como expusimos en el apartado anterior. Supongamos que hacemos una página con una estructura que pueda acomodarse al mínimo usual en todos los monitores: 800x600 píxeles.

Cuando decimos que una página tiene una estructura fija debemos entender que su estructura se especifica con dimensiones fijas. No debe confundirse con una página con marcos CSS fijados que vimos en el tema anterior, donde exponíamos un ejemplo al respecto. En esa página lo que se fija es la posición de algunos de ellos, no sus dimensiones. De hecho una página con marcos CSS fijados (o no fijados) puede realizarse con estructura de dimensiones fijas, líquidas o elásticas.

En la página de ejemplo pagina-fija-1.html puede ver el resultado, donde ponemos un marco cabecera y un pie de página así como el contenido interior, pero con un único lateral izquierdo para no complicar el ejemplo. Esquemáticamente la página se compone de los siguientes marcos.

<div id="cabeza">
    TITULO DE LA PÁGINA
</div>
<div id="lateral">
    <ul>
        <li><a href="...1</a></li>
        ...                      
    </ul>
</div>
<div id="contenido">
    ...
    <p>...contenido...</p>
    ...
</div>
<div class="borra-flotacion"></div>
<div id="pie">
    Este es el pie de página
</div> 
    

A estos elementos le aplicamos el siguiente estilo para conseguir la estructura fija. Ponemos en color azul aquellas propiedades que tienen que ver con las dimensiones que afectarán a la estructura:

div#cabeza {
    width: 750px; 
    padding: 5px;
    border: red solid 1px; 
    }
div#lateral {
    width: 100px; 
    padding: 5px;
    height: 100%; 
    float: left; 
    border: blue solid 1px; 
    }
div#lateral ul{
    padding-left: 16px;
    border: green dotted 1px; 
    }
div#lateral ul li {
    margin-left: 0; 
    }
div#contenido {
    width: 638px; 
    margin-left: 112px;
    padding: 5px; 
    border: green solid 1px; 
    }
div#contenido p {
    text-align: justify; 
    }
div#pie {
    width: 750px; 
    padding: 5px;           
    border: red solid 1px; 
    }
div.borra-flotacion {
    clear: both; 
    }    
    

El alto no suele fijarse pues es más cómodo para el usuario que el contenido se alargue verticalmente en lugar de horizontalmente. Entonces fijamos el ancho en una medida absoluta de 800 píxeles, medida que decíamos que era la considerada como mínima de ancho de monitor. Pero hay que tener en cuenta lo siguiente:

Si calculamos 800-16-16 = 768 píxeles libres para el ancho de nuestra web. Para asegurarnos en caso de que las medidas de la barra y el margen del <body> sean mayores, lo podemos dejar en 762px, de los cuáles 2px serán para los bordes derecho e izquierdo de los marcos, cada uno con un ancho de 1 píxel. Si los marcos tienen un relleno de 5px (valores de padding derecho e izquierdo), entonces nos queda un ancho libre para los marcos cabeza y pie de 762-2-10 = 750px.

Luego tenemos que fijar el ancho del lateral, que elegimos en 100px, valor no dependiente de otros marcos y que irá en función del tipo de contenido que deseemos incluir en su interior. Sumando sus rellenos y bordes, el lateral tiene un ancho final de 100+10+2 = 112px. Quedará libre para el contenido 762-112 = 650px, de los cuáles hay que restar 12px para sus rellenos y bordes quedando un ancho libre para el contenido de 650-12 = 638px.

Además el contenido debe separarse del lateral que flota a la izquierda, lo que se consigue dando un margen izquierdo con margin-left:112px que es lo que ocupa el lateral con sus rellenos y bordes. Decíamos que el alto no lo especificamos, por lo que el navegador lo considera con valor auto, con lo que alargará verticalmente los marcos para ajustar el contenido. Sin embargo hemos de especificar la altura para el marco lateral con height:100% para que la flotación de ese marco no termine en toda la altura del marco de contenido. Al final de este marco hemos de borrar la flotación para lo cual aplicamos clear:both a un bloque vacío que sólo sirve para esto.

Cuando la pantalla tiene más de 800 píxeles resultaría con una mejor estética si todo el contenido apareciera centrado horizontalmente. No es difícil conseguirlo, siendo necesario encerrar todo lo que hay en la página en otro marco <div id="total">. Le dotamos de un ancho igual que los anteriores de 762 píxeles medidos por fuera del borde, con lo que el borde del marco "total" resulta envolver todos los demás marcos. Además esta posibilidad nos da la ventaja de no tener que declarar los anchos de los marcos interiores a excepción del lateral. Esto es porque los marcos se extienden a la derecha hasta ocupar toda la longitud del marco total que los contiene, marco que si tiene un ancho especificado.

div#total {
    width: 762px;
    margin: auto;
    border: maroon dashed 1px;
    }
div#cabeza { /* no hace falta el ancho */
    padding: 5px;
    border: red solid 1px; 
    }
div#lateral {
    width: 100px; 
    padding: 5px;
    height: 100%; 
    float: left; 
    border: blue solid 1px; 
    }
div#lateral ul{
    padding-left: 16px;
    border: green dotted 1px; 
    }
div#lateral ul li {
    margin-left: 0; 
    }
div#contenido { /* no hace falta el ancho */
    margin-left: 112px;
    padding: 5px; 
    border: green solid 1px; 
    }
div#contenido p {
    text-align: justify; 
    }
div#pie { /* no hace falta el ancho */
    padding: 5px;           
    border: red solid 1px; 
    }
div.borra-flotacion {
    clear: both; 
    }     
    

Para poder central el total le damos un valor de margen igual a auto. Así nos quedaría el segundo ejemplo de estructura fija centrada en la ventana que puede ver en pagina-fija-2.html, lo que supone una mejora respecto al primer ejemplo.

Particularmente considero que son muchas las desventajas de la estructura fija. Veamos algunas consideraciones:

Ejemplo de una estructura líquida para una página web

Cuando disponemos de un elemento de bloque como el que antes usamos <div id="total"> y no especificamos nada acerca de su ancho en la propiedad width, el navegador aplica el valor auto. Entonces el ancho viene determinado por el contenedor donde está alojado ese marco el cuál es el elemento <body>, que a su vez se aloja en la ventana <html>. Así que el ancho de nuestro elemento <div id="total"> será siempre el de la ventana, restando los márgenes de 8px del elemento <body>. Esto quiere decir que el ancho del marco total se ajustará siempre al tamaño de la ventana, por lo que si además hacemos uso de las medidas relativas en porcentajes para los marcos que se ajustan horizontalmente como el lateral y contenido, podríamos conseguir que todo se reajuste también al tamaño de la ventana.

Esto es lo que se conoce como una estructura líquida. Hemos reutilizado el ejemplo anterior para construir la siguiente pagina-liquida-1.html, cuyo código HTML es exactamente igual pero con un CSS distinto:

div#total {                     /* ancho 762px */
    border: maroon dashed 1px;
    }
div#cabeza {
    border: red solid 1px;
    padding: 0.67%;             /* 5px/750px = 0.0067 */
    }
div#lateral {
    width: 13.12%;              /* 100px/762px = 0.1312 */
    height: 100%;
    padding: 0.67%;             /* 5px/750px = 0.0067 */          
    float: left;
    border: blue solid 1px;
    }
div#lateral ul{
    padding-left: 16%;         /* 16px/100px = 0.16 */   
    border: green dotted 1px;
    }
div#lateral ul li {
    margin-left: 0;
    }
div#contenido {
    margin-left: 14.70%;        /* 112px/762px = 0.1470 */
    padding: 0.67%;             /* 5px/750px = 0.0067 */
    border: green solid 1px;
    }
div#contenido p {
    text-align: justify;
    }
div#pie {
    padding: 0.67%;            /* 5px/750px = 0.0067 */
    border: red solid 1px;
    }
div.borra-flotacion {
    clear: both;
    }    
    

Las medidas que aplicamos son las siguientes:

Cómo los cálculos anteriores los hemos basado en la estructura fija, ¿quiere decir que hemos de hacer primero la fija para luego calcular la líquida?. No necesariamente. Se trata de partir de que el marco total tiene un ancho de 762 partes, que pueden ser píxeles, milímetros, picas, etc., cualquier medida absoluta pues no es determinante. Elegimos este número porque luego necesitaremos saber cuantas partes de lateral, relleno y bordes estableceremos sobre ese número y ya conocemos por la experiencia que, por ejemplo, 5 partes en 762 nos da una medida de unos 5px para una resolución de 800 píxeles de pantalla. Pero sería lo mismo que elegir para el total 1524 partes y 10 partes para el relleno, pues lo que interesa es que 5/762 = 10/1524 que da la proporción relleno/total deseada.

El ajuste de los marcos se produce con el cambio del ancho de la ventana, de tal forma que si este ancho es muy reducido puede deformar el contenido de algún lateral muy estrecho. Esto se puede arreglar incorporando la propiedad min-width al marco total, como podrá ver en el segundo ejemplo pagina-liquida-2.html que es la misma página a excepción de incorporar min-width: 650px; en el estilo de div#total. Sin embargo es necesario especificar una medida absoluta, porque las relativas en porcentajes se expresan en referencia al ancho del contenedor cuando ese ancho queda también expresamente declarado con una medida absoluta. En otro caso los porcentajes declarados en el ancho mínimo no funcionarán. Por lo tanto es un grave contratiempo pues todo es líquido menos el ancho mínimo.

Con versiones de Internet Explorer anteriores a la 8 encontramos que no implementan la propiedad min-width, aunque hay una forma de resolverlo. Se trata de poner en div#total el ancho como una expresión width: expression(body.clientWidth < 650 ? "650px" : "auto") aunque más bien parece un parche y puede dar problemas de todas formas. Con IE8 puede probar emulando IE7 poniendo <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> dentro del <head> de la página.

Veamos las siguientes consideraciones finales de la estructura líquida:

Ejemplo de una estructura elástica para una página web

Por último tenemos la estructura elástica basada en que podemos declarar las dimensiones de un elemento proporcionales al tamaño de la fuente, es decir al valor de la propiedad font-size. Una característica de esta propiedad es que se hereda automáticamente en todos los elementos que permiten incluir texto. Así podríamos crear una página entera sin declarar en ningún sitio el tamaño de la fuente, en cuyo caso el navegador proporciona un tamaño (y una familia) que viene por defecto. Por ejemplo, suelen poner por defecto la fuente Times New Roman con un tamaño de unos 16px. Este valor se va heredando de padre a hijo, de tal forma que todos los elementos tienen la misma propiedad si no se especifica otra cosa.

Entonces podemos usar tamaños de fuentes también relativos. Si en un elemento declaramos font-size: 2em significa que el tamaño de su fuente será dos veces el tamaño de la fuente del contenedor donde está albergado. Pero además esta medida relativa puede aplicarse a cualquier otra dimensión, como anchos (width), rellenos (padding), márgenes (margin) y gruesos de bordes (border-width), con lo que podemos resolver el problema que teníamos en la estructura líquida con los bordes. Es importante entender que em no es una medida, sino una proporción tal como lo es el porcentaje %.

Volvemos a tomar la página del último ejemplo tal que no es necesario modificar el HTML, aunque si cambiamos el estilo CSS. Puede ver este primer resultado en la siguiente pagina-elastica-1.html. El código de estilo es el siguiente, donde los comentarios en verde se han puesto para ver la equiparación de dimensiones con los ejemplos anteriores:

body {
    font-family: Times New Roman;
    font-size: 1em;          /* 1em equivale a 16px por defecto */
    }
div#total {
    min-width: 40.625em;             /* 650px/16px = 40.625em */
    border: maroon dashed 0.0625em;  /* 1px/16px = 0.0625em */
    }
div#cabeza {
    border: red solid 0.0625em;
    padding: 0.3125em;               /* 5px/16px = 0.3125em */
    }
div#lateral {
    width: 6.25em;                   /* 100px/16px = 6.25em */
    height: 100%;
    padding: 0.3125em;                       
    float: left;
    border: blue solid 0.0625em;
    }
div#lateral ul{
    padding-left: 1em;               /* 16px/16px = 1em */   
    border: green dotted 0.0625em;
    }
div#lateral ul li {
    margin-left: 0;
    }
div#contenido {
    /* Con el ancho del lateral del ejemplo anterior: 112px/16px = 7em
    Que es lo mismo que sumar el ancho del lateral más sus dos
    rellenos y bordes, todo sumado en em's:
    6.25em + (2 x 0.3125em) + (2 x 0.0625em) = 7em
    */
    margin-left: 7em;
    padding: 0.3125em;
    border: green solid 0.0625em;
    }
div#contenido p {
    text-align: justify;
    }
div#pie {
    padding: 0.3125em;      
    border: red solid 0.0625em;
    }
div.borra-flotacion {
    clear: both;
    }    
    

En primer lugar hay que establecer el tamaño de la fuente del cuerpo <body> y también conviene el nombre de la fuente. Así nos aseguramos que controlamos esta medida independientemente de la que por defecto se establezca para el navegador. En este ejemplo ponemos Times New Roman y 1em para poder comparar el ejemplo con los anteriores, pero podría ser cualquier otra fuente y tamaño. Lo importante es que el resto de marcos que irán dentro del <body> heredarán esta fuente y, sobre todo, su tamaño.

Luego en div#total que es el marco total que recoge toda la página, declaramos su mínimo tamaño con min-width: 40.625em, valor que podemos estimar realizando algunas pruebas, pues dependerá de la fuente elegida en el paso anterior. En todo caso ya sabíamos que podíamos darle un min-width: 650px en el ejemplo 2 de estructura líquida con ancho mínimo. Sólo tenemos que hallar la proporción 650px/16px = 40.625em, pues 1em es equiparable a 16px para una fuente como la Times New Roman. Que sea equiparable no es lo mismo que sea igual, pues todas las fuentes no tienen el mismo tamaño aparente para 1em. En todo caso es cuestión de probar algunos anchos mínimos en em's y ver el resultado.

Si nuestros marcos no tienen bordes podemos obviar poner sus anchos con em's. También podemos hacerlos todos con medidas absolutas de 1px, aunque podrían observarse pequeños desajustes en ampliaciones de zoom. En todo caso también vamos a convertir 1px/16px = 0.0625em que aplicamos a todos los marcos.

Para los marcos interiores cabeza, lateral, contenido y pie le aplicamos un relleno de 5px que serán 5px/16px = 0.3125em. Para el lateral le ponemos un valor de 6.25em, resultado de la proporción 100px/16px = 6.25em. Al igual que el relleno bien podría ser cualquier valor que se adapte a nuestras necesidades, aunque lo hacemos así para poder comparar el resultado del ejemplo con las otras estructuras. Por lo tanto es muy importante entender que aunque estamos haciendo estas operaciones, bien podríamos directamente poner una cantidad en em's y mediante prueba ir buscando el valor que más nos guste.

El cálculo del margen izquierdo del contenido que lo separa del lateral lo hacemos directamente en em's: 6.25em + (2 x 0.3125em) + (2 x 0.0625em) = 7em, siendo el ancho del lateral más dos veces su relleno y 2 veces el grueso de su borde. En este caso si es necesario hacer este cálculo, pero es mucho más sencillo que los correspondientes de las estructuras fijas o líquidas.

Una ventaja de la estructura elástica es que podemos también expresar los gruesos de los bordes en em's. Así tenemos el siguiente ejemplo pagina-elastica-2.html, cuyo código CSS queda modificado en lo que respecta al grosor de bordes, incluyendo un grosor excesivo pero necesario para ver el efecto de redimensionamiento. En el código ponemos en azul aquello que cambia con respecto al ejemplo anterior:

body {
    font-family: Times New Roman;
    font-size: 1em;          /* 1em equivale a 16px por defecto */
    }
div#total {
    min-width: 40.625em;             /* 650px/16px = 40.625em */
    border: maroon dashed 0.5em;     /* 8px/16px = 0.5em */
    }
div#cabeza {
    padding: 0.3125em;              /* 5px/16px = 0.3125em */
    border: red solid 0.5em;            
    }
div#lateral {
    width: 6.25em;                  /* 100px/16px = 6.25em */
    height: 100%;
    padding: 0.3125em;   
    float: left;
    border: blue solid 0.5em;
    }
div#lateral ul{
    padding-left: 1em;              /* 16px/16px = 1em */   
    border: green dotted 0.5em;
    }
div#lateral ul li {
    margin-left: 0;
    }
div#contenido {
    /* Con el ancho del lateral del ejemplo anterior: 112px/16px = 7em
    Que es lo mismo que sumar el ancho del lateral más sus dos
    rellenos y bordes, todo sumado en em's:
    6.25em + (2 x 0.3125em) + (2 x 0.5em) = 7.875em
    */
    margin-left: 7.875em; 
    padding: 0.3125em;
    border: green solid 0.5em;
    }
div#contenido p {
    text-align: justify;
    }
div#pie {
    padding: 0.3125em;   
    border: red solid 0.5em;
    }
div.borra-flotacion {
    clear: both;
    }    
    
    

Como se observa, el único cálculo que debemos tener en cuenta es el relacionado con el margen izquierdo del contenido, pero aún así es una operación más simple pues no involucra cálculos de proporciones sino sumas de longitudes del lateral en em's. Si actuamos con el zoom del navegador, el grosor de los bordes también resulta afectado por ese zoom de una forma adecuada. Todo el conjunto parece que ajusta mejor que con las otras estructuras.

Consideraciones finales de la estructura elástica:

Para incorporar una imagen en la barra de la cabecera de una página líquida o elástica a modo de banner, podemos usar una imagen de fondo con background-image o el elemento <img>. Hay varias razones a tener en cuenta a la hora de incluir una imagen en esta estructura. El principal inconveniente es que la imagen ha de extenderse para pantallas grandes. Si el monitor es de 1280 píxeles de ancho, la imagen no ha de ser mucho más pequeña pues perdería calidad cuando la ventana esté maximizada. Otro detalle es que al elemento <img> no podemos declararle sus dimensiones con width o height. Esto también va a hacer que la página se cargue más lentamente pues el navegador no sabrá inicialmente que espacio reservar para esa imagen.

Con la opción CSS incorporamos una imagen con la propiedad {background-image}. Este es un ejemplo de la página elástica con banner CSS. El estilo CSS modificado es:

Agregamos un fondo con {background} usando cover para extender la imagen. He agregado un color y tamaño de letra para que resalte en ese fondo. La imagen ha de ser preparada antes con un tamaño de 1000×100 píxeles, quizá demasiado grande, pero con el objeto de que al extenderse no pierda calidad. Será cuestión de probar otros tamaños menores y otras proporciones con objeto de que no sea muy pesada. La altura de la cabecera queda condicionada por el contenido HTML y no por la imagen de fondo. Para que verticalmente se presente la imagen completa habría que incrementar el alto de la cabecera, pues no podemos darle valores absolutos a {background-size} pues entonces no se readaptará al contenedor.

La otra forma es mediante un elemento <img>, con el ejemplo página elástica con banner HTML. Ahora la imagen es también el contenido de la cabecera, por lo que ésta ajustará tanto su alto como su ancho a las medidas de la imagen. El código HTML a modificar es este:

Eliminamos el padding para que la imagen ocupe toda la cabecera. Resaltamos texto y le damos un posicionamiento con valor relative pues vamos a posicionar elementos. El contenido que antes había, es decir, el elemento <a> y el texto del título, lo metemos todo en un elemento <div class="headvinc"> para posicionarlo de forma absoluta arriba y a la izquierda, a 0.7em de esa esquina. Lo ponemos en una capa más alta con z-index: 1 para situarlo sobre la imagen. Ésta irá en el fondo y al darle un tamaño de width: 100% se extenderá para ocupar toda la cabecera. Es importante notar que no podemos darle atributos width o height a la imagen, pues de otra forma tomaría esos valores. Ahora la imagen se escala en ambas direcciones presentándose completa. Aunque el alto de la cabecerá va incrementándose con el ancho de la ventana, cosa que antes no pasaba. Además el hecho de que la imagen no tenga inicialmente un tamaño declarado supone que el navegador deberá cargarla completamente para seguir renderizando el resto de la página. Y esto es una desventaja en relación con la optimización de la carga de una página, donde todas los elementos <img> deberían ser especificados en tamaño.