使用CSS,使用“...”表示溢出的多行块

时间:2011-06-03 03:16:34

标签: html css ellipsis css3

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
如果溢出,

“...”将显示在行尾。 但是,这只会在一行中显示。 但我希望它以多行显示。

看起来像是:

+--------------------+
|abcde feg hij   dkjd|
|dsji jdia js ajid  s|
|jdis ajid dheu d ...|/*Here it's overflowed, so "..." is shown. */
+--------------------+

15 个答案:

答案 0 :(得分:84)

还有几个jquery插件可以解决这个问题,但是很多插件不能处理多行文本。以下作品:

还有一些preformance tests

答案 1 :(得分:58)

我已经入侵了,直到我成功实现了这一目标。它附带了一些警告:

  1. 这不是纯粹的CSS;你必须添加一些HTML元素。但是不需要JavaScript。
  2. 省略号在最后一行右对齐。这意味着如果您的文本没有右对齐或对齐,则最后一个可见单词和省略号之间可能存在明显的差距(取决于第一个隐藏单词的长度)。
  3. 省略号的空格始终保留。这意味着如果文本几乎精确地放在框中,它可能会被不必要地截断(最后一个字是隐藏的,尽管从技术上来说不是这样)。
  4. 您的文字需要有固定的背景颜色,因为我们使用彩色矩形来隐藏省略号,以防不需要。
  5. 我还应该注意,文本将在单词边界处断开,而不是字符边界。这是故意的(因为我认为对于较长的文本更好),但因为它与text-overflow: ellipsis的不同,我认为我应该提及它。

    如果您能够接受这些警告,HTML就像这样:

    <div class="ellipsify">
        <div class="pre-dots"></div>
        <div class="dots">&hellip;</div>
        <!-- your text here -->
        <span class="hidedots1"></span>
        <div class="hidedots2"></div>
    </div>
    

    这是相应的CSS,使用150像素宽的盒子的例子,在白色背景上有三行文字。假设您有一个CSS重置或类似的设置,在必要时将边距和填充设置为零。

    /* the wrapper */
    .ellipsify {
        font-size:12px;
        line-height:18px;
        height: 54px;       /* 3x line height */
        width: 150px;
        overflow: hidden;
        position: relative; /* so we're a positioning parent for the dot hiders */
        background: white;
    }
    
    /* Used to push down .dots. Can't use absolute positioning, since that
       would stop the floating. Can't use relative positioning, since that
       would cause floating in the wrong (namely: original) place. Can't 
       change height of #dots, since it would have the full width, and
       thus cause early wrapping on all lines. */
    .pre-dots {
        float: right;
        height: 36px;  /* 2x line height (one less than visible lines) */
    }
    
    .dots {
        float: right; /* to make the text wrap around the dots */
        clear: right; /* to push us below (not next to) .pre-dots */
    }
    
    /* hides the dots if the text has *exactly* 3 lines */
    .hidedots1 {
        background: white;
        width: 150px;
        height: 18px;       /* line height */
        position: absolute; /* otherwise, because of the width, it'll be wrapped */
    }
    
    /* hides the dots if the text has *less than* 3 lines */
    .hidedots2 {
        background: white; 
        width: 150px;
        height: 54px;       /* 3x line height, to ensure hiding even if empty */
        position: absolute; /* ensures we're above the dots */
    }
    

    结果如下:

    image of the rendered result with different text lengths

    为了阐明它是如何工作的,这里是相同的图像,除了.hidedots1以红色突出显示,.hidedots2以青色突出显示。这些是在没有不可见文本时隐藏省略号的矩形:

    the same image as above, except that the helper elements are highlighted in color

    在IE9,IE8(仿真),Chrome,Firefox,Safari和Opera中测试过。在IE7中不起作用。

答案 2 :(得分:41)

这是最近讨论过的css-tricks article

上述文章中的一些解决方案(此处未提及)是

1)-webkit-line-clamp和2)将一个绝对定位的元素放在右下方并淡出

两种方法都采用以下标记:

<div class="module"> /* Add line-clamp/fade class here*/
  <p>Text here</p>
</div>

用css

.module {
  width: 250px;
  overflow: hidden;
}

1)-webkit-line-clamp

line-clamp FIDDLE (..最多3行)

.line-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;  
  max-height: 3.6em; /* I needed this to get it to work */
}

2)淡出

  

假设您将行高设置为1.2em。如果我们想暴露   三行文字,我们可以只做容器的高度   3.6em(1.2em×3)。隐藏的溢出将隐藏其余部分。

<强> Fade out FIDDLE

p
{
    margin:0;padding:0;
}
.module {
  width: 250px;
  overflow: hidden;
  border: 1px solid green;
  margin: 10px;
}

.fade {
  position: relative;
  height: 3.6em; /* exactly three lines */
}
.fade:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 70%;
  height: 1.2em;
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
}

解决方案#3 - 使用@supports

的组合

我们可以使用@supports在webkit浏览器上应用webkit的line-clamp,并在其他浏览器中应用淡出。

@supports line-clamp with fade fallback fiddle

<div class="module line-clamp">
  <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</div>

CSS

.module {
  width: 250px;
  overflow: hidden;
  border: 1px solid green;
  margin: 10px;
}

.line-clamp {
      position: relative;
      height: 3.6em; /* exactly three lines */
    }
.line-clamp:after {
      content: "";
      text-align: right;
      position: absolute;
      bottom: 0;
      right: 0;
      width: 70%;
      height: 1.2em;
      background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
 }

@supports (-webkit-line-clamp: 3) {
    .line-clamp {
        display: -webkit-box;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;  
        max-height:3.6em; /* I needed this to get it to work */
        height: auto;
    }
    .line-clamp:after {
        display: none;
    }
}

答案 3 :(得分:34)

以下链接为此问题提供了纯HTML / CSS解决方案。

浏览器支持 - 如文章中所述:

  

到目前为止,我们已经测试了Safari 5.0,IE 9(必须采用标准模式),   Opera 12和Firefox 15。

     

旧的浏览器仍然可以很好地工作,作为布局的核心   处于正常定位,边距和填充属性。如果你的   平台较旧(例如Firefox 3.6,IE 8),你可以使用这个方法   将渐变重做为独立的PNG图像或DirectX过滤器。

http://www.mobify.com/dev/multiline-ellipsis-in-pure-css

css:

p { margin: 0; padding: 0; font-family: sans-serif;}

.ellipsis {
    overflow: hidden;
    height: 200px;
    line-height: 25px;
    margin: 20px;
    border: 5px solid #AAA; }

.ellipsis:before {
    content:"";
    float: left;
    width: 5px; height: 200px; }

.ellipsis > *:first-child {
    float: right;
    width: 100%;
    margin-left: -5px; }        

.ellipsis:after {
    content: "\02026";  

    box-sizing: content-box;
    -webkit-box-sizing: content-box;
    -moz-box-sizing: content-box;

    float: right; position: relative;
    top: -25px; left: 100%; 
    width: 3em; margin-left: -3em;
    padding-right: 5px;

    text-align: right;

    background: -webkit-gradient(linear, left top, right top,
        from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
    background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);           
    background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white); }

html:

<div class="ellipsis">
    <div>
        <p>Call me Ishmael.  Some years ago &ndash; never mind how long precisely &ndash; having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world.  It is a way I have of driving off the spleen, and regulating the circulation.  Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off &ndash; then, I account it high time to get to sea as soon as I can.</p>  
    </div>
</div>

fiddle

(调整浏览器的测试窗口)

答案 4 :(得分:21)

在查看W3 spec for text-overflow之后,我认为只使用CSS是可行的。省略号是一个新兴的属性,所以它可能还没有得到很多用法或反馈。

然而,this guy似乎已经提出了类似(或相同)的问题,并且有人能够提出一个不错的jQuery解决方案。您可以在此处演示解决方案:http://jsfiddle.net/MPkSF/

如果javascript不是一个选项,我想你可能会运气不好......

答案 5 :(得分:8)

很棒的问题......我希望有一个答案,但这是你现在最接近CSS的答案。没有省略号,但仍然可以使用。

overflow: hidden;
line-height: 1.2em;
height: 3.6em;      // 3 lines * line-height

答案 6 :(得分:6)

这是我用css最接近的解决方案。

HTML

<div class="ellipsis"> <span>...</span>
Hello this is Mr_Green from Stackoverflow. I love CSS. I live in CSS and I will never leave working on CSS even my work is on other technologies.</div>

CSS

div {
    height: 3em;
    line-height: 1.5em;
    width: 80%;
    border: 1px solid green;
    overflow: hidden;
    position: relative;
}
div:after {
    content:". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
    background-color: white;
    color: white;
    display: inline;
    position: relative;
    box-shadow: 8px 1px 1px white;
    z-index: 1;
}
span {
    position: absolute;
    bottom: 0px;
    right: 0px;
    background-color: white;
}

Working Fiddle调整窗口大小以检查

Link to my blog for explanation

Updated Fiddle

我希望现在一些css专家能够了解如何使其完美。 :)

答案 7 :(得分:6)

我发现这个css(scss)解决方案效果很好。在webkit浏览器上,它显示省略号,在其他浏览器上,它只是截断文本。这对我的预期用途很好。

$font-size: 26px;
$line-height: 1.4;
$lines-to-show: 3;

h2 {
  display: block; /* Fallback for non-webkit */
  display: -webkit-box;
  max-width: 400px;
  height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
  margin: 0 auto;
  font-size: $font-size;
  line-height: $line-height;
  -webkit-line-clamp: $lines-to-show;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

创作者的一个例子:http://codepen.io/martinwolf/pen/qlFdp

答案 8 :(得分:4)

这次聚会迟到了,但我想出了,我认为,这是一个独特的解决方案。而不是试图通过css trickery或js插入你自己的省略号,我以为我会尝试使用单行限制滚动。因此,我复制每个“行”的文本,只使用负文本缩进,以确保一行开始最后一行停止。 FIDDLE

<强> CSS:

#wrapper{
    font-size: 20pt;
    line-height: 22pt;
    width: 100%;
    overflow: hidden;
    padding: 0;
    margin: 0;
}

.text-block-line{
    height: 22pt;
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    white-space: nowrap;
    width: auto;
}
.text-block-line:last-child{
    text-overflow: ellipsis;
}

/*the follwing is suboptimal but neccesary I think. I'd probably just make a sass mixin that I can feed a max number of lines to and have them avialable. Number of lines will need to be controlled by server or client template which is no worse than doing a character count clip server side now. */
.line2{
    text-indent: -100%;
}
.line3{
    text-indent: -200%;
}
.line4{
    text-indent: -300%;
}

<强> HTML:

<p id="wrapper" class="redraw">
    <span class="text-block-line line1">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line2">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line3">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
    <span class="text-block-line line4">This text is repeated for every line that you want to be displayed in your element. This example has a max of 4 lines before the ellipsis occurs. Try scaling the preview window width to see the effect.</span>
</p>

小提琴中的更多细节。浏览器回流时出现了一个问题,即我使用JS重绘,所以请查看它,但这是基本概念。任何想法/建议都非常感谢。

答案 9 :(得分:3)

感谢@balpha和@Kevin,我将两种方法结合在一起。

此方法不需要js。

你可以使用background-image而不需要任何渐变来隐藏点。

innerHTML .ellipsis-placeholder不是必需的,我使用.ellipsis-placeholder.ellipsis-more保持相同的宽度和高度。 您可以改为使用display: inline-block

&#13;
&#13;
.ellipsis {
    overflow: hidden;
    position: relative;
}
.ellipsis-more-top {/*push down .ellipsis-more*/
    content: "";
    float: left;
    width: 5px;
}
.ellipsis-text-container {
    float: right;
    width: 100%;
    margin-left: -5px;
}
.ellipsis-more-container {
    float: right;
    position: relative;
    left: 100%;
    width: 5px;
    margin-left: -5px;
    border-right: solid 5px transparent;
    white-space: nowrap;
}
.ellipsis-placeholder {/*keep text around ,keep it transparent ,keep same width and height as .ellipsis-more*/
    float: right;
    clear: right;
    color: transparent;
}
.ellipsis-placeholder-top {/*push down .ellipsis-placeholder*/
    float: right;
    width: 0;
}
.ellipsis-more {/*ellipsis things here*/
    float: right;
}
.ellipsis-height {/*the total height*/
    height: 3.6em;
}
.ellipsis-line-height {/*the line-height*/
    line-height: 1.2;
}
.ellipsis-margin-top {/*one line height*/
    margin-top: -1.2em;
}
.ellipsis-text {
    word-break: break-all;
}
&#13;
<div class="ellipsis ellipsis-height ellipsis-line-height">
    <div class="ellipsis-more-top ellipsis-height"></div>
    <div class="ellipsis-text-container">
        <div class="ellipsis-placeholder-top ellipsis-height ellipsis-margin-top"></div>
        <div class="ellipsis-placeholder">
           <span>...</span><span>more</span>
        </div>
        <span class="ellipsis-text">text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text text </span>
    </div>
    <div class="ellipsis-more-container ellipsis-margin-top">
        <div class="ellipsis-more">
            <span>...</span><span>more</span>
        </div>
    </div>
</div>
&#13;
&#13;
&#13;

jsfiddler

答案 10 :(得分:3)

这里有很多答案,但我需要的是:

  • 仅限CSS
  • 面向未来(与时间更加兼容)
  • 不会破坏单词(只在空格上打破)

需要注意的是,它没有为不支持-webkit-line-clamp规则(目前是IE,Edge,Firefox)的浏览器提供省略号,但它确实使用渐变来淡化它们发短信。

&#13;
&#13;
.clampMe {
  position: relative;
  height: 2.4em; 
  overflow: hidden;
}

.clampMe:after {
  content: "";
  text-align: right;
  position: absolute;
  bottom: 0;
  right: 0;
  width: 50%;
  height: 1.2em; /* Just use multiples of the line-height */
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 80%);
}

/* Now add in code for the browsers that support -webkit-line-clamp and overwrite the non-supportive stuff */
@supports (-webkit-line-clamp: 2) {
  .clampMe {
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
  }
  
  .clampMe:after {
    display: none;
  }
}
&#13;
<p class="clampMe">There's a lot more text in here than what you'll ever see. Pellentesque habitant testalotish morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
&#13;
&#13;
&#13;

你可以在this CodePen中看到它的实际效果,你也可以看到Javascript version here(没有jQuery)。

答案 11 :(得分:2)

javascript解决方案会更好

  • 获取文字行数
  • 如果窗口调整大小或更改,则
  • 切换is-ellipsis

getRowRects

Element.getClientRects()的作用类似于this

enter image description here

同一行中的每个rects都具有相同的top值,因此找出具有不同top值的rects,例如this

enter image description here

function getRowRects(element) {
    var rects = [],
        clientRects = element.getClientRects(),
        len = clientRects.length,
        clientRect, top, rectsLen, rect, i;

    for(i=0; i<len; i++) {
        has = false;
        rectsLen = rects.length;
        clientRect = clientRects[i];
        top = clientRect.top;
        while(rectsLen--) {
            rect = rects[rectsLen];
            if (rect.top == top) {
                has = true;
                break;
            }
        }
        if(has) {
            rect.right = rect.right > clientRect.right ? rect.right : clientRect.right;
            rect.width = rect.right - rect.left;
        }
        else {
            rects.push({
                top: clientRect.top,
                right: clientRect.right,
                bottom: clientRect.bottom,
                left: clientRect.left,
                width: clientRect.width,
                height: clientRect.height
            });
        }
    }
    return rects;
}

float ...more

喜欢this

enter image description here

检测窗口调整大小或元素已更改

喜欢this

enter image description here

enter image description here

enter image description here

答案 12 :(得分:0)

display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical; 

see more click here

答案 13 :(得分:0)

基于-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'>...more</div>
        </div>
    </div>
</div>

答案 14 :(得分:-1)

我发现了一个javascript技巧,但你必须使用字符串的长度。假设您想要3行宽250px,您可以计算每行的长度,即

//get the total character length.
//Haha this might vary if you have a text with lots of "i" vs "w"
var totalLength = (width / yourFontSize) * yourNumberOfLines

//then ellipsify
function shorten(text, totalLength) {
    var ret = text;
    if (ret.length > totalLength) {
        ret = ret.substr(0, totalLength-3) + "...";
    }
    return ret;
}