2013-05-18 16 views
13

Provare a ottenere font-weight per passare con grazia da "400" a "600" utilizzando CSS, ma non sembra funzionare in Chrome. È un bug noto o sto facendo qualcosa di sbagliato?Transizione CSS basata su font in Chrome

Check the Fiddle here for an example

+0

sarebbe bello mostrarci cosa hai fatto fino ad ora in modo da poter analizzare il tuo codice, per dire se hai fatto qualcosa di sbagliato o no – aspirinemaga

+0

c'è un violino – Funktr0n

+0

Non funziona neanche in IE10. 'font-weight' dovrebbe essere animabile, ma non sono sicuro che il motore di rendering dei caratteri di qualsiasi browser lo supporti. –

risposta

11

Animazione di tipo di carattere non è attualmente supportata in Chrome e IE-10 in base a numerosi test. Questo potrebbe cambiare in futuro.

45

Il problema è che font, quando rappresentato numericamente, deve essere un multiplo di 100. Per animare tra 400 e 600, il carattere potrebbe cambiare da 400 a 500 Per 600 (3 'frames', se ti piace) e non sembrerebbe molto liscio. Un'animazione non incrementa il peso di 1 ogni volta (400, 401, 402 ...) incrementerebbe il peso di 100 (400, 500, 600). Se la tua animazione è durata 2 secondi, dopo 1 secondo il peso diventerebbe improvvisamente 500, e dopo 2 secondi il peso diventerebbe improvvisamente 600; non ci sono variazioni intermedie.

Un ulteriore problema con quello che stai cercando qui è che il tipo di carattere che si sta utilizzando (o di default di JSFiddle, almeno) non ha nulla di diverso per font-weight:500, il che significa che il valore predefinito è 400:

<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/

font numerici per i caratteri che forniscono più di un semplice normale e in grassetto. Se il peso esatto fornito non è disponibile, 600-900 utilizza il peso più scuro disponibile più vicino (o, se non ce n'è, il peso più leggero disponibile più vicino) e 100-500 usa il peso più leggero disponibile più vicino (o, se non ce n'è nessuno , il peso più scuro disponibile più vicino). Ciò significa che per i caratteri che forniscono solo normale e grassetto, 100-500 sono normali e 600-900 sono in grassetto.

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

Ciò significa che non si può agevolmente animare font-weight. Anche se avessi il supporto per tutti i pesi tra 100 e 900 il cambiamento non sarebbe piacevole e ci sarebbe un cambiamento drammatico tra 500 e 600 (dove il peso più leggero incontra più scuro).

+0

In Chrome, non si sta affatto animando, ma in FF/Opera si anima. "Smoothness" è una questione di relatività e mentre ascolto ciò che stai dicendo (e leggi i documenti sorgente a cui ti sei collegato), non penso che questo sia il problema qui. Penso che non sia attualmente supportato in Chrome/IE10. – Funktr0n

+1

L'unica differenza che posso vedere tra Firefox e Chrome è che Chrome applica 'font-weight: 600' all'inizio dell'animazione e Firefox lo applica alla fine. –

+0

Anche se si modifica il carattere in una famiglia robusta conosciuta e si imposta lo stato non-hover su un peso di "100" e lo stato con passaggio del mouse su un peso di "900", si applica comunque 900 immediatamente, il che significa che quella transizione molto probabilmente non è supportato. – Funktr0n

4

Mi sembra di aver ottenuto un effetto di transizione "font-weight" accidentalmente, eseguendo una rapida transizione di colore (da grigio chiaro a blu scuro) allo stesso tempo.

6

I caratteri non sono semplici raccolte di immagini vettoriali (è per questo che i caratteri svg non sono mai decollati). I font Opentype includono tutti i tipi di magia per bloccare i caratteri sulla griglia di pixel, il che rende irrealistico aspettarsi che una famiglia di font includa sempre tutti i possibili valori di peso.

Poiché i caratteri non sono semplici raccolte di immagini vettoriali, non verranno mai ridimensionate in modo lineare - ci saranno dei rigonfiamenti per tenere conto della griglia di pixel.

Questo white paper di Google spiega perché il ridimensionamento lineare non funziona per il testo sugli schermi attuali https://docs.google.com/document/d/1wpzgGMqXgit6FBVaO76epnnFC_rQPdVKswrDQWyqO1M/edit

è per questo che nessun browser tenterà esso e saranno tutti contare su font pre-calcolate.

Questo potrebbe cambiare in un decennio in cui i display retina sono il minimo comune denominatore, ma la tecnologia dei font corrente si rivolge agli schermi correnti.

Questo whitepaper Microsoft documenta valori di un certo peso di carattere standard http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-components-postattachments/00-02-24-90-36/WPF-Font-Selection-Model.pdf

(ma solo perché sono documentati non significa che il numero di caratteri che in realtà comprendono tutti loro non è abbastanza piccolo)

Puoi probabilmente ottieni l'effetto desiderato con un font svg e qualche javascript. Il font svg sarà comunque una merda per il testo.

2

Anche se non esiste un modo diretto per far sì che il peso del font possa transitare agevolmente, ho trovato un modo per farlo indirettamente (sebbene con alcune limitazioni).

In sostanza si può semplicemente usare uno degli pseudo elementi per fare una copia speculare dell'elemento su cui il font si desidera passare in grassetto, dove il font-weight sull'elemento pseudo è in grassetto e l'opacità è 0 E al passaggio del mouse si passa semplicemente alla transizione dell'opacità dell'elemento pseudo e questo fa il trucco con una transizione molto fluida.

Potete vedere una demo qui:
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> 

In HTML si può già vedere uno dei limiti, perché stiamo usando elementi pseudo abbiamo bisogno di passare la anche il contenuto dell'elemento come attributo, quindi il contenuto è duplicato.

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; 
} 

Il secondo limite deriva dalla natura della tecnica, vale a dire perché si sono semplicemente sovrapponendo l'elemento pseudo sopra l'originale, quindi l'elemento deve avere un solido background o questo non lavoro, perché l'elemento originale rimarrà visibile sullo sfondo.

Una cosa che dovresti davvero tenere d'occhio è che lo pseudo elemento e l'elemento originale hanno le stesse dimensioni, a tal fine, nella demo, ho rimosso il padding sullo pseudoelemento, quindi potresti aver bisogno fare qualcosa di simile.

Come potete vedere, questo modo di ottenere la transizione di font-weight non è privo di problemi e lontano dall'ideale, ma questo è il meglio che posso attualmente pensare e in casi limitati come per i pulsanti e cosa no questo è abbastanza utile e se fatto correttamente sembrerà decente anche nei browser legacy.

-2

C'è un modo semplice per creare una transizione più fluida.

  1. Inizia con un font-weight più leggero (ad esempio 300) e la transizione a un più audace font-weight (ad esempio 700)
  2. modificare il carattere tipografico a un webfont o un carattere Google
  3. Add '-webkit- font-smoothing: antialiased; ' per contribuire a sostenere le transizioni bordi del carattere

Testato in Chrome e Mozilla

Cheers!

a { 
 
    font-family: sans-serif; 
 
    font-style: normal; 
 
    letter-spacing: 1px; 
 
    text-decoration: none; 
 
    text-transform: uppercase; 
 
    -webkit-font-smoothing: antialiased; 
 
    -mox-font-smoothing: antialiased; 
 
    -ms-font-smoothing: antialiased; 
 
    -o-font-smoothing: antialiased; 
 
    font-smoothing: antialiased; 
 
} 
 

 
.element a { 
 
    font-weight: 300; 
 
    font-size: 40px; 
 
    line-height: 100px; 
 
    text-align: center; 
 
} 
 

 
.element a:hover { 
 
    font-weight: 700; 
 
    -webkit-transition: 0.5s; 
 
    -moz-transition: 0.5s; 
 
    -ms-transition: 0.5s; 
 
    -o-transition: 0.5s; 
 
    transition: 0.5s; 
 
}
<div class="element"><a href="http://udundi.com">udundi</a></div>

4

Sono venuto qui per scoprire la risposta me stesso per come transizione spessore del carattere, e sono rimasto deluso quando ho letto la risposta approvato sopra dicendo che non si può fare (o, almeno non molto bene).

Con l'animazione di tipo carattere non disponibile, ho deciso di provare un altro effetto, che in realtà ti dà un effetto peso font ... che non pensavo nemmeno avrebbe funzionato per questo tipo di transizione.

Ecco come far crescere il peso:

.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; 
} 

perfettamente liscia e esattamente quello che cercavo quando sono arrivato in questa pagina. Spero che aiuti qualcuno.

+0

applausi, per altri la lettura, vale la pena giocare con il 1px e passare a .3px o .4px ecc se necessario – Adrian