Do not speak Spanish? Read this post in English.

Viernes, 18 d mayo d 2012.

CSS3 “display:box”: Maquetación con el modelo de caja flexible

Hacía mucho que no escribía un post sobre desarrollo puro. Quizás demasiado. Esta claro que a algunos no os va a a interesar en absoluto, pero a veces hay cosas que aprendes y que debes compartir.

Como sabéis (si me leeis, claro) no me gusta quedarme en las modas y juzgar la utilidad de las nuevas tecnologías por sus aspectos más espectaculares, sino por lo que aportan en su día a día. El mundo del desarrollo web esta plagado de estas modas y valoraciones de tecnologías completas por sus detalles puntuales más vistosos. Pasó con ajax, con los frameworks javascript, con canvas y ahora con HTML5, CSS3 y las nuevas funciones de javascript.

En este caso quisiera tocar una de las mejoras más importantes que se nos vienen encima con CSS3 y que sin duda, una vez se estandarice del todo conseguirá que la mayor parte de los problemas de maquetación actuales desaparezcan: el modelo de caja flexible.

Antecedentes del modelo de caja

Css nunca ha sido un sistema cómodo. Recordemos que CSS es el sistema por el cual se crean las indicaciones para aportar los elementos de diseño a los elementos del HTML. Un HTML por si solo (salvo aberraciones varias) no tiene estilos: es texto, titulos y listados agrupados en una estructura más o menos semántica. Bien pues este sistema, como tantos otros, se quedó anclado en el pasado durante mucho tiempo -demasiado!-y ahora empeza a dar su siguiente paso. Actualmente la inmesa mayoría de páginas web están maquetadas con CSS 2.1 y cada vez más vamos viendo como distintas etiquetas de CSS 3 empiezan a ser usadas por distintos motivos.

Algunas nos son muy comunes: Bordes redondeados, fondos con degradados, sombras, fuentes, etc. Hemos leido mil artículos sobre como implementar estas propiedades de css3 en distintos navegadores con un éxito cada vez mayor. Como siempre el lastre nos lo trae Internet Explorer en sus versiones antiguas: de la 6 a la 8 o incluso la 9. Pero la verdad es que el tema tiene miga y hay que perder mucho tiempo aprendiendo a sacar partido a CSS3 en la mayoría de los navegadores.

Entre las distintas propiedades de CSS3 hay unas que realmente pueden cambiar nuestra forma de maquetar las webs haciéndolo todo mucho más cercano a como siempre debería haber sido: El modelo de caja flexible.

Para entender porque este detalle es tan importante debemos comprender el modelo de caja clásico de CSS. En este modelo cada elemento HTML puede ser una Caja -un bloque, un rectángulo en el diseño, etc. Como queramos llamarlo-. Pero en css2.1 las distintas formas por las que las cajas van colocándose en el diseño de nuestras páginas empujándose unas a otras para ir formando nuestras páginas es bastante peculiar y sobretodo poco cercano a como concebimos esos objetos en el espacio de forma natural. Efectivamente, el CSS2.1 actual las cajas se empujan unas a otras lo que hace que muchos elementos aparezcan donde los vemos como resultado de ser empujados por sus elementos anteriores. Eso unido a distintas peculariedades sobre como se realiza este proceso forma un pequeño caos que trae de cabeza a los maquetadores menos experimentados y que solo con experiencia se supera.

Pero todo eso va a desaparecer. Era demasiado evidente que esto suponía un problema y por lo tanto en CSS3 se ha creado un nuevo modelo de Caja que se crea con distintas propiedades y que permite ubicar los elementos indicando las relaciones entre distintos elementos y sus tamaños de forma que la forma de crear el CSS resulta mucho más cercana a como la percibimos nosotros.

¿lo vemos?

Pasos previos para poder usar el modelo de caja flexible de CSS3

Lo primero que tenemos que solucionar si queremos maquetar de esta forma es cómo conseguiremos que nuestros diseños se vean correctametne en un número decente de navegadores. Deberemos validar que lo que creemos se vea bien en un volumen de usuarios de nuestro site bastante elevado (99%, 98%...) por lo que sí o sí nos vamos a encontrar con Internet explorer.

Aquí os indico una metodología pero podréis encontrar muchas más por internet basadas en otros sistemas.

1) Evolucionar Internet Explorer al menos hasta IE9

Para esto, tenemos un código Javascript en Google Code que podemos usar y que realiza la mayor parte de las aproximaciones por si solo. Si lo cargamos en un tag html condicional conseguiremos este proceso creando más carga de página tan solo para los navegadores antiguos. Yo lo tengo claro: si eres un usuario que aun sigues con ese tipo de herramientas el tiempo de proceso no te preocupa mucho. Pero es mi opinión.

Bueno, pues incluimos este tag al principio del "head" de nuestro HTML y ya tendremos unos navegadores mucho más compatibles:

<!--[if lt IE 9]><script src="//ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script><![endif]-->

Ni que decir, que si además nos bajamos el JS en nuestro servidor para no llevarnos sorpresas y no provocar demasiada resolución de DNS al navegador, mejor que mejor.

Bien, ya hemos solucionado la mayor parte de nuestros problemas.

2) Llevar al menos el modelo de caja flexible al de IE10

Pero esto no resulta suficiente. El modelo de caja flexible no funciona ni siquiera en Internet Explorer 9. Si que podremos usar gran parte de las propiedades nuevas de CSS3 el modelo de caja no acabará de funcionar.

Solución? La misma, usaremos una librería Javascript con un tag condicional para IE menores que el 10 que arregle estos problemas por si solo.

En este caso os presento Flexie.js un script que realiza el trabajo perfectamente por si solo y que está probado en multitud de webs. En este caso no nos va a quedar otra que bajarnos el código y copiarlo en el servidor. Así que deberemos acudir a la web de Flexie.js y bajarnos el archivo. Después lo añadiremos al final de nuestro "head"

<!--[if lt IE 10]><script type="text/javascript" src="/js/flexie.js"></script><![endif]-->

Por si lo deseamos y pese a que no suele ser muy importante, flexie.js también hará funcionar el modelo de caja flexible en Opera 10 y superiores y corregirá algun detallito de otros navegadores. Así es decisión nuestra si lo indicamos con un tag condicional o se lo hacemos cargar a todos los usuarios.

3) Evitar el uso de los prefijos para CSS3 que usan algunos navegadores

Otro de los detalles de la implantación de CSS3 es que muchos navegadores se lanzaron a la aventura de implementarlo pero dado que eran sus primeros pasos en esta aplicación, no se atrevieron a usar los nombres depropiedades reales de CSS. Así que crearon propiedades nuevas añadiéndoles un prefijo a las reales. (por ejemplo firefox usa -moz-[nombre de propiedad]). Esto obliga a inundar nuestro CSS de gran cantidad de etiquetas de este tipo para poder tocar un poco de CSS3. A mi no me resulta nada adecuado este sistema: haces más grandes tus CSS, los haces mucho más difíciles de mantener y te facilita más equivocarte.

Por eso, y como recomendación final, os indico un tercer código javascript que se encarga de estos problemas. Se trata de cssFX y hace precisamente eso: transformar un CSS3 sin prefijos ni tonterias en la versión que necesita el navegador que está cargando la web. Por lo tanto nos permite maquetar a día de hoy con las propiedades reales de CSS.

Así que otra vez más, lo subimos a nuestro servidor y lo incluimos detrás de la carga del CSS en nuestro head del HTML y etiquetamos las llamadas a archivos CSS que contengan propiedades CSS con la clase "cssfx"

<link class="cssfx" rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
<script type="text/javascript" src="/js/cssfx.min.js"></script>

Y esto, ¿No es mucho javascript?

Sí, es mucho. Vivimos un momento en el que la carga de página es un factor relevante de nuestras webs y además de todo esto seguramente vamos a cargar un framework Javascript y algunos eventos. Muchos de estos archivos tan solo van a afectar a algunas versiones de Internet Explorer pero eso no es excusa: Sin duda es mucho.

Pero estos añadidos no solo nos van a solucionar tan solo el tema del modelo de caja flexible sino que nos van a facilitar en gran medida la maquetación en CSS3 permitiéndonos adelantarnos unos años en nuestros trabajos. Sin duda sigue siendo pronto para hacerlo todo en CSS3, pero algunos proyectos con mucha continuidad pueden tener sentido.

En definitiva tu decides... Para mi, por ejemplo, usar cssfx para ahorrarme gran cantidad de carácteres en el CSS merece la pena y usar CSS3 para ahorrarme muchas imágenes de fondo también. Pero sin duda depende del uso que vayas a hacer.

EL nuevo modelo de caja flexible de css3

Bien, nuestro sistema ya debería soportar el nuevo modelo de caja flexible. Así que vayamos a ver de que va todo esto:

Vayamos con la base: El nuevo modelo de caja se basa en un sistema de contenedores flexibles que afecta todos los elementos HTML con posicionamiento no absoluto que sean directamente hijos de uno de estos contenedores. En otras palabras, este modelo debe declararse en algunos elemetos de bloque del HTML; pero al declarar cualquier elemento con este modelo a quien realmente afectaremos será a todos sus elementos hijos (pero solo al primer nivel de estos).

Así pues hay dos tipos de elemento a tener en cuenta al usar este modelo de caja:

- El contenedor: que se comportará como si fuese un elemento con display:block.

- Y sus hijos inmediatos: que entrarán en este nuevo mundo del modelo de caja flexible.

Nota: Este modelo no se va a comportar bien con elementos "float", por lo que al usarlo debemos evitar usar estas propiedades en todos los elementos hijos. Por otro lado, gracias a este nuevo modelo, los float van a carecer de sentido en nuestras webs.

Nota 2: Esto solo va a afectar a los elementos hijos inmediatos sin posicionamiento absoluto. Esto significa que los elementos dentro de estos elementos hijos no se verán afectados y que si posicionamos algún elemento en "position:absolute" este elemento ni será afectado por el modelo de caja flexible ni se tendrá en cuenta para calcular como se comportan el resto de sus elementos hermanos. Esto que en un principio puede parecer rebuscado, en realidad nos da la oportunidad de jugar mucho con este sistema.

Como funciona

Para implementarlo usaremos al menos 3 propiedades -2 nuevas y la tipica de display- en el elemento contenedor que serán las que definan pero luego veremos que podemos añair algunas más.

Esto es lo más curioso de este sistema: Nosotros vamos a ir incluyendo propiedades en el elemento contenedor, pero estas no van a afectar a la apariencia, tamaño o posición del contenor, sino de sus elementos hijos inmediatos no posicionados en absoluto.

Así pues, lo que tenemos que hacer es comprender qué propiedades son estas y como van a afectar al resultado:

display:box;

Este es el principio de la declaración de modelo de caja. Recordemos: nuestro elementos se comportará como si fuese un display:block pero serán sus elementos hijos los afectados.

#miContenedor{ display:box; }

box-orient: (vertical, horizontal )

Esta propiedad indíca en que eje se van a repartir las cajas flexibles hijas de este contenedor. Si usamos "box-orient:horizontal", estas se distribuirán en el eje X si indicamos "box-orient:vertical" lo harán en el "Y".

Por lo general en la mayoría de los casos usaremos el horizontal para crear columnas o separaciones equitativas entre elementos. El vertical se usará para aquellos casos puntuales en los que necesitabamos hacer crecer las alturas de todos los elementos para que sean iguales y para distribuir elementos en un bloque vertical (como un sidebar, por ejemplo).

Por defecto (si no se indica) esta propiedad está marcada como "horizontal" pero yo os recomendaría empezar indicándola siempre o os podéis liar un poco al principio.

Nota: También podéis encontrar documentación que os hable de block-axis o inline-axis como valores para box-orient. Pero por lo general no son necesarios.

#miContenedor{ display:box; box-orient:horizontal;}

box-align: ( stretch, start, end, center)

Box-align es la propiedad complementaria de box-orient y se encarga de definir como ocuparán es espacio disponible en el eje contrario al definido a box-orient. Es decir, si yo indico un "box-orient:horizontal", al estar los elementos hijos distribuidos por el eje X, box-align definirá como se colocan estos en el eje Y. Al revés sucederá para "box-orient:vertical".

Así pues los distintos valores determinan distintas formas de ocupar este espacio:

  • box-align:stretch
    Hace que los elementos hijos se estiren por si solos hasta ocupen todo el espacio disponible en el elemento contenedor.
    Así pues en un "box-orient:horizontal; box-align:stretch" los elementos hijos se distribuirán por el eje X ocupando de alto toda la altura del elemento contenedor.
  • box-align:start
    Hace que los elementos no se estiren por si solos y se alineen al principio del espacio disponible (arriba o a la izquierda dependiendo de la orientación).
    Así pués en un "box-orient:horizontal; box-align:start" los elementos hijos se distribuirán por el eje X ocupando tan solo lo que les corresponde y situándose alineados a la izquierda del elemento contenedor.
  • box-align:end
    Actúa exactamente al revés que "box-align:end"
    Así pués en un "box-orient:horizontal; box-align:end" los elementos hijos se distribuirán por el eje X ocupando tan solo lo que les corresponde y situándose alineados a la derecha del elemento contenedor.
  • box-align:center
    Hace que los elementos no se estiren por si solos y se alineen en el centro del espacio disponible del eje contrario.
    Así pués en un "box-orient:horizontal; box-align:center" los elementos hijos se distribuirán por el eje X ocupando tan solo lo que les corresponde y situándose alineados en el centro del contenedor para el eje Y.

Por defecto esta propiedad (si no se indica) está asignada a "stretch" -que por otro lado es la que se usa el 90% de las veces- pero para empezar, como antes es recomendable indicarla igualmente para ser consciente del modelo de cajas que estamos creando.

#miContenedor{ display:box; box-orient:horizontal; box-align:stretch;}

Parémonos a pensar...

La explicación es algo liosa, pero una vez comprendida no es un concepto complejo. Al final lo que nos aportan estas propiedades es un sistema por el cual distribuir una lista de items en el espacio que aporta el bloque contenedor. Por lo tanto tenemos que dejar de ver como los elementos se empujan y pasar a crear contenedores con espacios fijos en nuestro diseño y a distribuir sus elementos internos.

Esto es lo que comentábamos al principio. Este modelo es mucho más cercano a como comprendemos los diseños. Diseñamos un bloque luego nos preocupamos de rellenar su interior lo cual nos da mucha más libertad en nuestros diseños y va a hacer más fácil cumplir alguno de esos diseños imposibles que a veces nos llegan.

Para terminar de entenderlo nada mejor que una herramienta práctica. Flexie.js, la misma herramienta que nos permitía aplicar este modelo de caja a varios navegadores nos da una herramienta con la que poder probar como van cambiando distintas cajas al cambiar sus propiedades.

Así que podemos entrar en Flexbox Playground y jugar con los distintos valores de "Box Orient" y "Box Align" para teminar de comprender estos conceptos. ¡Pruebalo!

En esta misma herramienta también encontraréis otras propiedades con las que jugar y que dan aún más posibilidades al sistema. Veamoslas...

Otras propiedades del contenedor en el modelo de caja flexible de css3

Siguiendo con propiedades que asignar al contenedor para afectar a sus cajas hijas, tenemos dos más que pueden resultarnos útiles para algún caso concreto. Estas propiedades son ya más particulares por lo que quizás es mejor empezar sin usarlas mucho y añadirlas solo para solucionar algún caso concreto.

box-direction: (normal, reverse)

Esta propiedad nos permite cambiar el orden en el que se colocan las cajas hijas en el eje indicado por la propiedad "box-orient". Básicamente podemos colcarlas según el orden de lectura del html ("normal") o al revés de como aparecen en el orden de lectura del html ("reverse").

Básicamente nos va permitir que el aspecto de nuestras webs dependa aun menos del HTML. Ahora que un elemento vaya antes que el otro no significa que no podamos darles la vuelta.

Por defecto (si no se indica), esta propiedad queda indicada como "normal". Sin embargo, el uso de esta propiedad no es muy necesario en la mayor parte de maquetas por lo que es preferible indicarla tan solo en los casos en los que se vaya realmente a jugar con estos elementos.

box-pack: (start, end, center, justify, distribute)

Por lo general, si usamos el modelo de caja flexible de css3 lo que buscaremos es repartir los elementos hijos de forma equitativa en el espacio disponible en el elemento contenedor y durante el eje marcado por "box-orient". No nos va a preocupar mucho más.

Sin embargo en ocasiones querremos indicar como se reparten estos elementos por el propio eje en el que se distribuyen. Esto podemos querer hacerlo sobretodo en aquellos casos en los que definamos el el ancho (en orientaciones horizontales) o el alto (en orientaciones verticales) de los elementos hijos.

Hasta ahora estábamos dejando que fuese el propio modelo de caja flexible el que decidiese esos valores, creando por ejemplo anchos equitativos para todas las columnas de un contenedor con "box-orient:horizontal". Pero es posible que algunos de estos elementos haya definido sus valores:

A - En el caso de definir el ancho o el alto de solo algunos de los elementos Hijos, no tendremos que preocuparnos. Los elemenos que no han sido definidos se adaptarán al espacio sobrante...

Ejemplo:

#miContenedor{ width:300px; display:box; box-orient:horizontal; box-align:stretch;}
#hijo_1{ width:100px }
#hijo_2{ /* sin definir width */ }

En este caso, al distribuirse los elementos #hijo_1 tendrá un ancho de 100px, pues así ha sido definido, dejando a #hijo_2 ocupando el resto del espacio.

Ejemplo 2:

#miContenedor{ width:200px; display:box; box-orient:horizontal; box-align:stretch;}
#hijo_1{ width:100px }
#hijo_2{ /* sin definir width */ }
#hijo_3{ /* sin definir width */ }

Al igual que antes #hijo_1 tendrá un ancho de 100px, pero en este caso, al quedar 100px por repartir entre los hijos 2 y 3 estos cogerán un ancho de 50px cada uno.

B - En el caso de de que todos los elementos tengan definido su ancho o alto (dependiendo de la orientación) hará falta indicar como distribuir los espaciados entre ellos. Para ello es para lo que se usa fundamentalmente box-pack indicando la alineación que deberán tener estos elementos:

  • start
    Colocará todos los elementos al principio del Eje, sin dejar espacio entre ellos
    Por ejemplo: un "box-orient:horizontal; box-pack:start" con hijos con elementos con width definido, los colocará todos apretados y seguidos a la izquierda del elemento contenedor.
  • end
    Colocará todos los elementos al final del Eje, sin dejar espacio entre ellos
    Por ejemplo: un "box-orient:horizontal; box-pack:end" con hijos con elementos con width definido, los colocará todos apretados y seguidos a la derecha del elemento contenedor.
  • center
    Colocará todos los elementos en el centro del Eje, sin dejar espacio entre ellos
    Por ejemplo: un "box-orient:horizontal; box-pack:center" con hijos con elementos con width definido, los colocará todos apretados y seguidos en el centro horizontal del elemento contenedor.
  • justify
    Colocará todos los elementos repartidos durante todo el eje, para ello creará espacios equitativos entre ellos, pero no a los lados del primer y último elemento.
  • distribute
    Colocará todos los elementos repartidos durante todo el eje, para ello creará espacios equitativos entre ellos y los bordes del contenedor. Es decir, también dejará el mismo espacio a los lados del primer y último elemento hijos.

Nota: realmente box-pack puede usarse con elementos sin width definido y si miramos distintas documentaciones este es un elemento principal y más importante que box-align. Pero en la práctica resulta confuso usarlo de esta forma por lo que mi recomendación es la de solo usarlo para el caso concreto de widths definidos y manipular en ellos esta distribución de espacios. Ya habrá tiempo más adelante para liarse con este tema pero de momento aprendamos lo básico.

Propiedades asignables a los elementos hijos del modelo de caja flexible de CSS3

Como no podía ser de otra forma, también hay aspectos de los propios elementos que están siendo distribuidos y que deben marcarse en los mismos. Estos son los aspectos que pueden afectar puntualmente a cada uno de ellos por separado.

Existen un par de propiedades nuevas de este modelo pero antes de verlas veamos como afectan algunas propiedades que ya conocemos:

width y height

Como decíamos anteriormente estos elementos serán respetados en la distribución de las cajas. Por lo general, cualquier elemento que tenga un width o un height definido se mantiene con sus valores siendo el resto de elementos los que deberán adaptarse con el espacio sobrante.

position

"position:relative" no afecta al modelo de caja, pero cualquier elemento con "position:absolute" al pasar a no estar situado realmente en el orden lógico de la página se saca de la distribución. Así si yo tengo 4 elementos hijos de un ejemplo del tipo "display:box; box-orient:horizontal;" y uno de ellos está posicionado en absoluto, los otros tres cogeran cada uno un tercio del ancho del elemento padre.

float

Declarar un elemento como flotante rompe el modelo de caja y provoca comportamientos no deseados. Sencillamente no declares los elementos hijos nunca como float.

box-flex

Esta es una de las nuevas propiedades derivadas del modelo de caja flexible. Se trata de un punto intermedio entre declarar width y no hacerlo. Básicamente se trata de una medida relativa de las cajas donde podemos indicar cuantos espacios ocupa cada elemento del total. Así si en un contenedor del tipo "display:box; box-orient:horizontal;" si un elemento tiene un "box-flex:1" y otro un box-flex:2", el segundo tendrá un ancho del doble que el primero al realizar la distribución entre el espacio total del elemento contenedor.

Por defecto (si no está indicado) box-flex es igual a "0". Esto significa que se anula su flexibilidad. Es decir, todo lo mencionado hasta el momento sobre distribución de espacios es asumiendo que los elementos hijos tienen todos definidos su box-flex para que sean flexibles, de otra forma cogerán su ancho o alto mínimo según su contenido (como cualquier otro elemento sin ancho o alto) algo que no tiene sentido para casi ningún tipo de diseño.

La norma que debes aplicar al empezar (y hasta que controles lo suficiente este sistema) es que un elemento hijo de una caja flexible debe estar en una de estas dos situaciones:

A) Con box-flex definido con algún numero.

B) Con "box-flex:0" o no definido y width o height (dependiendo del eje de box-orient) definidos para suplir que no se esté definiendo el solo automáticamente.

También es recomendable definir en los elementos hijos siempre el box-flex por dos motivos:
1. Tener claro si su comportamiento es flexible o no de forma rápida al mirar el CSS.
2. Idenfiticar en el CSS rápidamente que elementos están dentro de una caja flexible.

Ejemplo:

#miContenedor{ width:300px; display:box; box-orient:horizontal; box-align:stretch;}
#miContenedor div{ box-flex:1}

De esta forma estamos haciendo que todos los "div" dentro del contenedor sean flexibles y por lo tanto todas las reglas comentadas hasta ahora funcionarán sin problemas.

Ejemplo 2:

#miContenedor{ width:300px; display:box; box-orient:horizontal; box-align:stretch;}
#hijo_1{ box-flex:5 }
#hijo_2{ box-flex:1 }

En este caso, al distribuirse los elementos #hijo_1 tendrá un ancho de 250px, y el #hijo_2 uno de 50px pues así #hijo_1 es 5 veces mayor que #hijo_2

Ejemplo 3:

#miContenedor{ width:300px; display:box; box-orient:horizontal; box-align:stretch;}
#hijo_1{ box-flex:0; width:100px; }
#hijo_2{ box-flex:3 }
#hijo_3{ box-flex:1 }

Al estar definido su width #hijo_1 tendrá un ancho de 100px, para el resto de elementos se recoge el espacio sobrante (200px) y se reparte según su box-flex quedando #hijo_2 con 150px de ancho e #hijo_3 con los 50 restantes.

box-ordinal-group

Por último esta propiedad nos va a permitir reordenar desde el CSS cada uno de nuestros elementos hijos del contenedor. Al igual que "box-direction" esta propiedad esta hecha para que el HTML no nos obligue a un orden de elementos determinado permitiéndonos definir nosotros mismos este orden. Aún así es una propiedad que es raro que useis mucho.

Por defecto (si no se indica) "box-ordinal-group" tiene el valor de 1, lo que significa que podemos pasar cualquier elemento al final de la lista de elementos simplemente marcándolo como "box-ordinal-group:2". En el caso de que varios elementos coincidan con el mismo número estos si que se ordenarán por el orden normal del HTML y según el valor de "box-direction".

Volvamos a pensar...

El modelo de caja flexible de CSS3 es realmente potente y va a solucionarnos todos los problemas que teníamos para poder crear nuestras webs tal cual están diseñadas. Permite un sin fin de aplicaciones dinámicas con elementos que se reajustan, centran y reordenan según van apareciendo. Esto aplicado a sistemas con un CMS por detrás o a aplicaciones con Javascript y/o ajax abre nuevas posibilidades al desarrollo al hacerlo simplemente mucho más sencillo y rápido: Todo esto ya podía hacerse, pero muchos hacks y horas de pruebas.

Ahora que conoceis todas las propiedades os invito a volver a visitar esa fabulosa herramienta de Flexie.js: Flexbox Playground para terminar de entender el uso de las distintas propiedades.

Nota: Ten en cuenta que algunas propiedades no producirán ningún efecto si otras están indicadas de forma especial:

- "Box Pack" no será percibido si los "Box Flex" no están todos a "0".
- "Box Direction" no será percibido si no están todos los elementos con "Box Ordinal Group" al mismo número.

Hacks interesantes para el modelo de caja flexible de CSS3

Por el momento solo he requerido de un hack para un comportamiento extraño en Firefox:

Resulta que cuando un elemento se define con "display:box" y "width:100%" firefox no asigna correctamente este 100% en la caja contenedora. Esto es realmente frustrante sobretodo cuando queremos que un elemento ocupe todo el ancho de página y sea a su vez una caja flexible.

Esto se soluciona con un pequeño código CSS que no es muy correcto, pero que hasta que Firefox no arregle este bug (ya les ha sido reportado) es necesario:

#tuElemento {width:100%; display:box; box-orient:vertical; box-align:center; }
/* Fix FF width */ html>/**/body #tuElemento, x:-moz-any-link, x:default  {width:9999px !important;}

Creando nuestro Layout

A partir de aquí el primer paso que hay que dar para poder crear un layout que no requiera usar elementos flotantes para todo. Pero cada uno aquí seguirá distintas técnicas.

Yo os dejo un pequeño ejemplo de layout creado con cajas flexibles para que tengáis alguna guía de todo lo hablado.

Solo tienes que entrar y examinar su código HTML y CSS.

Esto es todo... ¿Seguro?

No. Existen más propiedades que puedes aplicar a tus cajas flexibles. Sobretodo propiedades que te permiten indicar el comportamiento de estas cuando empieza a ocupar más de una línea y la caja flexible empieza a crecer en alguno de sus Ejes.

Temas muy interesantes que tendrás que terminar dominando pero que me parecen demasiado complejos para lanzarnos a ellos en una primera aproximación.

Espero que esta explicación te haya servido y te animes a hacer tus pinitos con cajas flexibles. Así mismo si encontras algún error o te apetece compartir algo con los demás no dudes en dejar tu comentario.

Algunos enlaces para seguir aprendiendo

Temas Relacionados: maquetacion tutoriales

Autor:

7 Comentarios para “CSS3 “display:box”: Maquetación con el modelo de caja flexible”

  1. Kseso dice:

    Gracias Iñaqui por incluir mi artículo entre las referencias.
    Por si quieres actualizar un par de cosillas, te comento que el consorcio en el Documento "CSS Box Alignment Module Level 3" ( http://dev.w3.org/csswg/css3-align ) modifica algunas cosillas del flexbox

    Un saludo

  2. Hilario dice:

    Enhorabuena por este artículo!!.

    Llevo meses intentando maquetar con el modelo de caja flexible, pero los problemas de compatibilidad con IE (para variar) hacían que me decantara a seguir usando técnicas anteriores, con sus correspondientes problemas a la hora de conseguir una maquetación complicada.

    Pero después de mucho buscar por internet he encontrado tu artículo en el que das soluciones que yo desconocía, y con las que parece que se pueden diseñar layouts compatibles con todos los navegadores!!, o al menos con la mayoría utilizados en la actualidad.

    Creo que ha llegado el momento de utilizar esta técnica!!

    Muchas gracias por el aporte!! 8)

  3. Hilario dice:

    Hola otra vez, quisiera hacer una consulta, a ver si alguien pudiera ayudarme.

    Después de leer este artículo he comenzado a maquetar con el modelo de caja flexible y todo a funcionado bastante bien, hasta que he intentado hacer un diseño adaptable a la resolución de pantalla, lo que ahora está de moda con las media queries.

    Supongamos que tengo una fila con display: box que contiene 3 elementos, los cuales se adaptan cuando es una resolución alta, pero al bajar la resolución quiero que dicha fila se quede con 2 elementos y el tercero se desplace hacia abajo, y no lo consigo.

    He probado a quitarle el box-flex y ponerlo como display: block, pero sigue en la misma línea, no se desplaza.

    Alguien puede ayudarme?, Muchas gracias.

  4. eliezer dice:

    Hilario dice:
    14 Agosto 2012 a las 17:17
    Hola otra vez, quisiera hacer una consulta, a ver si alguien pudiera ayudarme.

    Después de leer este artículo he comenzado a maquetar con el modelo de caja flexible y todo a funcionado bastante bien, hasta que he intentado hacer un diseño adaptable a la resolución de pantalla, lo que ahora está de moda con las media queries.

    Supongamos que tengo una fila con display: box que contiene 3 elementos, los cuales se adaptan cuando es una resolución alta, pero al bajar la resolución quiero que dicha fila se quede con 2 elementos y el tercero se desplace hacia abajo, y no lo consigo.

    He probado a quitarle el box-flex y ponerlo como display: block, pero sigue en la misma línea, no se desplaza.

    Alguien puede ayudarme?, Muchas gracias.

    ------------------------------------------
    tienes que usar el meta viewport.. y para que se desplaze hacia abajo haces que los elementos por ejemplo

    a tu section le das un max-heigth (hace que tenga maximo ese ancho y que se vaya adaptando automaticamente)
    y a sus hijos le das la propiedad display:inline-block; lo que hace que estos articles se mantengan en linea cuando su padre ocupa su 100% una vez que el padre va a disminuir su tamaño ellos se mueven para abajo alineandose.. ya con los media query lo unico que haras es darle tal vez algunos estilos diferentes.. y a tus articles para que cuando esten en linea tengan las misma altura le das un min-height:; y un vertical align para que se mantengan en el mismo margen.. y a tu section deberias darle un min-height para que los articles no se salgan del section cuando este se achica.. en fin.. son propiedades que uso para hacer un diseño adaptable.. p.d: los text-align afectan a los display:inline-block, por lo tanto no es necesario el uso de floats.. lo que te digo es muy viejo ya.. porque lo que lei en este articulo esta muy muy interesante.. yo no lo sabia.. ahora lo practicare y tratare de dominarlo.. estaria bueno un tuto de pseudo clases y pseudo elementos.. ya que los uso mucho.. pero tengo dudas en ciertos casos puntuales como por ejemplo si es que pueden llegar a existir conflictos con php

  5. azul dice:

    Lo del problema con float ¿no se corrige con un simple "overflow: hidden" en el nodo padre?

    • ikhuerta dice:

      En su dia lo probé y no funcionaba. A día de hoy quizás ya esté resuelto.

      La verdad es que en la práctica para centrar contenido sigue siendo más efectivo el "display:block margin:0 auto;" te evitas dolores de cabeza mientras arreglan los navegadores.

  6. Tobal dice:

    Lo del arreglo para IE no me funciona, tengo instalado el IE9, he probado todos los js existentes y me parece que son todos una milonga, no funciona ninguno. Algo más hacéis los desarrolladores que no contáis, porque no funciona ninguno.

Anímate y deja tu comentario

Esto son experimentos, no preguntes ;) prueba metadescription Prueba title