使用 CSS 截断文本,但添加文本而不是省略号

Truncate text with CSS but add text instead of ellipsis

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

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

如果框的末尾不需要“and more”,它就会错位,因为它仍然具有为该文本留出空间所需的 padding-right。如果我左对齐文本看起来不错,但我需要它居中。有什么想法吗?

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

中的任何解决方案

但如果您可以使用 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>