Cómo usar CSS puro para crear una hermosa animación de carga para su aplicación

Si ha estado en Internet últimamente, lo más probable es que haya visto una bonita animación de carga sutil que llena el contenido de la página antes de cargarla con gracia.

Algunos de los gigantes sociales como Facebook incluso usan este enfoque para brindar una mejor experiencia al cargar la página. ¿Cómo podemos hacer eso con un simple CSS?

  • ¿Qué vamos a construir?
  • ¿Solo quieres el fragmento?
  • Parte 1: Creando nuestra animación de carga
  • Parte 2: uso de nuestra animación de carga en una aplicación dinámica

¿Qué vamos a construir?

Vamos a crear una animación de carga usando una clase CSS que puede aplicar a prácticamente cualquier elemento que desee (dentro de lo razonable).

Esto le brinda una gran flexibilidad para usarlo y hace que la solución sea agradable y simple con solo CSS.

Si bien el fragmento es bastante pequeño y puede copiarlo y pegarlo, lo guiaré a través de lo que está sucediendo y un ejemplo de cómo usarlo dinámicamente al cargar datos.

¿Solo quieres el fragmento?

¡Puedes agarrarlo aqui!

CSS Cargando animación CSS Cargando animación. GitHub Gist: comparte instantáneamente código, notas y fragmentos. 262588213843476 Gist

¿Necesito saber cómo animar antes de este tutorial?

¡No! Analizaremos en detalle exactamente lo que necesita hacer. De hecho, la animación de este tutorial es relativamente simple, ¡así que profundicemos!

Parte 1: Creando nuestra animación de carga

Esta primera parte se centrará en reunir la animación de carga y verla en un sitio web HTML estático. El objetivo es recorrer la creación real del fragmento. Solo usaremos HTML y CSS para esta parte.

Paso 1: creación de contenido de muestra

Para comenzar, queremos un poco de contenido de muestra. Realmente no hay restricciones aquí, puede crear esto con HTML y CSS básicos o puede agregar esto a su aplicación Create React.

Para el recorrido, usaré HTML y CSS con algunos ejemplos de contenido que nos permitirán ver esto en efecto.

Para comenzar, cree un nuevo archivo HTML. Dentro de ese archivo HTML, rellénelo con algo de contenido que nos dará la posibilidad de jugar con nuestra animación. ¡Voy a usar fillerama que usa líneas de mi programa de televisión favorito, Futurama!

Si vas a seguir conmigo, así es como se ve mi proyecto:

my-css-loading-animation-static - index.html - main.css 

¡Sigue el compromiso!

Paso 2: Comenzando con una clase de carga básica

Para nuestra base, creemos una nueva clase de CSS. Dentro de nuestro archivo CSS, agreguemos:

.loading { background: #eceff1; } 

Con esa clase, agreguemosla a algunos o todos nuestros elementos. Lo agregué a algunos párrafos, títulos y listas.

For example...

Eso nos da un trasfondo básico, pero probablemente querríamos ocultar ese texto. Cuando se está cargando, todavía no tendremos ese texto, por lo que lo más probable es que queramos usar texto de relleno o una altura fija. De cualquier manera, podemos establecer el color en transparente:

.loading { color: transparent; background: #eceff1; } 

Si observa con elementos de lista, si aplica la clase al elemento de lista de nivel superior (

    o
      ) frente al elemento de la lista en sí (
    • ), parece un gran bloque. Si agregamos un pequeño margen al final de todos los elementos de la lista, podemos ver una forma diferente en cómo se muestran:

      li { margin-bottom: .5em; } 

      Y ahora está empezando a juntarse, pero parece como marcadores de posición. Así que animemos esto para que parezca que realmente se está cargando.

      ¡Sigue el compromiso!

      Paso 3: estilizar y animar nuestra clase de carga

      Antes de animar nuestra clase, necesitamos algo para animar, así que agreguemos un degradado a nuestra .loadingclase:

      .loading { color: transparent; background: linear-gradient(100deg, #eceff1 30%, #f6f7f8 50%, #eceff1 70%); } 

      Esto quiere decir que queremos un gradiente lineal que esté inclinado a 100 grados, donde comenzamos #eceff1y nos desvanecemos al #f6f7f830% y regresamos al #eceff170%;

      Es difícil de ver inicialmente cuando está quieto, ¡puede parecer un resplandor en su computadora! Si desea verlo antes de continuar, siéntase libre de jugar con los colores de arriba para ver el degradado.

      Ahora que tenemos algo para animar, primero necesitaremos crear una regla de fotogramas clave:

      @keyframes loading { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } } 

      Esta regla, cuando se aplica, cambiará la posición del fondo desde el 100% del eje x hasta el 0% del eje x.

      Con la regla, podemos agregar nuestra propiedad de animación a nuestra .loadingclase:

      .loading { color: transparent; background: linear-gradient(100deg, #eceff1 30%, #f6f7f8 50%, #eceff1 70%); animation: loading 1.2s ease-in-out infinite; } 

      Our animation line is setting the keyframe to loading, telling it to last for 1.2 seconds, setting the timing function to ease-in-out to make it smooth, and tell it to loop forever with infinite.

      If you notice though after saving that, it's still not doing anything. The reason for this is we're setting our gradient from one end of the DOM element to the other, so there's nowhere to move!

      So let's try also setting a background-size on our .loading class.

      .loading { color: transparent; background: linear-gradient(100deg, #eceff1 30%, #f6f7f8 50%, #eceff1 70%); background-size: 400%; animation: loading 1.2s ease-in-out infinite; } 

      Now, since our background expands beyond our DOM element (you can't see that part), it has some space to animate with and we get our animation!

      Follow along with the commit!

      Part 2: Using our loading animation in a dynamic app

      Now that we have our loading animation, let's put it into action with a basic example where we fake a loading state.

      The trick with actually using this is typically we don't have the actual content available, so in most cases, we have to fake it.

      To show you how we can do this, we're going to build a simple React app with Next.js.

      Step 1: Creating an example React app with Next.js

      Navigate to the directory you want to create your new project in and run:

      yarn create next-app # or npm init next-app 

      It will prompt you with some options, particularly a name which will determine the directory the project is created in and the type of project. I'm using my-css-loading-animation-dynamic and the "Default Starter App".

      Once installed, navigate into your new directory and start up your development server:

      cd [directory] yarn dev # or npm run dev 

      Next, let's replace the content in our pages/index.js file. I'm going to derive the content from the previous example, but we'll create it similar to how we might expect it to come from an API. First, let's add our  content as an object above our return statement:

      const content = { header: `So, how 'bout them Knicks?`, intro: `What are their names? I'm Santa Claus! This opera's as lousy as it is brilliant! Your lyrics lack subtlety. You can't just have your characters announce how they feel. That makes me feel angry! Good news, everyone! I've taught the toaster to feel love!`, list: [ `Yes! In your face, Gandhi!`, `So I really am important? How I feel when I'm drunk is correct?`, `Who are those horrible orange men?` ] }

      To display that content, inside , let's replace the content with:

      { content.header }

      { content.intro }

        { content.list.map((item, i) => { return (
      • { item }
      • ) })}

      And for the styles, you can copy and paste everything from our Part 1 main.css file into the tags at the bottom of our index page. That will leave us with:

      With that, we should be back to a similar point we finished at in Part 1 except we're not actively using any of the loading animations yet.

      Follow along with the commit!

      Step 2: Faking loading data from an API

      The example we're working with is pretty simple. You'd probably see this coming pre-generated statically, but this helps us create a realistic demo that we can test our loading animation with.

      To fake our loading state, we're going to use React's useState, useEffect, and an old fashioned setTimeout to preload some "loading" content, and after the setTimeout finishes, update that content with our actual data. In the meantime, we'll know that we're in a loading state with a separate instance of useState.

      First, we need to import our dependencies. At the top of our pages/index.js file, add:

      import { useState, useEffect } from 'react'; 

      Above our content object, let's add some state:

      const [loadingState, updateLoadingState] = useState(true); const [contentState, updateContentState] = useState({}) 

      And in our content, we can update the instances to use that state:

      { contentState.header }

      { contentState.intro }

        { contentState.list.map((item, i) => { return (
      • { item }
      • ) })}

      Once you save and load that, you'll first notice we get an error because our list property doesn't exist on our contentState, so we can first fix that:

      { Array.isArray(contentState.list) && contentState.list.map((item, i) => { return ( 
    • { item }
    • ) })}

      And after that's ready, let's add our setTimeout inside of a useEffect hook to simulate our data loading. Add this under our content object:

      useEffect(() => { setTimeout(() => { updateContentState(content); updateLoadingState(false) }, 2000); }, []) 

      Once you save and open up your browser, you'll notice that for 2 seconds you don't have any content and then it loads in, basically simulating loading that data asynchronously.

      Follow along with the commit!

      Step 3: Adding our loading animation

      Now we can finally add our loading animation. So to do this, we're going to use our loading state we set up using useState and if the content is loading, add our .loading  class to our elements.

      Before we do that, instead of individually adding this class to each item in the DOM, it might make more sense to do so using CSS and adding the class to the parent, so let's do that first.

      First, update the .loading class to target our elements:

      .loading h1, .loading p, .loading li { color: transparent; background: linear-gradient(100deg, #eceff1 30%, #f6f7f8 50%, #eceff1 70%); background-size: 400%; animation: loading 1.2s ease-in-out infinite; } 

      Then we can dynamically add our class to our tag:

      Note: if you use Sass,  you can manage your loading styles by extending the .loading class in the instances you want to use it or create a placeholder and extend that!

      And if you refresh the page, you'll notice it's still just a blank page for 2 seconds!

      The issue, is when we load our content, nothing exists inside of our tags that can that would allow the line-height of the elements to give it a height.

      But we can fix that! Because our .loading class sets our text to transparent, we can simply add the word Loading for each piece of content:

      const [contentState, updateContentState] = useState({ header: 'Loading', intro: 'Loading', list: [ 'Loading', 'Loading', 'Loading' ] }) 

      Note: We can't use an empty space here because that alone won't provide us with a height when rendered in the DOM.

      And once you save and reload the page, our first 2 seconds will have a loading state that reflects our content!

      Follow along with the commit!

      Some additional thoughts

      This technique can be used pretty broadly. Being a CSS class makes it nice and easy to add where every you want.

      If you're not a fan of setting the Loading text for the loading state, another option is to set a fixed height. The only issue with that is it requires more maintenance for tweaking the CSS to match what the content loading in will look like.

      Además, esto no será perfecto. La mayoría de las veces, no sabrá exactamente cuánta copia tiene en una página. El objetivo es simular e insinuar que habrá contenido y que se está cargando actualmente.

      ¿Cuál es tu animación de carga favorita?

      ¡Házmelo saber en Twitter!

      ¡Únete a la conversación!

      Si está esperando a que se cargue una página, es útil saber que algo funciona en segundo plano.

      Así que deberías crear una bonita animación de carga para tu aplicación.

      Es por eso que @colbyfayock escribió esta guía que le muestra cómo construir esa animación con CSS puro.//t.co/h8hGwqZ3sl

      - freeCodeCamp.org (@freeCodeCamp) 24 de mayo de 2020

      ¡Sígueme para obtener más Javascript, UX y otras cosas interesantes!

      • ? Sigueme en Twitter
      • ? ️ Suscríbete a mi Youtube
      • ✉️ Suscríbete a mi boletín