Sådan bruges ren CSS til at oprette en smuk indlæser animation til din app

Hvis du har været på Internettet for nylig, har du højst sandsynligt set en dejlig subtil indlæsningsanimation, der udfylder sideindhold, før du indlæser yndefuldt.

Nogle af de sociale giganter som Facebook bruger endda denne tilgang til at give sideindlæsning en bedre oplevelse. Hvordan kan vi gøre det med bare nogle enkle CSS?

  • Hvad skal vi bygge?
  • Vil du bare have uddraget?
  • Del 1: Oprettelse af vores loading-animation
  • Del 2: Brug af vores loading-animation i en dynamisk app

Hvad skal vi bygge?

Vi opretter en indlæsningsanimation ved hjælp af en CSS-klasse, som du kan anvende på stort set ethvert element, du ønsker (inden for grund).

Dette giver dig stor fleksibilitet til at bruge det og gør løsningen pæn og enkel med kun CSS.

Mens uddraget er ret lille, og du bare kan kopiere og indsætte det, vil jeg gå igennem, hvad der sker, og et eksempel på at bruge det dynamisk, når du indlæser data.

Vil du bare have uddraget?

Du kan få fat i det her!

CSS Loading Animation CSS Loading Animation. GitHub Gist: del straks kode, noter og uddrag. 262588213843476 Gist

Skal jeg vide, hvordan jeg animerer inden denne tutorial?

Ingen! Vi gennemgår i detaljer nøjagtigt, hvad du skal gøre. Faktisk er animationen i denne vejledning relativt enkel, så lad os grave ind!

Del 1: Oprettelse af vores loading-animation

Denne første del vil fokusere på at samle indlæsningsanimationen og se den på et statisk HTML-websted. Målet er at gå igennem faktisk oprettelse af uddraget. Vi bruger kun HTML og CSS til denne del.

Trin 1: Oprette noget prøveindhold

For at komme i gang vil vi have et lille eksempel på indhold. Der er virkelig ingen begrænsninger her, du kan oprette dette med grundlæggende HTML og CSS, eller du kan tilføje dette til din Opret React-app!

Til gennemgangen skal jeg bruge HTML og CSS med et par eksempler på indhold, der giver os mulighed for at se dette i kraft.

For at komme i gang skal du oprette en ny HTML-fil. Inde i denne HTML-fil skal du udfylde det med noget indhold, der giver os muligheden for at lege med vores animation. Jeg skal bruge fillerama, som bruger linjer fra mit foretrukne tv-show Futurama!

Hvis du vil følge med mig, ser mit projekt sådan ud:

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

Følg med på forpligtelsen!

Trin 2: Starter med en fundamentbelastningsklasse

Lad os oprette en ny CSS-klasse til vores fundament. Lad os tilføje i vores CSS-fil:

.loading { background: #eceff1; } 

Med den klasse, lad os tilføje det til et par eller alle vores elementer. Jeg tilføjede det til et par afsnit, overskrifter og lister.

For example...

Det giver os en grundlæggende baggrund, men vi vil sandsynligvis skjule den tekst. Når den indlæses, har vi ikke den tekst endnu, så sandsynligvis vil vi bruge fyldstof eller en fast højde. Uanset hvad kan vi indstille farven til gennemsigtig:

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

Hvis du bemærker med listeelementer, om du anvender klassen på topelementelisteelementet (

    eller
      ) vs selve listen (
    • ), det ligner en stor blok. Hvis vi tilføjer en lille margen i bunden af ​​alle listeelementer, kan vi se et andet i, hvordan de vises:

      li { margin-bottom: .5em; } 

      Og nu begynder det at komme sammen, men det ligner bare pladsholdere. Så lad os animere dette for at se ud som om det faktisk indlæses.

      Følg med på forpligtelsen!

      Trin 3: Styling og animering af vores loading class

      Før vi faktisk animerer vores klasse, har vi brug for noget at animere, så lad os tilføje en gradient til vores .loadingklasse:

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

      Dette siger, at vi vil have en lineær gradient, der er vippet ved 100 grader, hvor vi starter med #eceff1og falmer til #f6f7f830% og tilbage til #eceff170%;

      Det er svært at se oprindeligt, når det er stille, det kan bare ligne et blænding på din computer! Hvis du gerne vil se det, inden du går videre, er du velkommen til at lege med farverne ovenfor for at se gradienten.

      Nu hvor vi har noget at animere, skal vi først oprette en keyframes-regel:

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

      Denne regel ændrer baggrundspositionen fra start ved 100% af x-aksen til 0% af x-aksen, når den anvendes.

      Med reglen kan vi tilføje vores animationsejendom til vores .loadingklasse:

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

      Derudover vil dette ikke være perfekt. Oftere end ikke ved du ikke nøjagtigt, hvor meget kopi du har på en side. Målet er at simulere og antyde, at der vil være indhold, og at det i øjeblikket indlæses.

      Hvad er din yndlingsindlæser-animation?

      Lad mig vide det på Twitter!

      Deltag i samtalen!

      Hvis du venter på, at en side skal indlæses, hjælper det med at vide, at noget fungerer i baggrunden.

      Så du skal oprette en dejlig indlæsningsanimation til din app.

      Derfor skrev @colbyfayock denne vejledning, der viser dig, hvordan du bygger animationen med ren CSS. //T.co/h8hGwqZ3sl

      - freeCodeCamp.org (@freeCodeCamp) 24. maj 2020

      Følg mig for mere Javascript, UX og andre interessante ting!

      • ? Følg mig på Twitter
      • ? ️ Abonner på min Youtube
      • ✉️ Tilmeld dig mit nyhedsbrev