jquery css twitter-bootstrap css3 flexbox

jquery - ¿Cómo obtener un encabezado de tarjetas o similar para tener la misma altura con caja flexible?



css twitter-bootstrap (2)

Aquí tienes mi enfoque con jQuery. Las cosas se vuelven más complicadas porque quieres que la altura de cada fila sea igual, pero independiente del resto.

Lo que he hecho es usar la posición superior de cada elemento como un identificador de fila, recorrer todos los encabezados agregando una clase que tenga esta posición, para que luego podamos seleccionar una fila completa usando esa clase. En cada bucle, verifico la altura y guardo el valor máximo, y cuando detecto que estamos en una nueva fila (la posición superior ha cambiado), aplico la altura máxima de la fila a todos los elementos de la fila anterior usando la clase I He asignado.

Aquí está el código ...

function adjustHeaderHeights() { // First reset all heights to just increase if needed. $(''div.header'').css(''height'',''auto''); var curRow=$(''div.header'').first().offset().top, curRowMaxHeight=$(''div.header'').first().height(); var n = $(''div.header'').length; $(''div.header'').each(function(index) { // Get header top position as row identifier, and add it as a class. var rowId = $(this).offset().top; $(this).addClass(''rowid''+rowId); if (rowId != curRow) { // It''s a new row. $(''div.header.rowid''+curRow).height(curRowMaxHeight); curRow = rowId; curRowMaxHeight=$(this).height(); } else { curRowMaxHeight = $(this).height() > curRowMaxHeight ? $(this).height() : curRowMaxHeight; // It''s the last header element, so we adjust heights of the last row. if (index+1 == n) $(''div.header.rowid''+curRow).height(curRowMaxHeight); } }); } $(window).resize(function() { adjustHeaderHeights(); }); adjustHeaderHeights();

Espero que ayude

No hacks por favor

Sin codificación dura. La idea no es resolverlo para un caso, por ejemplo, para el caso de que haya 4 columnas, sino resolverlo para contenido dinámico y para tamaños de pantalla receptivos.

El problema para mí es que básicamente no se trata de niños directos, sino del contenido

codepen aquí:

https://codepen.io/anon/pen/OxzrzV

HTML

<h1>disclaimer: resize the window. Make the blue headers in a row match height</h1> <div class="row mycontainer"> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">oh no this header wraps</div> <div class="content">some content lala </div> </div> </div> </div>

CSS

body{ padding: 20px; } .item{ height: 100%; padding-right: 20px; padding-top: 20px; display: flex; flex-direction: column } .header{ background-color: cornflowerblue; } .content{ background-color: salmon; flex-grow: 1; } .mycontainer{ max-width: 500px; }

¿Qué quiero?

los encabezados azules siempre tienen el mismo tamaño que todos los elementos de la fila actual.

una solución sólida de jquery también está bien ... pero debe ser infalible y trabajar en cambiar el tamaño también. El cambio general de estructura de html también está bien. Pero debe ser receptivo correcto.

entonces esto (logrado mediante codificación dura y no responde):


Básicamente hay 2 formas de lograr esto, la forma CSS,

y la forma del script, aquí usando jQuery.

El primer ejemplo de secuencia de comandos muestra cómo establecer la misma altura en todos los elementos.

La segunda muestra establece la misma altura por fila, y la forma de hacer que funcione es verificar el valor superior del elemento (cambia para una nueva fila) y establecer la altura para cada rango / fila procesada.

También agregué un par de optimizaciones, elementos de precarga y, por lo tanto, no los procesará si solo hay 1 elemento o columna.

Codepen actualizado 1

Fragmento de pila 1

(function ($) { // preload object array to gain performance var $headers = $(''.header'') // run at resize $( window ).resize(function() { $.fn.setHeaderHeight(0); }); $.fn.setHeaderHeight = function(height) { // reset to auto or else we can''t check height $($headers).css({ ''height'': ''auto'' }); // get highest value $($headers).each(function(i, obj) { height = Math.max(height, $(obj).outerHeight()) }); // set the height $($headers).css({ ''height'': height + ''px'' }); } // run at load $.fn.setHeaderHeight(0); }(jQuery));

body{ padding: 20px; } .item{ height: 100%; padding-right: 20px; padding-top: 20px; display: flex; flex-direction: column } .header{ background-color: cornflowerblue; } .content{ background-color: salmon; flex-grow: 1; } .mycontainer{ max-width: 500px; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.css" rel="stylesheet"/> <div class="row mycontainer"> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">oh no this header wraps</div> <div class="content">some content lala </div> </div> </div> </div>

Codepen 2 actualizado

Fragmento de pila 2

(function ($) { // preload object array to gain performance var $headers = $(''.header'') // only do this if there is more than 1 item if ($headers.length < 2) { return; } // run at resize $( window ).resize(function() { $.fn.setHeaderHeight(0,0); }); $.fn.setHeaderHeight = function(height, idx) { // reset to auto or else we can''t check height $($headers).css({ ''height'': ''auto'' }); $($headers).each(function(i, obj) { // only continue if there is more than 1 column if ($($headers).eq(0).offset().top !== $($headers).eq(1).offset().top ) { return false; } // get highest value height = Math.max(height, $(obj).outerHeight()) // did top value changed or are we at last item if (i != 0 && $($headers).eq(i - 1).offset().top != $(obj).offset().top) { // set height for row $($headers).slice(idx, i).css({ ''height'': height + ''px'' }); // reset height and startIndex height = 0; idx = i; } else if ($headers.length - 1 == i) { // last row $($headers).slice(idx, i + 1).css({ ''height'': height + ''px'' }); } }); } // run at load $.fn.setHeaderHeight(0,0); }(jQuery));

body{ padding: 20px; } .item{ height: 100%; padding-right: 20px; padding-top: 20px; display: flex; flex-direction: column } .header{ background-color: cornflowerblue; } .content{ background-color: salmon; flex-grow: 1; } .mycontainer{ max-width: 500px; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.css" rel="stylesheet"/> <div class="row mycontainer"> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">oh no this header wraps</div> <div class="content">some content lala </div> </div> </div> </div>

Como algunos prefieren JavaScript simple, también actualicé con dicha muestra (estableciendo la misma altura en todos los elementos), que aplican / agregan una clase dinámicamente, con el valor de height calculado.

Fragmento de pila

(function(d,t,h) { /* preload some variables */ h = (d.head || d.getElementsByTagName(''head'')[0]); var items = d.querySelectorAll(''.header''); function resized() { var heights = [], i = 0, css; /* delete set style so we get proper value */ removeElement(''head_dynamic_css''); for (i = 0; i < items.length; i++) { heights.push(parseFloat(window.getComputedStyle(items[i], null).getPropertyValue("height"))); } css = ".header { height: " + Math.max.apply(null, heights) + "px; }"; /* create and add style with height */ var s = d.createElement(''style''); s.type = ''text/css''; s.id = ''head_dynamic_css''; if (s.styleSheet) { s.styleSheet.cssText = css } else { s.appendChild(d.createTextNode(css)); } h.appendChild(s); } window.addEventListener("load", resized, false); window.addEventListener("resize", resizer, false); function resizer() { if (!t) { t = setTimeout(function() { t = null; resized(); }, 66); } } function removeElement(el) { var el = document.getElementById(el); if (el) { el.parentElement.removeChild(el); } } }(document,null));

body { padding: 20px; } .item { height: 100%; padding-right: 20px; padding-top: 20px; display: flex; flex-direction: column } .header { background-color: cornflowerblue; } .content { background-color: salmon; flex-grow: 1; } .mycontainer { max-width: 500px; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.css" rel="stylesheet"/> <div class="row mycontainer"> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">bippo</div> <div class="content">some content lala some content lala some content lala </div> </div> </div> <div class="col-12 col-md-4 col-lg-3"> <div class="item"> <div class="header">oh no this header wraps</div> <div class="content">some content lala </div> </div> </div> </div>