Obcinanie długich łańcuchów za pomocą CSS: czy jest to jeszcze możliwe?

210

Czy istnieje dobry sposób obcinania tekstu za pomocą zwykłego HTML i CSS, aby zawartość dynamiczna mieściła się w układzie o stałej szerokości i wysokości?

Obcinam po stronie serwera o szerokość logiczną (tj. Ślepo odgadniętą liczbę znaków), ale ponieważ „w” jest szersze niż „i”, to zwykle nie jest optymalne i wymaga ode mnie ponownego odgadnięcia ( i dostrajaj) liczbę znaków dla każdej stałej szerokości. Najlepiej byłoby, gdyby obcięcie nastąpiło w przeglądarce, która zna fizyczną szerokość renderowanego tekstu.

Przekonałem się, że IE ma text-overflow: ellipsiswłaściwość, która robi dokładnie to, co chcę, ale potrzebuję tego, aby działała w różnych przeglądarkach. Ta właściwość wydaje się (nieco?) Standardowa, ale nie jest obsługiwana przez Firefox. Znalazłem różne obejścia na podstawie overflow: hidden, ale albo nie wyświetlają wielokropka (chcę, aby użytkownik wiedział, że treść została obcięta), albo wyświetlają ją przez cały czas (nawet jeśli treść nie została obcięta).

Czy ktoś ma dobry sposób na dopasowanie dynamicznego tekstu w ustalonym układzie, czy też obcinanie po stronie serwera o logiczną szerokość jest tak dobre, jak na razie?

Sam Stokes
źródło
2014: zobacz aktualną odpowiedź stackoverflow.com/questions/802175/…
Adrien Be

Odpowiedzi:

187

Aktualizacja: text-overflow: ellipsisjest teraz obsługiwana od wersji Firefox 7 (wydanej 27 września 2011 r.). Tak! Moja oryginalna odpowiedź jest historycznym zapisem.

Justin Maxwell ma rozwiązanie CSS dla różnych przeglądarek. Ma jednak tę wadę, że nie pozwala na zaznaczanie tekstu w przeglądarce Firefox. Sprawdź jego post gościnny na blogu Matta Snidera, aby uzyskać szczegółowe informacje na temat tego, jak to działa.

Uwaga: ta technika zapobiega również aktualizacji zawartości węzła w JavaScript przy użyciu innerHTMLwłaściwości w Firefox. Obejście tego problemu znajduje się na końcu tego postu.

CSS

.ellipsis {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
    -moz-binding: url('assets/xml/ellipsis.xml#ellipsis');
}

ellipsis.xml zawartość pliku

<?xml version="1.0"?>
<bindings
  xmlns="http://www.mozilla.org/xbl"
  xmlns:xbl="http://www.mozilla.org/xbl"
  xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
>
    <binding id="ellipsis">
        <content>
            <xul:window>
                <xul:description crop="end" xbl:inherits="value=xbl:text"><children/></xul:description>
            </xul:window>
        </content>
    </binding>
</bindings>

Aktualizowanie zawartości węzła

Aby zaktualizować zawartość węzła w sposób działający w przeglądarce Firefox:

var replaceEllipsis(node, content) {
    node.innerHTML = content;
    // use your favorite framework to detect the gecko browser
    if (YAHOO.env.ua.gecko) {
        var pnode = node.parentNode,
            newNode = node.cloneNode(true);

        pnode.replaceChild(newNode, node);
    }
};

Zobacz post Matta Snidera, aby uzyskać wyjaśnienie, jak to działa .

Simon Lieschke
źródło
To niesamowite, dziękuję za zwrócenie na to uwagi! Niewybieralny tekst i ograniczenia dotyczące treści, które mogą przejść w obciętym pliku div, są wstydem, ale ogólnie wygląda to na dobre rozwiązanie.
Sam Stokes,
Jedyną prawdziwą frustracją, którą dotknąłem, jest to, że spacje są renderowane jako & nbsp ;, więc wcięcia nie są tak naprawdę wykonalne ... = /
Matchu
Natknąłem się również na ten sam problem. Nie mogę uwierzyć, że Firefox jeszcze tego nie obsługuje.
mcjabberz
czy to podejście działa dla każdego na elementach OPTION formantów SELECT w Webkit i IE8. Wydaje się, że Webkit nic dla mnie nie robi, a IE8 po prostu przycina go bez elipsy.
Rajat
Dokumentacja Microsoft dla text-overflownie wskazuje wsparcia dla optionelementów (zobacz sekcję Dotyczy msdn.microsoft.com/en-us/library/ms531174(VS.85).aspx ).
Simon Lieschke,
45

Marzec 2014: Obcinanie długich ciągów za pomocą CSS: nowa odpowiedź z naciskiem na obsługę przeglądarki

Demo na http://jsbin.com/leyukama/1/ (używam jsbin, ponieważ obsługuje starą wersję IE).

<style type="text/css">
    span {
        display: inline-block;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;     /** IE6+, Firefox 7+, Opera 11+, Chrome, Safari **/
        -o-text-overflow: ellipsis;  /** Opera 9 & 10 **/
        width: 370px; /* note that this width will have to be smaller to see the effect */
    }
</style>

<span>Some very long text that should be cut off at some point coz it's a bit too long and the text overflow ellipsis feature is used</span>

Właściwość -ms-text-overflow CSS nie jest konieczna: jest to synonim właściwości CSS z przepełnieniem tekstu, ale wersje IE od 6 do 11 już obsługują właściwość CSS z przepełnieniem tekstu.

Pomyślnie przetestowano (na Browserstack.com) w systemie operacyjnym Windows dla przeglądarek internetowych:

  • IE6 do IE11
  • Opera 10.6, Opera 11.1, Opera 15.0, Opera 20.0
  • Chrome 14, Chrome 20, Chrome 25
  • Safari 4.0, Safari 5.0, Safari 5.1
  • Firefox 7.0, Firefox 15

Firefox: jak wskazał Simon Lieschke (w innej odpowiedzi), Firefox obsługuje tylko właściwość CSS z przepełnieniem tekstu od Firefox 7 (wydana 27 września 2011 r.).

Dokładnie sprawdziłem to zachowanie w Firefox 3.0 i Firefox 6.0 (przepełnienie tekstu nie jest obsługiwane).

Konieczne byłyby dalsze testy w przeglądarkach systemu Mac OS.

Uwaga: możesz pokazać etykietkę po najechaniu myszką po zastosowaniu elipsy, można to zrobić za pomocą javascript, zobacz następujące pytania: Wykrywanie elipsy z przepełnieniem tekstu HTML i HTML - jak mogę wyświetlać etykietkę TYLKO po aktywacji elipsy

Zasoby:

Adrien Be
źródło
@chiragpatel spróbuj sam, edytując to demo na żywo jsbin.com/leyukama/1
Adrien Be
Dla każdego zainteresowanego FF7 <stanowi obecnie 0,05% użytkowników Firefoksa
Tom Tom
19

Jeśli nie masz nic przeciwko rozwiązaniu JavaScript, istnieje wtyczka jQuery, która robi to w przeglądarce internetowej - patrz http://azgtech.wordpress.com/2009/07/26/text-overflow-ellipsis-for -firefox-via-jquery /

RichieHindle
źródło
To zdecydowanie przydatne, dzięki! Wygląda na to, że wszystkie przeglądarki oprócz Firefoksa obsługują właściwość CSS, więc dzięki tej wtyczce jedynymi osobami, dla których nie działałby, są użytkownicy Firefoksa, którzy wyłączyli Javascript - i to i tak pełna gracji degradacja. Masz pojęcie, jakie są konsekwencje dla wydajności?
Sam Stokes
Nie, przepraszam ... Nie korzystałem z kodu w prawdziwym życiu, po prostu grałem z wersją demonstracyjną. Łatwo byłoby wziąć demo i wyciąć i wkleić go sto razy na tej samej stronie.
RichieHindle
2
JavaScript truncate () (czy to ciąg kropkowy dla jQuery, Prototyp czy cokolwiek innego) to tylko rozwiązanie w połowie drogi, ponieważ nie biorą pod uwagę szerokości znaku. Jeśli więc chcesz obciąć tekst ze względu na wstępnie zdefiniowaną ograniczoną przestrzeń, funkcje te działają niezawodnie tylko przy użyciu czcionek o stałej szerokości. Każde poważne rozwiązanie musiałoby działać na glifach, a nie na liczbie znaków.
Matthias
@Matthias: Być może kod został zaktualizowany od czasu jego przetestowania, ale właśnie obejrzałem wersję demonstracyjną i działa idealnie z czcionką o zmiennej szerokości.
RichieHindle
7

OK, Firefox 7 zaimplementowany, text-overflow: ellipsisjak również text-overflow: "string". Ostateczne wydanie planowane jest na 27.09.2011.

jj
źródło
6

Innym rozwiązaniem tego problemu może być następujący zestaw reguł CSS:

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

.ellipsis:after{
  content:'...';
}

Jedyną wadą powyższego CSS jest to, że dodaje „...” niezależnie od tego, czy tekst przepełnia kontener, czy nie. Jeśli jednak masz przypadek, w którym masz wiele elementów i masz pewność, że zawartość się przepełni, ten byłby prostszy zestaw reguł.

Moje dwa centy. Czapki z głów od oryginalnej techniki Justina Maxwella

Rajat
źródło
Problem z pseudo kodem polega na tym, że „...” wciąż zostaje odcięty lub ukryty, jeśli tekst się przepełni. Miałem nadzieję, że jeśli tekst się przepełni, upewni się, że pojawi się „...”. Najwyraźniej tak nie jest :(
Antony
@Antony Po prostu umieść pseudo element: position: absolute; right: 0;(i nie zapomnij position: relativeo prawdziwym elemencie, aby zadziałał). Nakłada się jednak na tekst, więc możesz też chcieć dodać kolor tła.
ostatnie dziecko