CSS 文本省略号,包括“更多”链接

CSS Text ellipsis including "More" link

提问人:Ferran Negre 提问时间:9/24/2014 更新时间:10/20/2023 访问量:21187

问:

因此,我有以下小提琴,它将文本中的省略号设置为两行。然后,我希望在文本中内联一个“更多”链接。

http://jsfiddle.net/csYjC/2876/

因此,如果我们的文本有两行以上的行,它应该看起来像这样:

enter image description here

没错。然而:

enter image description here

这是不正确的(应该与文本内联)。

代码如下:

<div class="text">
  <div>Lorem ipsum dolor sit amet, Lorem Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, Lorem Lorem i</div>
  <a href="#">More</a>
</div>

还有 css:

.text{
   display: inline;
   overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
   line-height: 24px;     /* fallback */
   max-height: 48px;      /* fallback */
   -webkit-line-clamp: 2; /* number of lines to show */
   -webkit-box-orient: vertical;
}

.text a {
    position: absolute;
}

我想一定很容易......先谢谢你。

JavaScript CSS 省略号

评论

0赞 George G 9/24/2014
你不能放进去吗?adiv
0赞 Cyril Duchon-Doris 9/24/2014
if our text has more than two lines=>听起来像 JavaScript。当用户调整窗口大小时,您需要事件(以保持正确的行为)
0赞 Ferran Negre 9/24/2014
该省略号属性负责 2 行......如果我在 div 里面写 a...jsfiddle.net/csYjC/2879如果“更多”在同一行中,那很好,但如果不是,那就不是。
0赞 OJFord 9/24/2014
即使显示所有内容,该“更多”链接也不会始终显示吗?(除非你有JS要阻止?
0赞 Ferran Negre 9/24/2014
奥利,你说得对,这可能是另一个需要解决的问题。但我认为更容易的问题,就像当我们单击“更多”时,我们将其设为 <a> 不显示。

答:

0赞 Adam Fratino 9/24/2014 #1

里面的 div 仍显示为块元素。使用此选项可修复:.text

.text > div { display: inline; }

http://jsfiddle.net/csYjC/2880/

评论

0赞 Ferran Negre 9/24/2014
嗨,这以正确的方式将“更多”与文本内联。但请注意,如果您调整窗口大小,则“更多”不在正确的位置(有点疯狂)。此外,我刚刚意识到在Firefox中,省略号不起作用。
0赞 OJFord 9/24/2014
@FerranNegre更改为 jsfiddle.net/hegsgwrv.text a{position: relative;}
0赞 Ferran Negre 9/24/2014
你好。我试过了。还是不行。现在总是与文本内联(当两行完成时,我希望它在下面)。如果你经常调整它的大小,你会看到“更多”链接消失了。而且仍然不是Firefox的省略号...那可能是另一回事。
0赞 Adam Fratino 9/24/2014
@FerranNegre这在Firefox中不起作用,因为您只使用前缀。Firefox 不使用 webkit。-webkit
0赞 Adam Fratino 9/24/2014
不幸的是,我不确定如何在不使用 Javascript 的情况下解决这个问题。我以为在内部 div 上强制高度会解决您的问题,但夹子正在覆盖它。到目前为止,奥利似乎在我的答案中加入是最好的可能性。
0赞 Christina 9/24/2014 #2

演示:http://jsbin.com/hatuv/1/edit

<div class="text">
    <p>Lorem ipsum dolor sit amet, Lorem Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, Lorem Lorem i </p>  <a href="#">More</a>
    </div>

CSS的

.text {
    overflow: hidden /* just for clearing */
}
.text p {
    display: inline-block;
    text-overflow: ellipsis;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    margin-top: 0;
    box-sizing: border-box;
    padding-right: 40px;
    margin-right: -40px;
}
.text a {
    float: right
}

评论

0赞 Ferran Negre 9/24/2014
这看起来不错。当文本已经适合所有行时,是否可以使“更多”按钮位于文本下方?此外,您只使用 1 行,我正在尝试使用 2 行。
0赞 Christina 9/24/2014
如果没有jQuery脚本,我无法让多行工作,这就是我最终使用的。jQuery Succinct 插件
0赞 Christina 9/24/2014
@FerranNegre -- Firefox 和多行给我带来了问题,所以我放弃了,最终使用了 jQuery Succinct 插件
0赞 Ferran Negre 9/24/2014
你有这方面的例子吗?还有“更多”链接?只是想在行不适合所有空间时内联文本,并在行行不适合所有空间时内联文本。我认为可以在纯CSS中完成。
0赞 Christina 9/24/2014
这是我发现唯一在Firefox中也有效的东西,实现起来很痛苦,所以我选择了jQuery,它不会在调整大小时重排,只会在加载时重排。我不在乎,因为除了测试人员之外,几乎没有人在到处调整他们的视口大小。mobify.com/blog/multiline-ellipsis-in-pure-css
-2赞 developppper 9/24/2014 #3

只需将一些类添加到 div 并给它:display:inline;

<div class="text">
    <div class="loremclass">Lorem ipsum dolor sit amet, Lorem Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, Lorem Lorem ipsum dolor sit amet</div>
    <a href="#">More</a>
</div>

body {
   margin: 20px;
}

.text{
   display: inline;
   overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
   line-height: 24px;     /* fallback */
   max-height: 48px;      /* fallback */
   -webkit-line-clamp: 2; /* number of lines to show */
   -webkit-box-orient: vertical;
}

.text a {
    position: absolute;
}
.loremclass{display:inline;}

评论

0赞 Ferran Negre 9/24/2014
当文本不适合所有 2 行时,这不会将“更多”链接内联到文本中。
0赞 Ferran Negre 9/24/2014
是的,现在就像我们以前尝试过的那样。当“更多”与文本不内联时,会处于疯狂位置(调整窗口大小以查看它)。
0赞 Adam Fratino 9/24/2014
这是我的答案的重复,除了您为内部 div 添加了一个任意类。
0赞 developppper 9/24/2014
@88 MPG,这就是你给我的原因-?我没看你的解决方案
0赞 Adam Fratino 9/24/2014
是的,这正是原因。将来,请在发布答案之前阅读所有当前答案。如果有人发布了你的解决方案,并且你有一些要添加的内容,请对现有答案发表评论。如果您同意答案,请投赞成票。
0赞 Defims 2/12/2017 #4

基于 -webkit-line-clamp 的纯 CSS 方法,您可以自定义 ...更多像老板一样的内容:

@-webkit-keyframes ellipsis {/*for test*/
    0% { width: 622px }
    50% { width: 311px }
    100% { width: 622px }
}
.ellipsis {
    max-height: 40px;/* h*n */
    overflow: hidden;
    background: #eee;

    -webkit-animation: ellipsis ease 5s infinite;/*for test*/
    /**
    overflow: visible;
    /**/
}
.ellipsis .content {
    position: relative;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-box-pack: center;
    font-size: 50px;/* w */
    line-height: 20px;/* line-height h */
    color: transparent;
    -webkit-line-clamp: 2;/* max row number n */
    vertical-align: top;
}
.ellipsis .text {
    display: inline;
    vertical-align: top;
    font-size: 14px;
    color: #000;
}
.ellipsis .overlay {
    position: absolute;
    top: 0;
    left: 50%;
    width: 100%;
    height: 100%;
    overflow: hidden;

    /**
    overflow: visible;
    left: 0;
    background: rgba(0,0,0,.5);
    /**/
}
.ellipsis .overlay:before {
    content: "";
    display: block;
    float: left;
    width: 50%;
    height: 100%;

    /**
    background: lightgreen;
    /**/
}
.ellipsis .placeholder {
    float: left;
    width: 50%;
    height: 40px;/* h*n */

    /**
    background: lightblue;
    /**/
}
.ellipsis .more {
    position: relative;
    top: -20px;/* -h */
    left: -50px;/* -w */
    float: left;
    color: #000;
    width: 50px;/* width of the .more w */
    height: 20px;/* h */
    font-size: 14px;

    /**
    top: 0;
    left: 0;
    background: orange;
    /**/
}
<div class='ellipsis'>
    <div class='content'>
        <div class='text'>text text text text text text text text text text text text text text text text text text text text text </div>
        <div class='overlay'>
            <div class='placeholder'></div>
            <div class='more'>...<a href="http://hai.li">more</a></div>
        </div>
    </div>
</div>

评论

0赞 Teetrinker 10/19/2017
不错,但仅适用于 Webkit 浏览器。所以不能用于生产。
0赞 batgerel.e 5/11/2019 #5

好吧,使用 Flexbox 让它变得简单。试试这个

.text {
  display: flex;
  > div {
    flex: 0 0 40%;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
  }
}

https://codepen.io/baagii95/pen/byeNqZ

顺便说一句,我用的是 sass。如果你想在css版本中试试这个。

.text {
  display: flex;
}

.text > div {
  flex: 0 0 40%;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
0赞 ac_mmi 1/10/2021 #6

我用canvas来获取div中内容所占用的字符串宽度(至于不同的字体,测量会略有不同)。在这里,我通过将字符串的宽度(即 content.textContent)除以 div 内容的宽度来计算内容被划分为的行数

当它达到大于或等于 3 时,锚标记的显示属性将更改为 block,当它小于 3 时,它将恢复为内联。

输出:

enter image description here

这将起作用

var content = document.getElementsByClassName('content')[0];
var more = document.getElementsByClassName('more');

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var font = "30px times new roman";
context.font = font;
var text = content.textContent;
var width = context.measureText(text).width;
var w = Math.ceil(width);



window.onload = function() {
  change_more();
}

window.onresize = function() {
  change_more();
}


function change_more() {
  var check = Math.ceil(w / content.offsetWidth);

  if (check > 2) {
    more[0].style.display = "none";
    more[1].style.display = "block";
    content.style.textOverflow = "ellipsis";
  } else {
    more[0].style.display = "inline";
    more[1].style.display = "none";
    content.style.textOverflow = "clip";
  }
}
* {
  margin-left: 0px;
  padding: 0px;
}

.content {
  overflow: hidden;
  display: -webkit-box;
  /* fallback */
  font-size: 30px;
  max-height: 90px;
  /* fallback */
  -webkit-line-clamp: 2;
  /* number of lines to show */
  -webkit-box-orient: vertical;
}

a {
  font-size: 30px;
}
<div class="text">
  <div class="content" style="">Lorem ipsum dolor sit amet, Lorem Lorem ipsum dolor sit amet, Lorem ipsum dolor sit amet, Lorem Lorem Lorem ipsum dolor sit amet, Lorem Lorem ipsum dolor sit amet, <a href="#/" class="more">MORE</a></div>
  <a href="#/" class="more">MORE</a>
</div>

评论

0赞 1/12/2021
不在 firefox 中。
0赞 ac_mmi 1/12/2021
@QuestionsBoy你在说什么,我在firefox中检查了它,当内容从超过第二行“MORE”链接位置改变时,当它再次小于或==2时又变回来了
0赞 ac_mmi 1/14/2021
@QuestionsBoy它仍然无法在您的Firefox中工作吗?
0赞 imhvost 3/17/2023
在某些时候,该链接会在右侧和底部消失
0赞 Adam 1/11/2021 #7

好吧,这是一个使用伪元素的纯 CSS 的有趣解决方案。http://jsfiddle.net/j8ekzvLq/

.text {
   display: inline;
   overflow: hidden;
   text-overflow: ellipsis;
   display: -webkit-box;
   line-height: 24px;     /* fallback */
   max-height: 48px;      /* fallback */
   -webkit-line-clamp: 2; /* number of lines to show */
   -webkit-box-orient: vertical;
   position: relative;
   padding-bottom: 24px;
}

.text::before {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 24px;
    background-color: #fff;
    z-index: 1;
}

.text div {
    background-color: #fff;
    display: inline;
    position: relative;
}

.text div::after {
    content: "";
    background-color: #fff;
    position: absolute;
    bottom: -24px;
    left: 0;
    width: 100%;
    height: 24px;
    z-index: 2;
}

.text a::before {
    content: "More";
    position: absolute;
    bottom: 0;
    left: 0;
    text-decoration: underline;
    z-index: 1;
}

评论

0赞 imhvost 3/17/2023
如果背景是半透明的,你如何遮挡?.text a::before
0赞 imhvost 3/17/2023 #8

不幸的是,如果没有javascript,这个问题就无法解决。 有必要计算链路位置。其中一个实现选项可以如下所示(为方便起见,使用 jquery):

positionMore();
$(window).on('resize', positionMore);

function positionMore(){
    $('.text').each(function(){
        const t = $(this);
        const container = t.closest('.container-text');
        const more = t.find('.text-more');
        if(
            Math.ceil(more.position()?.left + more.width()) > t.width() ||
            Math.ceil(more.position()?.top) >= t.height()
        ){
            container.addClass('active');
        }else{
            container.removeClass('active');
        }
    })
}
.container-text > .text-more {
  display: none;
}
.container-text.active > .text-more {
  display: inline;
}
.container-text.active .text .text-more {
  opacity: 0;
}
.text {
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  line-height: 24px;
  /* fallback */
  max-height: 48px;
  /* fallback */
  -webkit-line-clamp: 2;
  /* number of lines to show */
  -webkit-box-orient: vertical;
  position: relative;
  font-size: 18px;
}
.text .text-more {
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-text">
  <div class="text">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Alias eveniet sequi quos accusantium fuga corrupti voluptate nihil reprehenderit voluptatem tenetur, et modi nisi, consequatur dolore fugit iusto perferendis consequuntur illum, nemo esse natus fugiat? Et, ratione? Asperiores sequi, eaque ullam mollitia quos quidem vitae. Nihil velit provident accusamus est corporis nobis harum fugiat!&nbsp;
    <a href="#" class="text-more">More</a>
  </div>
  <a href="#" class="text-more">More</a>
</div>

0赞 vsync 9/19/2023 #9

HTML 元素(例如“阅读更多”链接)可以在截断的文本块的末尾直观地呈现,这样添加的元素就可以放入容器中,并且不会通过使用“技巧”的组合来覆盖文本(覆盖文本的一部分):

第一部分 - 伪元素

伪元素与 3 个属性一起使用,其中容器也使用该变量来指示在哪一行之后截断:--line-clamp

p::before {
  content: '';
  float: right;
  height: calc((var(--line-clamp) - 1) * 1lh);
}

第二部分 - “显示更多”链接

在容器内的任何文本之前放置一个锚点元素。元素 必须是第一个节点,这样它就不会被修剪,所以 它可以一直“浮动”到右边(在 LTR 文本中)<a class='show-more'>Show More</a>

p .show-more {
  clear: both;
  float: right;
}

在下面的示例中,我使用 javascript 来检测文本何时被截断(溢出其容器):

现场示例

function isTextTruncated( elm ){
  const truncated = elm.scrollHeight > elm.clientHeight
  elm.classList.toggle('truncated', truncated)
}

// observe resize
const resizeObserver = new ResizeObserver(m => isTextTruncated(m[0].target))

resizeObserver.observe(document.querySelector('p'), { attributes: true })
p {
  --line-clamp: 4;
  
  display: -webkit-box;
  -webkit-line-clamp: var(--line-clamp);
  -webkit-box-orient: vertical;
  
  hyphens: auto;
  width: clamp(300px, 50%, 900px);
  resize: horizontal;
  overflow: hidden;
}

p::before {
  content: '';
  float: right;
  height: calc((var(--line-clamp) - 1) * 1lh);
}

p .show-more {
  clear: both;
  float: right;
  
  color: blue;
  margin-left: 0.5em;
}

/* 
  no need to render the "show more" link if 
  the text is fully-visible and not truncated
*/
p:not(.truncated) .show-more {
  display: none;
}
<p>
  <a class='show-more'>Show More</a>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
  sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
  Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
  nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in 
  reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
</p>

如果“文本不合适”,则截断:

这目前超出了 CSS 功能的范围,但这是我创建的一个 javascript polyfill,它将文本限制在其容器的高度,并用省略号修剪它:

https://codepen.io/vsync/pen/eYbGgGL