Add a pipe separator after items in an unordered list unless that item is the last on a line

前端 未结 10 986
逝去的感伤
逝去的感伤 2020-11-29 18:54

Is it possible to style this html ...

  • Dogs
  • Cats
  • Lions
  • Tig
相关标签:
10条回答
  • 2020-11-29 18:57

    Use :after pseudo selector. Look http://jsfiddle.net/A52T8/1/

    <ul>
        <li>Dogs</li>
        <li>Cats</li>
        <li>Lions</li>
        <li>Tigers</li>
        <li>Zebras</li>
        <li>Giraffes</li>
        <li>Bears</li>
        <li>Hippopotamuses</li>
        <li>Antelopes</li>
        <li>Unicorns</li>
        <li>Seagulls</li>
    </ul>
    
    ul li { float: left; }
    ul li:after { content: "|"; padding: 0 .5em; }
    

    EDIT:

    jQuery solution:

    html:

    <div>
        <ul id="animals">
            <li>Dogs</li>
            <li>Cats</li>
            <li>Lions</li>
            <li>Tigers</li>
            <li>Zebras</li>
            <li>Giraffes</li>
            <li>Bears</li>
            <li>Hippopotamuses</li>
            <li>Antelopes</li>
            <li>Unicorns</li>
            <li>Seagulls</li>
            <li>Monkey</li>
            <li>Hedgehog</li>
            <li>Chicken</li>
            <li>Rabbit</li>
            <li>Gorilla</li>
        </ul>
    </div>
    

    css:

    div { width: 300px; }
    ul li { float: left; border-right: 1px solid black; padding: 0 .5em; }
    ul li:last-child { border: 0; }
    

    jQuery

    var maxWidth = 300, // Your div max-width
        totalWidth = 0;
    $('#animals li').each(function(){
        var currentWidth = $(this).outerWidth(),
            nextWidth = $(this).next().outerWidth();
        totalWidth += currentWidth;
        if ( (totalWidth + nextWidth) > maxWidth ) {
            $(this).css('border', 'none');
            totalWidth = 0;
        }
    });
    

    Take a look here. I also added a few more animals. http://jsfiddle.net/A52T8/10/

    0 讨论(0)
  • 2020-11-29 19:04

    One solution is to style the left border like so:

    li { display: inline; }
    li + li {
      border-left: 1px solid;
      margin-left:.5em;
      padding-left:.5em;
    }
    

    However, this may not give you desirable results if the entire lists wraps, like it does in your example. I.e. it would give something like:

    foo | bar | baz
     | bob | bill
     | judy
    
    0 讨论(0)
  • 2020-11-29 19:05

    This is now possible with flex-box

    The keys to this technique:

    • A container element set to overflow: hidden.
    • Set justify-content: space-between on the ul (which is a flex-box) to force its flex-items to stretch to the left and right edges.
    • Set margin-left: -1px on the ul to cause its left edge to overflow the container.
    • Set border-left: 1px on the li flex-items.

    The container acts as a mask hiding the borders of any flex-items touching its left edge.

    .flex-list {
        position: relative;
        margin: 1em;
        overflow: hidden;
    }
    .flex-list ul {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: space-between;
        margin-left: -1px;
    }
    .flex-list li {
        flex-grow: 1;
        flex-basis: auto;
        margin: .25em 0;
        padding: 0 1em;
        text-align: center;
        border-left: 1px solid #ccc;
        background-color: #fff;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet"/>
    <div class="flex-list">
        <ul>
            <li>Dogs</li>
            <li>Cats</li>
            <li>Lions</li>
            <li>Tigers</li>
            <li>Zebras</li>
            <li>Giraffes</li>
            <li>Bears</li>
            <li>Hippopotamuses</li>
            <li>Antelopes</li>
            <li>Unicorns</li>
            <li>Seagulls</li>
        </ul>
    </div>

    0 讨论(0)
  • 2020-11-29 19:05

    I know I'm a bit late to the party, but if you can put up with having the lines left-justified, one hack is to put the pipes before the items and then put a mask over the left edge, basically like so:

    li::before {
      content: " | ";
      white-space: nowrap;
    }
    
    ul, li {
      display: inline;
    }
    
    .mask {
      width:4px;
      position: absolute;
      top:8px; //position as needed
    }
    

    more complete example: http://jsbin.com/hoyaduxi/1/edit

    0 讨论(0)
  • 2020-11-29 19:11

    Before showing the code, it's worth mentioning that IE8 supports :first-child but not :last-child, so in similar situations, you should use the :first-child pseudo-class.

    Demo

    #menu{
        list-style: none;
    }
    #menu li{
        display: inline;
        padding: 0 10px;
        border-left: solid 1px black;
    }
    #menu li:first-child{
        border-left: none;
    }
    <ul id="menu">
        <li>Dogs</li>
        <li>Cats</li>
        <li>Lions</li>
        <li>More animals</li>
    </ul>

    0 讨论(0)
  • 2020-11-29 19:12

    Just

    li + li::before {
        content: " | ";
    }
    

    Of course, this does not actually solve the OP's problem. He wants to elide the vertical bars at the beginning and end of lines depending on where they are broken. I will go out on a limb and assert that this problem is not solvable using CSS, and not even with JS unless one wants to essentially rewrite the browser engine's text-measurement/layout/line breaking logic.

    The only pieces of CSS, as far as I can see, that "know" about line breaking are, first, the ::first-line pseudo element, which does not help us here--in any case, it is limited to a few presentational attributes, and does not work together with things like ::before and ::after. The only other aspect of CSS I can think of that to some extent exposes line-breaking is hyphenation. However, hyphenating is all about adding a character (usually a dash) to the end of lines in certain situations, whereas here we are concerned about removing a character (the vertical line), so I just can't see how to apply any kind of hyphenation-related logic, even with the help of properties such as hyphenate-character.

    We have the word-spacing property, which is applied intra-line but not at line beginnings and endings, which seems promising, but it defines the width of the space between words, not the character(s) to be used.

    One wonders if there's some way to use the text-overflow property, which has the little-known ability to take two values for display of overflow text at both left and right, as in

    text-overflow: '' '';
    

    but there still doesn't seem to be any obvious way to get from A to B here.

    0 讨论(0)
提交回复
热议问题