text-overflow: puntos suspensivos en Firefox 4? (y FF5)


104

La text-overflow:ellipsis;propiedad CSS debe ser una de las pocas cosas que Microsoft ha hecho bien para la web.

Todos los demás navegadores ahora lo admiten ... excepto Firefox.

Los desarrolladores de Firefox han estado discutiendo sobre él desde 2005, pero a pesar de la obvia demanda, parece que no se atreven a implementarlo (incluso una -moz-implementación experimental sería suficiente).

Hace unos años, alguien ideó una forma de piratear Firefox 3 para que admita puntos suspensivos . El truco usa la -moz-bindingfunción para implementarlo usando XUL. Un gran número de sitios están utilizando este truco.

¿Las malas noticias? Firefox 4 está eliminando la -moz-bindingfunción , lo que significa que este truco ya no funcionará.

Tan pronto como se lance Firefox 4 (a finales de este mes, según he oído), volveremos al problema de que no sea compatible con esta función.

Entonces mi pregunta es: ¿Hay alguna otra forma de evitar esto? (Estoy tratando de evitar recurrir a una solución de Javascript si es posible)

[EDITAR]
Muchos votos a favor, así que obviamente no soy el único que quiere saber, pero tengo una respuesta hasta ahora que básicamente dice 'use javascript'. Todavía espero una solución que no necesite JS en absoluto o, en el peor de los casos, solo la use como alternativa cuando la función CSS no funcione. Así que voy a publicar una recompensa por la pregunta, en caso de que alguien, en algún lugar, haya encontrado una respuesta.

[EDITAR]
Una actualización: Firefox ha entrado en modo de desarrollo rápido, pero a pesar de que ahora se ha lanzado FF5, esta función aún no es compatible. Y ahora que la mayoría de los usuarios se han actualizado desde FF3.6, el truco ya no es una solución. Las buenas noticias me dijeron que podría agregarse a Firefox 6, que con el nuevo calendario de lanzamientos debería estar disponible en solo unos meses. Si ese es el caso, supongo que puedo esperar, pero es una pena que no lo hayan solucionado antes.

[EDICIÓN FINAL]
Veo que la función de puntos suspensivos finalmente se ha agregado al "Canal Aurora" de Firefox (es decir, la versión de desarrollo). Esto significa que ahora debería ser lanzado como parte de Firefox 7, que saldrá a finales de 2011. Qué alivio.

Notas de la versión disponibles aquí: https://developer.mozilla.org/en-US/Firefox/Releases/7


19
fwiw, otras cosas increíbles que Microsoft hizo por la web: AJAX, innerHTML, copiar JavaScript con suficiente fidelidad para que en realidad fuera el mismo lenguaje en diferentes navegadores, incluso si las API no eran exactamente iguales, IE6
sdleihssirhc

8
@sdleihssirhc: la transición IE5.5 -> IE6 fue de hecho una revolución. Eres una de las pocas personas que he visto que lo reconoce públicamente;).
mingos

3
@mingos Sí, soy bastante de mente abierta, profética, aguda e inteligente así.
sdleihssirhc

6
@mingos & @sdleihssirhc: Punto bien hecho, y estoy de acuerdo: IE6 fue bueno en su día. Mis problemas con IE6 no son lo bueno que era en ese momento, sino cómo causó 10 años de estancamiento en la web. Pero este no es el lugar para entrar en un debate sobre el bien o el mal de IE. :-) Hay muchos otros lugares a donde ir para eso. Mientras tanto, todavía estoy frustrado con los desarrolladores de Firefox por ser tercos con las elipsis.
Spudley

4
Desafortunadamente, por ahora no existe una solución CSS. La solución alternativa que utilizo, modernizr, tampoco tiene la prueba para esta propiedad. Puede verificar si el UserAgent es Firefox y cargar el javascript en lugar del CSS
nunopolonia

Respuestas:


27

Spudley, podría lograr lo mismo escribiendo un pequeño JavaScript usando jQuery:

var limit = 50;
var ellipsis = "...";
if( $('#limitedWidthTextBox').val().length > limit) {
   // -4 to include the ellipsis size and also since it is an index
   var trimmedText = $('#limitedWidthTextBox').val().substring(0, limit - 4); 
   trimmedText += ellipsis;
   $('#limitedWidthTextBox').val(trimmedText);
}

Entiendo que debería haber alguna forma de que todos los navegadores admitan esto de forma nativa (sin JavaScript), pero eso es lo que tenemos en este momento.

EDITAR Además, puede hacerlo más ordenado adjuntando una cssclase a todos esos campos de ancho fijo, fixWidth y luego hacer algo como lo siguiente:

$(document).ready(function() {
   $('.fixWidth').each(function() {
      var limit = 50;
      var ellipsis = "...";
      var text = $(this).val();
      if (text.length > limit) {
         // -4 to include the ellipsis size and also since it is an index
         var trimmedText = text.substring(0, limit - 4); 
         trimmedText += ellipsis;
         $(this).val(trimmedText);
      }
   });
});//EOF

2
Le he dado +1, pero dudo en aceptar una solución de Javascript a menos que no haya nada más posible. Esperaré un poco más para ver si obtengo otras respuestas. Si JS es la única opción, entonces sería bueno tener uno que se adapte bien text-overflow:ellipsis;para poder usar la opción CSS en otros navegadores.
Spudley

En ausencia de otra solución de trabajo, tendré que aceptar esta de mala gana. Lo modificaré para que solo se ejecute en Firefox, de modo que pueda usar la función CSS en otros navegadores. Esperamos que los chicos de Mozilla puedan implementar puntos suspensivos para FF5. Gracias por la ayuda.
Spudley

¿No debería length()ser length? Es una propiedad.
alex

Es difícil elegir una longitud de carácter que funcione todo el tiempo, especialmente si está utilizando fuentes de ancho variable o ha aumentado o disminuido el tamaño del texto en el navegador.
spb

21

EDITAR 30/09/2011

FF7 está fuera, este error está resuelto y ¡funciona!


EDITAR 29/08/2011

Este problema está marcado como resuelto y estará disponible en FF 7; actualmente programado para lanzarse el 27/09/2011.

Marque sus calendarios y prepárese para eliminar todos esos trucos que ha implementado.

ANTIGUO

Tengo otra respuesta: espera .

El equipo de desarrollo de FF está en la búsqueda de resolver este problema.

Tienen una solución tentativa establecida para Firefox 6.

Firefox 6 !! ¿¡¿Cuándo saldrá eso?!?

Tranquilo, imaginario, persona hiperactiva. Firefox está en la vía rápida de desarrollo. FF6 está programado para su lanzamiento seis semanas después de Firefox 5. Firefox 5 está programado para su lanzamiento el 21 de junio de 2011.

Entonces eso pone la solución en algún momento a principios de agosto de 2011 ... con suerte.

Puede inscribirse en la lista de correo siguiendo el error del enlace en la pregunta del póster original.

O puede hacer clic aquí ; lo que sea más fácil.


Este hacks.mozilla.org/2011/07/aurora7 implica que estará en Firefox 7, no en 6. Pero tu punto principal ( espera ) es válido de cualquier manera.
MatrixFrog

"Espera" parece ser la única respuesta realista, pero es una respuesta difícil de aceptar cuando tu jefe lo exige. :( Afortunadamente, la espera parece estar llegando a su fin (aunque el problema persistirá mientras haya personas que usen versiones antiguas de
Firefox

5
No, está programado para Firefox 7 : developer.mozilla.org/en/CSS/…
Christian

6

Debo decir que estoy un poco decepcionado de que el único truco específico del navegador en mi aplicación sea compatible con FF4. La solución de JavaScript anterior no tiene en cuenta las fuentes de ancho variable. Aquí hay una secuencia de comandos más detallada que explica esto. El gran problema con esta solución es que si el elemento que contiene el texto está oculto cuando se ejecuta el código, se desconoce el ancho del cuadro. Esto fue un factor decisivo para mí, así que dejé de trabajar / probarlo ... pero pensé en publicarlo aquí en caso de que sea útil para alguien. Asegúrese de probarlo bien, ya que mis pruebas no fueron exhaustivas. Tenía la intención de agregar una verificación del navegador para ejecutar solo el código para FF4 y permitir que todos los demás navegadores usen su solución existente.

Esto debería estar disponible para tocar el violín aquí: http://jsfiddle.net/kn9Qg/130/

HTML:

<div id="test">hello World</div>

CSS:

#test {
    margin-top: 20px;
    width: 68px;
    overflow: hidden;
    white-space: nowrap;
    border: 1px solid green;
}

Javascript (usa jQuery)

function ellipsify($c){
    // <div $c>                 content container (passed)
    //    <div $b>              bounds
    //       <div $o>           outer
    //          <span $i>       inner
    //       </div>
    //       <span $d></span>   dots
    //    </div>
    // </div>

    var $i = $('<span>' + $c.html() + '</span>');
    var $d = $('<span>...</span>');
    var $o = $('<div></div>');
    var $b = $('<div></div>');

    $b.css( {
        'white-space' : "nowrap",
        'display' : "block",
        'overflow': "hidden"
    }).attr('title', $c.html());

    $o.css({
        'overflow' : "hidden",
        'width' : "100%",
        'float' : "left"
    });

    $c.html('').append($b.append( $o.append($i)).append($d));

    function getWidth($w){
        return parseInt( $w.css('width').replace('px', '') );
    }

    if (getWidth($o) < getWidth($i))
    {
        while (getWidth($i) > (getWidth($b) - getWidth($d)) )
        {
             var content = $i.html();
             $i.html(content.substr(0, content.length - 1));
        }

        $o.css('width', (getWidth($b) - getWidth($d)) + 'px');
    }
    else
    {
        var content = $i.html();
        $c.empty().html(content);
    }
}

Se llamaría así:

$(function(){
    ellipsify($('#test'));
});

6

También me he encontrado con este gremlin durante la última semana.

Dado que la solución aceptada no tiene en cuenta las fuentes de ancho variable y la solución de wwwhack tiene un bucle while, agregaré mi $ .02.

Pude reducir drásticamente el tiempo de procesamiento de mi problema usando la multiplicación cruzada. Básicamente, tenemos una fórmula que se ve así:

ingrese la descripción de la imagen aquí

La variable x en este caso es lo que necesitamos resolver. Cuando se devuelve como un entero, dará la nueva longitud que debería tener el texto desbordado. Multipliqué MaxLength por 80% para dar a las elipses suficiente espacio para mostrarse.

Aquí hay un ejemplo completo de html:

<html>
    <head>
        <!-- CSS setting the width of the DIV elements for the table columns.  Assume that these widths could change.  -->
        <style type="text/css">
            .div1 { overflow: hidden; white-space: nowrap; width: 80px; }
            .div2 { overflow: hidden; white-space: nowrap; width: 150px; }
            .div3 { overflow: hidden; white-space: nowrap; width: 70px; }
        </style>
        <!-- Make a call to Google jQuery to run the javascript below.  
             NOTE:  jQuery is NOT necessary for the ellipses javascript to work; including jQuery to make this example work -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {  
                //Loop through each DIV element
                $('div').each(function(index) {
                    var myDiv = this;  //The original Div element which will have a nodeType of 1 (e.g. ELEMENT_NODE)
                    var divText = myDiv; //Variable used to obtain the text from the DIV element above  

                    //Get the nodeType of 3 (e.g. TEXT_NODE) from the DIV element.  For this example, it will always be the firstChild  
                    divText = divText.firstChild;  

                    //Create another variable to hold the display text  
                    var sDisplayText = divText.nodeValue;  

                    //Determine if the DIV element is longer than it's supposed to be.
                    if (myDiv.scrollWidth > myDiv.offsetWidth) {  
                        //Percentage Factor is just a way of determining how much text should be removed to append the ellipses  
                        //With variable width fonts, there's no magic number, but 80%, should give you enough room
                        var percentageFactor = .8;  

                        //This is where the magic happens.
                        var sliceFactor = ((myDiv.offsetWidth * percentageFactor) * sDisplayText.length) / myDiv.scrollWidth;
                        sliceFactor = parseInt(sliceFactor);  //Get the value as an Integer
                        sDisplayText = sDisplayText.slice(0, sliceFactor) + "..."; //Append the ellipses
                        divText.nodeValue = sDisplayText; //Set the nodeValue of the Display Text
                    }
                });
            });
        </script>
    </head>
    <body>
        <table border="0">
            <tr>    
                <td><div class="div1">Short Value</div></td>    
                <td><div class="div2">The quick brown fox jumps over the lazy dog; lots and lots of times</div></td>    
                <td><div class="div3">Prince</div></td> 
            </tr>
            <tr>    
                <td><div class="div1">Longer Value</div></td>   
                <td><div class="div2">For score and seven year ago</div></td>   
                <td><div class="div3">Brown, James</div></td>   
            </tr>
            <tr>    
                <td><div class="div1">Even Long Td and Div Value</div></td> 
                <td><div class="div2">Once upon a time</div></td>   
                <td><div class="div3">Schwarzenegger, Arnold</div></td> 
            </tr>
        </table>
    </body>
</html>

Entiendo que esta es una solución solo de JS, pero hasta que Mozilla corrija el error, no soy lo suficientemente inteligente como para encontrar una solución CSS.

Este ejemplo funciona mejor para mí porque se llama al JS cada vez que se carga una cuadrícula en nuestra aplicación. El ancho de columna para cada cuadrícula varía y no tenemos control sobre qué tipo de computadora nuestros usuarios de Firefox ven nuestra aplicación (que, por supuesto, no deberíamos tener ese control :)).


Gracias por la respuesta; Lo intentaré y estoy seguro de que será útil para quienes busquen resolver el mismo problema. +1
Spudley

Mmm, parece que has configurado mal tu editor de texto ;-P - ¡parece que estás usando pestañas de menos de 8 caracteres de ancho!
SamB

3

Esta solución CSS pura está muy cerca, excepto por el hecho de que hace que aparezcan puntos suspensivos después de cada línea.


gracias por la respuesta. Por mucho que me gustaría aceptar una solución CSS pura, esta no es realmente viable para mí, ya que requiere un marcado adicional y, como usted dice, deja los puntos suspensivos mostrados cuando no lo desea. aunque gracias. Sin embargo, te di +1.
Spudley
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.