2012-03-23 15 views
28

Ho una non ordinata [inline] elenco di link che si avvolge su due linee:
links widgetCSS: Ultimo elemento on line

<ul> 
    <li><a href="http://google.com">Harvard Medical School</a></li> 
    <li><a href="http://google.com">Harvard College</a></li> 
    ... 
</ul> 

aggiungo il separatore di punti tramite una pseudo-elemento CSS:

#widget-links li { display: inline; } 
#widget-links li:after { content: " \00b7"; } 

Sfortunatamente, il separatore viene visualizzato dopo l'ultimo elemento su ciascuna riga. Con una sola riga, mi piacerebbe semplicemente prendere :last-child e rimuovere l'elemento psuedo.

Eventuali trucchi per nascondere l'ultimo punto con più di una linea? Sono aperto a strani CSS o JavaScript se assolutamente necessario.

+1

Anche con JavaScript, sarebbe difficile scoprire dove esattamente avvolgono le voci di elenco. – BoltClock

risposta

25

Interessante domanda! Ecco quello che io considero una soluzione "low-tech" con jQuery che fa il trucco:

$(function() { 
    var lastElement = false; 
    $("ul > li").each(function() { 
     if (lastElement && lastElement.offset().top != $(this).offset().top) { 
      lastElement.addClass("nobullet"); 
     } 
     lastElement = $(this); 
    }).last().addClass("nobullet"); 
});​ 

L'algoritmo non è difficile da seguire, ma ecco l'idea: iterata sugli elementi, approfittando che tutti hanno il stesse proprietà (dimensione, margine, visualizzazione in linea ecc.) che influiscono sulla loro posizione quando il browser calcola il layout. Confronta l'offset verticale di ogni oggetto con quello del precedente; se differiscono, il precedente deve essere stato alla fine della linea quindi contrassegnarlo per un trattamento speciale. Infine, segna anche l'ultimo oggetto nel set per un trattamento speciale, poiché per definizione è l'ultimo elemento nella riga su cui appare.

IMHO il fatto che questa sia una soluzione basata su Javascript (si può fare senza, mi chiedo?) Non è affatto un problema qui, poiché anche se lo script non viene eseguito non ci sarà che una leggerissima degrado visivo della tua pagina web.

See it in action.

+3

Questo è bello. – BoltClock

+0

@BoltClock: Grazie. :) – Jon

+0

concordato: questo è bello. Grazie mille, Jon! – benesch

0

Sulla base della risposta accettata nel caffè:

do lastinline = -> 
     $('[lastinline]').each -> 
      $parent = $ @ 
      lastElement = false 
      $parent.find('> *').each -> 
       $child = $ @ 
       if lastElement && lastElement.offset().top != $child.offset().top 
        lastElement.addClass "last-in-line" 
       lastElement = $child 

      .last().addClass "last-in-line" 

$(window).on 'resize', lastinline 
4

sto affrontando la stessa situazione, e facendo questo in un responsive design. ecco la mia unica soluzione CSS.

div { 
 
    overflow: hidden; 
 
    margin: 1em; 
 
} 
 
div ul { 
 
    list-style: none; 
 
    padding: 0; 
 
    margin-left: -4px; 
 
} 
 
div ul li { 
 
    display: inline; 
 
    white-space: nowrap; 
 
} 
 
div ul li:before { 
 
    content: " \00b7"; 
 
}
<div> 
 
    <ul> 
 
    <li>item 1</li> 
 
    <li>item B</li> 
 
    <li>item 3</li> 
 
    <li>item IV</li> 
 
    <li>the long item</li> 
 
    <li>item 6</li> 
 
    <li>item 7</li> 
 
    <li>item awesome</li> 
 
    <li>give me your money</li> 
 
    <li>contact</li> 
 
    <li>menu item more</li> 
 
    <li>CSS is awesome</li> 
 
    <li>CSS3 is great</li> 
 
    <li>more</li> 
 
    <li>last item</li> 
 

 
    </ul> 
 
</div>

here it is as a fiddle too

+0

È decisamente utile e intelligente, ma sfortunatamente funziona solo per elenchi allineati a sinistra. Inoltre, per assicurarti che ci sia uno spazio uguale tra i punti, ti suggerisco di: div ul li: before {content: "\ 00b7 \ 00a0";} Questo dà più margine di manovra al margine negativo per i caratteri con metriche diverse. Ho usato div ul {margin-left: -.4em;} che ho trovato funzionerà con la maggior parte dei tipi di carattere. –

3

realtà ho trovato un difetto nella Jon's solution: Nella situazione rara in cui due (o più) li s si adatterebbe in una fila, ma le due li s più il proiettile non si adatterebbe, si renderebbero uno vicino all'altro. (. Avendo il proiettile non originariamente causerebbero due li s per essere su righe separate, applicando la classe nobullet e riducendo la spaziatura, spostando il secondo li una linea)

Ecco un esempio del difetto: http://jsfiddle.net/W2ULx/61/ (Nota nella prima riga, gli ultimi due rendering di li senza punto elenco tra di loro. L'unica cosa modificata dal violino originale è la larghezza dello ul per forzare il problema.)

La soluzione più semplice che ho trovato è stato quello di cambiare in CSS

ul li.nobullet:after { content: none; } 

a

ul li.nobullet:after { color: transparent; } 

in modo che invece di rimuovere la spaziatura, appena lo rende invisibile. Qualunque cosa che si sarebbe rotta su una nuova linea, tuttavia, si interromperà in una nuova riga, invece di essere schiacciata da una pallottola rimossa.

0

Ecco un solo JavaScript versione della risposta accettata (No jQuery necessario!):

document.addEventListener("DOMContentLoaded", function(event) { 
    var lastElement = false; 
    var els = document.querySelectorAll('ul li'); 
    for(var i = 0; i < els.length; i++){ 
     var el = els[i]; // current element 
     if (lastElement && lastElement.offsetTop !== el.offsetTop) { 
      lastElement.className += " nobullet"; 
     } 
     lastElement = el; 
    } 
    els[els.length - 1].className += " nobullet"; 
}); 

UPDATE

Ecco un altro modo se avete bisogno di tenere traccia delle posizioni reali del elementi in ogni riga (gruppo):

var i = 0; 
var j = 0; 
var keys = []; 
var groupsList = []; 
$("ul li").each(function() { 
    var topOffset = $(this).offset().top; 
    if(Array.isArray(groupsList[topOffset])) { 
     groupsList[topOffset].push(i); 
    } else { 
     if(j > 0) { 
      var lastElementIndexOnRow = groupsList[keys[j-1]][groupsList[keys[j-1]].length - 1]; 
      $($('ul li').get(lastElementIndexOnRow)).addClass('nobullet'); 
     } 
     groupsList[topOffset] = []; 
     groupsList[topOffset].push(i); 
     keys.push(topOffset); 
     j++; 
    } 
    i++; 
}).last().addClass("nobullet"); 
1

Volevo una versione t Il cappello sarebbe stato visivamente centrato e avrebbe anche affrontato il bug di ri-layout che Randall ha gestito elegantemente. Questa soluzione aggiunge anche un punto centrale e uno spazio al primo elemento su ciascuna linea, che controbilancia il punto medio e lo spazio all'estremità di ogni linea. Potresti voler rimuovere questo se hai lasciato il tuo menu.

Sono passato anche a offset(). Sinistra nel codice perché Firefox non funzionava con offset(). Top.

Il codice è sotto, ma qui c'è un collegamento in modo da poterlo vedere più facilmente. http://kpao.typepad.com/files/middle-dot-separated-list-v2.html

<html> 
<head> 
<title>Wildlife Conservation Network programs menu</title> 
<style> 
body, div, p, div, li, a {font-family:"Avenir Next","Segoe UI",sans-serif; font-size:15px;} 
a {color:royalblue; text-decoration:none;} 
a:hover, a:active {text-decoration:underline;} 
ul.menu {background-color:#f2f2f2; text-align:center; padding:1em 0; margin:0;} 
ul li {display:inline; white-space:nowrap;} 
ul li::before {content:""; padding-right:3px;} 
ul li::after {content:"\00a0\00b7"; padding-left:3px;} 
ul li.firstdot::before, ul li:first-child::before {content:"\00b7\00a0"; color:transparent;} 
ul li.lastdot::after, ul li:last-child::after {color:transparent;} 
</style> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<script> 
function midDotIt() { 
    var lastElement = false; 
    $("ul li").each(function() { 
     if (lastElement && lastElement.offset().left > $(this).offset().left) { 
      $(lastElement).addClass("lastdot"); 
      $(this).addClass("firstdot"); 
     } else if (lastElement) { 
      $(lastElement).removeClass("lastdot"); 
      $(this).removeClass("firstdot"); 
     } 
     lastElement = $(this); 
    }); 
} 
</script> 
</head> 
<body onload="midDotIt();" onresize="midDotIt();"> 

<ul class="menu"> 
<li><a href="https://wildnet.org/wildlife-programs/african-wild-dog">African Wild Dog</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/andean-cat">Andean Cat</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/cheetah-botswana">Cheetah - Botswana</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/cheetah-namibia">Cheetah - Namibia</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/cotton-top-tamarin">Cotton-Top Tamarin</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/elephant">Elephant</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/elephant-crisis-fund">Elephant Crisis Fund</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/ethiopian-wolf">Ethiopian Wolf</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/grevys-zebra">Grevy&#039;s Zebra</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/lion-ewaso">Lion - Ewaso</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/lion-niassa-0">Lion - Niassa</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/lion-recovery-fund">Lion Recovery Fund</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/okapi">Okapi</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/penguin">Penguin</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/saiga-antelope">Saiga Antelope</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/sharks-rays">Sharks and Rays</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/small-wild-cats">Small Wild Cats</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/snow-leopard">Snow Leopard</a></li> 
<li><a href="https://wildnet.org/wildlife-programs/spectacled-bear">Spectacled Bear</a></li> 
<li><a href="https://wildnet.org/what-we-do/scholarships">Scholarship Program</a></li> 
</ul> 
</body> 
</html>