Cambiar el orden de los div con CSS según el ancho del dispositivo

Resuelto 3ocene asked hace 8 años • 1 respuestas

Estoy trabajando en un sitio responsivo y encontré un problema interesante. Tengo algunos divs uno al lado del otro. Podría haber entre 2 y 6 aproximadamente. Cuando la pantalla no es lo suficientemente ancha para mostrar todo el contenido correctamente, los divs se apilan verticalmente. Lo suficientemente simple como para hacerlo con CSS.

El problema es que necesito que estén en un orden diferente según el diseño. Esto es fácil de hacer con 2 o 3 divs ( cambiar el orden de los divs según el ancho ), pero mucho más desafiante cuando agrega un cuarto.

Podría usar position: absolute;y configurar manualmente la posición, sin embargo, esto hace que el padre se reduzca y no los contenga correctamente.

Para hacer esto aún más complicado, no puedo usar JavaScript.

Trabajando con dos columnas:

(no probado)

HTML:

<div id="container">
    <div class="column-half column-half-2">
        First div on mobile, right div on desktop
    </div>
    <div class="column-half column-half-1">
        Second div on mobile, left div on desktop
    </div>
</div>

CSS:

.container {
    width: 80%;
    max-width: 1200px;
    margin: 0 auto;
    padding-bottom: 20px;
    position: relative;
}
.column-half {
    display: table-cell;
    padding: 25px;
    vertical-align: top;
    width: 40%;
}
.column-half-1 {
    float: left;
}
.column-half-2 {
    float: right;
}

HTML, con 4 columnas:

<div id="container">
    <div class="column-quarter column-quarter-3">
        First div on mobile, third div on desktop
    </div>
    <div class="column-quarter column-quarter-2">
        Second div on mobile, second div on desktop
    </div>
    <div class="column-quarter column-quarter-1">
        Third div on mobile, first div on desktop
    </div>
    <div class="column-quarter column-quarter-4">
        Fourth div on mobile, fourth div on desktop
    </div>
</div>
3ocene avatar Sep 29 '15 01:09 3ocene
Aceptado

Esto es factible en CSS gracias a la maravillosa especificación flexbox . Usando las propiedades ordery flex-flow, podemos lograr lo que deseas. Sin prefijos, IE11 y todos los navegadores tradicionales lo admitirán. Prefijos IE10 -ms-ordery no admite flex-flow.

La solución tiene en cuenta todas las restricciones que enumeró:

  • Tener una lista de elementos en un orden determinado mostrado como una fila.
  • Cuando la ventana sea demasiado pequeña, cámbiela para que se muestre en una columna.
  • Cambia el orden de los elementos cuando se muestran en una columna.

Debido a las limitaciones de Stack Snippets, deberá ver la demostración en modo de página completa y cambiar el tamaño de su navegador para ver el efecto.

.container div {
    width: 100px;
    height: 50px;
    display: inline-block;
}

.one { background: red; }
.two { background: orange; }
.three { background: yellow; }
.four { background: green; }
.five { background: blue; }

@media screen and (max-width: 531px) {
    .container { display: flex; flex-flow: column; }
    .five { order: 1; }
    .four { order: 2;  }
    .three { order: 3; }
    .two { order: 4; }
    .one { order: 5 }
}
<div class="container">
    <div class="one">I'm first</div>
    <div class="two">I'm second</div>
    <div class="three">I'm third</div>
    <div class="four">I'm fourth</div>
    <div class="five">I'm fifth</div>
</div>
Expandir fragmento

Alternativamente, aquí hay una demostración de JSFiddle .


También puede usarlo simplemente flex-flow: column-reversesin la orderpropiedad asignada a cada div, si así lo prefiere el CSS detallado. Se aplican las mismas restricciones de demostración; Vea esta demostración en pantalla completa y cambie el tamaño de la ventana del navegador en consecuencia.

.container div {
    width: 100px;
    height: 50px;
    display: inline-block;
}

.one { background: red; }
.two { background: orange; }
.three { background: yellow; }
.four { background: green; }
.five { background: blue; }

@media screen and (max-width: 531px) {
    .container { display: flex; flex-flow: column-reverse; }
}
<div class="container">
    <div class="one">I'm first</div>
    <div class="two">I'm second</div>
    <div class="three">I'm third</div>
    <div class="four">I'm fourth</div>
    <div class="five">I'm fifth</div>
</div>
Expandir fragmento

Vale la pena señalar que flex-flowes una propiedad abreviada que abarca tanto las propiedades flex-directioncomo flex-wrap.

TylerH avatar Sep 28 '2015 18:09 TylerH