4 votes

vertical-align et inline-block se comportent différemment dans chrome et firefox

J'essaie actuellement de me concentrer sur un problème, mais je ne parviens pas à le résoudre.

Dans une liste non ordonnée pour une navigation, je veux ajouter une icône avant chaque élément de la liste via la pseudo classe css before.

<ul class="list">
    <li class="list-item"><a href="#">one</a></li>
    <li class="list-item"><a href="#">two</a></li>
    <li class="list-item"><a href="#">three</a></li>
    <li class="list-item"><a href="#">four</a></li>
</ul>

Ma première idée a été de donner aux deux éléments (l'icône et la balise a) display:inline-block et d'aligner l'icône avec vertical-align:middle. Avec quelques petits ajustements (margin-bottom), cela fonctionne bien dans chrome :

.list-item {
    display: block;
    font-weight: bold;
    text-transform: uppercase;
    margin: 10px 0;
    padding-bottom: 10px;
    border-bottom: 1px solid #F3F3F3;
    height:1.5em;
    overflow:hidden;
}

.list-item:before {
    display: inline-block;
    content: '';
    vertical-align: middle;
    background-color: red;
    width: 5px;
    height: 7px;
    margin: 0 4px 0.125em 5px;
}

.list-item a {
    display: inline-block;
    overflow: hidden;
    line-height: 1.5;
    height:1.5em;
}

Mais lorsque vous chargez la page dans firefox, l'icône se trouve tout en bas. http://jsfiddle.net/pUhPB/4/

J'ai essayé ce qui me semble être toutes les combinaisons possibles d'affichage, d'alignement vertical et de valeurs de marge pour y parvenir dans les deux navigateurs, et finalement, si je donne à la balise a un alignement vertical : milieu et à l'icône un alignement vertical : ligne de base, cela semble fonctionner :

.list-item {
    display: block;
    font-weight: bold;
    text-transform: uppercase;
    margin: 10px 0;
    padding-bottom: 10px;
    border-bottom: 1px solid #F3F3F3;
    height:1.5em;
    overflow:hidden;
}

.list-item:before {
    display: inline-block;
    content: '';
    vertical-align: baseline;
    background-color: red;
    width: 5px;
    height: 7px;
    margin: 0 4px 0 5px;
}

.list-item a {
    display: inline-block;
    vertical-align:middle;
    overflow: hidden;
    line-height: 1.5;
    height:1.5em;
}

http://jsfiddle.net/L3N3f/

Mais je ne comprends pas. Pourquoi la première version ne fonctionne-t-elle pas ? Pour moi, elle semble bien plus logique que la version qui fonctionne réellement. Et lequel des deux navigateurs ne rend pas les éléments de la bonne manière ?

J'ai déjà trouvé une solution qui semble fonctionner pour moi, ce n'est donc pas une question très urgente, mais cela me gêne de ne pas comprendre le cœur de mon problème (et la solution), je serais donc vraiment reconnaissant si quelqu'un pouvait m'éclairer à ce sujet.

merci

7voto

JDuarteDJ Points 409

Selon la norme web, seuls les éléments en ligne peuvent être "alignés verticalement", bien que certains navigateurs, comme chrome, les alignent encore. Notez que c'est l'élément qui est aligné et non son contenu ! Ainsi, si vous l'appliquez à un élément <span> les <span> s'aligne sur le texte environnant et non sur ce qu'il contient.

ispo lorem <span> text </span> due carpe diem

ajoutant span {vertical-align:top; border: 1px solid black} fait <span> text </span> (l'ensemble de l'encadré) devient plus haut que le reste du texte et ne pousse pas l'image de marque. text au plafond de la boîte <span> .

Le problème principal est que Firefox est très littéral lorsqu'il s'agit de standards web, tandis que Chrome ajoute quelques fonctionnalités implicites comme celle-ci.

Pour plus de détails, cliquez ici.

EDIT : apparemment, si vous utilisez vertical-align:top UNIQUEMENT sur le <a> cela fonctionne aussi.

6voto

Boris Zbarsky Points 22158

Votre problème est que, selon les spécifications overflow:hidden modifie la position de base d'un bloc en ligne. Firefox met en œuvre ce que dit la spécification. Chrome ne le fait pas.

Ainsi, tant que votre .list-item a est aligné sur la ligne de base, le rendu sera différent dans les deux navigateurs. La seule façon de rendre les rendus identiques est de s'assurer que vous n'alignez pas à la base les blocs en ligne dont le débordement n'est pas visible, ce que fait votre deuxième collage de code (il utilise la fonction vertical-align: middle sur le bloc en ligne).

0voto

MiniRagnarok Points 799

Essayez ceci : http://jsfiddle.net/pUhPB/6/

La première chose que je fais dans ces situations est d'ouvrir le code dans les deux navigateurs. Ensuite, je commence à supprimer le code CSS jusqu'à ce que je puisse voir le problème. En supprimant les marges et l'alignement vertical, les deux navigateurs ont rendu le code différemment. Je continue donc à supprimer du code jusqu'à ce que les deux navigateurs soient identiques. Une fois qu'ils sont identiques dans les deux navigateurs, je modifie ce que je peux pour obtenir l'effet désiré.

Voici le nouveau CSS :

.list-item:before 
{
    content: '';
    background-color: red;
    width: 5px;
    height: 7px;
    margin: 5px 4px 0 5px;
    float:left;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X