Inserir reticências (…) na tag HTML se o conteúdo for muito amplo

148

Eu tenho uma página da Web com um layout elástico que altera sua largura se a janela do navegador for redimensionada.

Nesse layout, há títulos ( h2) que terão um comprimento variável (na verdade, títulos de postagens de blog sobre os quais eu não tenho controle). Atualmente - se forem mais largos que a janela - são divididos em duas linhas.

Existe uma solução elegante e testada (entre navegadores) - por exemplo, com jQuery - que reduz oHTML interno dessa tag de título e adiciona "..." se o texto for muito amplo para caber em uma linha na tela atual / largura do contêiner?

BlaM
fonte
1
Resposta atualizada de 2014: stackoverflow.com/a/22811590/759452
Adrien Seja o
Eu criei um plug-in com base nesse segmento que usa as propriedades CSS espaço em branco e quebra de linha para formatar o texto. github.com/nothrem/jQuerySmartEllipsis
Radek Pech

Respostas:

119

Eu tenho uma solução trabalhando em FF3, Safari e IE6 + com texto único e multilinha

.ellipsis {
    white-space: nowrap;
    overflow: hidden;
}

.ellipsis.multiline {
    white-space: normal;
}

<div class="ellipsis" style="width: 100px; border: 1px solid black;">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>
<div class="ellipsis multiline" style="width: 100px; height: 40px; border: 1px solid black; margin-bottom: 100px">Lorem ipsum dolor sit amet, consectetur adipisicing elit</div>

<script type="text/javascript" src="/js/jquery.ellipsis.js"></script>
<script type="text/javascript">
$(".ellipsis").ellipsis();
</script>

jquery.ellipsis.js

(function($) {
    $.fn.ellipsis = function()
    {
        return this.each(function()
        {
            var el = $(this);

            if(el.css("overflow") == "hidden")
            {
                var text = el.html();
                var multiline = el.hasClass('multiline');
                var t = $(this.cloneNode(true))
                    .hide()
                    .css('position', 'absolute')
                    .css('overflow', 'visible')
                    .width(multiline ? el.width() : 'auto')
                    .height(multiline ? 'auto' : el.height())
                    ;

                el.after(t);

                function height() { return t.height() > el.height(); };
                function width() { return t.width() > el.width(); };

                var func = multiline ? height : width;

                while (text.length > 0 && func())
                {
                    text = text.substr(0, text.length - 1);
                    t.html(text + "...");
                }

                el.html(t.html());
                t.remove();
            }
        });
    };
})(jQuery);
alex
fonte
22
Bom, eu estive procurando como lidar com o estouro com várias linhas. Uma melhoria: em vez de acrescentar três períodos, acrescente o caractere de reticências, '...'.
Simon Lieschke
4
Isso funciona muito bem. Você deve publicá-lo no site jQuery.
Edgar
1
Embora no IE, se a função de reticências for aplicada em uma div que possui apenas um link, após as reticências, o link desaparece. Alguma dica sobre isso?
Chantz
6
Se você gostaria de ver isso em ação, pode vê-lo aqui (desculpe a formatação complicada no código do plug-in) jsfiddle.net/danesparza/TF6Rb/1
Dan Esparza
22
Para melhorar o desempenho, faça uma pesquisa binária em vez de remover 1 caractere por vez no loop "while". Se 100% do texto não couber, tente 50% do texto; em seguida, 75% do texto se 50% encaixa, ou 25% se 50% não se encaixa, etc
StanleyH
182

A solução CSS a seguir para truncar texto em uma única linha funciona com todos os navegadores listados em http://www.caniuse.com desde a escrita, com exceção do Firefox 6.0. Observe que o JavaScript é totalmente desnecessário, a menos que você precise oferecer suporte à quebra de texto de várias linhas ou a versões anteriores do Firefox.

.ellipsis {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
}

Se você precisar de suporte para versões anteriores do Firefox, confira minha resposta nesta outra pergunta .

Simon Lieschke
fonte
2
Esta é uma ordem de magnitude mais rápida que a abordagem jQuery. Funciona bem no IE7 + e no Chrome.
JDB ainda se lembra de Monica
3
Isso funciona bem em navegadores antigos também. Estávamos usando-o com sucesso no Google em ~ 2004, onde éramos obrigados a oferecer suporte ou degradar normalmente em alguns navegadores realmente de canto.
ElBel
2
JS Fiddle para aqueles que querem provar-lo em um navegador - jsfiddle.net/r39Ad
Deepak Bala
@DilipRajkumar você precisará fornecer mais detalhes por exemplo, um jsFiddle exemplo demonstrando que não funciona no IE 8.
Simon Lieschke
1
@SharpCoder você não. Onde o texto é cortado é ditado pela largura do elemento que o contém, ou seja, ele trunca quando excederia a largura do elemento.
Simon Lieschke
40

Criei esse código usando várias outras postagens, com os seguintes aprimoramentos:

  1. Ele usa uma pesquisa binária para encontrar o tamanho correto do texto.
  2. Ele lida com os casos em que o (s) elemento (s) de reticências são ocultados inicialmente, configurando um evento de apresentação única que executa novamente o código de reticências quando o item é exibido pela primeira vez. Isso é útil para visualizações de detalhes principais ou de árvores em que alguns itens não são exibidos inicialmente.
  3. Opcionalmente, ele adiciona um atributo de título ao texto original para um efeito de passar o mouse.
  4. Adicionado display: blockao estilo, o trabalho se estende
  5. Ele usa o caractere de reticências em vez de 3 pontos.
  6. Ele executa automaticamente o script para qualquer coisa com a classe .ellipsis

CSS:

.ellipsis {
        white-space: nowrap;
        overflow: hidden;
        display: block;
}

.ellipsis.multiline {
        white-space: normal;
}

jquery.ellipsis.js

(function ($) {

    // this is a binary search that operates via a function
    // func should return < 0 if it should search smaller values
    // func should return > 0 if it should search larger values
    // func should return = 0 if the exact value is found
    // Note: this function handles multiple matches and will return the last match
    // this returns -1 if no match is found
    function binarySearch(length, func) {
        var low = 0;
        var high = length - 1;
        var best = -1;
        var mid;

        while (low <= high) {
            mid = ~ ~((low + high) / 2); //~~ is a fast way to convert something to an int
            var result = func(mid);
            if (result < 0) {
                high = mid - 1;
            } else if (result > 0) {
                low = mid + 1;
            } else {
                best = mid;
                low = mid + 1;
            }
        }

        return best;
    }

    // setup handlers for events for show/hide
    $.each(["show", "toggleClass", "addClass", "removeClass"], function () {

        //get the old function, e.g. $.fn.show   or $.fn.hide
        var oldFn = $.fn[this];
        $.fn[this] = function () {

            // get the items that are currently hidden
            var hidden = this.find(":hidden").add(this.filter(":hidden"));

            // run the original function
            var result = oldFn.apply(this, arguments);

            // for all of the hidden elements that are now visible
            hidden.filter(":visible").each(function () {
                // trigger the show msg
                $(this).triggerHandler("show");
            });

            return result;
        };
    });

    // create the ellipsis function
    // when addTooltip = true, add a title attribute with the original text
    $.fn.ellipsis = function (addTooltip) {

        return this.each(function () {
            var el = $(this);

            if (el.is(":visible")) {

                if (el.css("overflow") === "hidden") {
                    var content = el.html();
                    var multiline = el.hasClass('multiline');
                    var tempElement = $(this.cloneNode(true))
                        .hide()
                        .css('position', 'absolute')
                        .css('overflow', 'visible')
                        .width(multiline ? el.width() : 'auto')
                        .height(multiline ? 'auto' : el.height())
                    ;

                    el.after(tempElement);

                    var tooTallFunc = function () {
                        return tempElement.height() > el.height();
                    };

                    var tooWideFunc = function () {
                        return tempElement.width() > el.width();
                    };

                    var tooLongFunc = multiline ? tooTallFunc : tooWideFunc;

                    // if the element is too long...
                    if (tooLongFunc()) {

                        var tooltipText = null;
                        // if a tooltip was requested...
                        if (addTooltip) {
                            // trim leading/trailing whitespace
                            // and consolidate internal whitespace to a single space
                            tooltipText = $.trim(el.text()).replace(/\s\s+/g, ' ');
                        }

                        var originalContent = content;

                        var createContentFunc = function (i) {
                            content = originalContent.substr(0, i);
                            tempElement.html(content + "…");
                        };

                        var searchFunc = function (i) {
                            createContentFunc(i);
                            if (tooLongFunc()) {
                                return -1;
                            }
                            return 0;
                        };

                        var len = binarySearch(content.length - 1, searchFunc);

                        createContentFunc(len);

                        el.html(tempElement.html());

                        // add the tooltip if appropriate
                        if (tooltipText !== null) {
                            el.attr('title', tooltipText);
                        }
                    }

                    tempElement.remove();
                }
            }
            else {
                // if this isn't visible, then hook up the show event
                el.one('show', function () {
                    $(this).ellipsis(addTooltip);
                });
            }
        });
    };

    // ellipsification for items with an ellipsis
    $(document).ready(function () {
        $('.ellipsis').ellipsis(true);
    });

} (jQuery));
Adam Tegen
fonte
2
Lindo. Bravo por implementar minha sugestão de uma pesquisa binária.
precisa saber é o seguinte
2
Apenas uma observação rápida ... vale a pena adicionar .css ('max-width', 'none') à variável tempElement ... Dessa forma, você pode usar uma declaração de largura máxima em seu css, tornando o plug-in muito mais flexível (pelo menos na maioria dos casos de uso que tenho). Bom trabalho de qualquer maneira. :)
gordyr
3
Esta é uma implementação muito mais rápida que a resposta aceita acima. Se você tiver vários elementos .ellipsis e estiver fazendo algo dinâmico com eles, este terá um desempenho muito melhor.
Mjvotaw
Você pode fornecer um exemplo? Minha pergunta está aqui: stackoverflow.com/questions/26344520/…
SearchForKnowledge
Binary Search é preferível, mas não com muito pequenos conjuntos de dados e é, neste caso, dificulta a busca como indexOf () ... aparentemente o desempenho em comparação com um linear reta
user1360809
20

Minha resposta suporta apenas texto de linha única. Confira o comentário de gfullam abaixo para o garfo de várias linhas, parece bastante promissor.

Reescrevi o código da primeira resposta algumas vezes e acho que esse deve ser o mais rápido.

Ele primeiro localiza um tamanho de texto "Estimado" e depois adiciona ou remove um caractere até que a largura esteja correta.

A lógica usada é mostrada abaixo:

insira a descrição da imagem aqui

Depois que um comprimento de texto "estimado" é encontrado, os caracteres são adicionados ou removidos até que a largura desejada seja atingida.

Tenho certeza de que precisa de alguns ajustes, mas aqui está o código:

(function ($) {
    $.fn.ellipsis = function () {
        return this.each(function () {
            var el = $(this);

            if (el.css("overflow") == "hidden") {
                var text = el.html().trim();
                var t = $(this.cloneNode(true))
                                        .hide()
                                        .css('position', 'absolute')
                                        .css('overflow', 'visible')
                                        .width('auto')
                                        .height(el.height())
                                        ;
                el.after(t);

                function width() { return t.width() > el.width(); };

                if (width()) {

                    var myElipse = "....";

                    t.html(text);

                    var suggestedCharLength = (text.length * el.width() / t.width()) - myElipse.length;

                    t.html(text.substr(0, suggestedCharLength) + myElipse);

                    var x = 1;
                    if (width()) {
                        while (width()) {
                            t.html(text.substr(0, suggestedCharLength - x) + myElipse);
                            x++;
                        }
                    }
                    else {
                        while (!width()) {
                            t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                            x++;
                        }
                        x--;
                        t.html(text.substr(0, suggestedCharLength + x) + myElipse);
                    }

                    el.html(t.html());
                    t.remove();
                }
            }
        });
    };
})(jQuery);
Mikey G
fonte
3
Sua solução pode não ser a melhor, mas está muito bem explicada. E eu gosto desse tipo de lógica de aproximação. +1 :)
Flater 25/10
2
Tenho bifurcada este para adicionar suporte para textareas e várias linhas (vertical) reticências truncamento: jsfiddle.net/gfullam/j29z7381 (I como a lógica de aproximação entre)
gfullam
19

Apenas no caso de vocês terminarem aqui em 2013 - aqui está uma abordagem css pura que encontrei aqui: http://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

.truncate {
  width: 250px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Isso funciona bem.

Joseph Juhnke
fonte
1
FWIW, text-overflownão funciona com textareaelementos (a partir de 2015). Se você precisar de suporte, textareapoderá obtê-lo modificando a resposta aceita ou usando esta bifurcação .
Gfullam
18

Eu criei um plugin jQuery muito legal para lidar com todas as variedades de reticências de texto, um chamado ThreeDots @ http://tpgblog.com/threedots

É muito mais flexível do que as abordagens CSS e suporta comportamentos e interações personalizáveis ​​muito mais avançados.

Aproveitar.

Jeremy Horn
fonte
8

Um plug-in jQuery mais flexível, permitindo manter um elemento após as reticências (por exemplo, um botão "leia mais") e atualizar onWindowResize. Também funciona em torno de texto com marcação:

http://dotdotdot.frebsite.nl

Matt
fonte
Acabei de testar este plugin, mas não consegui fazê-lo funcionar. Trunk8 foi uma escolha melhor para mim.
Guilherme Garnier
8

O plugin trunk8 jQuery suporta várias linhas e pode usar qualquer html, não apenas caracteres de reticências, para o sufixo de truncamento: https://github.com/rviscomi/trunk8

Demonstração aqui: http://jrvis.com/trunk8/

Eliot Sykes
fonte
Sim, mas isso é antigo agora. parece que não é suportado?
user2513846
1
Parece que ele é apoiado ativamente - no momento da redação (março de 2016), os problemas e PRs mostram atividades recentes envolvendo o criador do projeto.
Eliot Sykes #
5

Na verdade, existe uma maneira bastante simples de fazer isso no CSS, explorando o fato de o IE estender isso com padrões não compatíveis com o FF:after

Você também pode fazer isso em JS, se desejar, inspecionando a largura de rolagem do destino e comparando-a com a largura dos pais, mas, no entanto, isso é menos robusto.

Edit: isto é aparentemente mais desenvolvido do que eu pensava. Em breve, o suporte ao CSS3 poderá existir e algumas extensões imperfeitas estarão disponíveis para você tentar.

Essa última é uma boa leitura.

annakata
fonte
Na verdade, prefiro a solução JS - porque ela apenas adiciona "..." se o texto for maior que o espaço disponível.
1160 BlaM
3

Eu tinha feito algo semelhante para um cliente recentemente. Aqui está uma versão do que eu fiz por eles (exemplo testado em todas as versões mais recentes do navegador no Win Vista). Não é perfeito em todos os aspectos, mas pode ser ajustado com bastante facilidade.

Demonstração: http://enobrev.info/ellipsis/

Código:

<html>
    <head>
        <script src="http://www.google.com/jsapi"></script>
        <script>            
            google.load("jquery", "1.2.6");
            google.setOnLoadCallback(function() {
                $('.longtext').each(function() {
                    if ($(this).attr('scrollWidth') > $(this).width()) {
                        $more = $('<b class="more">&hellip;</b>');

                        // add it to the dom first, so it will have dimensions
                        $(this).append($more);

                        // now set the position
                        $more.css({
                            top: '-' + $(this).height() + 'px',
                            left: ($(this).attr('offsetWidth') - $more.attr('offsetWidth')) + 'px'
                        });
                    }
                });
            });
        </script>

        <style>
            .longtext {
                height: 20px;
                width: 300px;
                overflow: hidden;
                white-space: nowrap;
                border: 1px solid #f00;
            }

            .more {
                z-index: 10;
                position: relative;
                display: block;
                background-color: #fff;
                width: 18px;
                padding: 0 2px;
            }
        </style>
    </head>
    <body>
        <p class="longtext">This is some really long text.  This is some really long text.  This is some really long text.  This is some really long text.</p>
    </body>
</html>
enobrev
fonte
3

Bem, uma solução simples, que não adiciona o "...", mas evita que o <h2> se divida em duas linhas, seria adicionar este pedaço de css:

h2 {
    height:some_height_in_px; /* this is the height of the line */
    overflow:hidden; /* so that the second (or third, fourth, etc.)
                        line is not visible */
}

Pensei mais um pouco, e eu vim com essa solução, você precisa envolver o conteúdo textual da sua tag h2 com outra tag (por exemplo, um espaço) (ou alternativamente, envolver os h2s com algo que tenha a altura especificada) e depois você pode usar esse tipo de javascript para filtrar as palavras desnecessárias:

var elems = document.getElementById('conainter_of_h2s').
                     getElementsByTagName('h2');

    for ( var i = 0, l = elems.length; i < l; i++) {
        var span = elems.item(i).getElementsByTagName('span')[0];
        if ( span.offsetHeight > elems.item(i).offsetHeight ) {
            var text_arr = span.innerHTML.split(' ');
            for ( var j = text_arr.length - 1; j>0 ; j--) {
                delete text_arr[j];
                span.innerHTML = text_arr.join(' ') + '...';
                if ( span.offsetHeight <= 
                                        elems.item(i).offsetHeight ){
                    break;
                }
            }
        }
    }
Ramuns Usovs
fonte
Na verdade, pensei em usar isso como base para uma possível solução, mas não tenho idéia se - com base nisso - seria possível descobrir se o texto inteiro agora está sendo exibido ou se preciso abreviá-lo e adicionar " ... " Apenas cortá-lo seria estranho.
11409 BlaM
3

Aqui está outra solução JavaScript. Funciona muito bem e muito rápido.

https://github.com/dobiatowski/jQuery.FastEllipsis

Testado no Chrome, FF, IE no Windows e Mac.

Adam Lukaszczyk
fonte
Embora isso seja menos automático, achei uma solução mais precisa do que a resposta de Adam Tegen . Este script requer que o número máximo de linhas de texto seja especificado em vez de adivinhar.
rosquinha
3

Existe uma solução para texto de várias linhas com css puro. É chamado line-clamp, mas só funciona em navegadores de kit da web. Existe, no entanto, uma maneira de imitar isso em todos os navegadores modernos (tudo mais recente que o IE8.) Além disso, ele só funciona em fundos sólidos porque você precisa de uma imagem de fundo para ocultar as últimas palavras da última linha. Aqui está como vai:

Dado este html:

<p class="example" id="example-1">
    Lorem ipsum dolor sit amet, consectetur adipisicing 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 pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

Aqui está o CSS:

p {
    position:relative;
    line-height:1.4em;
    height:4.2em;      /* 3 times the line-height to show 3 lines */
}
p::after {
    content:"...";
    font-weight:bold;
    position:absolute;
    bottom:0;
    right:0;
    padding:0 20px 1px 45px;
    background:url(ellipsis_bg.png) repeat-y;
}

ellipsis_bg.png sendo uma imagem da mesma cor do plano de fundo, que teria cerca de 100 px de largura e teria a mesma altura que a altura da linha.

Não é muito bonito, pois seu texto pode ser cortado no meio de uma carta, mas pode ser útil em alguns casos.

Referência: http://www.css-101.org/articles/line-clamp/line-clamp_for_non_webkit-based_browsers.php

Jules Colle
fonte
Isso é legal, mas você precisa ter certeza de que seu texto é longo o suficiente, porque esse CSS adicionará "..." mesmo que o texto seja curto o suficiente para caber no espaço disponível. BTW: A mesma resposta foi fornecida pela Apopii há um mês;)
BlaM
@ Bla Praticamente o mesmo. Mas acho que o truque do gradiente é legal e esse código no CSS, em vez do SASS, então acho que vale a pena ser uma resposta separada.
Jules Colle
3

Elipse de várias linhas CSS puro para conteúdo de texto:

.container{
    position: relative;  /* Essential */
    background-color: #bbb;  /* Essential */
    padding: 20px; /* Arbritrary */
}
.text {
    overflow: hidden;  /* Essential */
    /*text-overflow: ellipsis; Not needed */
    line-height: 16px;  /* Essential */
    max-height: 48px; /* Multiples of line-height */
}
.ellipsis {
    position: absolute;/* Relies on relative container */
    bottom: 20px; /* Matches container padding */
    right: 20px; /* Matches container padding */
    height: 16px; /* Matches line height */
    width: 30px; /* Arbritrary */
    background-color: inherit; /* Essential...or specify a color */
    padding-left: 8px; /* Arbritrary */
}
<div class="container">
    <div class="text">
        Lorem ipsum dolor sit amet, consectetur eu in adipiscing elit. Aliquam consectetur venenatis blandit. Praesent vehicula, libero non pretium vulputate, lacus arcu facilisis lectus, sed feugiat tellus nulla eu dolor. Nulla porta bibendum lectus quis euismod. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat.
    </div>
    <div class="ellipsis">...</div>
</div>

Confira o snippet para ver um exemplo ao vivo.

Jason Williams
fonte
2

Isso é semelhante ao de Alex, mas faz isso em tempo de log em vez de linear e usa um parâmetro maxHeight.

jQuery.fn.ellipsis = function(text, maxHeight) {
  var element = $(this);
  var characters = text.length;
  var step = text.length / 2;
  var newText = text;
  while (step > 0) {
    element.html(newText);
    if (element.outerHeight() <= maxHeight) {
      if (text.length == newText.length) {
        step = 0;
      } else {
        characters += step;
        newText = text.substring(0, characters);
      }
    } else {
      characters -= step;
      newText = newText.substring(0, characters);
    }
    step = parseInt(step / 2);
  }
  if (text.length > newText.length) {
    element.html(newText + "...");
    while (element.outerHeight() > maxHeight && newText.length >= 1) {
      newText = newText.substring(0, newText.length - 1);
      element.html(newText + "...");
    }
  }
};
Dave Aaron Smith
fonte
2

Existe uma solução jQuery simples de Devon Govett :

https://gist.github.com/digulla/5796047

Para usar, basta chamar reticências () em um objeto jQuery. Por exemplo:

$ ("span"). elipse ();

BlaM
fonte
Eu estava prestes a postar o mesmo link. :)
Gumbo
O link nesta postagem está morto.
Justin Tanner
Adicionei
1

Reescrevi a função de Alex para usar na biblioteca MooTools. Eu mudei um pouco para salto de palavra em vez de adicionar as reticências no meio de uma palavra.

Element.implement({
ellipsis: function() {
    if(this.getStyle("overflow") == "hidden") {
        var text = this.get('html');
        var multiline = this.hasClass('multiline');
        var t = this.clone()
            .setStyle('display', 'none')
            .setStyle('position', 'absolute')
            .setStyle('overflow', 'visible')
            .setStyle('width', multiline ? this.getSize().x : 'auto')
            .setStyle('height', multiline ? 'auto' : this.getSize().y)
            .inject(this, 'after');

        function height() { return t.measure(t.getSize).y > this.getSize().y; };
        function width() { return t.measure(t.getSize().x > this.getSize().x; };

        var func = multiline ? height.bind(this) : width.bind(this);

        while (text.length > 0 && func()) {
            text = text.substr(0, text.lastIndexOf(' '));
            t.set('html', text + "...");
        }

        this.set('html', t.get('html'));
        t.dispose();
    }
}
});
Eu amo a Itália
fonte
1

Não consegui encontrar um script que funcionasse exatamente como eu queria, assim como o meu para o jQuery - algumas opções para definir mais a caminho :)

https://github.com/rmorse/AutoEllipsis

rmorse
fonte
1

Fiquei um pouco surpreso com o comportamento do CSS.

var cssEllipsis = 
{   "width": "100%","display": "inline-block", 
"vertical-align": "middle", "white-space": "nowrap", 
"overflow": "hidden", "text-overflow": "ellipsis" 
};

A menos que eu fornecesse a largura do controle ao qual eu precisava vincular as elipses, não defendia minha causa. A largura é uma propriedade obrigatória a ser adicionada ??? Por favor, coloque seus pensamentos.

Premanshu
fonte
1

O ELLIPSIS USANDO SOMENTE CSS

<html>
<head>
<style type="text/css">
#ellipsisdiv {
    width:200px;
    white-space: nowrap;  
    overflow: hidden;  
    text-overflow: ellipsis;  
}  
</style>
</head>
<body>
<div id="ellipsisdiv">
This content is more than 200px and see how the the ellipsis comes at the end when the content width exceeds the div width.
</div>
</body>
</html>

* Este código funciona nos navegadores mais atuais. Se você tiver algum problema com o Opera e o IE (o que provavelmente não acontecerá), adicione-os no estilo:

-o-text-overflow: ellipsis;  
-ms-text-overflow: ellipsis;

* Esse recurso faz parte do CSS3. Sua sintaxe completa é:

text-overflow: clip|ellipsis|string;
Robin Rizvi
fonte
1

Aqui está uma boa biblioteca de widgets / plug-ins que possui reticências embutidas: http://www.codeitbetter.co.uk/widgets/ellipsis/ Tudo o que você precisa fazer é referenciar a biblioteca e chamar o seguinte:

<script type="text/javascript"> 
   $(document).ready(function () { 
      $(".ellipsis_10").Ellipsis({ 
         numberOfCharacters: 10, 
         showLessText: "less", 
         showMoreText: "more" 
      }); 
   }); 
</script> 
<div class="ellipsis_10"> 
   Some text here that's longer than 10 characters. 
</div>
Tim
fonte
1

você pode fazer isso muito mais facilmente apenas com css, por exemplo: modo sass

.truncatedText {
   font-size: 0.875em;
   line-height: 1.2em;
   height: 2.4em; // 2 lines * line-height
   &:after {
      content: " ...";
   }
}

e você tem reticências;)

Apopii Dumitru
fonte
0

Assim como @acSlater, eu não consegui encontrar algo para o que precisava, então rolei o meu. Compartilhamento caso outras pessoas possam usar:

Método:
ellipsisIfNecessary(mystring,maxlength);
Uso:
trimmedString = ellipsisIfNecessary(mystring,50);
Link de código e demonstração: https://gist.github.com/cemerson/10368014
Christopher D. Emerson
fonte
Duas anotações: a) Este código não verifica o tamanho real de um elemento HTML. Você precisa especificar um determinado comprimento - que pode ser a funcionalidade necessária, mas é realmente trivial. b) Você acabou de adicionar "..." ao final da string. Há um sinal de reticências "..." que você pode / deve usar.
BlaM
Hey @BlaM - o código realmente verifica o comprimento em relação ao parâmetro maxlength. Está funcionando para mim pelo menos. Dito isto - este é apenas o meu humilde momento para a minha situação particular. Sinta-se à vontade para usar qualquer uma das soluções acima, se essa não funcionar corretamente para sua situação.
Christopher D. Emerson
Sim, funciona com um "comprimento", mas não com uma "largura" (tamanho do pixel).
BlaM
Ideia interessante - fique à vontade para fazer uma versão atualizada com suporte para isso. Não preciso disso agora, mas poderia ser útil no futuro.
97885 Christopher D. Emerson
0
<html>
<head>
    <!-- By Warren E. Downs, copyright 2016.  Based loosely on a single/multiline JQuery using example by Alex,
    but optimized to avoid JQuery, to use binary search, to use CSS text-overflow: ellipsis for end,
    and adding marquee option as well.
    Credit: Marquee: http://jsfiddle.net/jonathansampson/xxuxd/
            JQuery version: http://stackoverflow.com/questions/536814/insert-ellipsis-into-html-tag-if-content-too-wide
            (by Alex, http://stackoverflow.com/users/71953/alex)
            (Improved with Binary Search as suggested by StanleyH, http://stackoverflow.com/users/475848/stanleyh)
    -->
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <style>

        .single {
            overflow:hidden;
            white-space: nowrap;
            width: 10em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

        .multiline {
            overflow: hidden;
            white-space: wrap;
            width: 10em;
            height: 4.5em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

        .marquee {
            overflow: hidden;
            width: 40em;
            padding: 10px;
            margin: 0 auto;
            border: solid 1px blue;
        }

</style>
    <script>
        var _marqueeNumber=0;
        // mode=start,end,middle
        function clipText(text, len, mode) {
            if(!mode) { mode="end"; }
            else { mode=mode.toLowerCase(); }
            if(mode == "start") { return "&hellip;"+clipText(text,len,"_start"); }
            if(mode == "_start") { return text.substr(text.length - len); }
            if(mode == "middle") { 
                return clipText(text, len/2, "end") + clipText(text, len/2, "_start");
            }
            return text.substr(0, len) + "&hellip;";
        }

        function generateKeyframes(clsName, start, end) {
            var sec=5;
            var totalLen=parseFloat(start)-parseFloat(end);
            if(start.indexOf('em') > -1)      { sec=Math.round(totalLen/3); }
            else if(start.indexOf('px') > -1) { sec=Math.round(totalLen/42); }

            var style = document.createElement('style');
            style.type = 'text/css';
            style.innerHTML = 'body {}';
            document.getElementsByTagName('head')[0].appendChild(style);
            this.stylesheet = document.styleSheets[document.styleSheets.length-1];
            try {
                this.stylesheet.insertRule('.'+clsName+' {\n'+
                    '    animation: '+clsName+' '+sec+'s linear infinite;\n'+
                    '}\n', this.stylesheet.rules.length);
                this.stylesheet.insertRule('.'+clsName+':hover {\n'+
                    '    animation-play-state: paused\n'+
                    '}\n', this.stylesheet.rules.length);
                this.stylesheet.insertRule('@keyframes '+clsName+' {\n'+
                    '    0%   { text-indent: '+start+' }\n'+
                    '    100% { text-indent: '+end+' }\n'+
                    '}', this.stylesheet.rules.length);
            } catch (e) {
                console.log(e.message);
            }
        }

        function addClone(el, multiline, estyle) {
            if(!estyle) { 
                try { estyle=window.getComputedStyle(el); }
                catch(e) { return null; }
            }
            var t = el.cloneNode(true);
            var s=t.style;
            //s.display='none';
            s.visibility='hidden'; // WARNING: Infinite loop if this is not hidden (e.g. while testing)
            s.display='inline-block';
            s.background='black';
            s.color='white';
            s.position='absolute';
            s.left=0;
            s.top=0;
            s.overflow='visible';
            s.width=(multiline ? parseFloat(estyle.width) : 'auto');
            s.height=(multiline ? 'auto' : parseFloat(estyle.height));

            el.parentNode.insertBefore(t, el.nextSibling);

            return t;
        }
        function getTextWidth(el, multiline) {
            var t=addClone(el, multiline);
            if(!t) { return null; }
            var ts=window.getComputedStyle(t);
            var w=ts.width;
            if(multiline) {
                var es=window.getComputedStyle(el);
                var lines=Math.round(parseInt(ts.height)/parseInt(es.height))*2+0.5;
                w=w+'';
                var unit=''; // Extract unit
                for(var xa=0; xa<w.length; xa++) {
                    var c=w[xa];
                    if(c <= '0' || c >= '9') { unit=w.substr(xa-1); }
                }
                w=parseFloat(w);
                w*=lines; // Multiply by lines
                w+=unit; // Append unit again
            }
            t.parentNode.removeChild(t);
            return w;
        }

        // cls=class of element to ellipsize
        // mode=start,end,middle,marq (scrolling marquee instead of clip)
        function ellipsis(cls, mode) {
            mode=mode.toLowerCase();
            var elems=document.getElementsByClassName(cls);
            for(xa in elems) {
                var el=elems[xa];
                var multiline = el.className ? el.className.indexOf('multiline') > -1 : true;
                if(mode == "marq") {       
                    var w=getTextWidth(el, multiline);
                    if(!w) { continue; }
                    var mCls="dsmarquee"+(_marqueeNumber++);
                    var es=window.getComputedStyle(el);
                    generateKeyframes(mCls,es.width, '-'+w);
                    el.className+=" "+mCls; 
                    continue; 
                }
                if(mode == "end" && !multiline) { el.style.textOverflow="ellipsis"; continue; }
                var estyle=null;
                try { estyle=window.getComputedStyle(el); }
                catch(e) { continue; }
                if(estyle.overflow == "hidden") {
                    var text = el.innerHTML;
                    var t=addClone(el, multiline, estyle);

                    function height() {
                        var ts=window.getComputedStyle(t);
                        var es=window.getComputedStyle(el);
                        return parseFloat(ts.height) - parseFloat(es.height); 
                    }
                    function width() { 
                        var ts=window.getComputedStyle(t);
                        var es=window.getComputedStyle(el);
                        return parseFloat(ts.width) - parseFloat(es.width); 
                    }

                    var tooLong = multiline ? height : width;

                    var len=text.length;
                    var diff=1;
                    var olen=0;
                    var jump=len/2;
                    while (len > 0) {
                        var diff=tooLong();
                        if(diff > 0) { len-=jump; jump/=2; }
                        else if(diff < 0) { len+=jump; }
                        len=Math.round(len);
                        //alert('len='+len+';olen='+olen+';diff='+diff+';jump='+jump+';t='+JSON.stringify(t.innerHTML));
                        t.innerHTML=clipText(text, len, mode);
                        if(olen == len) { break; }
                        olen=len;
                    }
                    el.innerHTML=t.innerHTML;
                    t.parentNode.removeChild(t);
                }           
                //break;
                t.style.visibility='hidden';
            }
        }

        function testHarness() {
            ellipsis('ellipsis1', 'start'); 
            ellipsis('ellipsis2', 'end'); 
            ellipsis('ellipsis3', 'middle'); 
            ellipsis('marquee', 'marq')
        }
    </script>
    </head>
    <body onload="testHarness()">
    <div class="single ellipsis1" style="float:left">some long text that should be clipped left</div>
    <div class="single ellipsis2" style="float:right">right clip long text that should be clipped</div>
    <div class="single ellipsis3" style="float:center">some long text that should be clipped in the middle</div>

    <br />

    <p class="single marquee">Windows 8 and Windows RT are focused on your lifeyour friends and family, your apps, and your stuff. With new things like the <a href="http://windows.microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.microsoft.com/en-US/windows-8/microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
    &nbsp;

    <br />

    <div class="multiline ellipsis1" style="float:left">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped left(*)</div>

    <div class="multiline ellipsis2" style="float:right">right clip multiline long text, such as Test test test test test test, and some more long text that should be multiline clipped right.</div>

    <div class="multiline ellipsis3" style="float:center">Test test test test test test, some more long text, such as asdasdasdasdasd, that should be multiline clipped in the middle(*)</div>

    <br />

    <p class="multiline marquee">Multiline Marquee: Windows 8 and Windows RT are focused on your lifeyour friends and family, your apps, and your stuff. With new things like the <a href="http://windows.microsoft.com/en-US/windows-8/start-screen">Start screen</a>, <a href="http://windows.microsoft.com/en-US/windows-8/charms">charms</a>, and a <a href="http://windows.microsoft.com/en-US/windows-8/microsoft-account">Microsoft account</a>, you can spend less time searching and more time doing.</p>
    &nbsp;

    </body>
</html>
Warren Downs
fonte