¿Hay alguna manera de obtener un diseño de 2 columnas que se transforme en un diseño de 1 columna con una consulta de medios?

Condiciones para el diseño de 2 columnas:

  1. los elementos deben fluir uno tras otro dentro de las columnas
  2. los elementos dentro de las columnas tendrán diferentes alturas
  3. la posición del elemento (orden) puede ser impuesta por la posición del elemento de marcado html

Condiciones para el diseño de 1 columna:

  1. los elementos deben fluir uno tras otro
  2. los elementos dentro de las columnas tendrán diferentes alturas
  3. la posición del elemento (!) no puede ser impuesta por el marcado html (debe controlarse sobre css)

layout visualization

He estado considerando dos contenedores separados para columnas, pero esa construcción me bloquea para reordenar (mezclar) elementos entre columnas cuando el diseño se convierte en 1 columna. Parece que todos los elementos deben colocarse dentro de un contenedor; luego, para el diseño de 1 columna, se puede usar flex para reordenar, pero ¿cómo lograr el diseño de 2 columnas en ese caso?

Para simular el comportamiento de las consultas de medios, elimine la clase "una columna" del contenedor principal.

<div id="container" class="one-column"> -> <div id="container" class="">

En este concepto, el problema principal es que los elementos dentro de las columnas (diseño de 2 columnas) no fluyen directamente uno tras otro (hay espacios entre los elementos en la columna de la derecha).

Esto es lo que logré hasta ahora:

* {
  box-sizing: border-box;
}
div {
  width: 100%;
  height: 100px;
  float: left;
}
#container.one-column {
  display: flex;
  flex-direction: column;
  height: auto;
}
#container {
  display: block;
}
.col1 {
  width: 60%;
  background-color: red;
  height:300px;
  float: left;
}
.col2 {
  width: 40%;
  background-color: blue;
  border: 1px solid white;
  float: right;
}
.one-column > div {
  width: 100%;
}
<div id="container" class="one-column">
  <div class="col1" style="order:2;">
    ONE
  </div>
  <div class="col2" style="order:1;">
    TWO
  </div>
  <div class="col1" style="order:4;">
    THREE
  </div>  
  <div class="col2" style="order:3;">
    FOUR
  </div>
</div>

JSFiddle: https://jsfiddle.net/3b6htt1d/40/

5
IT Man 25 feb. 2018 a las 01:59

2 respuestas

La mejor respuesta

Condiciones para el diseño de 2 columnas:

  1. los elementos deben fluir uno tras otro dentro de las columnas
  2. los elementos dentro de las columnas tendrán diferentes alturas
  3. la posición del elemento (orden) puede ser impuesta por la posición del elemento de marcado html

Eso es exactamente lo que hace CSS Columns.

Condiciones para el diseño de 1 columna:

  1. los elementos deben fluir uno tras otro
  2. los elementos dentro de las columnas tendrán diferentes alturas
  3. la posición del elemento (!) no puede ser impuesta por el marcado html (debe controlarse sobre css)

Eso es exactamente lo que se puede hacer con Flexbox y la dirección column.


Entonces, si uno combina los dos, para 2 columnas, como se muestra en la muestra de imagen de la izquierda, fluirán de arriba hacia abajo, y para 1 columnas, puede controlar su posición con order.

Con esto evitas alturas fijas y obtienes artículos de tamaño dinámico / flexible.

Violín actualizado

Fragmento de pila

* {
  box-sizing: border-box;
}
div {
  width: 100%;
  height: 100px;
}
#container.one-column {
  display: flex;
  flex-direction: column;
  height: auto;
}
.col1 {
  width: 60%;
  background-color: red;
  height:300px;
}
.col2 {
  width: 40%;
  background-color: blue;
  border: 1px solid white;
}
.one-column > div {
  width: 100%;
}

@media (min-width: 500px) {
  #container.one-column {
    display: block;
    columns: 2;
  }
  #container.one-column > div {
    -webkit-column-break-inside: avoid;
    page-break-inside: avoid;
    break-inside: avoid;
  }
  .zcol1 ~ .col1 {
    background-color: yellow;
    height:100px;
  }
}
<div id="container" class="one-column">
  <div class="col1" style="order:2;">
    ONE
  </div>
  <div class="col2" style="order:1;">
    TWO
  </div>
  <div class="col1" style="order:4;">
    THREE
  </div>  
  <div class="col2" style="order:3;">
    FOUR
  </div>
</div>

Aquí hay otra respuesta mía, que podría ser otra opción, combinando Flexbox con float.


Actualizado según un comentario

Aquí hay una versión que combina Flexbox y float, que producen el diseño que muestra la captura de pantalla:

3
Ason 6 mar. 2018 a las 19:44

El diseño de 2 columnas también debe hacerse usando flex.

El único problema real es forzar una envoltura en el punto que desea que sea.

El mejor enfoque es donde puede establecer una altura definida para el contenedor. En este caso, forzar el ajuste se puede hacer con un pseudo elemento:

* {
  box-sizing: border-box;
}
div {
  width: 100%;
  height: 100px;
  border: 1px solid white;
}
.container {
  display: flex;
  flex-direction: column;
  height: auto;
  margin-top: 5px;
}
.col1 {
  width: 60%;
  background-color: red;
  height:300px;
}
.col2 {
  width: 40%;
  background-color: blue;
}
.one-column > div {
  width: 100%;
}
.two-column {
    flex-wrap: wrap;
    max-height: 800px;
}
.two-column:after {
    content: "";
    width: 10px;
    height: 10px;
    background-color: yellow;
    order: 2;
    margin-top: 1000px;
}
.two-column .col1 {
    order: 1;
}
.two-column .col2 {
    order: 3;
}
<div class="container two-column">
  <div class="col1">
    ONE
  </div>
  <div class="col2">
    TWO
  </div>
  <div class="col1">
    THREE
  </div>  
  <div class="col2">
    FOUR
  </div>
</div>
<div class="container one-column">
  <div class="col1">
    ONE
  </div>
  <div class="col2">
    TWO
  </div>
  <div class="col1">
    THREE
  </div>  
  <div class="col2">
    FOUR
  </div>
</div>
0
vals 25 feb. 2018 a las 11:25