web-dev-qa-db-fra.com

Transition CSS Font-Weight dans Chrome

Essayer d'obtenir que font-weight passe en douceur de 400 à 600 en utilisant CSS, mais cela ne semble pas fonctionner sous Chrome. Est-ce un bug connu ou est-ce que je fais quelque chose de mal?

Vérifiez le Fiddle ici pour un exemple

16
Funktr0n

À l'heure actuelle, Chrome et IE-10 ne prennent pas en charge l'animation d'épaisseur de police basée sur de nombreux tests. Cela pourrait changer dans le futur.

13
Funktr0n

Le problème est que les poids de police, lorsqu'ils sont représentés numériquement, doivent être un multiple de 100. Pour animer entre 400 et 600, la police changerait de 400 à 500 à 600 (3 "cadres", si vous voulez) et ne ressemblerait pas. Très doux. Une animation n'augmente pas le poids de 1 à chaque fois (400, 401, 402 ...) mais augmente de 100 (400, 500, 600). Si votre animation dure 2 secondes, après 1 seconde, le poids passe soudainement à 500 et après 2 secondes, le poids passe soudainement à 600; il n'y a pas de variations intermédiaires.

Un autre problème avec ce que vous essayez ici est que la police que vous utilisez (ou la police par défaut de JSFiddle, du moins) n’a rien de différent pour font-weight:500, ce qui signifie qu’elle vaut 400 par défaut:

<p style="font-weight:400;">a - 400, normal</p>
<p style="font-weight:500;">a - 500 (no support, defaults to 400)</p>
<p style="font-weight:600;">a - 600 (bold)</p>
<p style="font-weight:650;">a - 650 (not valid, defaults to 400)</p>

http://jsfiddle.net/r4gDh/6/

Pondération des polices numériques pour les polices offrant plus que des caractères normaux et gras. Si le poids exact indiqué n’est pas disponible, 600-900 utilisent le poids le plus sombre disponible le plus proche (ou, s’il n’en existe pas, le poids le plus léger disponible le plus proche), et entre 100 et 500 le poids le plus proche disponible (ou, s’il n’en existe pas) , le poids le plus sombre disponible le plus proche). Cela signifie que pour les polices ne contenant que des caractères normaux et gras, 100 à 500 sont des caractères normaux et 600 à 900 en gras.

https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight

Cela signifie essentiellement que vous ne pouvez pas animer en douceur font-weight. Même si vous aviez un support pour tous les poids compris entre 100 et 900, le changement ne serait pas agréable et il y aurait un changement radical entre 500 et 600 (où poids plus léger rencontre poids plus sombre).

47
James Donnelly

Les polices ne sont pas de simples collections d'images vectorielles (c'est pourquoi les polices svg n'ont jamais décollé). Les polices Opentype intègrent toutes sortes de techniques magiques pour fixer les polices à la grille de pixels, ce qui rend irréaliste d'espérer qu'une famille de polices inclue toutes les valeurs de poids possibles.

Etant donné que les polices ne sont pas de simples collections d’images vectorielles, elles ne seront jamais non plus redimensionnées linéairement - il y aura des obstacles pour prendre en compte la grille de pixels.

Ce livre blanc de Google explique pourquoi le redimensionnement linéaire ne fonctionne pas pour le texte sur les écrans actuels https://docs.google.com/document/d/1wpzgGMqXgit6FBVaO76epnnFC_rQPdVKswrDQWyqO1M/edit

c'est la raison pour laquelle aucun navigateur ne tentera cela et tous s'appuieront sur des poids de police pré-calculés.

Cela peut changer dans une décennie lorsque les affichages de rétine sont le plus petit dénominateur commun, mais que la technologie de la fonte actuelle cible les écrans actuels.

Ce livre blanc Microsoft décrit certaines valeurs d’épaisseur de police standard http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-components-postattachments/00-02-24-90-36/WPF- Font-Selection-Model.pdf

(mais le fait qu’elles soient documentées ne signifie pas que le nombre de polices qui les incluent toutes n’est pas très petit)

Vous pouvez probablement obtenir l'effet souhaité avec une police svg et du javascript. La police svg sera une merde pour utiliser du texte.

7
nim

Je suis venu ici pour trouver moi-même la réponse quant à la transition du poids de la police. J'ai été déçu lorsque j'ai lu la réponse approuvée ci-dessus, disant que cela ne pouvait pas être fait (ou du moins pas très bien).

Avec l'animation de fonte-poids non disponible, j'ai décidé d'essayer un autre effet, qui vous donne en fait un effet de fonte-poids ... que je ne pensais même pas qui fonctionnerait pour ce type de transition.

Voici comment faire grossir le poids:

.weightGrow:hover {
    text-shadow:
    -1px -1px 0 #2DD785,
    1px -1px 0 #2DD785,
    -1px 1px 0 #2DD785,
    1px 1px 0 #2DD785;
    -webkit-transition: all .5s;
    -moz-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
}

Parfaitement lisse et exactement ce que je cherchais quand je suis arrivé sur cette page. J'espère que ça aide quelqu'un.

6
user2943492

Il semble que j’ai obtenu un effet de transition "fonte grasse" accidentellement en effectuant une transition de couleur rapide (gris clair à bleu foncé) en même temps.

4
Rolf

Bien qu'il n'y ait pas de moyen direct d'obtenir une transition en douceur de la police de caractères, j'ai trouvé un moyen de le faire indirectement (bien qu'avec certaines limitations).

En substance, vous pouvez simplement utiliser l’un des pseudo-éléments pour créer une copie miroir de l’élément avec lequel vous souhaitez passer en mode gras, l’épaisseur de police sur le pseudo-élément étant en gras et l’opacité égale à 0. faites simplement la transition de l'opacité du pseudo-élément et cela se passe très bien.

Vous pouvez voir une démo ici:
http://jsfiddle.net/r4gDh/45/

HTML:

<div class="element" data-text="text will turn to bold on hover">
  text will turn to bold on hover
</div>

Dans le code HTML, vous pouvez déjà voir l’une des limitations, car nous utilisons des pseudo-éléments. Nous devons également transmettre le contenu de l’élément sous forme d’attribut. Le contenu est donc dupliqué.

CSS:

.element,
.element::before {
    background: red;
    font-weight:normal;
    font-size:40px;

    text-align:center;

    display: inline-block;

    padding: 0px 30px 0px 30px;

    position: relative;
    top: 0;
    left: 0;
}
.element::before {
    position: absolute;
    top: 0;
    left: 0;

    width: 100%;
    height: 100%;

    padding: 0;

    content: attr(data-text);
    opacity: 0;

    font-weight: bold;

    transition: all 1s linear;
}
.element:hover::before {
    opacity: 1;
}

La deuxième limite vient de la nature de la technique, à savoir parce que vous superposez simplement le pseudo-élément à l'original, alors l'élément doit avoir un arrière-plan solide ou cela ne fonctionnera pas, car l'élément d'origine restera visible en arrière-plan.

Il est important de garder à l’esprit que le pseudo-élément et l’élément d’origine ont les mêmes dimensions. Pour ce faire, dans la démo, j’ai supprimé le remplissage du pseudo-élément, vous devrez peut-être faire quelque chose de similaire. . 

Comme vous pouvez le constater, cette manière d’obtenir la transition police de poids n’est pas sans problèmes et loin d’être idéale, mais c’est la meilleure chose à laquelle je puisse penser actuellement et dans des cas limités, comme pour les boutons et autres, ce qui est très utile et si fait correctement aura l'air décent même dans les navigateurs hérités.

2
Idra

J'ai modifié le violon de @ Idra pour rendre la transition normale à audacieuse un peu plus douce. Voici le violon: http://jsfiddle.net/y7rLwx95/

Modifications ... La largeur du texte devenant plus large lorsque vous passerez en gras, j'ai ajouté une transition initiale "étirée" en augmentant l'espacement des lettres:

.element:hover {
   letter-spacing: 0.9px;
   transition: all .3s linear;
}

Puis retardé l'entrée en fondu de bold: before, élément:

.element:hover::before {
   opacity: 1;
   transition-delay: .2s
}

Aussi quelques ajustements supplémentaires ici:

.element::before {
   transition: all .3s linear;  /* replace */
   letter-spacing: 0;           /* additional */
}

Le moment de la transition est celui qui me convient le mieux. L'idée originale affichée par @Idra est importante pour moi. J’accepte le fait que les largeurs devraient être différentes entre normal et gras, car c’est l’intention de faire varier le poids des polices. Donc, le véritable défi, à mon humble avis, consiste à comprendre comment passer de l’un à l’autre des 2 regards d’une manière lisse et sans heurts. Cela semble être la meilleure solution que j'ai trouvée jusqu'à présent.

0
Michael Chen