28172 sujets

CSS et mise en forme, CSS3

Salut,

Je viens d'être confronté au problème de la propriété text-overflow (CSS3) qui n'est pas implémentée dans Firefox (alors qu'elle fonctionne avec IE6+, Konqueror, Opera et Safari... avouez que c'est ballot quand même).
Voici la contrainte : le site comporte des "boites" (graphiquement parlant), qui contiennent des listes d'un certain nombre d'éléments. Pour des raisons d'esthétique indépendantes de la volonté des développeurs, du webmaster et des graphistes, il faut que les boites soient toutes de même dimension. Pour parfaire ces boites, il faut qu'elles aient le même espacement en bas (c'est à dire entre le dernier élément et la bordure du bas). Comme chaque boite a autant d'éléments que ses soeurs (autant de lignes), il faut s'assurer que chaque ligne sera tronquée.
On peut évidemment le faire depuis PHP, avec une simple césure en nombre de caractères.
Inconvénients :
- on utilise PHP pour gérer la Vue (dans une logique MVC)
- suivant la police, sa taille, les caractères (les i sont moins larges que les m), on obtient un résultat plus ou moins satisfaisant.
L'autre solution est d'utiliser la propriété CSS3 text-overflow, en lui donnant la valeur ellipsis
Cette propriété permet d'ajouter (par exemple) "..." après le texte qui aura été préalablement césuré au bon endroit.
Inconvéinent : cela fonctionne avec à peu près tous les navigateurs récents, mais pas Firefox (même dans sa version 3).

Une solution qui ne me satisfaisait pas se trouve ici : http://www.jide.fr/emulate-text-overflowellipsis-in-firefox-with-css (il existe une petite erreur dans le CSS donné)
Elle n'est pas satisfaisante, parce que même si le texte n'est pas tronqué, il est quand même suivi de "...".
Pour pallier ceci, j'ai utilisé JS (plus exactement jQuery, parce que moi, JS, c'est vraiment pas mon truc à la base).

J'ai donc mon code HTML ressemble donc à quelque chose comme ça :
<div>
	<ul>
		<li class="ellipsis"><span>Texte trop long pour tenir sur une seule ligne</span></li>
		<li class="ellipsis"><span>Petit texte</span></li>
	</ul>
</div>


Niveau CSS :
.ellipsis span {
   white-space:nowrap;
   text-overflow:ellipsis; /* for internet explorer */
   -o-text-overflow:ellipsis /* for Opera */
   overflow:hidden;
   display:block;
   max-width:145px; /* à adapter en fonction des besoins */
   width:auto !important;
   float:left;
}
.ellipsis {
   clear: both;
}


Là, ça fonctionne sur IE, Konqueror, Safari (grâce à text-overflow: ellipsis;) et même sous Opera (avec -o-text-overflow:ellipsis;, ce qui est un moindre mal)
Sur Firefox, c'est tronqué, mais on n'a pas les trois petits points quand c'est coupé.

Il reste un petit bout de JS pour que sous Firefox, ça soit correct (avec jQuery) :
<script type="text/javascript" src="/jQuery-1.2.3.js"></script>
<script type="text/javascript">
$(document).ready(function() {
	$("li.ellipsis span").each(function(i) {
		if (this.offsetWidth == parseInt($('li.ellipsis span').css("maxWidth"))) {
			$(this).after('...');
		}
	})
});
</script>


Et le tour est joué.
Il ne reste plus qu'un petit inconvénient visuel, et un autre technique.
Visuellement : les lignes sont coupées "violemment", c'est à dire que ce n'est pas une vraie césure après un caractère. Une lettre peut être coupée en deux. Ca surprend un peu, mais ce n'est pas très gênant.
Techniquement : ça fait utiliser JS (pire : une lib entière dans le cas décrit ici) pour rajouter trois malheureux petits points... Si on utilise la lib pour autre chose, on rentabilise le chargement. Sinon, on remercie les développeurs de jQuery pour sa relative légèreté.

Voilà... J'espère ne pas m'être planté de forum pour partager ça, sinon, faut pas hésiter à ranger comme il faut.

Bonne journée Smiley smile
Eterneige a écrit :
L'autre solution est d'utiliser la propriété CSS3 text-overflow, en lui donnant la valeur ellipsis

Il n'y a pour l'instant pas de propriété CSS3 text-overflow. D'une part, le module CSS Text n'est pas en Candidate Recommendation ou Last Call, mais a le statut Draft (brouillon), et donc peut être complètement refondu. D'autre part, ce brouillon (datant de mars 2007) ne contient pas de propriété text-overflow, qui n'a pas encore été validée. Je cite:
a écrit :
Many sections intended for this module are not yet represented in this draft. In particular, the 'text-justify-trim', 'text-overflow', 'text-decoration', 'text-transformation', 'text-autospace', other properties have not yet been evaluated.

(Il y a une erreur de ponctuation: je ne sais pas s'il faut remplacer la dernière virgule par un point -- auquel cas text-overflow a été évaluée mais n'est pas encore décrite dans le document -- ou bien par un «and» -- auquel cas text-overflow et les autres propriétés citées n'ont pas été évaluées.)

PS: http://bugzilla.mozilla.org/show_bug.cgi?id=312156
Modifié par Florent V. (18 Jun 2008 - 12:41)
Un détail: il serait plus juste d'utiliser des points de suspension plutôt que trois points. L'entité HTML correspondante est &hellip;. À voir si ça passe via JS.
Salut,

Merci pour les précisions.
Je sais bien que le module CSS Text est encore en brouillon, mais il n'empêche que...
Par exemple, Opera utilise la propriété (propriétaire dans sa notation) -o-text-overflow qui permet de l'implémenter dans sa version actuelle, sans préjuger de possibles futures modifications. Mais c'est là un tout autre débat que le contournement proposé (que j'ai proposé ici avec JS, parce que je n'ai rien trouvé nulle part qui traite pleinement de la question, et qu'il me semblait intéressant de parler de text-overflow sur Alsacreations (qui était 100% absent d'après Google et le moteur interne)).

Merci également de me rappeler qu'il existe un caractères points de suspension, parce que j'avais complètement zappé (même si, dans la pratique, on doit pouvoir indiquer la troncature avec le ou les caractères que l'on souhaite).
Quant à savoir si ça passe en JS : oui, je viens de vérifier Smiley smile
Eterneige a écrit :
Par exemple, Opera utilise la propriété (propriétaire dans sa notation) -o-text-overflow qui permet de l'implémenter dans sa version actuelle, sans préjuger de possibles futures modifications.

Oui mais le problème c'est qu'il n y a pas de version actuelle. text-overflow n'est pas dans le brouillon du module Text CSS3. Il y est juste mentionné pour dire «on n'a rien écrit à ce sujet pour l'instant, et on n'est pas sûr de le mettre au final». Je ne sais pas quel document Opera a pris comme référence. Peut-être le brouillon de 2003 ou bien la documentation MSDN. On peut aussi lire dans la page du bug 312156 (Mozilla) qu'il y a des questions en suspens en ce qui concerne la gestion du texte en RTL, le mélange de texte LTR et RTL, et bien sûr l'internationalisation (quel caractère afficher? toutes les langues n'utilisent pas les points de suspension).

Merci en tout cas d'avoir proposé cette solution. Une autre possibilité (un peu bidouille mais ça reste correct) est d'«effacer» la fin de la ligne de texte en plaçant en absolu un élément avec une image de fond en PNG-32, avec un dégradé (de transparent à gauche à opaque à droite). Ça donne un effet intéressant. Smiley smile
Modifié par Florent V. (18 Jun 2008 - 16:40)
Florent V. a écrit :
Il y est juste mentionné pour dire «on n'a rien écrit à ce sujet pour l'instant, et on n'est pas sûr de le mettre au final».

Certes. Mais dans l'histoire des standards, certains ont été implémentés de manière propriétaire avant d'être inclus dans les specs. Ce n'est d'ailleurs pas une mauvaise chose que les idées des uns et des autres, implémentées comme ci ou comme ça, puissent donner naissance, dans un avenir plus ou moins lointain, à des standards.

Florent V. a écrit :
Je ne sais pas quel document Opera a pris comme référence.

Difficile à dire, puisque même sur le site d'Opera, ils ne disent pas la même chose d'une page à l'autre.
Ici on peut lire
a écrit :
CSS 3: Added support for attribute and UI selectors and for opacity. Added support for -o-text-overflow:ellipsis, synonymous to text-overflow:ellipsis.

Alors que ils disent que cette propriété n'est dans aucune spec CSS (ce qui, du coup, est vrai).

Florent V. a écrit :
Une autre possibilité (un peu bidouille mais ça reste correct) est d'«effacer» la fin de la ligne de texte en plaçant en absolu un élément avec une image de fond en PNG-32, avec un dégradé (de transparent à gauche à opaque à droite). Ça donne un effet intéressant.

Sauf que pour la peine, ça ne marchera pas sur IE6, qui occupe encore une part importante des navigateurs utilisés. Mais je dois bien reconnaître que l'idée est plaisante et que l'effet doit être sympa.
Eterneige a écrit :
Certes. Mais dans l'histoire des standards, certains ont été implémentés de manière propriétaire avant d'être inclus dans les specs. Ce n'est d'ailleurs pas une mauvaise chose que les idées des uns et des autres, implémentées comme ci ou comme ça, puissent donner naissance, dans un avenir plus ou moins lointain, à des standards.

Et c'est bien ce qui se passe:
1. innovation par un éditeur;
2. proposition pour inclusion dans un standard;
3. implémentation par les autres éditeurs.

Mais là, on est bloqué à (3), en partie parce que (2) est bancal. Smiley cligne

Eterneige a écrit :
Sauf que pour la peine, ça ne marchera pas sur IE6

Ça pourra marcher:
- avec un filtre DirectX (cf. la FAQ);
- sauf erreur de ma part, avec un PNG-8 avec jusqu'à 8 couleurs translucides ( (paletted PNG transparency).
Mais dans les deux cas c'est un peu délicat à gérer, effectivement. Smiley cligne