que grow espacio entre elementos ejemplo desventajas css

css - grow - flexbox que es



¿Igual número de elementos por fila con flexbox? (4)

Tengo contenido dinámico y un diseño receptivo, por lo que la cantidad de elementos y el ancho disponible variarán. A veces, los elementos de un div tendrán que ajustarse en una segunda ''fila''.

Con flexbox (o cualquier otro método CSS), ¿puede hacer que el número de elementos en cada fila sea igual?

<div class="cont"> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> </div> .cont { display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; border: 1px solid grey; margin: auto; width: 60%; padding: 10px; } .elem { height: 100px; width: 100px; border: 1px solid blue; display: -webkit-flex; display: -ms-flexbox; display: flex; margin-right: 10px; margin-bottom: 10px; }

http://codepen.io/anon/pen/qEQzqY


Aunque pediste una solución Css, no pude encontrar una, así que creé una solución basada en jquery (como supongo puede optimizarse mucho).

Esta solución funciona solo si conoce el ancho del elemento y es estático como en su ejemplo (actualmente 112px con border y margin ).

Espero que este se adapte a sus necesidades.

CSS y HTML no han cambiado

Javascript

$(window).resize(function () { var elementWidth = 112; var Elements = $(".elem"); var parentWidth = $(".cont").width(); var rowsCount = Math.ceil((Elements.length * elementWidth) / parentWidth); var perRow = Math.ceil(Elements.length / rowsCount); perRow = perRow * elementWidth > parentWidth ? perRow - 1 : perRow; $.each(Elements, function (index, item) { $(this).css("margin-right", ""); }); for (i = 1; i <= rowsCount && rowsCount > 1; i++) { if (i * perRow <= Elements.length) Elements.eq((i * perRow) - 1).css("margin-right", parentWidth - (perRow * elementWidth)); } });

Aquí hay un Fiddle

NOTA

Esto no se ha probado en todos los tamaños de pantalla y diferentes números de elementos, solo un par de casos, por lo que puedo fallar en algún momento.


Como dice Dalgard, las consultas de cantidad son una solución si desea una solución CSS.

Sin embargo, necesitarás escribir varios casos.

Vamos a verlo trabajando para el caso de los siete elementos.

.cont { display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; border: 1px solid grey; margin: auto; width: 500px; padding: 10px; } .elem { height: 100px; width: 100px; border: 1px solid blue; display: -webkit-flex; display: -ms-flexbox; display: flex; margin-right: 10px; margin-bottom: 10px; } .elem:nth-last-child(7):first-child { border-color: red; } .elem:nth-last-child(7):first-child ~ .elem:nth-child(3) { border-color: green; margin-right: 100px; }

<div class="cont"> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> </div> <div class="cont"> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> <div class="elem"></div> </div>

He establecido la regla del borde rojo solo para mostrar que se aplica al caso de los siete elementos, pero no al caso de los demás. Luego, el tercer elemento afert este objetivo es hacer que la fila termine (y se muestre con un color de borde diferente para hacer esto visible


Si el número de elementos está dentro de la razón, puede ser factible escribir css para cada caso individual utilizando la técnica de consultas de cantidad .


Tengo más de 2 años de retraso, pero me gustó la idea de Maksym Stepanenko. Originalmente probé una solución css pura con flexbox usando:

flex-direction: column; align-content: flex-start;

pero esto requeriría que especifique una Altura, y ajuste la Altura según sea necesario.

Por lo tanto, el enfoque de Respaldo que utiliza la idea de Maksym Stepanenko de ajustar el margen derecho según sea necesario, funciona con elementos flotantes o elementos envueltos en flexbox, de cualquier manera. Terminé corrigiendo algunos de los cálculos de Maksym Stepanenko para este ejemplo:

JS BIN Enlace o fragmento de código a continuación (usando una biblioteca ''Detect Element Resize'' para que el oyente del contenedor funcione).

/** * Detect Element Resize * * https://github.com/sdecima/javascript-detect-element-resize * Sebastian Decima * * version: 0.5.3 **/ (function () { var attachEvent = document.attachEvent, stylesCreated = false; if (!attachEvent) { var requestFrame = (function(){ var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function(fn){ return window.setTimeout(fn, 20); }; return function(fn){ return raf(fn); }; })(); var cancelFrame = (function(){ var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.clearTimeout; return function(id){ return cancel(id); }; })(); function resetTriggers(element){ var triggers = element.__resizeTriggers__, expand = triggers.firstElementChild, contract = triggers.lastElementChild, expandChild = expand.firstElementChild; contract.scrollLeft = contract.scrollWidth; contract.scrollTop = contract.scrollHeight; expandChild.style.width = expand.offsetWidth + 1 + ''px''; expandChild.style.height = expand.offsetHeight + 1 + ''px''; expand.scrollLeft = expand.scrollWidth; expand.scrollTop = expand.scrollHeight; }; function checkTriggers(element){ return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height; } function scrollListener(e){ var element = this; resetTriggers(this); if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__); this.__resizeRAF__ = requestFrame(function(){ if (checkTriggers(element)) { element.__resizeLast__.width = element.offsetWidth; element.__resizeLast__.height = element.offsetHeight; element.__resizeListeners__.forEach(function(fn){ fn.call(element, e); }); } }); }; /* Detect CSS Animations support to detect element display/re-attach */ var animation = false, animationstring = ''animation'', keyframeprefix = '''', animationstartevent = ''animationstart'', domPrefixes = ''Webkit Moz O ms''.split('' ''), startEvents = ''webkitAnimationStart animationstart oAnimationStart MSAnimationStart''.split('' ''), pfx = ''''; { var elm = document.createElement(''fakeelement''); if( elm.style.animationName !== undefined ) { animation = true; } if( animation === false ) { for( var i = 0; i < domPrefixes.length; i++ ) { if( elm.style[ domPrefixes[i] + ''AnimationName'' ] !== undefined ) { pfx = domPrefixes[ i ]; animationstring = pfx + ''Animation''; keyframeprefix = ''-'' + pfx.toLowerCase() + ''-''; animationstartevent = startEvents[ i ]; animation = true; break; } } } } var animationName = ''resizeanim''; var animationKeyframes = ''@'' + keyframeprefix + ''keyframes '' + animationName + '' { from { opacity: 0; } to { opacity: 0; } } ''; var animationStyle = keyframeprefix + ''animation: 1ms '' + animationName + ''; ''; } function createStyles() { if (!stylesCreated) { //opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360 var css = (animationKeyframes ? animationKeyframes : '''') + ''.resize-triggers { '' + (animationStyle ? animationStyle : '''') + ''visibility: hidden; opacity: 0; } '' + ''.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: /" /"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }'', head = document.head || document.getElementsByTagName(''head'')[0], style = document.createElement(''style''); style.type = ''text/css''; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style); stylesCreated = true; } } window.addResizeListener = function(element, fn){ if (attachEvent) element.attachEvent(''onresize'', fn); else { if (!element.__resizeTriggers__) { if (getComputedStyle(element).position == ''static'') element.style.position = ''relative''; createStyles(); element.__resizeLast__ = {}; element.__resizeListeners__ = []; (element.__resizeTriggers__ = document.createElement(''div'')).className = ''resize-triggers''; element.__resizeTriggers__.innerHTML = ''<div class="expand-trigger"><div></div></div>'' + ''<div class="contract-trigger"></div>''; element.appendChild(element.__resizeTriggers__); resetTriggers(element); element.addEventListener(''scroll'', scrollListener, true); /* Listen for a css animation to detect element display/re-attach */ animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) { if(e.animationName == animationName) resetTriggers(element); }); } element.__resizeListeners__.push(fn); } }; window.removeResizeListener = function(element, fn){ if (attachEvent) element.detachEvent(''onresize'', fn); else { element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); if (!element.__resizeListeners__.length) { element.removeEventListener(''scroll'', scrollListener); element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__); } } } })();

<!doctype html> <head> <meta charset="UTF-8"> <style> .flex{ display: -webkit-flex; display: -ms-flexbox; display: flex; } .wrap{ -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap;} .cont { border: 1px solid grey; margin: auto; width: 448px; padding-right: 0; padding-bottom: 0; /*flex-direction: column;height: 225px;align-content: flex-start;*/ } .controls{ width: 500px; margin: auto; justify-content: space-around; text-align: center; } .elem { border: 1px solid blue; text-align:center; } input{ width: 25px; color: blue; } #resizableBorder{ resize: horizontal; overflow: auto; } </style> <style id="jsManipulated"> .elem { height: 100px; width: 100px; line-height: 100px; margin-right: 10px; margin-bottom: 10px; } .cont { padding-top: 10px; padding-left: 10px; } </style> </head> <body> <br> <div class="flex controls"> <button id="adder">(+) add item</button> <button id="remover">(-) remove item</button> <span> Box Size: <input id="sizer" type="text" value="100" boxCountlength="3" onkeypress=''return event.charCode > 47 && event.charCode < 58''> </span> <span> Padding: <input id="padder" type="text" value="10" boxCountlength="3" > </div> <br><hr><br> <div id="resizableBorder" class="cont flex wrap"> <div class="elem"> 1</div><div class="elem"> 2</div><div class="elem"> 3</div> <div class="elem"> 4</div><div class="elem"> 5</div><div class="elem"> 6</div> <div class="elem"> 7</div><div class="elem"> 8</div><div class="elem"> 9</div> </div> <script> document.addEventListener(''DOMContentLoaded'', function(){ var boxCount = 9; var boxWidth = 100; var boxBorderWidth = 10; var adder = document.getElementById(''adder''); var remover = document.getElementById(''remover''); var sizer = document.getElementById(''sizer''); var padder = document.getElementById(''padder''); var flexParent = document.getElementsByClassName(''cont'')[0]; var styleEle = document.getElementById(''jsManipulated''); var resizableBorder = document.getElementById(''resizableBorder''); function addItem(){ console.log("add"); var newItem = document.createElement(''div''); newItem.className += ''elem''; newItem.innerHTML = ++boxCount; flexParent.appendChild( newItem ); repaint(); } function removeItem(){ console.log("remove"); if(boxCount != 0){ --boxCount; //flexParent.removeChild(flexParent.lastChild); var position = flexParent.children.length -1; if( flexParent.children[position].className == "resize-triggers"){ --position; } //ignore resize-triggers div. flexParent.removeChild( flexParent.children[ position ] ); repaint(); } } function resizeBoxes(event) { if( event.keyCode > 47 && event.keyCode < 58){ boxWidth = this.value; } else if( event.keyCode == 40 ){ boxWidth = --this.value; } else if( event.keyCode == 38 ){ boxWidth = ++this.value; } else { console.log(''non-numeric keypress ignored: ''+event.keyCode); return; } updateBoxStyles( boxWidth, boxBorderWidth); } function repadBoxes(event) { if( event.keyCode > 47 && event.keyCode < 58){ boxBorderWidth= this.value; } else if( event.keyCode == 40 ){ boxBorderWidth = --this.value; } else if( event.keyCode == 38 ){ boxBorderWidth = ++this.value;} else { console.log(''non-numeric keypress ignored: ''+event.keyCode); return; } updateBoxStyles( boxWidth, boxBorderWidth); } function updateBoxStyles( size, edge ){ styleEle.innerHTML = ".elem { height: " +size+"px; width: " +size+"px; line-height: " +size+"px; margin-right: " +edge+"px; margin-bottom: " +edge+"px;} .cont { padding-top: " +edge+"px; padding-left: " +edge+"px;}" repaint(); } /* LISTENERS */ window.onresize = repaint; //Only needed if ''width'' of container is a percentage ex: ''.cont{width:60%}'' adder.addEventListener(''click'', addItem ); remover.addEventListener(''click'', removeItem ); sizer.addEventListener(''keyup'', resizeBoxes ); padder.addEventListener(''keyup'', repadBoxes ); addResizeListener( resizableBorder, repaint); //using the ''detect-element-resize.js library'' /** Most Important Function Called Everytime Anything Changes, in order to keep elements to the left using ''margin-right'' **/ repaint(); //initial resize on pageload; function repaint() { console.log(''repaint''); var elementWidth = 2- -boxWidth- -boxBorderWidth; // 2 because: border is 1px*2, ''- -'' because ''+'' causes string concatination. var elements = document.getElementsByClassName(''elem''); var count = elements.length; var parentWidth = parseInt( window.getComputedStyle( flexParent).getPropertyValue(''width'') ); var rowsCount = Math.ceil( count / Math.floor(parentWidth/elementWidth) ); var perRow = Math.floor( count / rowsCount); var extra = count % rowsCount; for (var i=0, ele; ele = elements[i]; i++) { ele.style["margin-right"] = ""; } if( rowsCount == Infinity || rowsCount == 0){ return; }//when elementWidth < parentWidth or Zero Boxes var allPrevRowsTotal = 0; for (var i = 1; i <= rowsCount && rowsCount > 1; i++) { var perThisRow = perRow; if( extra != 0){ --extra; perThisRow++; } elements[ allPrevRowsTotal + perThisRow - 1 ].style["margin-right"] = parentWidth - (perThisRow * elementWidth) +"px"; allPrevRowsTotal += perThisRow; } } }); //https://.com/questions/29125444/equal-number-of-element-per-row-with-flexbox </script> </body>