CSS: последний элемент в строке

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

<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 ответов

Решение

Интересный вопрос! Вот что я считаю "низкотехнологичным" решением с 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 (можно ли обойтись без него, интересно?), Не представляет здесь никакой проблемы, так как даже если скрипт не запускается, это приведет к очень незначительной визуальной деградации вашего страница интернета.

Смотрите это в действии.

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

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

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

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

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

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

в

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

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

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

Я также переключился на 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>

Вот версия принятого ответа только для 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";
});

ОБНОВИТЬ

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

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");

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

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
Другие вопросы по тегам