web-dev-qa-db-fra.com

débordement de texte: des points de suspension dans Firefox 4? (et FF5)

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

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

Les développeurs de Firefox ont été se disputant dessus depuis 2005 mais malgré la demande évidente pour cela, ils ne semblent pas vraiment se résoudre à l'implémenter (même un expérimental -moz- la mise en œuvre serait suffisante).

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

Les mauvaises nouvelles? Firefox 4 est en supprimant le -moz-binding feature , ce qui signifie que ce hack ne fonctionnera plus.

Donc, dès que Firefox 4 sera publié (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: existe-t-il une autre solution? (J'essaie d'éviter de retomber dans une solution Javascript si possible)

[ÉDITER]
Beaucoup de votes positifs, donc je ne suis évidemment pas le seul à vouloir le savoir, mais j'ai jusqu'à présent une réponse qui dit en gros "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 repli 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.

[ÉDITER]
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 m'a dit qu'il pourrait être ajouté à Firefox 6, qui avec le nouveau calendrier de sortie devrait être disponible dans quelques mois seulement. Si tel est le cas, je suppose que je peux attendre, mais c'est dommage qu'ils n'aient pas pu le régler plus tôt.

[MODIFICATION FINALE]
Je vois que la fonction Ellipsis a finalement été ajoutée au "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

104
Spudley

Spudley, vous pourriez 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 cela nativement (sans JavaScript) mais, c'est ce que nous avons à ce stade.

EDIT Vous pouvez également le rendre plus soigné en attachant une classe css à tous ces champs de largeur fixe disons fixWidth et puis faites quelque chose comme ceci:

$(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
27
peakit

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ésol et sera disponible dans FF 7; actuellement sur le point de sortir le 27/09/2011.

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

[~ # ~] ancien [~ # ~]

J'ai une autre réponse: attendez.

L'équipe de développement FF est en quête de résoudre ce problème.

Ils ont un correctif provisoire pour Firefox 6.

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

Là-bas, personne imaginaire, hyper-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 du mois d'août 2011 ... j'espère.

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

Ou vous pouvez cliquez ici ; celui qui est le plus facile.

21
ray

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

Étant donné que la solution acceptée ne prend pas en compte les polices de largeur variable et que la solution de wwwhack a une boucle While, je jetterai mon $ .02.

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

enter image description here

La variable x dans ce cas est ce que nous devons résoudre. Lorsqu'il est retourné sous forme de nombre entier, il donnera la nouvelle longueur que le texte débordant devrait être. J'ai multiplié la longueur maximale par 80% pour donner aux ellipses suffisamment d'espace 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 qu'il s'agit d'un correctif JS uniquement, mais jusqu'à ce que Mozilla corrige le bogue, je ne suis tout simplement pas assez intelligent pour proposer une solution CSS.

Cet exemple me convient le mieux 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 consultent notre application (qui, bien sûr, nous ne devrions pas avons ce contrôle :)).

6
ray

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 prend pas en compte les polices de largeur variable. Voici un script plus détaillé qui explique cela. 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. Cela a été une rupture pour moi, alors j'ai arrêté de travailler/de le tester ... mais j'ai pensé le publier ici au cas où cela serait utile à quelqu'un. Assurez-vous de bien le tester car mes tests n'étaient pas exhaustifs. J'avais l'intention d'ajouter une vérification de navigateur pour exécuter uniquement le code pour 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);
    }
}

Cela s'appellerait comme:

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

Cette solution CSS pure est vraiment proche, sauf qu'elle fait apparaître des points de suspension après chaque ligne.

3
jhuebsch