Truncar cadenas largas con CSS: ¿factible todavía?

210

¿Hay alguna buena manera de truncar texto con HTML y CSS simples, de modo que el contenido dinámico pueda caber en un diseño de ancho y alto fijo?

He estado truncando el lado del servidor por el ancho lógico (es decir, un número de caracteres adivinado a ciegas), pero dado que una 'w' es más ancha que una 'i', esto tiende a ser subóptimo y también requiere que vuelva a adivinar ( y sigue ajustando) el número de caracteres para cada ancho fijo. Idealmente, el truncamiento ocurriría en el navegador, que conoce el ancho físico del texto renderizado.

Descubrí que IE tiene una text-overflow: ellipsispropiedad que hace exactamente lo que quiero, pero necesito que sea un navegador cruzado. Esta propiedad parece ser (¿algo?) Estándar pero no es compatible con Firefox. He encontrado varias soluciones basadas en overflow: hidden, pero no muestran puntos suspensivos (quiero que el usuario sepa que el contenido se truncó) o lo muestran todo el tiempo (incluso si el contenido no se truncó).

¿Alguien tiene una buena manera de ajustar el texto dinámico en un diseño fijo, o el truncamiento del lado del servidor por ancho lógico es tan bueno como voy a obtener por ahora?

Sam Stokes
fuente

Respuestas:

187

Actualización: text-overflow: ellipsisahora es compatible a partir de Firefox 7 (lanzado el 27 de septiembre de 2011). ¡Hurra! Mi respuesta original sigue como un registro histórico.

Justin Maxwell tiene una solución CSS de navegador cruzado. Sin embargo, viene con la desventaja de no permitir que el texto se seleccione en Firefox. Echa un vistazo a su publicación de invitado en el blog de Matt Snider para obtener todos los detalles sobre cómo funciona

Tenga en cuenta que esta técnica también impide actualizar el contenido del nodo en JavaScript utilizando la innerHTMLpropiedad en Firefox. Vea el final de esta publicación para una solución alternativa.

CSS

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

ellipsis.xml contenido del archivo

<?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>

Actualización del contenido del nodo

Para actualizar el contenido de un nodo de una manera que funcione en Firefox, use lo siguiente:

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);
    }
};

Vea la publicación de Matt Snider para obtener una explicación de cómo funciona esto .

Simon Lieschke
fuente
¡Eso es increíble, gracias por señalarlo! El texto no seleccionable y las restricciones sobre qué contenido puede ir en el div truncado son una pena, pero en general eso parece una buena solución.
Sam Stokes
La única frustración real que he encontrado es que los espacios se representan como & nbsp ;, por lo que la sangría no es realmente factible ... = /
Matchu
Me encontré con este mismo problema también. No puedo creer que Firefox no admita esto de alguna forma todavía.
mcjabberz
¿Este enfoque funciona para cualquier persona en los elementos OPTION de los controles SELECT en Webkit e IE8? Webkit no parece estar haciendo nada por mí e IE8 simplemente lo recorta sin puntos suspensivos.
Rajat
La documentación de Microsoft para text-overflowno indica la compatibilidad con optionelementos (consulte la sección Se aplica a en msdn.microsoft.com/en-us/library/ms531174(VS.85).aspx ).
Simon Lieschke
45

Marzo de 2014: truncamiento de cadenas largas con CSS: una nueva respuesta centrada en el soporte del navegador

Demostración en http://jsbin.com/leyukama/1/ (uso jsbin porque es compatible con la versión anterior de 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>

La propiedad CSS -ms-text-overflow no es necesaria: es sinónimo de la propiedad CSS text-overflow, pero las versiones de IE del 6 al 11 ya admiten la propiedad CSS text-overflow.

Probado con éxito (en Browserstack.com) en el sistema operativo Windows, para navegadores web:

  • IE6 a 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: como señaló Simon Lieschke (en otra respuesta), Firefox solo admite la propiedad CSS de desbordamiento de texto desde Firefox 7 en adelante (lanzado el 27 de septiembre de 2011).

Verifiqué este comportamiento en Firefox 3.0 y Firefox 6.0 (no se admite el desbordamiento de texto).

Se necesitarían algunas pruebas adicionales en los navegadores web de Mac OS.

Nota: es posible que desee mostrar una información sobre herramientas en el mouse cuando se aplica una elipsis, esto se puede hacer a través de javascript, consulte estas preguntas: Detección de puntos suspensivos de HTML con desbordamiento de texto y HTML: ¿cómo puedo mostrar información sobre herramientas SOLAMENTE cuando se activa la elipsis?

Recursos:

Adrien Be
fuente
@chiragpatel pruébalo tú mismo editando esta demostración en vivo jsbin.com/leyukama/1
Adrien Be
Para cualquier persona interesada, FF7 <es el 0,05% de los usuarios de Firefox hoy en día
Tom Tom
19

Si está de acuerdo con una solución de JavaScript, hay un complemento jQuery para hacer esto de manera cruzada en el navegador: consulte http://azgtech.wordpress.com/2009/07/26/text-overflow-ellipsis-for -firefox-via-jquery /

RichieHindle
fuente
Eso definitivamente es útil, ¡gracias! Parece que todos los navegadores, excepto Firefox, admiten la propiedad CSS, por lo que con este complemento, las únicas personas para las que no funcionaría son los usuarios de Firefox que han deshabilitado Javascript, y de todos modos es una degradación elegante. ¿Alguna idea de cómo son las implicaciones de rendimiento?
Sam Stokes
No, lo siento ... No he usado el código en la vida real, solo jugué con la demo. Sería fácil tomar la demostración y cortarla y pegarla cien veces en la misma página.
RichieHindle
2
JavaScript truncate () (ya sea una cadena de puntos para jQuery o Prototype o lo que sea) son solo una solución intermedia, porque no tienen en cuenta el ancho de los caracteres. Entonces, si desea truncar texto debido a un espacio limitado predefinido, esas funciones solo funcionan de manera confiable cuando se usan fuentes monoespaciadas. Cualquier solución seria tendría que operar en glifos, no en el recuento de caracteres.
Matthias
@Matthias: Quizás el código se haya actualizado desde que lo probó, pero acabo de ver la demostración y funciona perfectamente con una fuente de ancho variable.
RichieHindle
7

OK, Firefox 7 implementado text-overflow: ellipsistan bien como text-overflow: "string". El lanzamiento final está previsto para el 27/09/2011.

jj
fuente
6

Otra solución al problema podría ser el siguiente conjunto de reglas CSS:

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

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

El único inconveniente con el CSS anterior es que agregaría el "..." independientemente de si el texto desborda el contenedor o no. Aún así, si tiene un caso en el que tiene un montón de elementos y está seguro de que el contenido se desbordará, este sería un conjunto de reglas más simple.

Mis dos centavos. Felicitaciones a la técnica original de Justin Maxwell

Rajat
fuente
El problema con el pseudocódigo es que "..." aún se corta u oculta si el texto se desborda. Esperaba que si el texto se desborda, se aseguraría de que se muestre "...". Claramente, ese no es el caso :(
Antony
@Antony Simplemente coloque el pseudo elemento: position: absolute; right: 0;(y no olvide position: relativeel elemento real para que funcione). Sin embargo, se superpondrá con el texto, por lo que es posible que también desee agregar un color de fondo.
último hijo