Stavo ammazzando un po' di tempo sfogliando il mio feed CodePen per un po' di piacere per gli occhi e non avevo bisogno di andare oltre la prima pagina prima di notare un accurato effetto hover CSS di Adam Argyle.
Devo aver passato 10 minuti a fissare la demo con ammirazione. C'è qualcosa in questo che sembra così simile a un'app. Penso che potrebbe essere quanto sia contestualmente accurato in quanto il colore di sfondo entra da sinistra, quindi esce da destra. È esattamente il tipo di comportamento che mi aspetterei da un'interazione con il mouse dentro e fuori.
In ogni caso, ho acceso una nuova penna e mi sono messo al lavoro per ricrearla. E non è super complesso o altro, ma piuttosto un uso intelligente di transizioni e trasformazioni abbinate a offset adeguati. Abbastanza elegante! In realtà sono un po' imbarazzato per quanto tempo mi ci è voluto per capire come funziona la parte del mouse fuori.
Ecco come l'ho affrontato, nel bene e nel male.
"Scommetto che sta usando una transizione su uno sfondo."
Questo è stato il mio primo pensiero. Definisci il colore dello sfondo, imposta la dimensione e la posizione dello sfondo, quindi esegui la transizione della posizione dello sfondo. È così che ho visto fare in passato quella cosa del colore di sfondo "crescente". L'ho fatto io stesso su alcuni progetti, come questo:
a { /* Keeps the pseudo-element contained to the element */ position: relative; } a::before { background: #ff9800; content: ""; inset: 0; /* Logical equivalent to physical offsets */ position: absolute; transform: scaleX(0); /* Hide by default */ z-index: -1; /* Ensures the link is stacked on top */ }
Se potessi fare la stessa cosa, solo da sinistra a destra, tutto ciò che rimane è l'uscita del mouse, giusto? No. Il problema è che non c'è nulla che possa realmente effettuare la transizione della posizione dello sfondo da sinistra a destra a da sinistra a destra. Potrei fargli fare l'uno o l'altro, ma non entrambi.
"Forse è invece una trasformazione."
a::before { background: #ff9800; content: ""; inset: 0; position: absolute; transform: scaleX(0); transform-origin: left; transition: transform .5s ease-in-out; z-index: -1; }
Il mio tentativo successivo è stato quello di passare alle trasformazioni. La proprietà di trasformazione fornisce una serie di funzioni che possono passare insieme per movimenti leggermente più complessi. Ad esempio, lo sfondo può "crescere" o "rimpicciolirsi" modificando la scala dell'elemento(). Oppure, in questo caso, proprio lungo l'asse x con scaleX().
Ma come ho già detto, non esiste un modo per isolare lo sfondo dell'elemento per farlo. Passando da scaleX(0) a scaleX(1) si ridimensiona l'intero elemento, in modo da ridurre sostanzialmente il collegamento (il contenuto e tutto il resto) a nulla, quindi lo si estende nuovamente alla sua dimensione naturale, il che è un effetto completamente diverso. Inoltre, significa iniziare con scaleX(0) che nasconde l'intera cosa pericolosa per impostazione predefinita rendendola inutilizzabile.
Ma uno pseudo-elemento potrebbe funzionare! Non importa se viene schiacciato o nascosto perché non fa parte del contenuto reale. Devo invece mettere lo sfondo su quello e posizionarlo direttamente sotto il collegamento.
"Ora ho bisogno di ::before per cambiare al passaggio del mouse."
Sapevo che avrei potuto fare in modo che ::before scalasse da 0 a 1 concatenandolo allo stato :hover dell'elemento link.
Carino! Avevo capito qualcosa.
Cospargici sopra un po' di polvere di fata di transizione e le cose inizieranno a prendere vita.
"Hmm, la transizione si muove in entrambe le direzioni."
Ancora una volta, è qui che mi sono bloccato. Qualcosa nella mia testa semplicemente non funzionava per qualche motivo. Come al solito, sono corso all'Almanacco CSS-Tricks per vedere quale proprietà potrebbe essermi sfuggita di mente.
Ah sì. Sarebbe l'origine della trasformazione. Ciò mi consente di impostare il punto in cui inizia la trasformazione, il che non è del tutto dissimile dall'impostazione della posizione dello sfondo come ho provato in precedenza. La trasformazione potrebbe iniziare da sinistra anziché dalla posizione predefinita 50% 50%.
a:hover::before { transform: scaleX(1); transform-origin: right; }
Stavo già effettuando la transizione ::prima di scaleX(1) al passaggio del mouse sul collegamento. Se inverto l'origine della trasformazione da sinistra a destra allo stesso tempo, forse l'evidenziazione esce nel modo opposto a come è entrata quando il mouse esce?
Ops, all'indietro! Scambiamo i valori sinistro e destro. 🙃
Bellissimo. Grazie, Adam, per l'ispirazione!