提问人:Ferran Negre 提问时间:9/24/2014 更新时间:10/20/2023 访问量:21187
CSS 文本省略号,包括“更多”链接
CSS Text ellipsis including "More" link
问:
因此,我有以下小提琴,它将文本中的省略号设置为两行。然后,我希望在文本中内联一个“更多”链接。
http://jsfiddle.net/csYjC/2876/
因此,如果我们的文本有两行以上的行,它应该看起来像这样:
没错。然而:
这是不正确的(应该与文本内联)。
代码如下:
<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;
}
我想一定很容易......先谢谢你。
答:
里面的 div 仍显示为块元素。使用此选项可修复:.text
.text > div { display: inline; }
http://jsfiddle.net/csYjC/2880/
评论
-webkit
演示: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
}
评论
只需将一些类添加到 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;}
评论
基于 -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>
评论
好吧,使用 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;
}
我用canvas来获取div中内容所占用的字符串宽度(至于不同的字体,测量会略有不同)。在这里,我通过将字符串的宽度(即 content.textContent)除以 div 内容的宽度来计算内容被划分为的行数
当它达到大于或等于 3 时,锚标记的显示属性将更改为 block,当它小于 3 时,它将恢复为内联。
输出:
这将起作用
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>
评论
好吧,这是一个使用伪元素的纯 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;
}
评论
.text a::before
不幸的是,如果没有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!
<a href="#" class="text-more">More</a>
</div>
<a href="#" class="text-more">More</a>
</div>
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,它将文本限制在其容器的高度,并用省略号修剪它:
评论
a
div
if our text has more than two lines
=>听起来像 JavaScript。当用户调整窗口大小时,您需要事件(以保持正确的行为)