CSS:最后一个元素在线

时间:2012-03-23 23:17:42

标签: html css css-selectors html-lists

我有一个无序的[内联]链接列表,包含两行:
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 个答案:

答案 0 :(得分:29)

有趣的问题!以下是我认为使用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的解决方案(可以没有,我想知道吗?)这里完全没问题,因为即使脚本没有运行,也只会是极其微小的视觉效果您网页的恶化。

<强> See it in action

答案 1 :(得分:5)

我面临同样的情况,并在响应式设计中这样做。这是我唯一的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

答案 2 :(得分:3)

我实际上在Jon's solution中发现了一个缺陷:在极少数情况下,两个(或更多)li s适合一行,但两个li s加上子弹不合适,他们会在彼此旁边渲染没有子弹。 (最初使用子弹会导致两个li位于不同的行上,应用类nobullet并缩小间距,将第二个li向上移动一行。)

这是一个缺陷的例子:http://jsfiddle.net/W2ULx/61/(注意第一行,最后两个li渲染,它们之间没有子弹。唯一改变的原始小提琴是宽度ul迫使问题发生。)

我发现的简单解决方案是改变CSS

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

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

因此,不要删除间距,只是让它不可见。任何破坏到新线的东西仍然会破坏到一条新线,而不是被移除的子弹撞到一条线。

答案 3 :(得分:1)

我想要一个以视觉为中心的版本,并且还要处理Randall优雅处理的重新布局错误。此解决方案还为每条线上的第一个项添加了一个中间点和空格,这会平衡每条线末端的中间点和空间。如果左对齐菜单,您可能希望将其删除。

我还在代码中切换到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>

答案 4 :(得分:0)

以下是已接受答案的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");

答案 5 :(得分:-1)

根据咖啡中接受的答案:

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