CSS: dernier élément en ligne
J'ai une liste [inline] non ordonnée de liens qui s'enroule sur deux lignes:
<ul>
<li><a href="http://google.com">Harvard Medical School</a></li>
<li><a href="http://google.com">Harvard College</a></li>
...
</ul>
J'ajoute le séparateur de points via un pseudo-élément CSS:
#widget-links li { display: inline; }
#widget-links li:after { content: " 0b7"; }
Malheureusement, le séparateur apparaît après le dernier élément sur chaque ligne. Avec une seule ligne, je voudrais simplement saisir :last-child
et supprimer l'élément psuedo.
Des astuces astucieuses pour cacher ce dernier point avec plus d'une ligne? Je suis ouvert à css bizarre, ou JavaScript si absolument nécessaire.
6 réponses
Question intéressante! Voici ce que je considère comme une solution "low-tech" avec jQuery qui fait l'affaire:
$(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'algorithme n'est pas difficile à suivre, mais voici l'idée: itérer sur les éléments, en profitant qu'ils ont tous les mêmes propriétés (taille, marge, affichage en ligne, etc.) qui affectent leur position lorsque le navigateur calcule la mise en page. Comparez le décalage vertical de chaque élément avec celui du précédent; s'ils diffèrent, le précédent doit avoir été à la fin de la ligne donc marquer pour un traitement spécial. Enfin, marque le dernier élément dans l'ensemble d'un traitement spécial, puisque, par définition, c'est le dernier élément de la ligne sur laquelle il apparaît.
IMHO le fait que c'est une solution basée sur Javascript (peut - il être fait sans, je me demande?) n'y a aucun problème ici, car même si le script ne s'exécute pas, il n'y aura qu'une très légère dégradation visuelle de votre page Web.
Je suis confronté à la même situation, et le faire dans un design réactif. voici ma seule solution 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>
En fait, j'ai trouvé un défaut dans la solution de Jon : dans la situation rare où deux (ou plus) li
s tiennent sur une rangée, mais les deux li
S plus la balle ne rentrent pas, ils se rendraient l'un à côté de l'autre sans balle. (Avoir la puce là à l'origine ferait que les deux li
S soient sur des lignes séparées, en appliquant la classe nobullet
et en réduisant l'espacement, en déplaçant le second li
vers le haut d'une ligne.)
Voici un exemple de la faille: http://jsfiddle.net/W2ULx/61/ (Avis dans la première ligne, les deux derniers li
s sont rendus sans balle entre eux. La seule chose qui a changé par rapport au violon d'origine est la largeur du ul
pour forcer le problème.)
La solution simple que j'ai trouvée était de changer dans le CSS
ul li.nobullet:after { content: none; }
À
ul li.nobullet:after { color: transparent; }
De sorte qu'au lieu de supprimer l'espacement, il le rend invisible. Tout ce qui aurait brisé une nouvelle ligne se cassera toujours à une nouvelle ligne, au lieu d'être cogné une ligne par la balle enlevée.
Je voulais une version qui serait visuellement centrée et qui traiterait également du bogue de re-mise en page que Randall manipulerait avec élégance. Cette solution ajoute également un point central et un espace au premier élément de chaque ligne, ce qui contrebalance le point central et l'espace à la fin de chaque ligne. Vous pouvez les supprimer si vous alignez votre menu.
Je suis également passé à offset ().laissé dans le code parce que Firefox ne fonctionnait pas avec offset ().haut.
Le code est ci-dessous, mais voici un lien pour vous pouvez plus facilement le voir fonctionner. 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'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>
Voici une version JavaScript seulement de la réponse acceptée (Pas de jQuery nécessaire!):
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";
});
Mise à jour
Voici une autre façon si vous avez besoin de garder une trace des positions réelles des éléments dans chaque ligne (Groupe):
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");
Basé sur la réponse acceptée dans le café:
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