2014-04-24 24 views
5

Sto cercando di ottenere una quantità dinamica di elementi da mostrare su 5 elementi utilizzando CSS3 column-count, ma quando espongo l'altezza degli elementi di elenco su passaggio del mouse, occasionalmente causa il salto (un elemento che sta andando alla prossima colonna).Elementi di conteggio di colonne CSS che saltano tra le colonne

È possibile vedere il comportamento here

sto supponendo che sia perché column-count utilizza l'altezza per calcolare quale elemento va dove o qualcosa ... come possiamo farlo funzionare come previsto?

Se tento di aumentare l'altezza di <ol>, diventano 4 colonne o anche 3 colonne perché gli elementi riempiono la prima colonna, quindi iniziano la seconda colonna e così via.

+4

Penso che sia il normale comportamento delle colonne: se il contenuto di una colonna è troppo alto, passa a quello successivo. –

+0

devi usare il conteggio delle colonne? Potrebbe essere più facile farlo, per esempio, in un tavolo senza bordi. – pennstatephil

+0

Ho trovato questo. Hai provato? [JSFIDDLE] (http://jsfiddle.net/yeshansachithak/Q97m4/). – yeshansachithak

risposta

5

In breve, le colonne CSS3 non sono la soluzione giusta per ciò che si sta tentando di fare. (Se ho capito bene, vuoi che l'elemento hovered abbia un overflow del suo contenitore genitore andando fuori dalla sua casella. Tuttavia, le colonne CSS3 sono progettate in modo tale che l'overflow continui nella parte superiore della colonna successiva, e non c'è modo che io sappia di cambiare questo comportamento).

Si consiglia di utilizzare un approccio diverso per ottenere l'interfaccia utente desiderata, ad esempio l'utilizzo di JQuery per inserire wrapper in ogni colonna.

Tuttavia, se si sta insieme sull'utilizzo di column-count, si può essere in grado di incidere facendo qualcosa di simile a questo:

JSFiddle:

http://jsfiddle.net/p6r9P/

CSS:

ol li:nth-child(5n) { 
    padding-bottom: 40px; 
} 

JQuery:

function togglePadding(li, status) { 
    var index = li.index(); 
    var target = (index % 5 === 4) ? li : li.siblings().eq(index + 3 - (index % 5)); 
    target.stop(true).animate({ 
     "padding-bottom": (status === "on") ? "40px" : 0 
    }); 
} 

$('a.song').each(function() { 
    var origwidth = $(this).width(); 
    var origheight = $(this).height(); 
    $(this).hover(function() { 
     togglePadding($(this).parent(), "off"); 
     $(this).stop(true).animate({ 
      width: origwidth * 2, 
      height: origheight * 2 
     }) 
    }, function() { 
     $(this).stop(true).animate({ 
      width: origwidth, 
      height: origheight 
     }); 
     togglePadding($(this).parent(), "on"); 
    }); 
    $(this).clone(true).attr({ 
     "class": "song-detail" 
    }).css({ 
     "z-index": 1, 
     "background-color": "#CCC" 
    }).appendTo('ol').wrap("<li></li>"); 
}); 

Questa è solo una demo ruvida e avrebbe bisogno di essere ripulito per la produzione. Fondamentalmente la strategia è di aggiungere un "buffer" di 40px padding dopo ogni quinto elemento (la fine di una colonna). Quando un elemento è al passaggio del mouse, troviamo il fratello alla fine della sua colonna e ne anima il riempimento a 0.

Ma si può vedere che se si esegue il mouse su più elementi rapidamente in successione, a volte le scatole rabbrividiranno come una casella salta temporaneamente alla colonna successiva. Il conteggio di colonne CSS3 REALMENTE vuole bilanciare quelle colonne.

Quindi consiglierei di utilizzare un approccio diverso, ma sentitevi liberi di giocare con quello e vedere se riesci a farlo funzionare.

** EDIT: Un modo per farlo senza column-count **

Dal momento che si sta già utilizzando jQuery, si potrebbe avere avvolgere ogni X elementi in un <div class="col">, e utilizzare tali div come le tue colonne.

JSFiddle:http://jsfiddle.net/QhTvH/

JQuery:

var container; 
var i = 0; 
var numCols = 5; 
var colCount = Math.ceil($('.songs a').length/numCols); 

$('.songs a').each(function() { 
    if (i % colCount === 0) { 
     container = $('<div class="col"></div>').appendTo(".songs"); 
    } 
    $(this).appendTo(container); 
    i++; 
}); 

CSS:

.songs .col { 
    max-width: 18%; 
    overflow: hidden; 
    display: inline-block; 
    vertical-align: top; 
    margin: 0 5px; 
} 
.songs a { 
    display: block; 
    margin: 10px 10px; 
    background-color: #EEE; 
    width: 200px; 
    height: 40px; 
    cursor: pointer; 
    text-overflow:ellipsis; 
    overflow: hidden; 
    white-space: nowrap; 
} 

HTML:

<section class="songs"> 
    <a class="song" data-src="songs/Titanic.mp3" style="width: 187px;">Titanic</a> 
    <a class="song" data-src="songs/Titanic.mp3" style="width: 187px;">Titanic2</a> 
    etc... 
</section> 
+0

Sì, ho praticamente lo stesso problema. Come faresti senza contare le colonne CSS3? – theintellects

+0

Vedere la mia modifica per un modo per farlo senza contare le colonne, usando JQuery. –

0

Si potrebbe anche, scoprire quanto spazio rimane nell'ultima colonna e riempirlo anche per le colonne.

DEMO codepen \ 0/DEMO fiddle dalla vostra.

Il jQuery ha aggiunto:

var col = 5; // number of columns 
var liH =50; // average height ol li, including margins 
var nbli = $('ol li').length; // how many do we have ? 
var olH = nbli*liH; // total height of ol 
var colnbli = Math.ceil(nbli/col); // how many li would it make if each column is fully filled ? 
var colH = colnbli*liH; // what's average height of each col 
var ceilOlH= colH*col; //what's total height of columns together 
var olH = nbli*liH; // what's real height of ol ? 
var fixLiH = ceilOlH - olH; // how much difference do i have ? 
var fixcol = $('<li style="height:'+fixLiH+'px;width:50%;padding:0; "></li>').appendTo('ol'); // let's see if we can fill the remaining gap 

e il CSS

li:hover ~li:last-child { 
    margin-top:-10px ; 
    display:block 
} 

da abbinare con animate e evitare di saltare li s, aggiungere un transition-li per il margin:

ol li { 
    display:inline-block; 
    margin: 5px 10px; 
    transition:0.5s;/* to match jQuery animate */ 
} 

Add/remove <li> s per vedere se questo è ciò che si cercato o resettare column-count:5; sia in CSS e var col = 5 ;

0

Hai provato ad utilizzare il tag come contenitore? e animare un div interno (o altro)

Js Fiddle qui: http://jsfiddle.net/keypaul/Yk2du/41/

html

<ol> 
    <li> 
     <a class="song" data-src="songs/Titanic.mp3" style="width: 187px;"> 
      <div>Titanic</div> 
     </a> 
    </li> 
    <li> 
     <a class="song" data-src="songs/Titanic.mp3" style="width: 187px;"> 
      <div>Titanic</div> 
     </a> 
    </li> 
    <li> 
     <a class="song" data-src="songs/Titanic.mp3" style="width: 187px;"> 
      <div>Titanic</div> 
     </a> 
    </li> 
    <li> 
     <a class="song" data-src="songs/Titanic.mp3" style="width: 187px;"> 
      <div>Titanic</div> 
     </a> 
    </li> 
    <li> 
     <a class="song" data-src="songs/Titanic.mp3" style="width: 187px;"> 
      <div>Titanic</div> 
     </a> 
    </li> 
</ol> 

js

$('a.song').each(function() { 
    var origwidth = $(this).width(); 
    var origheight = $(this).height(); 
    $(this).hover(
     function() { 
      $(this).find('div').stop().animate({width: origwidth * 2, height: origheight * 2}); 
     }, function() { 
      $(this).find('div').stop().animate({width: origwidth, height: origheight}); 
     }); 
    $(this).clone(true).attr({"class":"song-detail"}).css({"z-index": 1, "background-color":"#CCC"}).appendTo('ol').wrap("<li></li>"); 
}); 

css

ol { 
    padding: 0px; 
    list-style: decimal-leading-zero inside; 
    color: #000; 
    font-size: 0.9em; 
    -moz-column-count: 5; 
    -webkit-column-count: 5; 
    column-count: 5; 
} 

ol li { 
    display: inline-block; 
    margin: 5px 10px; 
} 

ol li a { 
    background-color: #EEE; 
    display: block; 
    width: 200px; 
    height: 40px; 
    cursor: pointer; 
    text-overflow:ellipsis; 
    white-space: nowrap; 
    margin: 0; 
    position:relative; 
} 

ol li a div { 
    position:absolute; 
    top:0;left:0; 
    width:187px; 
    height:40px; 
    background:red; 
} 
Problemi correlati