tutorial framework example español css flexbox grid-layout

example - grid css framework



Flex-box: alinear la última fila a la cuadrícula (23)

Tengo un diseño de caja flexible simple con un contenedor como:

.grid { display: flex; flex-flow: row wrap; justify-content: space-between; }

Ahora quiero que los elementos de la última fila estén alineados con el otro. justify-content: space-between; debe utilizarse porque el ancho y la altura de la rejilla se pueden ajustar.

Actualmente parece

Aquí, quiero que el elemento en la parte inferior derecha esté en la "columna central". ¿Cuál es la forma más sencilla de lograr eso? Aquí hay un pequeño jsfiddle que muestra este comportamiento.


Agregue un ::after cual rellene automáticamente el espacio. No hay necesidad de contaminar tu HTML. Aquí hay un código que lo muestra: http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid { display: flex; flex-flow: row wrap; justify-content: space-between; } .grid::after { content: ""; flex: auto; }


Aquí hay otro par de mixins scss.

Estas combinaciones suponen que no vas a utilizar complementos js como Isotope (no respetan el orden de marcado html, por lo que se equivocan con las reglas del css nth).

Además, podrá aprovecharlos al máximo, especialmente si está escribiendo sus puntos de interrupción de respuesta de manera móvil. Lo ideal es utilizar flexbox_grid () en el punto de interrupción más pequeño y flexbox_cell () en los siguientes puntos de interrupción. flexbox_cell () se encargará de restablecer los márgenes establecidos previamente que ya no se usan en puntos de interrupción más grandes.

Y, por cierto, siempre que configure correctamente las propiedades de flexión de su contenedor, también puede usar solo flexbox_cell () en los elementos, si lo necesita.

Aquí está el código:

// apply to the container (for ex. <UL> element) @mixin flexbox_grid($columns, $gutter_width){ display: flex; flex-direction:row; flex-wrap:wrap; justify-content: flex-start; > *{ @include flexbox_cell($columns, $gutter_width); } } // apply to the cell (for ex. a <LI> element) @mixin flexbox_cell($columns, $gutter_width){ $base_width: 100 / $columns; $gutters: $columns - 1; $gutter_offset: $gutter_width * $gutters / $columns; flex-grow: 0; flex-shrink: 1; flex-basis: auto; // IE10 doesn''t support calc() here box-sizing:border-box; // so you can freely apply borders/paddings to items width: calc( #{$base_width}% - #{$gutter_offset} ); // remove useless margins (for cascading breakponts) &:nth-child(#{$columns}n){ margin-right: 0; } // apply margin @for $i from 0 through ($gutters){ @if($i != 0){ &:nth-child(#{$columns}n+#{$i}){ margin-right: $gutter_width; } } } }

Uso:

ul{ // just this: @include flexbox_grid(3,20px); } // and maybe in following breakpoints, // where the container is already setted up, // just change only the cells: li{ @include flexbox_cell(4,40px); }

Obviamente, depende de usted establecer eventualmente el relleno / margen / ancho del contenedor y los márgenes inferiores de la celda y similares.

¡Espero eso ayude!


Asumiendo:

  • Desea diseño de cuadrícula de 4 columnas con envoltura
  • El número de elementos no es necesariamente un múltiplo de 4

Establezca un margen izquierdo en cada elemento, excepto el 1º, 5º y 9º, y así sucesivamente. Si el margen izquierdo es 10px, entonces cada fila tendrá un margen de 30px entre 4 elementos. El porcentaje de ancho para el artículo se calcula de la siguiente manera:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Esta es una solución decente para problemas relacionados con la última fila de flexbox.

.flex { display: flex; flex-direction: row; flex-wrap: wrap; margin: 1em 0; background-color: peachpuff; } .item { margin-left: 10px; border: 1px solid; padding: 10px; width: calc(100% / 4 - 22px - 2px - 10px * (4 - 1) / 4); background-color: papayawhip; } .item:nth-child(4n + 1) { margin-left: 0; } .item:nth-child(n + 5) { margin-top: 10px; }

<div class="flex"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> </div> <div class="flex"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> </div> <div class="flex"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> <div class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div>


Como han mencionado otros carteles, no hay una forma clara de alinear a la izquierda la última fila con flexbox (al menos según la especificación actual)

Sin embargo, para lo que vale: con el módulo de diseño de cuadrícula CSS es sorprendentemente fácil de producir:

Básicamente el código relevante se reduce a esto:

ul { display: grid; /* 1 */ grid-template-columns: repeat(auto-fill, 100px); /* 2 */ grid-gap: 1rem; /* 3 */ justify-content: space-between; /* 4 */ }

1) Hacer el elemento contenedor un contenedor de rejilla.

2) Establecer la cuadrícula con columnas automáticas de ancho 100px. (Tenga en cuenta el uso de la auto-fill de auto-fill (como corresponde a la auto-fit , que (para un diseño de 1 fila) colapsa las pistas vacías a 0), lo que hace que los elementos se expandan para ocupar el espacio restante. espacio entre diseño ''cuando la cuadrícula tiene solo una fila, que en nuestro caso no es lo que queremos (vea esta demostración para ver la diferencia entre ellos).

3) Establezca espacios / canales para las filas y columnas de la cuadrícula; aquí, ya que desea un diseño de ''espacio intermedio'', el espacio será un espacio mínimo ya que crecerá según sea necesario.

4) Similar a flexbox.

ul { display: grid; grid-template-columns: repeat(auto-fill, 100px); grid-gap: 1rem; justify-content: space-between; /* boring properties */ list-style: none; background: wheat; padding: 2rem; width: 80vw; margin: 0 auto; } li { height: 50px; border: 1px solid green; }

<ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul>

Codepen Demo (Redimensionar para ver el efecto)


Es posible utilizar "flex-start" y agregar los márgenes manualmente. Requiere un poco de pirateo matemático, pero es definitivamente fácil de hacer y hace que sea fácil de usar con un preprocesador CSS como LESS.

Vea por ejemplo esta mezcla MENOS:

.flexboxGridMixin(@columnNumber,@spacingPercent) { @contentPercent: 100% - @spacingPercent; @sideMargin: @spacingPercent/(@columnNumber*2); display: flex; flex-direction: row; flex-wrap: wrap; justify-content: flex-start; > * { box-sizing: border-box; width: @contentPercent/@columnNumber; margin-left: @sideMargin; margin-right: @sideMargin; } }

Y luego se puede usar fácilmente para mostrar un diseño de cuadrícula sensible:

ul { list-style: none; padding: 0; @spacing: 10%; @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); } @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); } @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); } @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); } @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); } } li { background: pink; height: 100px; margin-top: 20px; }

Aquí hay un ejemplo de

http://codepen.io/anon/pen/YyLqVB?editors=110


Esta es una combinación de muchas de las respuestas, pero hace exactamente lo que necesitaba, es decir, alinear el último niño en un contenedor flexible a la izquierda mientras se mantiene el espacio entre el comportamiento (en este caso es una columna de tres columnas). diseño).

Aquí está el marcado:

.flex-container { display: flex; justify-content: space-between; flex-direction: row; } .flex-container:after { content: ""; flex-basis: 30%; }


Esta versión es la mejor manera para bloques con ancho fijo:

http://codepen.io/7iomka/pen/oxxeNE

En otros casos - versión de dalgard.

http://codepen.io/dalgard/pen/Dbnus

body { padding: 5%; } div { overflow: hidden; background-color: yellow; } ul { display: flex; flex-wrap: wrap; justify-content:center; margin: 0 -4px -4px 0; list-style: none; padding: 0; } li { flex: 1 0 200px; height: 200px; max-width:200px; min-width:200px; border-right: 4px solid black; border-bottom: 4px solid black; background-color: deeppink; } li:empty { height: 0; border: none; } *, :before, :after { box-sizing: border-box; }

<div> <ul> <li>a</li> <li>b</li> <li>c</li> <li>d</li> <li>e</li> <li>f</li> <li>g</li> <li>h</li> <li>i</li> <li>j</li> <li>k</li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </div>


Esto es bastante raro, pero funciona para mí. Estaba tratando de lograr espacios / márgenes consistentes.

.grid { width: 1024px; display: flex; flex-flow: row wrap; padding: 32px; background-color: #ddd; &:after { content: ""; flex: auto; margin-left:-1%; } .item { flex: 1 0 24.25%; max-width: 24.25%; margin-bottom: 10px; text-align: center; background-color: #bbb; &:nth-child(4n+2), &:nth-child(4n+3), &:nth-child(4n+4) { margin-left: 1%; } &:nth-child(4n+1):nth-last-child(-n+4), &:nth-child(4n+1):nth-last-child(-n+4) ~ .item { margin-bottom: 0; } } }

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/


Esto se puede lograr simplemente con flex-start y max-width.

https://codepen.io/moladukes/pen/NvzBrQ

.container { display: flex; justify-content: flex-start; flex-flow: row wrap; } .item { width: 130px; max-width: 130px; height: 180px; background: red; margin: 20px; }


Existe una forma sin flexbox, aunque necesitaría cumplir las siguientes condiciones. 1) El contenedor tiene relleno. 2) Los artículos son del mismo tamaño y usted sabe exactamente cuántos desea por línea.

ul { padding: 0 3% 0 5%; } li { display: inline-block; padding: 0 2% 2% 0; width: 28.66%; }

El relleno más pequeño en el lado derecho del contenedor permite el relleno adicional a la derecha de cada elemento de la lista. Suponiendo que otros elementos en el mismo elemento primario que el objeto de la lista se rellenan con 0 5%, quedarán al mismo nivel que ellos. También puede ajustar los porcentajes según el margen que desee o usar calcular los valores de px.

Por supuesto, puede hacer lo mismo sin el relleno en el contenedor utilizando nth-child (IE 9+) para eliminar el margen en cada tercer cuadro.


Hice una mezcla SCSS para ello.

@mixin last-row-flexbox($num-columns, $width-items){ $filled-space: $width-items * $num-columns; $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1)); $num-cols-1 : $num-columns - 1; &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & { margin-left: $margin; } @for $i from 1 through $num-columns - 2 { $index: $num-columns - $i; &:nth-child(#{$num-columns}n+#{$index}):last-child{ margin-right: auto; } } }

Este es el enlace del código: http://codepen.io/diana_aceves/pen/KVGNZg

Solo tienes que configurar el ancho de los elementos en porcentaje y número de columnas.

Espero que esto pueda ayudarte.


Oh chico, creo que encontré una buena solución con un mínimo de CSS y sin JS. Echale un vistazo:

img {width:100%;} li { display: inline-block; width:8em; list-style:none; } ul {text-align: justify;}

<ul> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li> <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" /> </li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul>

La clave aquí es recordar que lo que estamos tratando de lograr es exactamente lo que text-align: justify hace!

Los elementos vacíos en el HTML están ahí para hacer que la última fila se muestre perfectamente sin cambiar la apariencia, pero es posible que no sean necesarios dado lo que está tratando de lograr. Para lograr un equilibrio perfecto en cada situación, necesita al menos x-4 elementos vacíos, siendo x el número de elementos para mostrar, o n-2, n es el número de columnas que desea mostrar.


Parece que nadie propuso la solución de crecimiento flexible en el último artículo. La idea es tener su último elemento flexible para tomar todo el lugar que pueda usando flex-grow: 1.

.grid { display: flex; flex-flow: row wrap; justify-content: space-between; } .grid > *:last-child { flex-grow: 1; }

Nota: esta solución no es perfecta, especialmente si tiene elementos centrados dentro de sus elementos de flexión, ya que se centrará en el elemento de la última flexión posiblemente enorme.


Pude hacerlo con justify-content: space-between en el contenedor


Sí.! Podemos, pero con algunas consultas de medios y el número máximo de columnas está predefinido .

Aquí estoy usando 4 columnas. Revisa mi código:

.container { display: flex; display: -webkit-flex; display: -moz-flex; flex-flow: row wrap; -webkit-flex-flow: row wrap; -moz-flex-flow: row wrap; } .container .item { display: flex; display: -webkit-flex; display: -moz-flex; justify-content: center; -webkit-justify-content: center; -moz-justify-content: center; flex-basis: 25%; //max no of columns in %, 25% = 4 Columns } .container .item .item-child { width: 130px; height: 180px; background: red; margin: 10px; } @media (max-width: 360px) { .container .item { flex-basis: 100%; } } @media (min-width:360px) and (max-width: 520px) { .container .item { flex-basis: 50%; } } @media (min-width:520px) and (max-width: 680px) { .container .item { flex-basis: 33.33%; } }

<div class="container"> <div class="item"> <div class="item-child">1</div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> <div class="item"> <div class="item-child"></div> </div> </div>

NOTA
1) No hay necesidad de crear div niño. Puede ser cualquier otra etiqueta como ''img'' r lo que quieras ..
2) Si desea más columnas, ajuste las consultas de los medios y el número máximo de columnas.


Si desea alinear el último elemento con la cuadrícula, utilice el siguiente código:

Contenedor de rejilla

.card-grid { box-sizing: border-box; max-height: 100%; display: flex; flex-direction: row; -webkit-box-orient: horizontal; -webkit-box-direction: normal; justify-content: space-between; align-items: stretch; align-content: stretch; -webkit-box-align: stretch; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-flow: row wrap; flex-flow: row wrap; } .card-grid:after { content: ""; flex: 1 1 100%; max-width: 32%; }

Elemento en la cuadrícula

.card { flex: 1 1 100%; box-sizing: border-box; -webkit-box-flex: 1; max-width: 32%; display: block; position: relative; }

El truco consiste en establecer el ancho máximo del elemento igual al ancho máximo de la .card-grid: después.

Demostración en vivo en Codepen


Si desea una cuadrícula con algo de espacio entre los elementos y los elementos que comienzan sin ningún espacio inicial, esta simple solución funciona:

.grid { display: flex; flex-flow: row wrap; margin: 0 -5px; // remove the inital 5px space width: auto; } .grid__item { width: 25%; padding: 0 5px; // should be same as the negative margin above. }

Si desea el espacio inicial de 5px, simplemente elimine el margen negativo :) Simple.

La respuesta aceptada, aunque es buena, hace que no haya espacio entre los elementos de la segunda fila.


Si el ancho de los hijos es variable (lo que resulta en un número variable de hijos por fila), no hay forma de hacerlo solo con CSS . Así que me volví a JavaScript para:

  • agregue un elemento .sizer como último hijo, inicialmente con flex-basis:100%
  • reduzca gradualmente su flex-basis hasta que "salte" en la fila anterior (o llegue a flex-basis:0% )
  • cuando sucede lo anterior, empuja todos los elementos en la última fila al comienzo de la fila: ¡trabajo hecho!

Trabajando, ejemplo genérico:

// first part of the script generates cards with random words, ignore it let words = [ ''interesting'', ''tongue'', ''excellent'', ''start'', ''sticky'', ''lame'', ''lopsided'', ''ill-informed'', ''terrible'', ''reduce'', ''near'', ''order'' ] for (var i = 0; i < 20; i++) { let text = ''''; for (var j = 0; j < 3; j++) { text += words[parseInt(Math.random() * words.length)] + '' '' } $(''.container'').append($(''<div />'', { class: ''card'', text: text })) } // the juice starts here: $(''.container'').append( $(''<div />'', { class:''sizer'' })); let topSizer = $(''.sizer'')[0].getBoundingClientRect().top, perCent = 100; while ( $(''.sizer'')[0].getBoundingClientRect().top === topSizer && topSizer > 0 ) { $(''.sizer'').css({flexBasis:(perCent--)+''%''}); }

.container { display: flex; flex-flow: row wrap; align-content: flex-start; } .card { flex: 1 1 0; padding: .8rem; border: 1px solid #ccc; margin: 0 -1px -1px 0; } .sizer { flex-basis: 100%; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"></div>

Si bien el script es bastante genérico, demuestra el principio. Probablemente debería usar nombres de clase más específicos en un escenario de la vida real.

Descargo de responsabilidad: sé que esta solución no alinea los elementos "a la cuadrícula" , como se solicitó inicialmente, pero, por algún motivo, esta pregunta se indica como la respuesta a otras preguntas , donde las personas solo preguntan cómo podrían alinear los elementos en la última fila, con anchos variables, a la izquierda, manteniendo a los niños en las filas anteriores extendiéndose para llenar la fila completa. Así que pensé que debería agregar mi respuesta aquí.


Sin ningún marcado adicional, simplemente agregando ::after trabajé para mí especificando el ancho de la columna.

.grid { display:flex; justify-content:space-between; flex-wrap:wrap; } .grid::after{ content: ''''; width: 10em // Same width of .grid__element } .grid__element{ width:10em; }

Con el HTML como este:

<div class=grid"> <div class="grid__element"></div> <div class="grid__element"></div> <div class="grid__element"></div> </div>


Una posible solución es utilizar justify-content: flex-start; en el contenedor .grid , las restricciones de tamaño en sus elementos secundarios y los márgenes en los elementos secundarios apropiados , dependiendo del número de columnas deseado.

Para una cuadrícula de 3 columnas, el CSS básico se vería así:

.grid { display: flex; flex-flow: row wrap; justify-content: flex-start; } .grid > * { flex: 0 0 32%; margin: 1% 0; } .grid > :nth-child(3n-1) { margin-left: 2%; margin-right: 2%; }

Es otra solución imperfecta, pero funciona.

http://codepen.io/tuxsudo/pen/VYERQJ


Una técnica sería insertar una cantidad de elementos adicionales (tantos como la cantidad máxima de elementos que espera tener en una fila) a los que se les asigna una altura cero. El espacio todavía está dividido, pero las filas superfluas se colapsan a nada:

http://codepen.io/dalgard/pen/Dbnus

body { padding: 5%; } div { overflow: hidden; background-color: yellow; } ul { display: flex; flex-wrap: wrap; margin: 0 -4px -4px 0; list-style: none; padding: 0; } li { flex: 1 0 200px; height: 200px; border-right: 4px solid black; border-bottom: 4px solid black; background-color: deeppink; } li:empty { height: 0; border: none; } *, :before, :after { box-sizing: border-box; }

<div> <ul> <li>a</li> <li>b</li> <li>c</li> <li>d</li> <li>e</li> <li>f</li> <li>g</li> <li>h</li> <li>i</li> <li>j</li> <li>k</li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </div>

En el futuro, esto puede lograrse mediante el uso de multiple ::after(n) .


Usando flexbox y algunas consultas de medios, hice esta pequeña solución: http://codepen.io/una/pen/yNEGjv (es un poco intrépido pero funciona):

.container { display: flex; flex-flow: row wrap; justify-content: flex-start; max-width: 1200px; margin: 0 auto; } .item { background-color: gray; height: 300px; flex: 0 30%; margin: 10px; @media (max-width: 700px) { flex: 0 45%; } @media (max-width: 420px) { flex: 0 100%; } &:nth-child(3n-1) { margin-left: 10px; margin-right: 10px; } }


Usted no puede Flexbox no es un sistema de red. No tiene las construcciones de lenguaje para hacer lo que estás pidiendo, al menos no si estás utilizando justify-content: space-between . Lo más cercano que puede obtener con Flexbox es usar la orientación de la columna, que requiere establecer una altura explícita:

http://cssdeck.com/labs/pvsn6t4z (nota: prefijos no incluidos)

ul { display: flex; flex-flow: column wrap; align-content: space-between; height: 4em; }

Sin embargo, sería más simple usar solo columnas, que tienen mejor soporte y no requieren establecer una altura específica:

http://cssdeck.com/labs/dwq3x6vr (nota: prefijos no incluidos)

ul { columns: 15em; }