Подтвердить что ты не робот

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

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

<ul>
    <li><a href="#" onclick="location.href='http://google.com'; return false;">Harvard Medical School</a></li>
    <li><a href="#" onclick="location.href='http://google.com'; return false;">Harvard College</a></li>
    ...
</ul>

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

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

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

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

4b9b3361

Ответ 1

Интересный вопрос! Вот что я считаю "низкотехнологичным" решением с 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");
});​

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

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

Посмотрите на действие.

Ответ 2

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

Я действительно нашел недостаток в решении Jon: в редкой ситуации, когда два (или более) 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; }

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

Ответ 4

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

Я также переключился на offset(), оставленный в коде, потому что Firefox не работал со смещением(). 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>

Ответ 5

Основываясь на принятом ответе на кофе:

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

Ответ 6

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