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.
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>
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>