CSS: последний элемент в строке - PullRequest
32 голосов
/ 24 марта 2012

У меня есть неупорядоченный [встроенный] список ссылок, заключенный в две строки:
links widget

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

Я добавляю разделитель точек через псевдоэлемент CSS:

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

К сожалению, разделитель появляется после последнего элемента в каждой строке. Всего одной строкой я бы просто взял :last-child и удалил псевдоэлемент.

Какие-нибудь изящные уловки, чтобы скрыть эту последнюю точку с более чем одной линией? Я открыт для странного CSS или JavaScript, если это абсолютно необходимо.

Ответы [ 6 ]

29 голосов
/ 24 марта 2012

Интересный вопрос! Вот то, что я считаю «низкотехнологичным» решением с помощью jQuery:

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

Алгоритму несложно следовать, но вот идея: перебирайте элементы, используя все их свойства (размер, поле, встроенный дисплей и т. Д.), Которые влияют на их положение, когда браузер вычисляет макет. Сравните вертикальное смещение каждого элемента с предыдущим; если они различаются, предыдущий должен быть в конце строки, поэтому отметьте его для особой обработки. Наконец, отметьте также самый последний элемент в наборе для специальной обработки, поскольку по определению это последний элемент в строке, в которой он появляется.

ИМХО тот факт, что это решение на основе Javascript (можно ли обойтись без него, интересно?), Не представляет здесь никакой проблемы, поскольку даже если скрипт не запускается, это будет очень слабое визуальное представление. деградация вашей веб-страницы.

См. Это в действии .

5 голосов
/ 27 февраля 2016

Я сталкиваюсь с той же ситуацией, и делаю это в адаптивном дизайне.вот мое решение только для 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>

здесь тоже как скрипка

3 голосов
/ 06 мая 2016

На самом деле я нашел недостаток в решении Джона : в редкой ситуации, когда два (или более) li с уместились бы в ряд, но два li с плюс пуля не сработали бы не подходят, они будут отображаться рядом друг с другом без пули. (Из-за наличия пули там два li будут находиться на отдельных строках, применяя класс nobullet и уменьшая интервал, перемещая вторую li вверх по линии.)

Вот пример ошибки: http://jsfiddle.net/W2ULx/61/ (Обратите внимание, что в первой строке последние два li рендеринга без маркера между ними. Единственное, что изменилось из оригинальной скрипки, это ширина ul, чтобы вызвать проблему.)

Простым решением, которое я нашел, было изменение в CSS

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

до

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

чтобы вместо удаления пробела сделать его невидимым. Все, что могло бы прерваться на новую строку, все равно переместится на новую строку, вместо того, чтобы удаляться по линии удаленной пулей.

1 голос
/ 22 августа 2017

Я хотел версию, которая была бы визуально центрирована, а также имела бы дело с ошибкой перекомпоновки, элегантно обработанной Рэндаллом.Это решение также добавляет среднюю точку и пробел к первому элементу в каждой строке, что уравновешивает среднюю точку и пробел в конце каждой строки.Вы можете удалить это, если выровняли меню по левому краю.

Я также переключился на offset (). Left в коде, потому что Firefox не работал со offset (). Top.

Код приведен ниже, но здесь есть ссылка, чтобы вы могли легче увидеть, как он работает.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>
0 голосов
/ 15 августа 2017

Вот вариант принятого ответа только для JavaScript ( Не требуется jQuery! ):

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

Вот еще один способ, если вам нужно отслеживать фактическое положение элементов в каждой строке (группе):

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");
0 голосов
/ 02 ноября 2015

На основании принятого ответа в кофе:

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