Test de lettrine en image avec :first-letter

Le but de ce test est d'utiliser le pseudo-élément CSS :first-letter pour créer une lettrine à partir d'une image, sans toucher au code HTML des paragraphes pour rajouter des un marquage spécifique de la première lettre (un span par exemple).

Bien entendu, il s'agit plus d'un exercice de style que d'un cas pratique. Dans la pratique, si on souhaite réaliser une lettrine plus ou moins accessible on procédera ainsi:

<p>
    <img src="lettre-l.png" alt="L" />orem ipsum
    dolor sit amet, consectetuer adipiscing elit.
</p>

Mais revenons à notre exercice.

Les limites des pseudo-éléments :first-line et :first-letter

Les pseudo-éléments :first-line et :first-letter sont plutôt limités. Ils n'acceptent que peu de propriétés CSS (avec des variations possibles d'un navigateur à l'autre). Par exemple, :first-line n'accepte pas les propriétés float, width, height, padding, border, position, etc. (d'après des tests avec Firefox 2, Opera 9 et Safari 3). Le pseudo-élément :first-letter est heureusement un peu moins limité.

De quoi avons-nous besoin pour créer une lettrine en image sans toucher au code HTML, c'est-à-dire en se contentant de styler un pseudo-élément :first-letter?

On pourrait tenter d'utiliser une technique CSS de remplacement d'image. Par exemple avec le code suivant:

p:first-letter {
    float: left;
    width: 50px;
    height: 50px;
    margin: 0 5px 5px 0;
    text-indent: -9000px;
    background: url(lettrine.png) no-repeat left top;
}

En procédant ainsi, on dimensionne le pseudo-élément aux dimensions voulues (disons que notre lettrine fait 50 pixels de côté), on cache le texte via un text-indent négatif, et on affiche l'image de la lettrine comme image de fond. Et voilà.

Sauf que… ça ne marche pas du tout. Les propriétés text-indent, width et height sont tout simplement ignorées.

Opération bidouille

Avec le code du test ci-dessus, le flottement à gauche fonctionne correctement, de même que les marges et l'affichage de l'image de fond. Le principal problème que nous avons, c'est d'avoir une hauteur et une largeur suffisante pour afficher l'image de fond. Pour cela, nous allons utiliser la propriété padding. Voici ce que cela donne:

p:first-letter {
    float: left;
    margin: 0 5px 5px 0;
    padding-right: 50px;
    padding-bottom: 50px;
    background: url(lettrine.png) no-repeat right bottom;
}

Le padding permet de réserver l'espace nécessaire. On positionnera l'image de fond en bas à droite afin d'éviter les recouvrements par la lettre de texte. Au fait, qu'en fait-on de cette lettre qui continue à s'afficher? La seule solution que j'ai trouvée consiste à l'afficher de la même couleur que le fond, en blanc sur fond blanc par exemple.

Avec quelques modifications esthétiques, on obtient:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.

Nulla tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus, felis magna fermentum augue, et ultricies lacus lorem varius purus. Curabitur eu amet.

Le code final

Voici le code complet, modifications cosmétiques incluses:

.test p:first-letter {
    float: left;
    margin: 0 10px 2px -6px;
    font-size: 10px;
    padding: 0 50px 50px 0;
    color: white;
    background: url(lettrine.png) no-repeat right bottom;
}

Je vous propose également cet aperçu qui permet de visualiser un peu la technique utilisée:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.

Nulla tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus, felis magna fermentum augue, et ultricies lacus lorem varius purus. Curabitur eu amet.

Compatibilité

Navigateur Résultat constaté
Internet Explorer 6.0 & 7.0 Rendu incorrect.
:first-letter est bien pris en compte, mais margin et padding semblent ignorés totalement ou partiellement.
Mozilla Firefox 2.0 Rendu correct.
Un problème mineur rencontré: la propriété line-height n'est pas prise en compte lorsqu'elle est appliquée au pseudo-élément :first-letter, ce qui n'aide pas à bien positionner la lettrine en hauteur.
Opera 9.25 Rendu correct.
Aucun problème à signaler.
Konqueror 3.5 Rendu correct.
Aucun problème à signaler.
Safari Non testé.