【问题标题】:Truncate text with CSS but add text instead of ellipsis使用 CSS 截断文本,但添加文本而不是省略号
【发布时间】:2026-02-08 19:35:01
【问题描述】:

我想根据响应宽度截断单行文本,并在末尾添加“和更多”而不在单词中间中断。我拼凑了一个工作示例,但我无法让它与居中对齐的文本一起工作。

https://jsfiddle.net/p02147zd/2/

当一个框最后不需要“和更多”时,它会错位,因为它仍然具有为该文本留出空间所需的填充权。如果我左对齐文本看起来不错,但我需要它居中。有什么想法吗?

.foo {
  padding-right: 58px; /* Always have room for "and more" */
  height: 1.1em; /* Only allow one line of text */
  overflow: hidden; /* Hide all the text below that line */
  background-color: yellow;
}
.foo > span {
  display: inline-block; /* These have to be inline block to wrap correctly */
  position: relative; /* Give "and more" an anchor point so it's positioned after the element */
  background-color: yellow; /* Cover "and more" of the previous element with the same background color */
  white-space: pre; /* Make sure the only point where wrapping is allowed is before a comma */
}
.foo > span:after {
  position: absolute; /* Take "and more" out of the flow, so the next item will cover it */
  content: 'and more'; /* Each span has an "and more" */
  margin-left:2px;
}
.foo > span:last-child:after {
  content: ""; /* Except for the last one */
}

谢谢!

【问题讨论】:

    标签: css truncate truncation


    【解决方案1】:

    很遗憾,我不知道 CSS 中的任何解决方案,

    但如果您可以使用 JavaScript,此示例代码会有所帮助:

    https://jsfiddle.net/orovan/89db4yw2/15/

    $(function(){
      and_more();
      $(window).resize(function(){
        and_more();
      });
    });
    
    function and_more(){
      $('.and-more').remove();
      $('.foo').removeClass('has-more');
      $('.foo').each(function(){
        $t = $(this);
        $total_width = $t.width();
        $width = 0;
        $done = false;
        $t.find('span').each(function(){
          $width = $width + $(this).width();
          if($width > $total_width && $done == false){
            $(this).before('<span class="and-more">and more</span>');
            $t.addClass('has-more');
            $done = true;
          }
        });
      });
    }
    .foo {
      padding: 0 30px;
      height: 1.1em; /* Only allow one line of text */
      overflow: hidden; /* Hide all the text below that line */
      background-color: yellow;
    }
    .foo > span {
      display: inline-block; /* These have to be inline block to wrap correctly */
      position: relative; /* Give "and more" an anchor point so it's positioned after the element */
      background-color: pink; /* Cover "and more" of the previous element with the same background color */
      white-space: pre; /* Make sure the only point where wrapping is allowed is before a comma */
    }
    
    .foo i {
      margin:2px;
      font-style:normal;
      position:relative;
    }
    .foo i:after {
      content:','
    }
    .foo > span:last-child i:after {
      content:'';
    }
    
    .wrap {
     padding:10px;
     background:yellow;
      position:relative;
      margin:10px;
      width:25%;
      text-align:center;
    }
    
    .grid {
      display:flex;
      flex-flow:wrap;
    }
    
    .foo.has-more{
      padding: 0;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="grid">
    
    
    <div class="wrap">
    
      <div class="foo">
        <!-- These *must not* have white space between them, or it will collapse to a space before the comma, and the ellipsis will become visible -->
        <span><i>design</i></span><span><i>account</i></span><span><i>web design</i></span><span><i>branding</i></span>
      </div>
    </div>
    <div class="wrap">
    
      <div class="foo">
        <!-- These *must not* have white space between them, or it will collapse to a space before the comma, and the ellipsis will become visible -->
        <span><i>design</i></span><span><i>animation</i></span>
      </div>
    </div>
    <div class="wrap">
    
      <div class="foo">
        <!-- These *must not* have white space between them, or it will collapse to a space before the comma, and the ellipsis will become visible -->
        <span><i>cinematography</i></span><span><i>account management</i></span><span><i>web design</i></span><span><i>branding</i></span>
      </div>
    </div>
    </div>
    
    
    That middle box should be centered because it doesn't have the "and more" but it still has the padding to account for it.
    
    
    <p>
    (The pink bg would normally be yellow to match the box bg. Just wanted to highlight the different elements for testing.)
    </p>

    【讨论】:

    • 我使用您的 JS 来添加/删除 .has-more 类,然后使用 CSS 从那里设置样式。这解决了问题并且需要更少的 JS。明天我会回来标记这个正确的,以防有人提出纯 CSS 的解决方案。谢谢!
    • 我也会对 CSS 解决方案感兴趣。找到了吗?
    • 不,我没有。不过,感谢您提醒将其标记为正确!