css - espacio - Mejor manera de establecer la distancia entre los elementos de flexbox
flexbox grid (30)
Columnify - Una clase solista para N columnas
Flexbox y SCSS
.columnify {
display: flex;
> * {
flex: 1;
&:not(:first-child) {
margin-left: 2rem;
}
}
}
Flexbox y CSS
.columnify {
display: flex;
}
.columnify > * {
flex: 1;
}
.columnify > *:not(:first-child) {
margin-left: 2rem;
}
<div class="columnify">
<div style="display: inline-block; height: 20px; background-color: blue;"></div>
<div style="display: inline-block; height: 20px; background-color: blue"></div>
<div style="display: inline-block; height: 20px; background-color: blue"></div>
</div>
Juega con él en JSFiddle .
Para establecer la distancia mínima entre los elementos de flexbox, estoy usando el margin: 0 5px
en .item
y el margin: 0 -5px
en el contenedor. Para mí, parece un truco, pero no puedo encontrar una mejor manera de hacerlo.
#box {
display: flex;
width: 100px;
margin: 0 -5px;
}
.item {
background: gray;
width: 50px;
height: 50px;
margin: 0 5px;
}
<div id=''box''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
flexbox y css calc ()
Hola, a continuación se muestra mi solución de trabajo para todos los navegadores que admiten flexbox. Sin márgenes negativos, sin cortes, sin soluciones, Css puro.
.flexbox {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.flexbox > div {
/*
1/3 - 3 columns per row
10px - spacing between columns
*/
box-sizing: border-box;
margin-bottom: 10px;
width: calc(1/3*100% - (1 - 1/3)*10px);
}
<div class="flexbox">
<div>col</div>
<div>col</div>
<div>col</div>
<div>col</div>
<div>col</div>
<div>col</div>
</div>
¿Por qué no hacerlo así?
.item + .item {
margin-left: 5px;
}
Esto usa el selector de hermanos adyacente , para dar a todos los elementos .item
, excepto al primero un margin-left
. Gracias a flexbox, esto resulta incluso en elementos igualmente anchos. Esto también podría hacerse con elementos posicionados verticalmente y margin-top
, por supuesto.
A menudo utilizo el operador + para tales casos
#box {
display: flex;
width: 100px;
}
.item {
background: gray;
width: 50px;
height: 50px;
}
.item + .item {
margin-left: 5px;
}
<div id=''box''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
Aquí está mi solución, que no requiere establecer ninguna clase en los elementos secundarios:
.flex-inline-row {
display: inline-flex;
flex-direction: row;
}
.flex-inline-row.flex-spacing-4px > :not(:last-child) {
margin-right: 4px;
}
Uso:
<div class="flex-inline-row flex-spacing-4px">
<span>Testing</span>
<span>123</span>
</div>
La misma técnica se puede utilizar para filas y columnas de flexión normales además del ejemplo en línea dado anteriormente, y se puede ampliar con clases para espaciado distinto de 4px.
Aquí hay una cuadrícula de elementos de la interfaz de usuario de la tarjeta con el espaciado completado utilizando el cuadro flexible
Estaba frustrado con el espaciado manual de las tarjetas al manipular el relleno y los márgenes con resultados dudosos. Así que aquí están las combinaciones de atributos CSS que he encontrado muy efectivas:
.card-container {
width: 100%;
height: 900px;
overflow-y: scroll;
max-width: inherit;
background-color: #ffffff;
/*Here''s the relevant flexbox stuff*/
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-start;
flex-wrap: wrap;
}
/*Supplementary styles for .card element*/
.card {
width: 120px;
height: 120px;
background-color: #ffeb3b;
border-radius: 3px;
margin: 20px 10px 20px 10px;
}
<section class="card-container">
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
</section>
Espero que esto ayude a la gente, presente y futuro.
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º, 9º elemento y así sucesivamente; y establecer ancho fijo en cada elemento. Si el margen izquierdo es 10px, entonces cada fila tendrá un margen de 30px entre 4 elementos, el porcentaje de ancho del elemento se puede calcular 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 - 2px - 20px - 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>
Con el tiempo agregarán la propiedad gap
a flexbox. Hasta entonces, podría usar la cuadrícula CSS que ya tiene la propiedad de gap
, y solo tener una fila. Mejor que tratar con márgenes.
Con flexbox, crear canales es un dolor, especialmente cuando se trata de envolver.
Debe usar márgenes negativos ( como se muestra en la pregunta ):
#box {
display: flex;
width: 100px;
margin: 0 -5px;
}
... o alterar el HTML ( como se muestra en otra respuesta ):
<div class=''flex-wrapper''>
<div class=''flex''>
<div class=''box''></div>
<div class=''box''></div>
...
</div>
</div>
... o algo mas.
En cualquier caso, necesita un truco feo para que funcione, ya que flexbox no proporciona una función de " flex-gap
" ( al menos por ahora ).
Sin embargo, el problema de las canaletas es simple y fácil con CSS Grid Layout.
La especificación de cuadrícula proporciona propiedades que crean espacio entre los elementos de la cuadrícula, mientras ignora el espacio entre los elementos y el contenedor. Estas propiedades son:
-
grid-column-gap
-
grid-row-gap
-
grid-gap
(la abreviatura de las dos propiedades anteriores)
Recientemente, la especificación se ha actualizado para cumplir con el Módulo de alineación de cuadros de CSS , que proporciona un conjunto de propiedades de alineación para su uso en todos los modelos de cuadros. Así que las propiedades son ahora:
-
column-gap
-
row-gap
-
gap
(taquigrafía)
Sin embargo, no todos los navegadores compatibles con Grid admiten las propiedades más nuevas, por lo que usaré las versiones originales en la siguiente demostración.
Además, si se necesita espacio entre los elementos y el contenedor, el padding
en el contenedor funciona bien (vea el tercer ejemplo en la demostración a continuación).
De la especificación:
10.1. Canales: las propiedades de
gap
row-gap
column-gap
ygap
Las propiedades de
column-gap
entre filas yrow-gap
entrecolumn-gap
(y su taquigrafía degap
), cuando se especifican en un contenedor de cuadrícula, definen los canales entre las filas de la cuadrícula y las columnas de la cuadrícula. Su sintaxis se define en CSS Box Alignment 3 §8 Gaps Between Boxes .El efecto de estas propiedades es como si las líneas de la cuadrícula afectadas adquirieran grosor: la pista de la cuadrícula entre dos líneas de cuadrícula es el espacio entre los canales que las representan.
.box {
display: inline-grid;
grid-auto-rows: 50px;
grid-template-columns: repeat(4, 50px);
border: 1px solid black;
}
.one {
grid-column-gap: 5px;
}
.two {
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.three {
grid-gap: 10px;
padding: 10px;
}
.item {
background: lightgray;
}
<div class=''box one''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
<hr>
<div class=''box two''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
<hr>
<div class=''box three''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
Más información:
- Soporte del navegador para CSS Grid
- Facilita la definición de márgenes que solo se aplican entre elementos flexibles (discusión)
- Espaciado entre los elementos de flexbox
Continuando con la respuesta de sawa, aquí hay una versión ligeramente mejorada que le permite establecer un espacio fijo entre los elementos sin el margen circundante.
http://jsfiddle.net/chris00/s52wmgtq/49/
También se incluye la versión de Safari "-webkit-flex".
.outer1 {
background-color: orange;
padding: 10px;
}
.outer0 {
background-color: green;
overflow: hidden;
}
.container
{
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
background-color: rgba(0, 0, 255, 0.5);
margin-left: -10px;
margin-top: -10px;
}
.item
{
flex-grow: 1;
-webkit-flex-grow: 1;
background-color: rgba(255, 0, 0, 0.5);
width: 100px;
padding: 10px;
margin-left: 10px;
margin-top: 10px;
text-align: center;
color: white;
}
<div class="outer1">
<div class="outer0">
<div class="container">
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
</div>
</div>
</div>
Digamos que si desea establecer 10px
espacio de 10 10px
entre los elementos, simplemente puede configurar .item {margin-right:10px;}
para todos, y restablecerlo en el último .item:last-child {margin-right:0;}
También puede usar el selector de hermano general ~
o siguiente +
hermano para establecer el margen izquierdo en los elementos excluyendo el primero .item ~ .item {margin-left:10px;}
o use .item:not(:last-child) {margin-right: 10px;}
Flexbox es tan inteligente que recalcula automáticamente y distribuye igualmente la red.
body {
margin: 0;
}
.container {
display: flex;
}
.item {
flex: 1;
background: gray;
height: 50px;
margin-right: 10px;
}
.item:last-child {
margin-right: 0;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Encontré un hack porque realmente necesito esto yo mismo.
/* grid */
.container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.container::after, /* this makes sure odd element goes left and not space between */
.item {
content:"";
width: calc(33.3333% - 20px);
margin-bottom: 40px;
}
/* extra styling - not important */
.item {
height: 100px;
background: #787878;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Aquí hay una cuadrícula de mensajes con buenas categorías de crecimiento flexible también. Creo que te gustaría. Ver Codepen
Encuentro que la forma más fácil de hacerlo es con porcentajes y simplemente permitiendo que el margen se ajuste a su ancho
Esto significa que terminará con algo como esto si usara su ejemplo.
#box {
display: flex;
}
.item {
flex: 1 1 23%;
margin: 0 1%;
}
Significa que sus valores se basan en el ancho, lo que podría no ser bueno para todos.
Esto no es un hack. La misma técnica también es utilizada por bootstrap y su cuadrícula, sin embargo, en lugar de margen, bootstrap usa relleno para sus cols.
.row {
margin:0 -15px;
}
.col-xx-xx {
padding:0 15px;
}
He encontrado una solución que se basa en el css preceded by
selector ~
, y permite el anidamiento inifinite.
Ver este código de la pluma para un ejemplo de trabajo
Básicamente, dentro de los contenedores de columnas, cada niño que está precedido por otro niño obtiene un margen superior. Del mismo modo, dentro de cada contenedor de filas, cada niño que está precedido por otro obtiene un margen izquierdo.
.box {
display: flex;
flex-grow: 1;
flex-shrink: 1;
}
.box.columns {
flex-direction: row;
}
.box.columns > .box ~ .box {
margin-left: 5px;
}
.box.rows {
flex-direction: column;
}
.box.rows > .box ~ .box {
margin-top: 5px;
}
<div class="box columns">
<div class="box" style="background-color: red;"></div>
<div class="box rows">
<div class="box rows">
<div class="box" style="background-color: blue;"></div>
<div class="box" style="background-color: orange;"></div>
<div class="box columns">
<div class="box" style="background-color: yellow;"></div>
<div class="box" style="background-color: pink;"></div>
</div>
</div>
<div class="box" style="background-color: green;"></div>
</div>
</div>
He usado esto para columnas envueltas y de ancho fijo. La clave aquí es calc()
Muestra SCSS
$gap: 10px;
dl {
display: flex;
flex-wrap: wrap;
padding: $gap/2;
dt, dd {
margin: $gap/2;}
dt { // full width, acts as header
flex: 0 0 calc(100% - #{$gap});}
dd { // default grid: four columns
flex: 0 0 calc(25% - #{$gap});}
.half { // hall width columns
flex: 0 0 calc(50% - #{$gap});}
}
Puede usar el selector & > * + *
para emular un flex-gap
(para una sola línea):
#box { display: flex; width: 230px; outline: 1px solid blue; }
.item { background: gray; width: 50px; height: 100px; }
/* ----- Flexbox gap: ----- */
#box > * + * {
margin-left: 10px;
}
<div id=''box''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
Si necesita admitir envoltura flexible , puede usar un elemento de envoltura:
.flex { display: flex; flex-wrap: wrap; }
.box { background: gray; height: 100px; min-width: 100px; flex: auto; }
.flex-wrapper {outline: 1px solid red; }
/* ----- Flex gap 10px: ----- */
.flex > * {
margin: 5px;
}
.flex {
margin: -5px;
}
.flex-wrapper {
width: 400px; /* optional */
overflow: hidden; /* optional */
}
<div class=''flex-wrapper''>
<div class=''flex''>
<div class=''box''></div>
<div class=''box''></div>
<div class=''box''></div>
<div class=''box''></div>
<div class=''box''></div>
</div>
</div>
Puede utilizar bordes transparentes.
He contemplado este problema al tratar de construir un modelo de cuadrícula flexible que puede recurrir a un modelo de tabla + celda-tabla para los navegadores más antiguos. Y las fronteras de las canaletas de las columnas me parecieron la mejor opción. es decir, las celdas de tabla no tienen márgenes.
p.ej
.column{
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 10px solid transparent;
}
También tenga en cuenta que necesita min-width: 50px;
para flexbox. El modelo flex no manejará tamaños fijos a menos que flex: none;
en el elemento secundario particular que desee como fijo y, por lo tanto, excluido de ser "flexi"
. http://jsfiddle.net/GLpUp/4/ Pero todas las columnas juntas con flex:none;
Ya no es un modelo flexible. Aquí hay algo más cercano a un modelo flexible: http://jsfiddle.net/GLpUp/5/
Por lo tanto, puede usar los márgenes normalmente si no necesita el respaldo de celdas de tabla para los navegadores más antiguos. http://jsfiddle.net/GLpUp/3/
Configuración de background-clip: padding-box;
será necesario cuando use un fondo, ya que de lo contrario el fondo fluirá hacia el área del borde transparente.
Puse el espacio en los elementos flexibles solo en la dirección establecida por su contenedor. Por ejemplo, si un contenedor flexible está configurado para fluir de izquierda a derecha ( flex-direction:row
), solo estableceré el margen derecho en sus hijos, excepto el último:
.flex-lr{
display:flex;
flex-direction:row;
}
.flex-lr > *:not(:last-child){
margin-right:5px;
}
Esto puede parecer que funciona a primera vista, pero espera! esto no se debe hacer cuando justify-content
se establece en un valor distinto que start
o end
, ya que todos los demás valores ya están distribuyendo el espacio por sí mismos.
¿Y si los artículos se envuelven? Entonces deberíamos agregar espacio al lado del eje transversal apropiado también. Pero, ¿cómo saber si un contenedor está permitiendo que sus hijos se envuelvan? ¿Y qué pasa con wrap-reverse
?
Todas estas consideraciones me hicieron pensar que esta no es una tarea trivial y requiere un pequeño paso más allá.
Mi enfoque se basa en la construcción de un breve conjunto de clases que actúa como un contenedor de flexbox. Esto tiene algunos beneficios:
- Permite "centralizar" todos los prefijos de proveedores en un solo punto y olvidarse de eso.
- Permite agrupar las propiedades de flexbox en una sola clase, o incluso cambiar el nombre de algunas de las palabras utilizadas por flexbox, que a veces pueden parecer poco intuitivas (IMHO).
- Si utilizo estas clases, podré escribir otras clases basadas en los valores de las propiedades de flexión en las que dependen. Por ejemplo, podría establecer el espaciado según la dirección del flujo, la alineación del eje transversal, la envoltura, etc.
Terminé construyendo un diseñador de flexbox para jugar con todo esto, para ayudarme a entenderme a mí mismo (y a otros) cómo funciona flexbox y darme cuenta de lo maravilloso que es flexbox. Por favor, siéntase libre de usarlo siguiendo el siguiente enlace:
http://algid.com/Flex-Designer
Entonces, a continuación encontrará un resumen de las clases que utilizo y la utilidad de espaciado (margen) para una dirección de flujo. Podrás inferir los otros o encontrarlos en el enlace que se proporciona arriba. Los prefijos de los proveedores se han omitido aquí por brevedad.
/* Flex container definition */
.flex-lr{display:flex; flex-direction:row;}
.flex-tb{display:flex; flex-direction:column;}
.flex-rl{display:flex; flex-direction:row-reverse;}
.flex-bt{display:flex; flex-direction:column-reverse;}
/* Wrapping */
.wrap{flex-wrap:wrap;}
.nowrap{flex-wrap:nowrap;}
.wrap-rev{flex-wrap:wrap-reverse;}
/* Main axis alignment */
.align-start{justify-content:flex-start;}
.align-end{justify-content:flex-end;}
.align-center{justify-content:center;}
.align-between{justify-content:space-between;}
.align-around{justify-content:space-around;}
.align-evenly{justify-content:space-evenly;}
/* Cross axis alignment */
.cross-align-start{align-items:flex-start;}
.cross-align-end{align-items:flex-end;}
.cross-align-center{align-items:center;}
.cross-align-stretch{align-items:stretch;}
.cross-align-baseline{align-items:baseline;}
/* Cross axis alignment when content is wrapped */
.wrap-align-start{align-content:flex-start;}
.wrap-align-end{align-content:flex-end;}
.wrap-align-center{align-content:center;}
.wrap-align-stretch{align-content:stretch;}
.wrap-align-between{align-content:space-between;}
.wrap-align-around{align-content:space-around;}
/* Item alignment */
.item-cross-align-start{align-self:flex-start;}
.item-cross-align-end{align-self:flex-end;}
.item-cross-align-center{align-self:center;}
.item-cross-align-stretch{align-self:stretch;}
.item-cross-align-baseline{align-self:baseline;}
.item-cross-align-auto{align-self:auto;}
Y ahora lo que nos trajo aquí: el espacio entre los elementos:
/* Flow margin (left to right) */
.flex-lr.fm-0 > *:not(:last-child){margin-right:0;}
.flex-lr.fm-1 > *:not(:last-child){margin-right:3px;}
.flex-lr.fm-2 > *:not(:last-child){margin-right:7px;}
.flex-lr.fm-3 > *:not(:last-child){margin-right:15px;}
.flex-lr.fm-4 > *:not(:last-child){margin-right:32px;}
/* Cross axis */
.flex-lr.wrap.fm-0:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-0.wrap-align-stretch.cross-align-stretch > * {margin-bottom:0;}
.flex-lr.wrap.fm-1:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-1.wrap-align-stretch.cross-align-stretch > * {margin-bottom:3px;}
.flex-lr.wrap.fm-2:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-2.wrap-align-stretch.cross-align-stretch > * {margin-bottom:7px;}
.flex-lr.wrap.fm-3:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-3.wrap-align-stretch.cross-align-stretch > * {margin-bottom:15px;}
.flex-lr.wrap.fm-4:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-4.wrap-align-stretch.cross-align-stretch > * {margin-bottom:32px;}
/* wrap reverse */
.flex-lr.wrap-rev.fm-0:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-0.wrap-align-stretch.cross-align-stretch > * {margin-top:0;}
.flex-lr.wrap-rev.fm-1:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-1.wrap-align-stretch.cross-align-stretch > * {margin-top:3px;}
.flex-lr.wrap-rev.fm-2:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-2.wrap-align-stretch.cross-align-stretch > * {margin-top:7px;}
.flex-lr.wrap-rev.fm-3:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-3.wrap-align-stretch.cross-align-stretch > * {margin-top:15px;}
.flex-lr.wrap-rev.fm-4:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-4.wrap-align-stretch.cross-align-stretch > * {margin-top:32px;}
Finalmente, así es como se vería el marcado:
<div class="flex-lr cross-align-center fm-3">
<div>
Some content here...
</div>
<div>
A bit more stuff here...
</div>
<div class="flex-tb fm-3">
<div>
Now vertical content
</div>
<div>
etc.
</div>
</div>
</div>
Esto es lo que yo llamo código en voz alta.
Si lo desea, siempre puede usar la combinación de hermanos CSS :
.item+.item{
margin-left: 5px;
}
El código anterior hará el truco. En este método, no es necesario dar margin: 0 -5px;
al #box
wrapper.
Una muestra de trabajo para ti
#box {
display: flex;
width: 100px;
}
.item {
background: gray;
width: 50px;
height: 50px;
}
.item+.item{
margin-left: 5px;
}
<div id=''box''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
Espero que esto haya sido útil.
ACTUALIZACIÓN ↓
Esto funcionará para todos los casos, incluso si hay varias filas o cualquier número de elementos.
estamos utilizando display: grid;
y sus propiedades ↓.
#box {
display: grid;
width: 100px;
grid-gap: 5px;
/* Space between items */
grid-template-columns: 1fr 1fr 1fr 1fr;
/* Decide the number of columns and size */
}
.item {
background: gray;
width: 100%;
/* width is not necessary only added this to understand that width works as 100% to the grid template allocated space **DEFAULT WIDTH WILL BE 100%** */
height: 50px;
}
<div id=''box''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
La desventaja de este método ↑ es que en Mobile Opera Mini no es compatible y en PC esto solo funciona después de IE11 .
Simplemente use .item + .item
en el selector para hacer coincidir desde el segundo .item
#box {
display: inline-flex;
margin: 0 -5px;
}
.item {
background: gray;
width: 10px;
height: 50px;
}
#box .item + .item {
margin-left: 10px;
}
<div id=''box''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
Un contenedor flexible con margen -x (negativo) y elementos flexibles con margen x (positivo) o relleno llevan al resultado visual deseado: los elementos flexibles tienen un espacio fijo de 2x solo entre ellos.
Parece ser simplemente una cuestión de preferencia, ya sea para utilizar el margen o el relleno en los elementos flexibles.
En este ejemplo, los elementos flexibles se escalan dinámicamente para preservar la brecha fija:
.flex-container {
margin: 0 -5px;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.flex-item {
margin: 0 5px; // Alternatively: padding: 0 5px;
flex: 1 0 auto;
}
Usando Flexbox en mi solución, he usado la propiedad justify justify-content
para el elemento principal (contenedor) y he especificado los márgenes dentro de la propiedad de flex-basis
de los elementos. Compruebe el fragmento de código a continuación:
.container {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
margin-bottom: 10px;
}
.item {
height: 50px;
display: flex;
justify-content: center;
align-items: center;
background-color: #999;
}
.item-1-4 {
flex-basis: calc(25% - 10px);
}
.item-1-3 {
flex-basis: calc(33.33333% - 10px);
}
.item-1-2 {
flex-basis: calc(50% - 10px);
}
<div class="container">
<div class="item item-1-4">1</div>
<div class="item item-1-4">2</div>
<div class="item item-1-4">3</div>
<div class="item item-1-4">4</div>
</div>
<div class="container">
<div class="item item-1-3">1</div>
<div class="item item-1-3">2</div>
<div class="item item-1-3">3</div>
</div>
<div class="container">
<div class="item item-1-2">1</div>
<div class="item item-1-2">2</div>
</div>
De hecho, hay una forma agradable, ordenada, solo de CSS para hacer esto (que uno puede considerar "mejor").
De todas las respuestas publicadas aquí, solo encontré una que usa calc () con éxito (por Dariusz Sikorski). Pero cuando se plantea con: "pero falla si solo hay 2 elementos en la última fila" no se expandió la solución.
Esta solución aborda la pregunta del OP con una alternativa a los márgenes negativos y aborda el problema planteado a Dariusz.
notas:
- Este ejemplo solo muestra un diseño de 3 columnas
- Se utiliza
calc()
para permitir que el navegador realice las100%/3
operaciones matemáticas de la manera que desee (aunque el 33.3333% debería funcionar también) y(1em/3)*2
(.66em también debería funcionar bien) . - Se usa
::after
para rellenar la última fila si hay menos elementos que columnas.
.flex-container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.flex-container:after {
content: "";
}
.flex-container > div,
.flex-container:after {
box-sizing: border-box;
width: calc((100%/3) - ((1em/3)*2));
}
.flex-container > :nth-child(n + 4) {
margin-top: 1em;
}
/* the following is just to visualize the items */
.flex-container > div,
.flex-container:after {
font-size: 2em;
}
.flex-container {
margin-bottom:4em;
}
.flex-container > div {
text-align: center;
background-color: #aaa;
padding: 1em;
}
.flex-container:after {
border: 1px dashed red;
}
<h2>Example 1 (2 elements)</h2>
<div class="flex-container">
<div>1</div>
<div>2</div>
</div>
<h2>Example 2 (3 elements)</h2>
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
También en https://codepen.io/anon/pen/rqWagE
#box {
display: flex;
width: 100px;
}
.item {
background: gray;
width: 50px;
height: 50px;
}
/* u mean utility */
.u-gap-10 > *:not(:last-child) {
margin-right: 10px;
}
<div id=''box'' class="u-gap-10">
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
</div>
El truco de margen negativo en el contenedor de la caja funciona muy bien. Aquí hay otro ejemplo que funciona muy bien con el orden, la envoltura y lo que no.
.container {
border: 1px solid green;
width: 200px;
display: inline-block;
}
#box {
display: flex;
flex-wrap: wrap-reverse;
margin: -10px;
border: 1px solid red;
}
.item {
flex: 1 1 auto;
order: 1;
background: gray;
width: 50px;
height: 50px;
margin: 10px;
border: 1px solid blue;
}
.first {
order: 0;
}
<div class=container>
<div id=''box''>
<div class=''item''>1</div>
<div class=''item''>2</div>
<div class=''item first''>3*</div>
<div class=''item''>4</div>
<div class=''item''>5</div>
</div>
</div>
Me encontré con el mismo problema antes, luego me topé con la respuesta para esto. Espero que ayude a otros para futuras referencias.
respuesta larga, breve, agregue un borde a los elementos flexibles de su hijo. luego puede especificar márgenes entre elementos flexibles para lo que desee. En el fragmento, uso negro para fines de ilustración, puede usar "transparente" si lo desea.
#box {
display: flex;
width: 100px;
/* margin: 0 -5px; *remove this*/
}
.item {
background: gray;
width: 50px;
height: 50px;
/* margin: 0 5px; *remove this*/
border: 1px solid black; /* add this */
}
.item.special{ margin: 0 10px; }
<div id=''box''>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item''></div>
<div class=''item special''></div>
</div>
No funcionará en todos los casos, pero si tiene anchos secundarios flexibles (%) y conoce la cantidad de elementos por fila, puede especificar de forma muy clara los márgenes de los elementos necesarios utilizando el nth-child
selector / s.
Depende en gran medida de lo que quieras decir con "mejor". De esta manera no se requiere un marcado de envoltorio adicional para elementos secundarios o negativos, pero ambas cosas tienen su lugar.
section {
display: block
width: 100vw;
}
.container {
align-content: flex-start;
align-items: stretch;
background-color: #ccc;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
width: 100%;
}
.child-item {
background-color: #c00;
margin-bottom: 2%;
min-height: 5em;
width: 32%;
}
.child-item:nth-child(3n-1) {
margin-left: 2%;
margin-right: 2%;
}
<html>
<body>
<div class="container">
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
</div>
</body>
</html>
Publiqué mi enfoque de flexbox here :
Una idea que rechacé fue eliminar el relleno de las columnas externas con algo como esto:
div:nth-child(#{$col-number}n+1) { padding-left: 0; }
div:nth-child(#{$col-number}n+#{$col-number}) { padding-left: 0; }
Pero, como otros carteles aquí, prefiero el truco del margen negativo. Mi violín también tiene capacidad de respuesta para cualquier persona que esté buscando una solución basada en Sass. Básicamente uso este enfoque en lugar de una cuadrícula.
- Flexbox no tiene márgenes de colapso.
- Flexbox no tiene nada parecido al
border-spacing
de losborder-spacing
de las tablas.
Por lo tanto, lograr lo que estás pidiendo es un poco más difícil.
En mi experiencia, la forma "más limpia" que no usa :first-child
/ :last-child
y funciona sin ninguna modificación en flex-wrap:wrap
es establecer el padding:5px
en el contenedor y margin:5px
en los niños . Eso producirá una brecha de 10px
entre cada niño y entre cada niño y sus padres.
.upper
{
margin:30px;
display:flex;
flex-direction:row;
width:300px;
height:80px;
border:1px red solid;
padding:5px; /* this */
}
.upper > div
{
flex:1 1 auto;
border:1px red solid;
text-align:center;
margin:5px; /* and that, will result in a 10px gap */
}
.upper.mc /* multicol test */
{flex-direction:column;flex-wrap:wrap;width:200px;height:200px;}
<div class="upper">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
<div class="upper mc">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>