2013-08-15 16 views
7

L'approccio attuale il nostro sito sta usando per rompere un unico elenco in più colonne è quello di utilizzare più ul s:Come posso interrompere una singola lista in più colonne semanticamente?

<ul> 
    <li>one</li> 
    <li>two</li> 
</ul> 
<ul> 
    <li>three</li> 
    <li>four</li> 
</ul> 

Questa non sembra l'ideale per me, in quanto semanticamente, non due liste, è uno . Ho visto molte soluzioni inadeguate per elenchi di più colonne. Sto cercando una soluzione che:

  1. utilizza la seguente struttura di markup

    <ul> 
        <li>one</li> 
        <li>two</li> 
        <li>three</li> 
        <li>four</li> 
    </ul> 
    
  2. organizza in questo modo:

    one three 
    two four 
    

    Non questo:

    one two 
    three four 
    
  3. Opere senza modifiche se la lunghezza della lista cambia o se gli elementi racchiudono più righe.

  4. Utilizza HTML semantico valido.
  5. Funziona fino a IE8.

La soluzione ideale è solo CSS, ma sono aperto a utilizzare l'interfaccia utente jQuery o Javascript leggero.

(. PS, here's my CSS attempt, con notevoli problemi)

Edit: Questa domanda è specifico per semantici liste. L'altra domanda apparentemente "duplicata" riguarda gli elementi <div>, che è un altro gioco a palla perché è ammesso markup addizionale. Nessun markup aggiuntivo è consentito tra uno <ul> e uno <li>. Questa domanda è incentrata sulla semantica , il che significa che c'è un'enfasi sull'uso dell'HTML per indicare con il maggior numero di dettagli possibile il significato del contenuto.

+0

Il solo CSS sarebbe difficile in quanto è necessario sapere quali devono essere spostati a sinistra e quali a virgola mobile, tuttavia con js tutto ciò che si deve fare è aggiungere una classe alla prima metà e un'altra classe alla seconda metà, una fluttuante lasciò l'altra a destra. –

+0

puoi usare nth selettori figlio come odd e even, ma non funzionerebbe in IE8 –

+0

@BrianGlaz odd/even risulterebbe in 'one two' sulla riga uno e' three four' sulla riga due piuttosto che come previsto ' three' and' two four' –

risposta

2

Mi dispiace di rispondere alla mia domanda, ma penso che ho avuto una soluzione solo CSS.

Here it is on jsFiddle.

Fondamentalmente, utilizzo il selettore di fratello generale (Questo simbolo: ~, funziona anche in IE7!) Per evidenziare tutti gli elementi dopo il punto di interruzione e spostarli avanti e indietro. Finché si imposta un'altezza di riga, sembra che funzioni cross browser in IE7.

HTML:

<ul> 
    <li>one</li> 
    <li>two</li> 
    <li class="newline">three</li> 
    <li>four</li> 
</ul> 

CSS:

.newrow, 
.newrow ~ li { 
    margin-left: 120px; 
    margin-top: -100px; 
    margin-bottom: 100px; 
} 

Mi sto perdendo qualcosa di ovvio qui?

+0

Ciao, grazie per aver condiviso questo, è una bella idea. Domanda: come fare tre colonne? – Drewdavid

+0

Basta fare 'class = col2' e' class = col3' dove vuoi che le interruzioni di colonna inizino. Quindi rendi il CSS uguale a quello che ho ma per 'col3' è' margin-left: 240px'. – brentonstrine

+1

[Ecco un JSfiddle] (http://jsfiddle.net/hH53F/20/) per spiegare meglio. Sostanzialmente '.col2, .col2 ~ li {margin-left: 270px; margin-top: -220px; margin-bottom: 220px;} ' – brentonstrine

2

CSS Columns è la soluzione migliore ma non funziona con i browser più vecchi. È possibile utilizzare nth-child per chiudere qualcosa, ma non si ottiene una lista divisa (è necessario anche un polyfill per utilizzarlo nei browser più vecchi). La soluzione più semplice sarebbe probabilmente uno javascript: dividerà le liste ma lascerà anche il tuo codice pulito. Ecco una funzione per trasformare gli elenchi in un numero qualsiasi di colonne.

http://jsfiddle.net/UrH69/

SCRIPT

$.fn.extend({ 
    list2Columns: function(numCols) { 
     var listItems = $(this).find('li'); /* get the list data */ 
     var listHeader = $(this); 
     var numListItems = listItems.length; 
     var numItemsPerCol = Math.ceil(numListItems/numCols); /* divide by the number of columns requires */ 
     var currentColNum = 1, currentItemNumber = 1, returnHtml = '', i = 0; 

     /* append the columns */ 
     for (i=1;i<=numCols;i++) { 
      $(this).parent().append('<ul class="column list-column-' + i + '"></ul>'); 
     } 

     /* append the items to the columns */ 
     $.each(listItems, function (i, v) 
     {  
      if (currentItemNumber <= numItemsPerCol){ 
       currentItemNumber ++; 
      } else { 
       currentItemNumber = 1; 
       currentColNum ++; 
      } 
      $('.list-column-'+currentColNum).append(v); 
     }); 
     $(this).remove(); 
    } 
}); 

USO

$('ul').list2Columns(2); // Change this number to change num of columns 

HTML

<ul> 
    <li>one</li> 
    <li>two</li> 
    <li>three</li> 
    <li>four</li> 
    <li>five</li> 
    <li>six</li> 
</ul> 

CSS

.column { float:left; } 
+0

Hai un buon inizio, ma non è finito. Questo codice fallirà, ad es. Se hai più elenchi su una pagina. – MightyPork

+0

Vero, ma se si fornisce alla lista un ID e lo si indirizza direttamente che risolverà il problema. –

5

Si potrebbe utilizzare le colonne per i browser che lo supportano

DEMO http://jsfiddle.net/kevinPHPkevin/eaewX/33/

Ecco un esempio jQuery per il supporto completo del browser

DEMO http://jsfiddle.net/kevinPHPkevin/MKL4g/131/

var postsArr = new Array(), 
    $postsList = $('ul.posts'); 

//Create array of all posts in lists 
$postsList.find('li').each(function(){ 
    postsArr.push($(this).html()); 
}) 

//Split the array at this point. The original array is altered. 
var firstList = postsArr.splice(0, Math.round(postsArr.length/2)), 
    secondList = postsArr, 
    ListHTML = ''; 

function createHTML(list){ 
    ListHTML = ''; 
    for (var i = 0; i < list.length; i++) { 
     ListHTML += '<li>' + list[i] + '</li>' 
    }; 
} 

//Generate HTML for first list 
createHTML(firstList); 
$postsList.html(ListHTML); 

//Generate HTML for second list 
createHTML(secondList); 
//Create new list after original one 
$postsList.after('<ul class="posts"></ul>').next().html(ListHTML); 
+0

ottimo approccio jQuery. Invece di cercare di capire cosa dividere, JavaScript lo fa per te. inoltre, tutto torna a una singola lista se JavaScript è disabilitato e si piega se la finestra è sottile. - grazie per la condivisione! – blackhawk

+0

Ciao Vector, userò il tuo codice e lo modificherò per ottenere un compito simile. Grazie per la pubblicazione. Sono sfocato sulla legalità e così collegherò anche a questa risposta nel mio codice. Per favore fatemi sapere se avete delle obiezioni. –

3

Il modo "corretto" per farlo sarebbe quello di utilizzare le colonne CSS3:

Ma questo solo si arriva a IE10.

Suggerirei di seguire quella rotta e quindi utilizzare spessori IE e javascript o gestire IE9 e IE8. Dimentico, ma modernizr potrebbe fornire uno spessore per aiutarti.

+1

Dov'è il codice? Se questi link si interrompono, questa risposta sarà inutile per gli utenti futuri. – cimmanon

0

è possibile utilizzare i CSS column-count per che questo demo funziona solo in Chrome, ma si può fare cross browser

http://jsfiddle.net/UuwKC/

ul {-webkit-column-count:2} 
Problemi correlati