Capítulo 3. Dominar el modelo de caja

left-arrow right-arrow

Este capitulo habla sobre:

Cuando se trata de diseñar elementos en la página, encontrará muchas cosas que suceden. En un sitio complejo, puede tener flotadores, elementos absolutamente posicionados y otros elementos de varios tamaños. También puede tener algunos diseños que utilicen construcciones CSS más nuevas, como un flexbox o un diseño de cuadrícula. Tiene muchas cosas de las que realizar un seguimiento y aprender todo lo relacionado con el diseño puede ser abrumador.

Dedicaremos varios capítulos a analizar de cerca varias técnicas de diseño. Antes de llegar a ellos, es importante tener una comprensión sólida de los fundamentos de cómo el navegador clasifica y coloca los elementos. Los temas más avanzados de diseño se basan en conceptos como el flujo de documentos y el box model; estas son las reglas básicas que determinan la posición y el tamaño de los elementos en la página.

En este capítulo, creará un diseño de página de dos columnas. Puede que esté familiarizado con esto como un ejercicio clásico para principiantes de CSS, pero lo guiaré a través de él de una manera que resalte varios matices de diseño que a menudo se pasan por alto. Veremos algunos de los casos extremos del modelo de caja y le daré consejos prácticos para dimensionar y alinear elementos. También abordaremos dos de los problemas más notorios en CSS: el centrado vertical y las columnas de igual altura.

3.1. DIFICULTADES CON WIDTH

En este capítulo, creará una página simple con un encabezado en la parte superior y dos columnas debajo. Al final del capítulo, su página se verá como la que se muestra en la figura 3.1. Hice intencionalmente el diseño de la página un poco "bloque", para que pueda ver fácilmente el tamaño y la posición de todos los elementos.

ibid
Figura 3.1. Diseño de página de dos columnas con encabezado

Inicie una nueva página y una hoja de estilo vacía, y luego vincúlelas. Agregue el marcado que se muestra junto a su página. Su página tendrá un encabezado, así como un elemento principal y un elemento de barra lateral que formarán las dos columnas de su página. Un contenedor envuelve las dos columnas.

          
<body>
  <header>
    <h1>Franklin Running Club</h1>
  </header>
  <div class="container">
    <main class="main">
      <h2>Come join us!</h2>
      <p>
        The Franklin Running club meets at 6:00pm every Thursday
        at the town square. Runs are three to five miles, at your
        own pace.
      </p>
    </main>
    <aside class="sidebar">
      <div class="widget"></div>
      <div class="widget"></div>
    </aside>
  </div>
</body>
          
          Listado 3.1. HTML para página con un diseño de dos columnas
        

Comencemos con algunos de los estilos obvios. Establecerás la fuente para la página, luego los colores de fondo para la página y cada uno de los contenedores principales. Esto le ayudará a ver la posición y el tamaño de cada uno a medida que avanza. Después de hacer esto, su página se verá como la que se muestra en la figura 3.2.

ibid
Figura 3.2. Tres contenedores principales con colores de fondo.

Para algunos diseños de sitios, el color de fondo de varios contenedores puede ser transparente. Cuando este es el caso, puede ser útil aplicar temporalmente un color de fondo al contenedor hasta que obtenga el tamaño y la posición adecuados.

Los estilos para esto se muestran en el listado 3.2. Actualmente, la barra lateral está vacía, por lo que, de forma predeterminada, no tiene altura. Agregará relleno para darle algo de altura. Los otros contenedores necesitarán relleno eventualmente, pero volveremos a eso. Por ahora, agregue este código a su hoja de estilo.

          
body {
  background-color: #eee;
  font-family: Helvetica, Arial, sans-serif;
}
  
header {
  color: #fff;
  background-color: #0072b0;
  border-radius: .5em;
}
  
main {                        
  display: block;              1   
}
  
.main {
  background-color: #fff;
  border-radius: .5em;
}
  
.sidebar {
  padding: 1.5em;                2
  background-color: #fff;
  border-radius: .5em;
}
          
          Listado 3.2. Aplicar fuente y colores
        
  1. Arregla el problema de IE
  2. Añade padding a la barra lateral

IE tiene un error en el que los elementos <main> se representan en línea de forma predeterminada, en lugar de como bloques. Corregimos eso aquí agregando una declaracion display: block.

A continuación, coloquemos las dos columnas en su lugar. Para empezar, utilizará un diseño basado en flotantes. Flotarás el main y el sidebar hacia la izquierda y les darás anchos de 70% y 30%, respectivamente. Actualice su hoja de estilo para que coincida con el CSS que se muestra aquí.

          
.main {
  float: left;
  width: 70%;                   1
  background-color: #fff;
  border-radius: .5em;
}
  
.sidebar {
  float: left;
  width: 30%;                   2
  padding: 1.5em;
  background-color: #fff;
  border-radius: .5em;
}
          
          Listado 3.3. Alineando dos columnas
        
  1. Flota la columna principal a la izquierda y establece el ancho al 70%
  2. Flota la barra lateral hacia la izquierda y establece el ancho al 30%.

Puede ver el resultado en la figura 3.3, pero no es exactamente lo que deseaba.

ibid
Figura 3.3. Columnas de la barra lateral y principal con anchos de 70% y 30%, respectivamente

En lugar de que las dos columnas se sientan una al lado de la otra, se envuelven en línea. Aunque especificó anchos de 70% y 30%, las columnas ocuparon más del 100% del espacio disponible. Eso se debe al comportamiento predeterminado del modelo de caja (figura 3.4). Cuando establece el ancho o alto de un elemento, está especificando el ancho o alto de su contenido; A continuación, se añaden a ese ancho cualquier relleno, borde y márgenes.

ibid
Figura 3.4. El modelo de caja predeterminado

Este comportamiento significa que un elemento con un ancho de 300px, un relleno de 10 px y un borde de 1px tiene un ancho renderizado de 322px (ancho más relleno izquierdo y derecho más borde izquierdo y derecho). Esto se vuelve aún más confuso cuando las unidades no son todas iguales.

En el ejemplo (listado 3.3), la barra lateral tiene un ancho del 30% más 1,5em de relleno izquierdo y derecho; el contenedor principal tiene solo un ancho del 70%. Esto eleva el total de las dos columnas al 100% más 3ems. Para que quepan, los contenedores deben envolverse.

3.1.1. Evitando los números mágicos

La solución ingenua es reducir el ancho de una de las columnas (la barra lateral, por ejemplo). En mi pantalla, un ancho del 26% para la barra lateral funciona, pero esto no es confiable. El 26% se conoce como número mágico. En lugar de usar un valor deseado, lo encontré haciendo cambios al azar en mis estilos hasta que obtuve el resultado que quería.

Para la programación en general, los números mágicos no son deseables. A menudo es difícil explicar por qué funciona un número mágico. Si no comprende de dónde proviene el número, no comprenderá cómo se comportará en diferentes circunstancias. Mi pantalla tiene 1440px de ancho, por lo que en las ventanas de visualización más pequeñas, la barra lateral aún se ajustará a la línea. Aunque hay un lugar para la prueba y el error en CSS, por lo general es para las elecciones que son de naturaleza estilística y no para forzar que las cosas encajen en su posición.

Una alternativa a este número mágico es dejar que el navegador haga los cálculos. En este caso, las columnas son 3em demasiado anchas (debido al relleno), por lo que puede usar la función calc(); para reducir el ancho exactamente en esa cantidad. Un ancho de barra lateral de calc(30% - 3em) le da exactamente lo que necesita. Pero todavía hay una forma mejor.

3.1.2. Ajuste del modelo de caja

Debido a los problemas que acaba de encontrar, el modelo de caja predeterminado no es el que normalmente querrá usar. En su lugar, querrá que los anchos especificados incluyan el padding y el border. CSS le permite ajustar el comportamiento del modelo de caja con su propiedad de box-sizing.

De forma predeterminada, box-sizing se establece en el valor de content-box. Esto significa que cualquier altura o ancho que especifique solo establece el tamaño del cuadro de contenido. En su lugar, puede asignar un valor de border-box al tamaño de la caja. De esa manera, las propiedades de height y widht establecen el tamaño combinado del contenido, el relleno y el borde, que es exactamente lo que desea en este ejemplo.

La Figura 3.5 muestra el modelo de caja con el tamaño de la caja establecido en border-box. Con este modelo, el padding no ensancha un elemento; hace que el contenido interno sea más estrecho. También hace lo mismo con la altura.

ibid
Figura 3.5. El modelo de caja con tamaño de caja establecido en border-box

Si actualiza estos elementos para utilizar el tamaño del cuadro de borde, se ajustarán a la misma línea, independientemente del relleno izquierdo y derecho (figura 3.6).

ibid
Figura 3.6. Las columnas con un modelo de caja ajustado ahora encajan una al lado de la otra.

Para ajustar el modelo de caja para los dos elementos, main y sidebar, actualice su hoja de estilo para que coincida con esta lista.

          
.main {
  box-sizing: border-box;            1
  float: left;
  width: 70%;
  background-color: #fff;
  border-radius: .5em;
}
  
.sidebar {
  box-sizing: border-box;            1
  float: left;
  width: 30%;
  padding: 1.5em;
  background-color: #fff;
  border-radius: .5em;
}
          
          Listado 3.4. Columnas flotantes con un modelo de caja corregido
        
  1. Cambia el modelo de caja a border-box sizing

Usando box-sizing: border-box, los dos elementos suman un ancho uniforme del 100%. Sus anchos de 70% y 30% ahora incluyen su padding, por lo que caben en la misma línea.

3.1.3 Usando el border-box universal

Ha hecho que el tamaño de las cajas sea más intuitivo para estos dos elementos, pero seguramente se encontrará con otros elementos con el mismo problema. Sería bueno arreglarlo una vez, universalmente para todos los elementos, para que no tenga que volver a pensar en este ajuste. Puede hacer esto con el selector universal <*>, que apunta a todos los elementos de la página como muestra la siguiente lista. También agregué selectores para orientar cada pseudoelemento en la página. Pon este código en la parte superior de tu hoja de estilo.

          
*,
::before,
::after {
  box-sizing: border-box;         1
}
          
          Listado 3.5.Arreglo del border-box universa
        
  1. Aplica el border box sizing a todos los elementos y pseudoelementos de la página

Después de aplicar esto a la página, height y el widht siempre especificarán la altura y el ancho reales de un elemento. El padding no los cambiará.

Agregar este fragmento cerca del comienzo de su hoja de estilo se ha convertido en una práctica común.

Sin embargo, si agrega componentes de terceros con su propio CSS a su página, es posible que vea algunos diseños rotos para esos componentes, especialmente si su CSS no se escribió con esta corrección en mente. Debido a que la corrección de border-box universal apunta a todos los elementos del componente con el selector universal, corregir esto puede ser problemático. Debería apuntar a cada elemento dentro del componente para volver al content-box sizing.

Puede facilitar esto con una versión ligeramente modificada de la corrección y la herencia. Actualice esta parte de su hoja de estilo para que coincida con la siguiente lista.

          
:root {
  box-sizing: border-box;          1
}
  
*,
::before,
::after {
  box-sizing: inherit;             2
}
          
          Listado 3.6.Arreglo más robusto del border-box
        
  1. Aplica el tamaño del cuadro de borde al elemento raíz
  2. Le dice a todos los demás elementos y pseudo-elementos que hereden su tamaño de caja

El Box sizing no es normalmente una propiedad heredada, pero al usar la palabra clave inherit, puede forzar que lo sea. Con la versión que se muestra aquí, puede convertir un componente de terceros en un content-box cuando sea necesario al apuntar a su contenedor de nivel superior. Entonces, todos los elementos dentro del componente heredarán el tamaño de la caja:

          
.third-party-component {
  box-sizing: content-box;
}
          
        

Ahora, cada elemento de su sitio tendrá un modelo de caja más predecible. Le recomiendo que agregue el listado 3.6 a su CSS cada vez que inicie un nuevo sitio; le ahorrará muchos problemas a largo plazo. Sin embargo, puede ser un poco problemático en una hoja de estilo existente, especialmente si ya ha escrito muchos estilos basados en el modelo de cuadro de contenido predeterminado. Si agrega esto a un proyecto existente, asegúrese de revisarlo a fondo para detectar cualquier error resultante.

A partir de este momento, todos los ejemplos de este libro supondrán que esta corrección del border-box se encuentra al comienzo de su hoja de estilo.

3.1.4. Agregar un canalón entre columnas

A menudo, es más atractivo visualmente tener un pequeño espacio <o canalón> entre las columnas. A veces, puede lograr esto agregando padding a una columna; pero en algunos casos, este enfoque no funciona. Si ambas columnas tienen un color de fondo o un borde, como en su página de ejemplo, querrá que el canalón aparezca entre los bordes de los dos elementos (;figura 3.7). Tenga en cuenta el espacio gris entre los dos fondos blancos. Puedes lograr este look de varias maneras. Veamos algunos de ellos, que se muestran en los listados 3.7 y 3.8.

ibid
Figura 3.7. Canalón agregado entre las dos columnas

Primero, puede agregar un margen a una de las columnas y ajustar el ancho de sus elementos para tener en cuenta el espacio agregado. El Listado 3.7 muestra cómo restar 1% del ancho de la columna de la barra lateral y moverlo al margen. Actualice su CSS para que coincida.

          
.main {
  float: left;
  width: 70%;
  background-color: #fff;
  border-radius: .5em;
}
  
.sidebar {
  float: left;
  width: 29%;                   1
  margin-left: 1%;              2
  padding: 1.5em;
  background-color: #fff;
  border-radius: .5em;
}
          
          Listado 3.7. Margen de medianil basado en porcentaje
        
  1. Resta 1% del ancho. . .
  2. ...y lo agrega como margen para la canaleta

Esto agrega un canalón, pero su ancho se basa en el ancho del contenedor exterior; el porcentaje es relativo al ancho completo del principal. ¿Qué sucede si desea especificar la canaleta en unidades que no sean un porcentaje? (;Prefiero un canalón basado en em, que encuentro más consistente). Puede lograr esto con calc<>.

En lugar de mover un 1% del ancho al margen, puede mover 1.5em. Este listado muestra cómo calc<> lo hace posible. Cambie su CSS nuevamente para que coincida con este listado.

          
.main {
  float: left;
  width: 70%;
  background-color: #fff;
  border-radius: .5em;
}
  
.sidebar {
  float: left;
  width: calc(30% - 1.5em);         1
  margin-left: 1.5em;               2
  padding: 1.5em;
  background-color: #fff;
  border-radius: .5em;
}
          
          Listado 3.8. Usando calc<> para restar la canaleta del ancho
        
  1. Resta 1,5 cm del ancho. . .
  2. ...y lo agrega como margen

Esto no solo le permite usar ems en lugar de porcentajes para el margen, sino que también tiene la ventaja de ser un poco más explícito en el código. Cuando revise el código más tarde, es posible que no sea evidente de dónde proviene un porcentaje específico, pero 30% - 1.5em proporciona una pista de que está haciendo algo basado en el 30%.

3.2. DIFICULTADES CON ELEMENT HEIGHT

Trabajar con la altura del elemento es diferente a trabajar con el ancho del elemento. Las correcciones del border-box que ha realizado hasta ahora todavía se aplican y pueden ser útiles; pero, por lo general, es mejor evitar establecer alturas explícitas en los elementos. El flujo de documentos normal está diseñado para trabajar con un ancho limitado y una altura ilimitada. Los contenidos llenan el ancho de la ventana gráfica y luego se ajustan según sea necesario. Debido a esto, la altura de un contenedor está determinada orgánicamente por su contenido, no por el contenedor en sí.

El flujo de documentos normal se refiere al comportamiento de diseño predeterminado de los elementos de la página. Los elementos Inline fluyen junto con el texto de la página, de izquierda a derecha, ajustando la línea cuando llegan al borde de su contenedor. Los elementos a nivel de bloque se ubican en líneas individuales, con un salto de línea arriba y abajo.

3.2.1. Controlar el comportamiento de overflow

Cuando establece explícitamente la altura de un elemento, corre el riesgo de que su contenido overflow el contenedor. Esto sucede cuando el contenido no se ajusta a la restricción especificada y se procesa fuera del elemento principal. La figura 3.8 muestra este comportamiento. El flujo de documentos no tiene en cuenta el desbordamiento, y cualquier contenido debajo del contenedor se procesará en la parte superior del contenido desbordado.

ibid
Figura 3.8. Contenido desbordando su contenedor

Puede controlar el comportamiento exacto del contenido desbordado con la propiedad overflow, que admite cuatro valores:

  • visible (valor predeterminado): todo el contenido es visible, incluso cuando desborda los bordes del contenedor.
  • hidden: el contenido que desborda el borde acolchado del contenedor se recorta y no será visible.
  • scroll: se agregan barras de desplazamiento al contenedor para que el usuario pueda desplazarse y ver el contenido restante. En algunos sistemas operativos, se agregan barras de desplazamiento horizontales y verticales, incluso si todo el contenido es visible. En este caso, las barras de desplazamiento estarán deshabilitadas (atenuadas).
  • auto: las barras de desplazamiento se agregan al contenedor solo si el contenido se desborda.

Por lo general, prefiero auto en lugar de scroll porque, en la mayoría de los casos, no quiero que aparezcan las barras de desplazamiento excepto cuando sea necesario. La Figura 3.9 muestra cuatro contenedores con estas configuraciones de desbordamiento.

ibid
Figura 3.9. Desbordamiento de izquierda a derecha: visible, oculto, de desplazamiento y automático

Sea prudente con el uso de barras de desplazamiento. Los navegadores insertan una barra de desplazamiento para desplazarse por la página, y agregar áreas de desplazamiento anidadas dentro de su página puede resultar frustrante para los usuarios. Si un usuario está usando una rueda de desplazamiento del mouse para desplazarse hacia abajo en la página, y su cursor llega a un área de desplazamiento más pequeña, su rueda de desplazamiento dejará de desplazarse por la página y desplazará el cuadro más pequeño en su lugar.

Es posible que el contenido se desborde horizontalmente, no solo verticalmente. Una situación típica es cuando aparece una URL larga en un contenedor estrecho. Aquí se aplican las mismas reglas que con el desbordamiento vertical.

Puede controlar solo el desbordamiento horizontal utilizando la propiedad overflow-x, o el desbordamiento vertical con overflow-y. Estas propiedades admiten los mismos valores que la propiedad de overflow. Sin embargo, establecer explícitamente X y Y en valores diferentes tiende a tener resultados impredecibles.

3.2.2. Aplicar alternativas a las alturas basadas en porcentajes

Especificar la altura mediante un porcentaje es problemático. El porcentaje se refiere al tamaño del bloque contenedor de un elemento; la altura de ese contenedor, sin embargo, suele estar determinada por la altura de sus elementos secundarios. Esto produce una definición circular que el navegador no puede resolver, por lo que ignorará la declaración. Para que funcionen las alturas basadas en porcentajes, el padre debe tener una altura definida explícitamente.

Una de las razones por las que la gente intenta usar alturas basadas en porcentajes es para hacer que un contenedor llene la pantalla. Un mejor enfoque es usar las unidades vh relativas a la ventana, que revisó en el capítulo 2. Una altura de 100vh es exactamente la altura de la ventana. Sin embargo, el uso más común es crear columnas de igual altura. Esto también se puede resolver sin porcentaje.

El problema de las columnas de igual altura es una debilidad que ha afectado a CSS desde el principio. A principios de la década de 2000, CSS reemplazó el uso de tablas HTML para diseñar contenido. En ese momento, las tablas eran la única forma de producir dos columnas de igual altura o, más específicamente, columnas de la misma altura sin especificar explícitamente la altura. Puede configurar fácilmente todas las columnas a una altura de 500 px o algún otro valor arbitrario. Pero si permitiera que las columnas determinaran sus alturas de forma natural, cada elemento se evaluaría a una altura diferente, según su contenido. Este se convirtió en un caso de uso simple lleno de frustración.

Se necesitaron algunos trucos creativos para solucionar el problema. A medida que CSS evolucionó, surgieron soluciones que involucraban pseudoelementos o márgenes negativos. Si todavía utiliza alguno de estos métodos complicados, es hora de solucionarlo. Los navegadores modernos lo hacen mucho más fácil: admiten tablas CSS. Por ejemplo, IE8 + admite display: table, e IE10 + permite una caja flexible o caja flexible, las cuales, de forma predeterminada, producen columnas de igual altura.

Varios diseños comunes requieren columnas de igual altura. Su página de dos columnas es un gran ejemplo. Se vería más pulido si alineara las alturas de la columna principal y la barra lateral (;figura 3.10). A medida que crece el contenido en cualquiera de las columnas, cada columna crecerá según sea necesario para que los fondos siempre estén al ras.

ibid
Figura 3.10. Columnas de igual altura

Puede lograr esto estableciendo una altura arbitraria en ambas columnas, pero ¿qué valor elegiría? Si es demasiado grande, tendrá un gran espacio vacío en la parte inferior de sus contenedores; demasiado pequeño, y tendrá que lidiar con un desbordamiento.

La mejor solución es que las columnas se dimensionen de forma natural y luego extiendan la columna más corta para que su altura sea igual a la altura de la más alta. Le mostraré cómo hacer esto usando diseños de tabla basados en CSS y un flexbox.

Primero, utilizará un diseño de tabla basado en CSS. En lugar de utilizar flotadores, convertirá el contenedor en una pantalla: tabla y cada columna en una pantalla: tabla-celda. Actualice sus estilos para que coincidan con la lista 3.9. (Puede notar que no hay un elemento de fila de tabla. Con las tablas CSS, la inclusión de un elemento de fila no es un requisito tan estricto como lo es con las tablas HTML).

          
.container {
  display: table;              1   
  width: 100%;                 2  
}
  
.main {
  display: table-cell;         3   
  width: 70%;
  background-color: #fff;
  border-radius: .5em;
}
  
.sidebar {
  display: table-cell;         3  
  width: 30%;
  margin-left: 1.5em;          4  
  padding: 1.5em;
  background-color: #fff;
  border-radius: .5em;
}
          
          Listado 3.9. Columnas de igual altura usando un diseño de tabla basado en CSS
        
  1. Hace que el diseño del contenedor se parezca a una tabla
  2. Hace que la tabla llene el ancho de su contenedor
  3. Hace que el diseño de la columna imite las celdas de la tabla
  4. El margen ya no funciona

De forma predeterminada, un elemento con un valor de visualización de table no se expandirá a un ancho del 100% como lo hará un elemento de block, por lo que tendrá que declarar el ancho explícitamente 2. Este código te acerca, pero ahora falta el canalón. Eso se debe a que los márgenes 4 no se pueden aplicar a elementos de table-cell. Tendrá que hacer más cambios para que esto sea exactamente como lo desea.

Para definir el espacio entre las celdas de una tabla, puede usar la propiedad de border-spacing del elemento de la tabla. Esta propiedad acepta dos valores de longitud: uno para el espaciado horizontal y otro para el espaciado vertical. (También puede especificar solo un valor para aplicar a ambos.) Podría agregar border-spacing: 1.5em 0 a su contenedor, pero esto tiene un efecto secundario peculiar: ese valor también se aplica a los bordes exteriores de la tabla. Ahora sus dos columnas ya no se alinean con el encabezado en los bordes izquierdo y derecho (figura 3.11).

ibid
Figura 3.11. El espaciado de los bordes se aplica entre las celdas de la tabla y afecta a los bordes exteriores.

Puede solucionar este problema con el uso inteligente de un margen negativo, pero eso debe ir en un nuevo contenedor que envuelva toda la tabla. Así es cómo. Agregue un <div class = "wrapper"> alrededor del contenedor y aplique un margen izquierdo y derecho de -1.5em para contrarrestar los 1.5em del espaciado del borde en las barras laterales. Esta parte de su hoja de estilo debería verse así.

          
  .wrapper {
    margin-left: -1.5em;               1 
    margin-right: -1.5em;              1 
  }
  
  .container {
    display: table;
    width: 100%;
    border-spacing: 1.5em 0;           2
  }
  
  .main {
    display: table-cell;
    width: 70%;
    background-color: #fff;
    border-radius: .5em;
  }
  
  .sidebar {
    display: table-cell;
    width: 30%;
    padding: 1.5em;
    background-color: #fff;
    border-radius: .5em;
  }
          
          Listado 3.10. Columnas basadas en tablas con un medianil corregido
        
  1. Agrega un nuevo elemento contenedor con márgenes negativos
  2. Aplica un espaciado de borde horizontal entre las celdas de la tabla

En lugar de que los márgenes positivos empujen los bordes del contenedor, el margen negativo los tira hacia afuera. Combinado con el border-spacing, los bordes de la columna exterior ahora se alinean con los bordes del <body> (el cuadro que contiene el wraper). Ahora tiene el diseño que desea: dos columnas con la misma altura, un canalón de 1,5em y bordes exteriores que se alinean con el encabezado (figura 3.12).

ibid
Figura 3.12. Columnas de igual altura funcionando correctamente

Los márgenes negativos tienen algunos usos interesantes que veremos en un momento.

Si ha trabajado en el desarrollo web durante un tiempo, probablemente haya escuchado que es una mala práctica usar tablas HTML para diseños. Muchos diseñadores de sitios web a principios de la década de 2000 diseñaron sus sitios utilizando elementos <table>. A menudo era más fácil diseñar páginas usando table en lugar de luchar con float (la única alternativa viable en ese momento). Finalmente, hubo muchas reacciones violentas contra el uso de tablas para diseños porque hacerlo significaba usar HTML no semántico. En lugar de las etiquetas HTML que representan el contenido, estaban haciendo el trabajo de diseño, algo de lo que CSS debería ser responsable.

Los navegadores ahora admiten la visualización de tablas para todo tipo de elementos distintos de <table>, por lo que puede disfrutar de los beneficios de los diseños de tablas y mantener el marcado semántico. Sin embargo, no es una solución del "santo grial". Los atributos de la tabla HTML colspan y rowspan no tienen equivalente, y los floats, flexboxes y los inline-blocks pueden diseñar el contenido de formas que las tablas no pueden.

También se puede lograr un diseño de dos columnas con columnas de igual altura con una flexbox que se muestra en el listado 3.11. En particular, un flexbox no requiere el uso de un contenedor div adicional. De forma predeterminada, el uso de un flexbox produce elementos de igual altura; no tendrá que preocuparse por los márgenes negativos.

Elimine el contenedor div que ha agregado al diseño de la tabla y actualice su hoja de estilo para que coincida con la siguiente lista. Si es nuevo en flexbox, esta será una suave introducción.

          
.container {
  display: flex;               1
}
  
.main {                        2
  width: 70%;
  background-color: #fff;
  border-radius: 0.5em;
}
  
.sidebar {                     2
  width: 30%;
  padding: 1.5em;
  margin-left: 1.5em;          3
  background-color: #fff;
  border-radius: .5em;
}
          
          Listado 3.11. Columnas de igual altura usando un flexbox
        
  1. Aplica flex display al contenedor
  2. Los elementos dentro del flex container no necesitan propiedades flotantes o de visualización especificadas.
  3. Los márgenes funcionan como antes con los floats

Al aplicar display: flex al contenedor, se convierte en un contenedor flexible. Sus elementos secundarios tendrán la misma altura de forma predeterminada. Puede establecer anchos y márgenes en los elementos; aunque esto sumaría más de un 100%, el flexbox lo ordena. Esta lista muestra píxel por píxel lo mismo que el diseño de la tabla. No necesita el contenedor adicional y el CSS es un poco más simple.

Un flexbox proporciona muchas opciones, que profundizaré en el capítulo 5. Este ejemplo muestra todo lo que necesita para construir su primer diseño basado en flexbox.

Nunca establezca explícitamente la altura de un elemento a menos que no tenga otra opción. Siempre busque primero un enfoque alternativo. Establecer una altura conduce invariablemente a más complicaciones.

3.2.3. Usando min-height y max-height

Dos propiedades que pueden ser de gran ayuda son min-height y max-height. En lugar de definir explícitamente una altura, puede usar estas propiedades para especificar un valor mínimo o máximo, lo que permite que el elemento tenga un tamaño natural dentro de esos límites.

Suponga que desea colocar su imagen principal detrás de un párrafo de texto más grande y le preocupa que desborde el contenedor. En lugar de establecer una altura explícita, puede especificar una altura mínima con min-height. Esto significa que el elemento será al menos tan alto como usted especifique, y si el contenido no encaja, el navegador permitirá que el elemento crezca de forma natural para evitar el desbordamiento.

La figura 3.13 muestra tres elementos. El elemento de la izquierda no tiene un min-height, por lo que su altura se determina de forma natural, mientras que cada uno de los otros dos tiene un min-height de 3em. El elemento en el medio tendría una altura natural más corta que eso, pero el valor de min-height lo ha llevado a una altura de 3em. El elemento de la derecha tiene suficiente contenido que ha excedido los 3em, y el contenedor ha crecido de forma natural para contener el contenido.

ibid
Figura 3.13. Tres elementos: uno sin altura especificada y dos elementos con una altura mínima de 3 cm

Del mismo modo, max-height permite que un elemento se dimensione de forma natural, hasta cierto punto. Si se alcanza ese tamaño, el elemento no se vuelve más alto y el contenido se desbordará. Las propiedades similares min-width y max-width restringen el ancho de un elemento.

3.2.4. Contenido centrado verticalmente

El centrado vertical en CSS es otro problema notorio. Históricamente, ha habido varias formas de lograr el centrado vertical, y cada una de ellas funciona solo en determinadas circunstancias. Con CSS, la respuesta a un problema a menudo es "depende", y ese ciertamente puede ser el caso aquí.

Los desarrolladores a menudo se sienten frustrados cuando aplican vertical-align: middle a un elemento de bloque, esperando que centre el contenido del bloque. En cambio, el navegador ignora esta declaración.

Una declaración vertical-align solo afecta a los elementos de celda de tabla y en línea. Con elementos en línea, controla la alineación entre otros elementos en la misma línea. Puede usarlo para controlar cómo se alinea una imagen en línea con el texto vecino, por ejemplo.

Con elementos de celda de tabla, vertical: align controla la alineación del contenido dentro de la celda. Si un diseño de tabla CSS funciona para su página, entonces puede lograr un centrado vertical con vertical-align.

Gran parte del problema proviene de establecer la altura de un contenedor en un valor constante y luego intentar centrar una pieza de contenido de tamaño dinámico dentro de él. Cuando sea posible, intente lograr el efecto deseado permitiendo que el navegador determine las alturas de forma natural.

Esta es la forma más sencilla de centrar verticalmente en CSS: proporcione a un contenedor el mismo relleno superior e inferior y deje que tanto el contenedor como su contenido determinen su altura de forma natural (figura 3.14). El listado 3.12 muestra el código para esto. Puede agregar temporalmente este código a su hoja de estilo para verlo en su página (;asegúrese de eliminarlo después, ya que no forma parte de su diseño).

ibid
Figura 3.14. Usar relleno para centrar verticalmente el contenido
          
  header {
    padding-top: 4em;         1
    padding-bottom: 4em;      1
    color: #fff;
    background-color: #0072b0;
    border-radius: .5em;
  }
          
          Listado 3.12. Usar relleno para centrar el contenido verticalmente
        
  1. El relleno igual en la parte superior e inferior centra verticalmente el contenido de un elemento sin una altura fija.

Este enfoque funciona si el contenido dentro del contenedor está inline, block o de cualquier otro valor de display. A veces, sin embargo, es posible que deba establecer una cierta altura en el contenedor, o no tiene la opción de usar padding porque quiere otro child en el contenedor cerca de la parte superior o inferior.

El mejor enfoque para centrar el contenido dentro de un contenedor puede depender de una serie de factores basados en su escenario particular. Para ayudarle a decidir, siga estas preguntas hasta que encuentre una solución que pueda utilizar. Algunas de estas técnicas se tratarán en capítulos posteriores, por lo que le he indicado dónde puede encontrar la respuesta.

  • ¿Puedes usar un contenedor de altura natural? Aplique un relleno igual en la parte superior e inferior del recipiente para centrar su contenido.
  • ¿Necesita un contenedor de altura específica o necesita evitar el uso de padding? Utilice display: table-cell y vertical-align: middle en su contenedor.
  • ¿Puedes usar flexbox? Si no necesita ser compatible con IE9, puede centrar su contenido con flexbox. Ver capítulo 5.
  • ¿El contenido interno es solo una línea de texto? Establezca una altura de línea alta igual a la altura deseada del contenedor. Esto obligará al contenedor a crecer para contener la altura de la línea. Si los contenidos no están inline, es posible que deba configurarlos en inline -block.
  • ¿Conoce la altura tanto del contenedor como del contenido interior? Centrar el contenido con posicionamiento absoluto. Consulte el capítulo 7. (Solo recomiendo esto cuando todos los enfoques mencionados aquí fallan).
  • ¿Qué pasa si no conoce la altura del elemento interior? Utilice el posicionamiento absoluto junto con una transformación. Consulte el capítulo 15 para ver un ejemplo. (Nuevamente, solo recomiendo esto si ha descartado todas las demás opciones).

En caso de duda, consulte https://howtocenterincss.com. Es un gran recurso. Puede completar varias opciones según su escenario exacto, y generará el código que puede usar para el centrado vertical.

3.3. MARGENES NEGATIVOS

A diferencia del relleno y el ancho del borde, puede asignar un valor negativo a los márgenes. Esto tiene algunos usos peculiares, como permitir que los elementos se superpongan o se estiren más que sus contenedores.

El comportamiento exacto de un margen negativo depende del lado del elemento al que lo aplique. Puede ver esto ilustrado en la figura 3.15. Si se aplica a la izquierda o arriba, el margen negativo mueve el elemento hacia la izquierda o hacia arriba, respectivamente. Esto puede hacer que el elemento se superponga a otro elemento que lo precede en el flujo de documentos. Si se aplica al lado derecho o inferior, un margen negativo no desplaza el elemento; en su lugar, extrae cualquier elemento sucesivo. Darle a un elemento un margen inferior negativo no es diferente de darle al elemento(s) debajo de él un margen superior negativo.

ibid
Figura 3.15. Comportamiento de márgenes negativos

Cuando un elemento de bloque no tiene un ancho especificado, naturalmente llena el ancho de su contenedor. Sin embargo, un margen derecho negativo puede cambiar esto: mientras no se especifique el ancho, tira del borde del elemento hacia la derecha, llevándolo fuera del contenedor. Une esto con un margen izquierdo negativo igual, y ambos lados del elemento se extenderán fuera del contenedor. Esta peculiaridad es lo que le permitió cambiar el tamaño del diseño de la tabla en la figura 3.12 para llenar el ancho de <body>, a pesar del espaciado de los bordes.

El uso de márgenes negativos para superponer elementos puede hacer que no se pueda hacer clic en algunos elementos si se mueven debajo de otros elementos.

Es posible que los márgenes negativos no sean algo que use con frecuencia, pero son útiles en algunas circunstancias. En particular, resultan útiles a la hora de crear diseños de columnas. Sin embargo, asegúrese de no usarlos con demasiada frecuencia, o puede que rápidamente pierda la noción de lo que sucede en la página.

3.4. MÁRGENES COLAPSADOS

Eche otro vistazo a su página. ¿Notas algo extraño en los márgenes? No ha aplicado ningún margen al encabezado o al contenedor, pero hay un espacio entre ellos (figura 3.16). ¿Por qué hay esa brecha ahí?

ibid
Figura 3.16. Brecha causada por el colapso de los márgenes

Cuando los márgenes superior e inferior están contiguos, se superponen y se combinan para formar un único margen. Esto se conoce como colapso. El espacio debajo del encabezado en la figura 3.16 es el resultado de márgenes contraídos. Veamos cómo funciona esto.

3.4.1. Colapso entre texto

La razón principal de los márgenes colapsados tiene que ver con el espaciado de los bloques de texto. Los párrafos (<p>), por defecto, tienen un margen superior de 1em y un margen inferior de 1em. Esto lo aplica la hoja de estilo del agente de usuario. Pero cuando apila dos párrafos, uno tras otro, sus márgenes no suman un espacio de 2em. En su lugar, se colapsan y se superponen para producir solo 1em de espacio entre los dos párrafos.

Puede ver este tipo de margen contraído en la columna izquierda de la página. El título (“¡Ven y únete a nosotros!”) En un <h2> tiene un margen inferior de 0.83em, que se contrae con el margen superior del siguiente párrafo. Los márgenes de cada uno se ilustran en la figura 3.17. Observe cómo los márgenes de cada elemento ocupan el mismo espacio en la página.

ibid
Figura 3.17. Márgenes delineados del encabezado (izquierda&) y párrafo (derecha)

El tamaño del margen contraído es igual al mayor de los márgenes unidos. En este caso, el encabezado tiene un margen inferior de 19.92px (tamaño de fuente de 24px × 0.83em), y el párrafo tiene un margen superior de 16px (tamaño de fuente de 16px × margen de 1em). El mayor de estos, 19.92px, es la cantidad de espacio renderizado entre los dos elementos.

3.4.2. Colapso de múltiples márgenes

Los elementos no tienen que ser hermanos adyacentes para que sus márgenes colapsen. Incluso si envuelve el párrafo dentro de un div adicional, como en la siguiente lista, el resultado visual será el mismo. En ausencia de cualquier otro CSS que interfiera, todos los márgenes superiores e inferiores adyacentes colapsarán.

          
  <main class="main">
    <h2>Come join us!</h2>
    <div>                                         1   
      <p>                                         1   
        The Franklin Running club meets at 6:00pm       1
        every Thursday at the town square. Runs         1
        are three to five miles, at your own pace.      1
      </p>                                        1  
    </div>                                        1  
  </main>
          
          Listado 3.13. Párrafo envuelto en un div, con el mismo resultado
        
  1. Los márgenes aún se colapsan incluso con el párrafo envuelto dentro de otro div.

En este caso, hay tres márgenes diferentes colapsando juntos: el margen inferior de <h2>, el margen superior de <div> y el margen superior de <p>. Los valores calculados de estos son 19.92px, 0px y 16px, respectivamente, por lo que el espacio entre los elementos sigue siendo 19.92px, el más grande de los tres. De hecho, puede anidar el párrafo dentro de varios div, y seguirá representando lo mismo: todos los márgenes se colapsan juntos.

En resumen, los márgenes superior e inferior adyacentes se colapsarán juntos. Si agrega un div vacío y sin estilo (uno sin altura, borde o relleno) a la página, sus propios márgenes superior e inferior colapsarán.

El colapso de los márgenes solo ocurre con los márgenes superior e inferior. Los márgenes izquierdo y derecho no se contraen.

Los márgenes contraídos actúan como una especie de "burbuja de espacio personal". Si dos personas paradas en una parada de autobús se sienten cómodas cada una con 3 pies de espacio personal entre ellas, felizmente estarán a 3 pies de distancia. No necesitan pararse a 6 pies de distancia para que ambos estén satisfechos.

Este comportamiento normalmente significa que puede aplicar estilo a los márgenes de varios elementos sin preocuparse mucho por lo que pueda aparecer por encima o por debajo de ellos. Si aplica un margen inferior de 1.5em a los títulos, puede esperar el mismo espaciado después de los títulos, ya sea que el siguiente elemento sea un <p> con un margen superior de 1em o un div sin margen superior. El margen contraído entre los elementos solo aparece más grande si el siguiente elemento requiere más espacio.

3.4.3. Colapso fuera de un contenedor

La forma en que colapsan tres márgenes consecutivos puede tomarlo desprevenido. El margen de un elemento que colapsa fuera de su contenedor normalmente produce un efecto no deseado si el contenedor tiene un fondo.

Observe nuevamente el espacio debajo del encabezado en la figura 3.16. El título de la página es <h1>, con un margen inferior de 0.67em (21.44 px) aplicado por los estilos de agente de usuario. Ese título está dentro de un <header> sin márgenes. Los márgenes inferiores de ambos elementos son adyacentes, por lo que se colapsan, lo que da como resultado un margen inferior de 21.44px en el encabezado. Lo mismo ocurre con los márgenes superiores de los dos elementos.

Esto es un poco extraño. En este caso, desea que el margen de <h1> permanezca dentro del <header>. Los márgenes no siempre se contraen exactamente en el lugar que desea. Afortunadamente, existen varias formas de prevenirlo. De hecho, ya lo ha arreglado para la sección principal de la página; observe que el margen sobre "¡Únase a nosotros!" no colapsa hacia arriba fuera de su contenedor. Eso se debe a que los márgenes de los elementos de flexbox no se contraen, y usted dispuso esa parte de la página utilizando flexbox.

El padding proporciona otra solución. Si agrega relleno superior e inferior al encabezado, los márgenes internos no se colapsarán hacia el exterior. Mientras lo hace, actualice el encabezado para que se vea como en la figura 3.18, y apliquemos el relleno izquierdo y derecho también. Para hacerlo, actualice su hoja de estilo para que coincida con la lista 3.14. Notarás que esto ahora significa que no hay margen entre el encabezado y el contenido principal. Volveremos a abordar eso en breve.

ibid
Figura 3.18. Agregar relleno al encabezado evita que el margen se contraiga
          
header {
  padding: 1em 1.5em;
  color: #fff;
  background-color: #0072b0;
  border-radius: .5em;
}
          
          Listado 3.14. Aplicar relleno al encabezado
        

A continuación, se muestran algunas formas de evitar que los márgenes colapsen:

  • La aplicación de overflow: auto (o cualquier valor que no sea visible) al contenedor evita que los márgenes dentro del contenedor se colapsen con los que están fuera del contenedor. Esta suele ser la solución menos intrusiva.
  • Agregar un borde o relleno entre dos márgenes evita que se contraigan.
  • Los márgenes no se colapsarán hacia el exterior de un contenedor que esté flotando, que sea un inline-block o que tenga una posición absoluta o fija.
  • Cuando se usa una caja flexbox, los márgenes no se colapsan entre los elementos que forman parte del diseño flexible. Este también es el caso del diseño de cuadrícula (capítulo 6).
  • Los elementos con un display de table-cell no tienen margen, por lo que no se contraerán. Esto también se aplica a la table-row y a la mayoría de los otros tipos de visualización de tabla. Las excepciones son table, table-inline y table-caption.

Sin embargo, muchos de estos cambian el comportamiento de diseño del elemento, por lo que probablemente no desee aplicarlos a menos que produzcan el diseño que está buscando.

3.5. ESPACIO DE ELEMENTOS DENTRO DE UN CONTENEDOR

La interacción entre el relleno de un contenedor y los márgenes de su contenido puede ser difícil de manejar. Pongamos algunos elementos en la barra lateral y solucionemos los problemas que puedan surgir. Al final, les mostraré una técnica útil que puede simplificar enormemente las cosas.

Agregará dos botones que enlazan con páginas de redes sociales y otro enlace menos importante a la barra lateral. Su objetivo es que la barra lateral se vea como la figura 3.19.

ibid
Figura 3.19. La barra lateral con contenido debidamente espaciado

Comencemos con los dos enlaces sociales. Agréguelos a su barra lateral como se muestra en la siguiente lista. La clase de button-link será un buen objetivo para su selector de CSS.

          
<aside class="sidebar">
  <a href="/twitter" class="button-link">
    follow us on Twitter
  </a>
  <a href="/facebook" class="button-link">
    like us on Facebook
  </a>
</aside>
          
          Listado 3.15. Agregar dos botones sociales a la barra lateral
        

A continuación, aplicará estilos para la apariencia general de los botones. Los hará elementos block para que llenen el ancho del contenedor, y cada uno aparecerá en su propia línea. Agregue este CSS a su hoja de estilo.

          
.button-link {
  display: block;                1
  padding: 0.5em;
  color: #fff;
  background-color: #0090C9;
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;
}
          
          Listado 3.16. Configurar el tamaño, las fuentes y los colores de los botones de la barra lateral
        
  1. El elemento de bloque llena el ancho disponible y coloca cada vínculo en su propia línea.

Ahora los enlaces tienen el estilo correcto, pero aún necesita averiguar el espacio entre ellos. Sin márgenes, se apilarán directamente uno encima del otro, como lo hacen ahora. Tiene opciones: puede darles márgenes superior e inferior separados o ambos, donde se produciría el colapso de los márgenes entre los dos botones.

No importa qué enfoque elija, sin embargo, seguirá encontrando un problema: el margen debe funcionar junto con el relleno de la barra lateral. Si agrega margin-top: 1.5em, obtendrá el resultado que se muestra en la figura 3.20.

ibid
Figura 3.20. El margen superior agrega espacio al relleno del contenedor.

Ahora tendrá espacio adicional en la parte superior del contenedor. El margen superior del primer botón más el padding superior del contenedor producen un espacio desigual con los otros tres lados del contenedor.

Puede solucionar este problema de varias formas. El listado 3.17 muestra una de las soluciones más simples. Utiliza el combinador de hermanos adyacente (+) para apuntar solo a enlaces de botón que siguen inmediatamente a otros enlaces de botón como hermanos bajo el mismo elemento principal. Ahora el margen solo aparece entre dos botones.

          
  .button-link {
    display: block;
    padding: .5em;
    color: #fff;
    background-color: #0090C9;
    text-align: center;
    text-decoration: none;
    text-transform: uppercase;
  }
  
  .button-link + .button-link {     1
    margin-top: 1.5em;              1
  }                                 1
          
          Listado 3.17. Usar un combinador hermano adyacente para aplicar un margen entre botones
        
  1. Solo aplique un margen superior a los enlaces de botón que siguen inmediatamente a otro enlace de botón

Esto parece funcionar (figura 3.21). El primer botón ya no tiene un margen superior, por lo que el espaciado es uniforme.

ibid
Figura 3.21. Se aplica un espaciado uniforme alrededor de los botones.

3.5.1. Considerando cambiar el contenido

Estás en el camino correcto, pero el problema de espaciado vuelve a surgir tan pronto como agregas más contenido a la barra lateral. Agregue el tercer enlace a su página, como se muestra en la siguiente lista. Este tiene el enlace de patrocinador de la clase para que pueda aplicar diferentes estilos al enlace.

          
<aside class="sidebar">
  <a href="/twitter" class="button-link">
    follow us on Twitter
  </a>
  <a href="/facebook" class="button-link">
    like us on Facebook<
    </a>
  <a href="/sponsors" class="sponsor-link">    1
    become a sponsor                                 1
  </a>                                         1
</aside>
          
          Listado 3.18. Agregar un tipo diferente de enlace a la barra lateral
        
  1. Agrega un tipo diferente de enlace a la barra lateral

Dará estilo a este, pero de nuevo, tendrá que abordar la cuestión del espacio entre él y los otros botones. La figura 3.22 muestra cómo se verá el enlace antes de arreglar el margen.

ibid
Figura 3.22. El espacio entre el segundo botón y el enlace inferior está desactivado.

Los estilos para esto se muestran en la siguiente lista. Agrégalos a tu hoja de estilo. Probablemente también esté tentado a agregar un margen superior al enlace; espere eso por ahora. A continuación, les mostraré una alternativa interesante.

          
.sponsor-link {
  display: block;
  color: #0072b0;
  font-weight: bold;
  text-decoration: none;
}
          
          Listado 3.19. Agregar estilos para el enlace del patrocinador
        

Podría agregar un margen superior y se vería bien. Pero considere esto: HTML tiene la desagradable costumbre de cambiar. En algún momento, ya sea el próximo mes o el próximo año, será necesario mover o reemplazar algo en esta barra lateral. Quizás el enlace de patrocinio deba moverse a la parte superior de la barra lateral. O tal vez deba agregar un widget para suscribirse a un boletín informativo por correo electrónico.

Cada vez que las cosas cambian, tendrá que volver a examinar la cuestión de estos márgenes. Deberá asegurarse de que haya espacio entre cada artículo, pero no espacio extraño en la parte superior (o inferior) del contenedor.

3.5.2. Creando una solución más general: el selector de búhos lobotomizado

El diseñador web Heydon Pickering dijo una vez que los márgenes son "como aplicar pegamento a un lado de un objeto antes de que hayas determinado si realmente quieres pegarlo a algo o qué podría ser ese algo". En lugar de arreglar los márgenes del contenido de la página actual, vamos a arreglarlo de una manera que funcione sin importar cómo se reestructura la página. Harás esto con algo que Pickering llama un selector de búhos lobotomizado. Tiene este aspecto: * + *.

Es un selector universal (*) que apunta a todos los elementos, seguido de un combinador hermano adyacente (+), seguido de otro selector universal. Se gana su nombre porque se asemeja a la mirada vacía de un búho. El búho lobotomizado no es diferente al selector que usaste antes: .social-button + .social-button. Excepto que, en lugar de apuntar a los botones que siguen inmediatamente a otros botones, apunta a cualquier elemento que siga inmediatamente a cualquier otro elemento. Es decir, selecciona todos los elementos de la página que no son el primer hijo de su padre.

Usemos el búho lobotomizado para agregar márgenes superiores a los elementos de su página. Si lo hace, espaciará uniformemente cada elemento en su barra lateral. También apuntará al contenedor principal porque un hermano sigue inmediatamente al encabezado, proporcionando el espacio que desea allí también. El resultado se muestra en la figura 3.23.

ibid
Figura 3.23. Todos los elementos hermanos adyacentes ahora tienen un margen superior

Agregue el listado 3.20 cerca de la parte superior de su hoja de estilo. He incluido el cuerpo al principio del selector. Esto restringe el selector para apuntar solo a elementos dentro del cuerpo. Si usa el búho lobotomizado por sí solo, apuntará al elemento <body> porque es un hermano adyacente del elemento <head>.

          
body * + * {
  margin-top: 1.5em;
}
          
          Listado 3.20. Objetos apilados en el espacio global con el búho lobotomizado
        

Es posible que le preocupen las implicaciones de rendimiento del selector universal (*). En IE6, era increíblemente lento, por lo que los desarrolladores evitaron usarlo. Hoy en día, esto ya no es una preocupación porque los navegadores modernos lo manejan bien. Además, usarlo en el búho lobotomizado reduce potencialmente la cantidad de selectores en su hoja de estilo, porque corrige globalmente la mayoría de los elementos. De hecho, podría ser más eficaz, dependiendo de los detalles de su hoja de estilo.

El margen superior del búho lobotomizado tiene un efecto secundario no deseado en la barra lateral. Debido a que la barra lateral es un hermano adyacente de la columna principal, también recibe un margen superior. Tendrás que revertir eso a cero. También tendrá que agregar relleno a las columnas principales porque aún no lo ha hecho. Actualice la parte correspondiente de su hoja de estilo para que coincida con la lista que se muestra aquí.

          
  .main {
    width: 70%;
    padding: 1em 1.5em;             1
    background-color: #fff;
    border-radius: .5em;
  }
  
  .sidebar {
    width: 30%;
    padding: 1.5em;
    margin-top: 0;                  2
    margin-left: 1.5em;
    background-color: #fff;
    border-radius: .5em;
  }
          
          Listado 3.21. Toques finales
        
  1. Agrega relleno a la columna principal
  2. Elimina el margen superior aplicado por el búho lobotomizado

Estos son los toques finales para tu página. Ahora debería verse como la figura 3.24.

ibid
Figura 3.24. Página final con un diseño de dos columnas

Usar el búho lobotomizado de esta manera es una compensación. Simplifica muchos márgenes en toda la página, pero tendrá que anularlo en lugares donde no desee que se aplique. Por lo general, esto solo ocurrirá en lugares donde haya elementos uno al lado del otro, como con diseños de varias columnas. Dependiendo de su diseño, también deberá establecer los márgenes deseados en los párrafos y encabezados.

Usaré el búho lobotomizado en más ejemplos en los próximos capítulos para ayudarlo a tener una idea de las compensaciones involucradas. Es posible que el búho lobotomizado no sea la solución correcta para todos los proyectos, y es difícil agregarlo a un proyecto existente sin romper el diseño, pero considérelo la próxima vez que inicie un nuevo sitio web o aplicación web.

          
:root {
  box-sizing: border-box;
}
  
*,
::before,
::after {
  box-sizing: inherit;
}
  
body {
  background-color: #eee;
  font-family: Helvetica, Arial, sans-serif;
}
  
body * + * {
  margin-top: 1.5em;
}
  
header {
  padding: 1em 1.5em;
  color: #fff;
  background-color: #0072b0;
  border-radius: .5em;
}
  
.container {
  display: flex;
}
  
.main {
  width: 70%;
  padding: 1em 1.5em;
  background-color: #fff;
  border-radius: .5em;
}
  
.sidebar {
  width: 30%;
  padding: 1.5em;
  margin-top: 0;
  margin-left: 1.5em;
  background-color: #fff;
  border-radius: .5em;
}
  
  .button-link {
    display: block;
    padding: .5em;
    color: #fff;
    background-color: #0090C9;
    text-align: center;
    text-decoration: none;
    text-transform: uppercase;
  }
  
.sponsor-link {
  display: block;
  color: #0072b0;
  font-weight: bold;
  text-decoration: none;
}
          
          Listado 3.22. Hoja de estilo final
        

RESUMEN

  • Utilice siempre una corrección de border-box universal para un tamaño de elemento predecible.
  • Evite establecer explícitamente la altura de un elemento para evitar problemas de desbordamiento.
  • Utilice técnicas de diseño modernas como display: table o flexbox para producir columnas de igual altura o para centrar el contenido verticalmente.
  • Si sus márgenes se comportan de manera extraña, tome medidas para evitar que se derrumben.
  • Considere usar el selector de búho lobotomizado en su página para aplicar márgenes globalmente entre elementos apilados.