Generar un grid con un div que ocupe más de una fila en Bootstrap 4

publicado por: Anonymous

Estaba utilizando una versión 3 de Bootstrap. Ahora que actualicé a la versión 4 tengo el siguiente problema:

introducir la descripción de la imagen aquí

Me funcionaba con Bootstrap 3 (ver en página completa):

_x000D_

_x000D_

.titulo {_x000D_
  height: 200px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}_x000D_
_x000D_
.dato {_x000D_
  height: 100px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}

_x000D_

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />_x000D_
_x000D_
<div class="row">_x000D_
  <div class="titulo col-lg-3 col-md-4 col-sm-4">Titulo</div>_x000D_
_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">1</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">2</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">3</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">4</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">5</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">6</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">7</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">8</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">9</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">10</div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

Y el mismo código me dejó de funcionar con Bootstrap 4:

_x000D_

_x000D_

.titulo {_x000D_
  height: 200px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}_x000D_
_x000D_
.dato {_x000D_
  height: 100px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}

_x000D_

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">_x000D_
_x000D_
<div class="row">_x000D_
  <div class="titulo col-lg-3 col-md-4 col-sm-4">Titulo</div>_x000D_
_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">1</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">2</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">3</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">4</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">5</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">6</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">7</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">8</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">9</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">10</div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

Pregunta:
¿Cómo puedo hacer para que el div .titulo ocupe 2 filas, y los divs .dato se acomoden de forma responsiva, utilizando el espacio restante, de acuerdo a si es un dispositivo sm o lg? Los divs tienen un alto fijo (el título es 2 veces el alto del resto).


Vale aclarar que armo las cajas pequeñas dinámicamente con un ngFor de angular, por lo tanto dividirlas dentro de contenedores de forma fija no es una opción. El código que tengo para generarlas es:

<div class="dato col-lg-3 col-md-4 col-sm-6" 
*ngFor="let dato of datos">
    {{dato.nombre}}
</div>

solución

Antes que nada, quiero aclarar que no conozco Angular, y asumo por lo que dice el OP que la estructura del HTML generado no se puede modificar por algún motivo.

El problema en este caso y por el cual no funciona el código con Bootstrap 4 (pero sí con Bootstrap 3), es porque la versión 4 utiliza flexbox para generar sus layouts de grillas, mientras la versión 3 utiliza el típico y antiguo esquema de float: left con elementos de bloque.

Flexbox es un Box Module de CSS que fue diseñado para generar layouts unidimensionales, o sea, en una sola dirección, bien sea columnas o filas.

En este caso se intenta generar un layout bidimensional, lo cual lo convierte una grilla y por lo cual Flexbox “se queda corto”. Para eso existen las Grillas de CSS. Ver ejemplos básicos de grillas.

Hay muchas soluciones a este problema, y teniendo en cuenta que no hay una flexibilidad a nivel de HTML ni del framework CSS utilizado, hay que plantear una solución que personalmente no prefiero, ni me parece la más adecuada o “limpia”.

Mi solución consiste en retroceder y “emular” el comportamiento de Bootstrap 3 para esta “grilla” específica, devolviendo el contenedor .row a que sea un bloque (y no un contenedor de flexbox), y haciendo que las columnas de dicho “row” utilicen float: left;

_x000D_

_x000D_

.titulo {_x000D_
  height: 200px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}_x000D_
_x000D_
.dato {_x000D_
  height: 100px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}_x000D_
_x000D_
.row {_x000D_
  display: block !important;_x000D_
}_x000D_
_x000D_
[class*="col-md-"] {_x000D_
  float: left;_x000D_
}

_x000D_

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">_x000D_
_x000D_
<div class="row">_x000D_
  <div class="titulo col-lg-3 col-md-4 col-sm-4">Titulo</div>_x000D_
_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">1</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">2</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">3</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">4</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">5</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">6</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">7</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">8</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">9</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4">10</div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

Considero esta la solución más sencilla, pero pueden haber mejores soluciones que esta, pero requieren probablemente un amplio refactoring:

  • Utilizar grillas para CSS y no aplicar Bootstrap a esta “grilla”.
  • Utilizar un framework enfocado a grillas.
  • Cambiar la orientación de Flexbox de Bootstrap y realinear todo (complicado en mi opinión).
  • Cambiar el display a table para el contenedor.
  • Cambiar el HTML generado por Angular para que se ajuste a Bootstrap 4 (ver la respuesta de Willian).

EDICIÓN:

Gracias a la sugerencia de Mariano, vemos que no es necesario agregar CSS adicional, utilizando las clases “helper” de Bootstrap: d-block y float-left, pero sí es necesario modificar ligeramente el HTML generado por Angular.

_x000D_

_x000D_

.titulo {_x000D_
  height: 200px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}_x000D_
_x000D_
.dato {_x000D_
  height: 100px;_x000D_
  background: #666;_x000D_
  border: 1px solid #333;_x000D_
}

_x000D_

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">_x000D_
_x000D_
<div class="row d-block">_x000D_
  <div class="titulo col-lg-3 col-md-4 col-sm-4 float-left">Titulo</div>_x000D_
_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">1</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">2</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">3</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">4</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">5</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">6</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">7</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">8</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">9</div>_x000D_
  <div class="dato col-lg-3 col-md-4 col-sm-4 float-left">10</div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *