flutter-modelo-cajas-container-decoration

Modelo de cajas en Flutter: Container, padding y decoración

  • 4 min

El modelo de cajas es la forma en la que Flutter da tamaño, espacio y estilo a los elementos visuales.

Hasta ahora nuestras Apps han sido funcionales, pero feas. Textos negros sobre fondo blanco. Ha llegado el momento de ponerlas bonitas.

Si vienes del desarrollo web, estarás acostumbrado a tener el HTML (estructura) por un lado y el CSS (estilo) por otro. En Flutter eso no existe. Aquí, la estructura y el estilo están fusionados en el mismo árbol de Widgets.

Para diseñar, necesitamos entender el Modelo de Cajas. Todo en Flutter es una caja rectangular, y hoy vamos a aprender a manipularla con el widget más polivalente de todos: el Container.

El widget Container

El Container es la navaja suiza de Flutter. Combina pintura, posicionamiento y tamaño de widgets. Es, esencialmente, una caja que puede tener:

  • Ancho y alto (width, height).
  • Color de fondo.
  • Borde y sombras.
  • Márgenes y relleno.
Container(
  width: 200,
  height: 100,
  color: Colors.blue,
  child: Text("Soy una caja"),
)
Copied!

Padding y margin

Esta es la duda eterna, pero la distinción es sencilla si miramos la caja:

Padding

Es el espacio INTERNO. Es la distancia entre el borde de la caja y su contenido (el hijo).

  • Efecto: Hace la caja “más gorda” o empuja el contenido hacia dentro.
  • Ejemplo: El aire dentro de un botón para que el texto no toque los bordes.

Margin

Es el espacio EXTERNO. Es la distancia entre la caja y sus vecinos.

  • Efecto: Empuja a los otros widgets para alejarlos.
  • Ejemplo: El espacio entre dos tarjetas en una lista.
Container(
  margin: EdgeInsets.all(20),  // Espacio FUERA de la caja azul
  padding: EdgeInsets.all(20), // Espacio DENTRO de la caja (alrededor del texto)
  color: Colors.blue,
  child: Text("Hola"),
)
Copied!

EdgeInsets para controlar las distancias

Tanto para el margen como para el padding, Flutter usa la clase EdgeInsets (Inserciones de Borde) para definir los valores. Tenemos varios constructores muy útiles:

  • EdgeInsets.all(10): aplica 10 píxeles lógicos a los cuatro lados.
  • EdgeInsets.symmetric(horizontal: 20, vertical: 10): Muy usado en botones. 20 a los lados, 10 arriba y abajo.
  • EdgeInsets.only(top: 15, left: 10): Aplica solo donde tú digas.
  • EdgeInsets.fromLTRB(left, top, right, bottom): Control total (más verboso).

BoxDecoration para estilizar la caja

Si solo quieres poner un color de fondo, la propiedad color del Container basta. Pero si quieres bordes redondeados, sombras, degradados o imágenes de fondo, necesitas la propiedad decoration.

Esta propiedad recibe un objeto BoxDecoration.

Container(
  width: 300,
  height: 150,
  decoration: BoxDecoration(
    color: Colors.white, // El color de fondo va AQUÍ dentro
    
    // Bordes redondeados
    borderRadius: BorderRadius.circular(20),
    
    // Borde de línea
    border: Border.all(
      color: Colors.blueAccent,
      width: 4,
    ),
    
    // Sombras (Lista de sombras)
    boxShadow: [
      BoxShadow(
        color: Colors.black26, // Color con transparencia
        blurRadius: 10,        // Cuánto se difumina
        offset: Offset(5, 5),  // Desplazamiento (X, Y)
      )
    ],
  ),
  child: Center(child: Text("Caja con Estilo")),
)
Copied!

El error clásico del color

Presta atención a esto: el Container tiene una propiedad color y otra decoration.

No puedes usar color y decoration a la vez.

Si usas decoration, el color de fondo DEBE ir dentro del BoxDecoration. Si lo dejas fuera, Flutter lanzará un error en tiempo de ejecución (la famosa pantalla roja).

// ❌ MAL: Dará error
Container(
  color: Colors.red, 
  decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
)

// ✅ BIEN
Container(
  decoration: BoxDecoration(
    color: Colors.red, // El color se mueve aquí dentro
    borderRadius: BorderRadius.circular(10),
  ),
)
Copied!

Dimensiones y restricciones

Por último, hablemos del tamaño.

  • width y height: Fijan un tamaño específico en píxeles lógicos.
  • double.infinity: Le dice al Container que intente ocupar todo el ancho (o alto) posible que le permita su padre.
Container(
  width: double.infinity, // Ocupa todo el ancho de la pantalla
  height: 100,
  color: Colors.green,
)
Copied!

El tamaño de un Container siempre depende de las restricciones que recibe de su padre. Sin hijo ni tamaño propio suele intentar ocupar todo el espacio permitido; con un hijo, normalmente intenta ajustarse a él, siempre dentro de esas restricciones.

Widgets especializados

Aunque el Container puede hacerlo todo, a veces es más eficiente y legible usar widgets específicos si solo necesitas una cosa:

  • ¿Solo necesitas espacio interno? Usa el widget Padding.
  • ¿Solo necesitas centrar? Usa el widget Center.
  • ¿Solo necesitas fijar un tamaño? Usa el widget SizedBox.