text-overflow: points de suspension dans Firefox 4? (et FF5)

104

La text-overflow:ellipsis;propriété CSS doit être l'une des rares choses que Microsoft a bien faites pour le Web.

Tous les autres navigateurs le prennent désormais en charge ... sauf Firefox.

Les développeurs de Firefox se disputent à ce sujet depuis 2005 mais malgré la demande évidente, ils ne semblent pas pouvoir se résoudre à l'implémenter (même une -moz-implémentation expérimentale serait suffisante).

Il y a quelques années, quelqu'un a trouvé un moyen de pirater Firefox 3 pour qu'il prenne en charge une ellipse . Le hack utilise la -moz-bindingfonctionnalité pour l'implémenter en utilisant XUL. Un certain nombre de sites utilisent maintenant ce hack.

Les mauvaises nouvelles? Firefox 4 supprime la -moz-bindingfonctionnalité , ce qui signifie que ce hack ne fonctionnera plus.

Donc, dès la sortie de Firefox 4 (plus tard ce mois-ci, j'entends), nous allons revenir au problème de ne pas pouvoir prendre en charge cette fonctionnalité.

Ma question est donc la suivante: y a-t-il un autre moyen de contourner cela? (J'essaie d'éviter de revenir à une solution Javascript si possible)

[EDIT]
Beaucoup de votes à la hausse, donc je ne suis évidemment pas le seul à vouloir savoir, mais j'ai jusqu'à présent une réponse qui dit essentiellement «utiliser javascript». J'espère toujours une solution qui n'aura pas besoin du tout de JS, ou au pire ne l'utilisera que comme solution de secours là où la fonctionnalité CSS ne fonctionne pas. Je vais donc publier une prime sur la question, au cas où quelqu'un, quelque part, aurait trouvé une réponse.

[EDIT]
Une mise à jour: Firefox est passé en mode de développement rapide, mais malgré la sortie de FF5, cette fonctionnalité n'est toujours pas prise en charge. Et maintenant que la majorité des utilisateurs sont passés de FF3.6, le hack n'est plus une solution. La bonne nouvelle, on me dit qu'il pourrait être ajouté à Firefox 6, qui, avec le nouveau calendrier de publication, devrait sortir dans quelques mois seulement. Si tel est le cas, alors je suppose que je peux attendre, mais c'est dommage qu'ils n'aient pas pu régler le problème plus tôt.

[EDIT FINAL]
Je vois que la fonction de sélection a finalement été ajoutée à "Aurora Channel" de Firefox (c'est-à-dire la version de développement). Cela signifie qu'il devrait maintenant être publié dans le cadre de Firefox 7, qui devrait sortir vers la fin de 2011. Quel soulagement.

Notes de version disponibles ici: https://developer.mozilla.org/en-US/Firefox/Releases/7

Spudley
la source
19
fwiw, d'autres choses géniales que Microsoft a faites pour le Web: AJAX, innerHTML, copier JavaScript avec suffisamment de fidélité pour qu'il s'agissait en fait du même langage sur différents navigateurs, même si les API n'étaient pas exactement les mêmes, IE6
sdleihssirhc
8
@sdleihssirhc: la transition IE5.5 -> IE6 était en effet une révolution. Vous êtes l'une des rares personnes que j'ai vues à le reconnaître publiquement;).
mingos
3
@mingos Ouais, je suis assez ouvert d'esprit et prophétique et vif et intelligent comme ça.
sdleihssirhc
6
@mingos & @sdleihssirhc: Point bien fait, et je suis d'accord - IE6 était bon en son temps. Mes problèmes avec IE6 ne sont pas liés à sa qualité à l'époque, mais à la façon dont il a causé 10 ans de stagnation sur le Web. Mais ce n'est pas le lieu pour entrer dans un débat sur le bien ou le mal d'IE. :-) Il y a plein d'autres endroits où aller pour ça. En attendant, je suis toujours frustré par les développeurs de Firefox d'être têtus sur les points de suspension.
Spudley
4
Malheureusement pour l'instant il n'y a pas de solution CSS. La solution de secours que j'utilise, modernizr, n'a pas non plus le test pour cette propriété. Vous pouvez vérifier si l'UserAgent est Firefox et charger le javascript au lieu du CSS
nunopolonia

Réponses:

27

Spudley, vous pouvez réaliser la même chose en écrivant un petit JavaScript en utilisant 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);
}

Je comprends qu'il devrait y avoir un moyen que tous les navigateurs prennent en charge nativement (sans JavaScript) mais, c'est ce que nous avons à ce stade.

EDIT En outre, vous pouvez le rendre plus soigné en attachant une cssclasse à tous ces champs de largeur fixe fixWidth , puis faites quelque chose comme ce qui suit:

$(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
peakit
la source
2
Je vous ai donné +1, mais j'hésite à accepter une solution Javascript à moins qu'il n'y ait rien d'autre possible. J'attendrai un peu plus longtemps pour voir si j'obtiens d'autres réponses. Si JS est la seule option, alors il serait bon d'en avoir une qui joue bien avec text-overflow:ellipsis;afin que je puisse toujours utiliser l'option CSS dans d'autres navigateurs.
Spudley
En l'absence de toute autre solution de travail, je devrai accepter celle-ci à contrecœur. Je vais le modifier pour qu'il ne fonctionne que dans Firefox, afin que je puisse utiliser la fonctionnalité CSS dans d'autres navigateurs. En espérant que les gars de Mozilla peuvent obtenir des ellipses implémentées pour FF5. Merci pour l'aide.
Spudley
Ne devrait pas l' length()être length? C'est une propriété.
alex
Il est difficile de choisir une longueur de caractère qui fonctionne tout le temps, surtout si vous utilisez des polices à largeur variable ou si vous avez augmenté ou diminué la taille du texte dans le navigateur.
spb du
21

EDIT 30/09/2011

FF7 est sorti, ce bug est résolu et ça marche!


EDIT 29/08/2011

Ce problème est marqué comme résolu et sera disponible dans FF 7; actuellement prévu pour sortir le 27/09/2011.

Marquez vos calendriers et préparez-vous à supprimer tous ces hacks que vous avez mis en place.

VIEUX

J'ai une autre réponse: attendez .

L'équipe de développement FF est à la recherche de résoudre ce problème.

Ils ont un ensemble de correctifs provisoires pour Firefox 6.

Firefox 6 !! Quand cela sortira-t-il?!?

Personne facile là-bas, imaginaire, trop réactive. Firefox est sur la voie du développement rapide. FF6 devrait sortir six semaines après Firefox 5. Firefox 5 devrait sortir le 21 juin 2011.

Cela met donc le correctif au début d'août 2011 ... j'espère.

Vous pouvez vous inscrire à la liste de diffusion en suivant le bug à partir du lien dans la question de l'affiche originale.

Ou vous pouvez cliquer ici ; selon la solution la plus simple.

rayon
la source
Ce hacks.mozilla.org/2011/07/aurora7 implique qu'il sera dans Firefox 7, pas 6. Mais votre point principal ( attendre ) est valable de toute façon.
MatrixFrog
"Attendre" semble être la seule réponse réaliste, mais c'est une réponse difficile à prendre lorsque votre patron l'exige. :( Heureusement, l'attente semble enfin toucher à sa fin (bien que le problème persiste tant qu'il y aura des personnes utilisant d'anciennes versions de Firefox)
Spudley
5
Non, il est prévu pour Firefox 7 : developer.mozilla.org/en/CSS/...
Christian
6

Je dois dire que je suis un peu déçu que le seul hack spécifique au navigateur dans mon application soit de prendre en charge FF4. La solution javascript ci-dessus ne tient pas compte des polices à largeur variable. Voici un script plus détaillé qui en tient compte. Le gros problème avec cette solution est que si l'élément contenant le texte est masqué lors de l'exécution du code, la largeur de la boîte n'est pas connue. C'était un facteur décisif pour moi, alors j'ai arrêté de travailler dessus / de le tester ... mais j'ai pensé que je le publierais ici au cas où il serait utile à quelqu'un. Assurez-vous de bien le tester car mes tests étaient loin d'être exhaustifs. J'avais l'intention d'ajouter une vérification du navigateur pour n'exécuter que le code de FF4 et laisser tous les autres navigateurs utiliser leur solution existante.

Cela devrait être disponible pour jouer ici: 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 (utilise 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);
    }
}

Il s'appellerait comme:

$(function(){
    ellipsify($('#test'));
});
wwwhack
la source
6

J'ai aussi rencontré ce gremlin la semaine dernière.

Étant donné que la solution acceptée ne tient pas compte des polices à largeur variable et que la solution de wwwhack a une boucle While, je vais ajouter 0,02 $.

J'ai pu réduire considérablement le temps de traitement de mon problème en utilisant la multiplication croisée. En gros, nous avons une formule qui ressemble à ceci:

entrez la description de l'image ici

La variable x dans ce cas est ce que nous devons résoudre. Lorsqu'il est retourné en tant qu'entier, il donnera la nouvelle longueur que le texte débordant devrait être. J'ai multiplié la MaxLength de 80% pour donner aux ellipses suffisamment de place pour s'afficher.

Voici un exemple html complet:

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

Je comprends que ce n'est qu'un correctif pour JS, mais tant que Mozilla ne corrige pas le bogue, je ne suis tout simplement pas assez intelligent pour proposer une solution CSS.

Cet exemple fonctionne le mieux pour moi car le JS est appelé chaque fois qu'une grille se charge dans notre application. La largeur des colonnes pour chaque grille varie et nous n'avons aucun contrôle sur le type d'ordinateur que nos utilisateurs de Firefox voient notre application (ce que, bien sûr, nous ne devrions pas avoir ce contrôle :)).

rayon
la source
Merci d'avoir répondu; Je vais essayer, et je suis sûr que cela sera utile à ceux qui cherchent à résoudre le même problème. +1
Spudley
Hmm, vous semblez avoir mal configuré votre éditeur de texte ;-P - vous semblez utiliser des onglets de moins de 8 caractères de large!
SamB
3

Cette solution CSS pure est vraiment proche, à l'exception du fait qu'elle fait apparaître des ellipses après chaque ligne.

jhuebsch
la source
Merci d'avoir répondu. Même si j'aimerais accepter une solution CSS pure, celle-ci n'est pas vraiment réalisable pour moi, car elle nécessite un balisage supplémentaire et, comme vous le dites, elle laisse les points de suspension affichés lorsque vous ne le voulez pas. Merci quand même. Je vous ai quand même donné +1.
Spudley