【问题标题】:Add a pipe separator after items in an unordered list unless that item is the last on a line在无序列表中的项目之后添加管道分隔符,除非该项目是最后一行
【发布时间】:2012-02-28 14:41:13
【问题描述】:

是否可以为这个 html 设置样式...

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

...像这样...

... 不向特定列表项添加类或诉诸 javascript?如果是的话怎么办?

换行符不固定;列表变宽以占用更多空间,并且列表项居中对齐。

【问题讨论】:

标签: html css


【解决方案1】:

只是

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

当然,这实际上并不能解决 OP 的问题。他想根据中断的位置来省略行首和行尾的竖线。我会竭尽全力断言这个问题无法使用 CSS 解决,甚至使用 JS 也无法解决,除非你想从根本上重写浏览器引擎的文本测量/布局/换行逻辑。

据我所知,唯一“了解”换行的 CSS 是 ::first-line 伪元素,它在这里对我们没有帮助——无论如何,它仅限于一些表现属性,并且不能与 ::before 和 ::after 之类的东西一起使用。我能想到的CSS的唯一其他方面在某种程度上暴露了换行符是连字符。然而,在某些情况下,断字只是添加一个字符(通常是破折号)到行尾,而这里我们关心的是删除一个字符(垂直线),所以我看不到如何应用任何与连字符相关的逻辑,即使借助 hyphenate-character 等属性也是如此。

我们有word-spacing 属性,该属性应用于行内但不在行首和行尾,这看起来很有希望,但它定义了单词之间的空间宽度,而不是要使用的字符。

有人想知道是否有某种方法可以使用text-overflow 属性,该属性具有鲜为人知的能力,可以在左右两侧显示溢出文本,如

text-overflow: '' '';

但这里似乎仍然没有任何明显的方式可以从 A 到 B。

【讨论】:

  • 是的,我很确定这是正确的答案,直到 CSS 得到扩展以了解换行符。
【解决方案2】:

flex-box 可以做到这一点

这项技术的关键:

  • 一个容器元素设置为overflow: hidden
  • ul(这是一个弹性盒)上设置justify-content: space-between,以强制其弹性项目向左右边缘拉伸。
  • ul 上设置margin-left: -1px,使其左边缘溢出容器。
  • li 弹性项目上设置 border-left: 1px

容器充当掩码,隐藏任何触及其左边缘的弹性项目的边框。

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

【讨论】:

  • 而您只用了三年时间就得到了答案。现在你可以完成那个项目了!迟到总比不到好。 ;)
  • 这很棒。我需要一个子弹字符分隔符,并且能够通过这种方法和一些调整来获得它。这可以用于您可以使用 CSS 设置样式的任何效果: - 相对定位 LI - 使用 :after 和 content 属性添加项目符号 - 绝对定位 :after - 将 :after 上的左侧属性调整为其宽度的一半内容 - 调整 UL 上的负边距以隐藏项目符号 - 调整右侧边距以固定间距
  • 我在使用 Bootstrap 时遇到了与 @nilon 相同的问题。我最终将 CSS 重置拆开,直到找到罪魁祸首,以下是导致我的原因:ul, li { padding: 0; }
  • 我有一些ul 的填充物。在.flex-list ul 中拥有padding: 0; 是最安全的。
  • @RicoPicone 我依靠 StackOverflow 的 reset.css 为列表提供全局 padding: 0。如果您不使用重置,或者您的重置未对列表应用零填充,则有必要自己应用零填充。
【解决方案3】:

在展示代码之前,值得一提的是IE8支持:first-child但不支持:last-child,所以在类似情况下,你应该使用:first-child伪类。

演示

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

【讨论】:

    【解决方案4】:

    使用:after 伪选择器。看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; }
    

    编辑:

    jQuery 解决方案:

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

    看这里。我还添加了一些动物。 http://jsfiddle.net/A52T8/10/

    【讨论】:

    • 这并不能解决拖尾管道断线问题 - jsfiddle.net/A52T8/3
    • @Dan 这基本上就是 kinakuta 的答案的工作原理,但反过来,出于同样的原因,它也存在缺陷。
    • 因为我也对此感到好奇,所以我为您设计了一个解决方案,我编辑了我的原始答案。它有效。
    • 糟糕,忘记添加 div 宽度。固定的。不需要反对票。大声笑我的坏jsfiddle.net/A52T8/9
    • 嗯,这是迄今为止唯一正确输出的答案,但不幸的是它需要 javascript。
    【解决方案5】:

    我知道我参加聚会有点晚了,但如果你能忍受让线条左对齐,一个技巧是将管道放在物品之前,然后在左边缘放置一个面具,基本上像这样:

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

    更完整的例子: http://jsbin.com/hoyaduxi/1/edit

    【讨论】:

      【解决方案6】:

      一种解决方案是像这样设置左边框的样式:

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

      但是,如果整个列表都包装起来,这可能不会给您带来理想的结果,就像在您的示例中那样。 IE。它会给出类似的东西:

      foo | bar | baz
       | bob | bill
       | judy
      

      【讨论】:

      • 是的,这正是问题所在。没有办法解决吗?
      • 我猜你需要一些 js 解决方案
      【解决方案7】:

      我今天遇到了一个似乎还没有出现的解决方案,到目前为止它似乎工作得很好。接受的答案在 IE10 上不能按原样工作,但这个答案可以。 http://codepen.io/vithun/pen/yDsjf/ 当然感谢作者!

      .pipe-separated-list-container {
        overflow-x: hidden;
      }
      .pipe-separated-list-container ul {
        list-style-type: none;
        position: relative;
        left: -1px;
        padding: 0;
      }
      .pipe-separated-list-container ul li {
        display: inline-block;
        line-height: 1;
        padding: 0 1em;
        margin-bottom: 1em;
        border-left: 1px solid;
      }
      <div class="pipe-separated-list-container">
        <ul>
          <li>One</li>
          <li>Two</li>
          <li>Three</li>
          <li>Four</li>
          <li>Five</li>
          <li>Six</li>
          <li>Seven</li>
          <li>Eight</li>
          <li>Nine</li>
          <li>Ten</li>
          <li>Eleven</li>
          <li>Twelve</li>
          <li>Thirteen</li>
          <li>Fourteen</li>
          <li>Fifteen</li>
          <li>Sixteen</li>
          <li>Seventeen</li>
          <li>Eighteen</li>
          <li>Nineteen</li>
          <li>Twenty</li>
          <li>Twenty One</li>
          <li>Twenty Two</li>
          <li>Twenty Three</li>
          <li>Twenty Four</li>
          <li>Twenty Five</li>
          <li>Twenty Six</li>
          <li>Twenty Seven</li>
          <li>Twenty Eight</li>
          <li>Twenty Nine</li>
          <li>Thirty</li>
        </ul>
      </div>

      【讨论】:

      • 有趣。它是如何工作的,它是否受父字体大小更改的影响?此外,此解决方案不会将项目居中对齐 :)
      • 哦,你是对的,它只在左对齐时有效!我没有想到,因为这实际上是我在特定情况下所追求的。
      【解决方案8】:

      稍微修改了 SCSS 版本,让您可以控制管道 | 的大小,并在尊重边框的同时消除第一个和最后一个列表项的填充。

      
      $pipe-list-height: 20px;
      $pipe-list-padding: 15px;
      
      .pipe-list {
          position: relative;
          overflow: hidden;
          height: $pipe-list-height;
      
          > ul {
              display: flex;
              flex-direction: row;
      
              > li {
                  position: relative;
                  padding: 0 $pipe-list-padding;
      
                  &:after {
                      content: " ";
                      position: absolute;
                      border-right: 1px solid gray;
                      top: 10%;
                      right: 0;
                      height: 75%;
                      margin-top: auto;
                      margin-bottom: auto;
                  }
      
                  &:first-child {
                      padding-left: 0;
                  }
      
                  &:last-child {
                      padding-right: 0;
      
                      &:after {
                          border-right: none;
                      }
                  }
              }
          }
      }
      
      <div class="pipe-list">
        <ul>
          <li>Link</li>
          <li>Link</li>
          <li>Link</li>
        </ul>
      </div>
      

      【讨论】:

        【解决方案9】:

        这应该可以在不使用边框的情况下解决问题。

        li {
          display: inline-block !important;
          list-style: none;
          margin: 0 auto;
          height: 14px;
          }
            ul li::after {
              content: " | ";
              margin: 0 10px;
            }
            ul li:last-child:after {
              content: '';
              margin: 0 10px;
            }
        <div>
          <ul>
            <li>One</li>
            <li>Two</li>
            <li>Three</li>
            <li>Four</li>
            <li>Five</li>
            <li>Six</li>
            <li>Seven</li>
            <li>Eight</li>
            <li>Nine</li>
            <li>Ten</li>
            <li>Eleven</li>
            <li>Twelve</li>
            <li>Thirteen</li>
            <li>Fourteen</li>
            <li>Fifteen</li>
            <li>Sixteen</li>
            <li>Seventeen</li>
            <li>Eighteen</li>
            <li>Nineteen</li>
            <li>Twenty</li>
            <li>Twenty One</li>
            <li>Twenty Two</li>
            <li>Twenty Three</li>
            <li>Twenty Four</li>
            <li>Twenty Five</li>
            <li>Twenty Six</li>
            <li>Twenty Seven</li>
            <li>Twenty Eight</li>
            <li>Twenty Nine</li>
            <li>Thirty</li>
          </ul>
        </div>

        【讨论】:

          【解决方案10】:

          是的,您需要使用伪元素和伪选择器:http://jsfiddle.net/cYky9/

          【讨论】:

          • 差不多了。这会删除列表一的结尾,但不会删除行的结尾 - jsfiddle.net/cYky9/4
          • 啊,没有意识到这是一个要求 - 如果不涉及一些逻辑,我想不出这怎么可能,这意味着服务器或 js。
          【解决方案11】:

          可以使用下面的CSS来解决。

          ul li { float: left; }
          ul li:before { content: "|"; padding: 0 .5em; }
          ul li:first-child:before { content: ""; padding: 0; }
          

          应该也适用于 IE8+。

          【讨论】:

          • 但它不会删除每行之前的条,它只会删除第一行的条。
          猜你喜欢
          • 2012-08-01
          • 2012-12-21
          • 2011-06-10
          • 2020-01-06
          • 2015-06-12
          • 1970-01-01
          • 2018-02-23
          • 1970-01-01
          • 2021-12-29
          相关资源
          最近更新 更多