Scroll a 60 FPS usando la proprietà pointer-events none

Oggi analizziamo una tecnica per evitare che gli stati hover durante lo scrolling della pagina possano abbassare le performance e la fluidità.
Scroll a 60 FPS usando la proprietà pointer-events none

Specifiche sulla traduzione

Di seguito la traduzione dell’articolo “60fps scrolling using pointer-events: none” di Ryan Seddon.

Toggle class sul body

Paul Lewis ha scritto un interessante articolo poco tempo fa a proposito dell’evitare i colori non necessari disabilitando gli effetti hover quando l’utente fa scorrere la pagina, che è una bella strategia. Il lato negativo è il dover gestire tutti gli stati hover attraverso una classe sull’elemento parent.

.hover .element:hover {
  box-shadow: 1px 1px 1px #000;
}

Questa strategia non scala bene e crea una specificità non necessaria nel tuo CSS.

Il concetto della tecnica è che facendo scorrere la schermata la classe .hover viene rimossa dal body e tutti i tuoi selettori .hover non si abbineranno finchè l’utente non finisce di scrollare e la classe è riaggiunta al body.

Ho visto un piccolo tweet geniale di Christian Schaefer.

Schermata 2013-12-16 alle 22.47.29

La proprietà Pointer-events come alternativa

Questa è una strategia di gran lunga migliore perché farà solamente passare il mouse attraverso l’elemento che ha impostato la proprietà “pointer-events: none”. Dai un’occhiata alla screencast che ho fatto e che mostra l’incredibile differenza disabilitando l’hover.

Otteniamo tutti i benefici della strategia iniziale senza introdurre questioni di manutenzione e specificità sul nostro CSS.

.disable-hover {
  pointer-events:none;
}

Tutto ciò che dobbiamo fare è aggiungere la classe .disable-hover al body quando l’utente inizia a scrollare. Questo permette al cursore dell’utente di passare attraverso il body disattivando ogni effetto hover.

var body = document.body,
    timer;

window.addEventListener('scroll', function() {
  clearTimeout(timer);
  if(!body.classList.contains('disable-hover')) {
    body.classList.add('disable-hover')
  }
  
  timer = setTimeout(function(){
    body.classList.remove('disable-hover')
  },500);
}, false);

Il codice è abbastanza semplice. Eseguiamo il clearTimeout, è importante dopo lo scroll iniziale, per verificare se la classe non sia già sul body e poi impostiamo un timer ritardato per rimuovere la classe una volta che l’utente ha finito di scrollare la pagina per almento 500ms.

Una teecnica più robusta

Applicare pointer-events al body funzionerà bene nella maggior parte dei casi ma se pointer-events: auto è applicata a qualche elemento figlio, ci sarà un’override causando uno scroll non fluido.

.disable-hover,
.disable-hover * {
  pointer-events: none !important;
}

Una soluzione semplice è di usare il selettore universale e aggiunge un !important al valore della proprietà cosi da disabilitare qualunque elemento figlio con pointer-events attivi.

Date un’occhiata al testcase e fate qualche prova per vedere se le performance aumentano usando questa semplice tecnica.

Search
Tags
Seleziona rubrica
Seleziona rubrica
Codice Github