An animation in CSS where an element moves off the screen to the right in absolute position and then returns from the

I am currently working on a website featuring moving clouds traveling across the screen from left to right. Although I have successfully implemented the animation for the clouds, there is one specific issue that has me stuck. My goal is to display some of the clouds on the screen upon page load, have them move off to the right, re-enter from the left, and continue this cycle.

To provide a clearer idea, here's an image illustrating my objective:

Below is the code segment:

<div class="clouds">
    <div class="firstCloud">        
        <svg id="svgCloud" data-name="clouder" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348 164"><defs><style>.cloud1Fill{fill:#d1dbd9;}</style></defs><title>Untitled-5</title><path class="cloud1Fill" d="M348,107.5a54.5,54.5,0,0,1-94.87,36.61,77.55,77.55,0,0,1-81.57-1.43A73,73,0,0,1,71,145.07,42.48,42.48,0,1,1,49.61,71.59,73,73,0,0,1,154.85,26.84,77.51,77.51,0,0,1,287.16,53.37,53,53,0,0,1,293.5,53,54.5,54.5,0,0,1,348,107.5Z"/></svg>
    </div>  
    <div class="secondCloud">
        <svg id="svgCloud2" data-name="cloud2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 291 124"><defs><style>.cloud1Fill{fill:#d3dddb;}.cloud2Fill{fill:#fff;}</style></defs><title>Untitled-4</title><path class="cloud1Fill" d="M2.29,123.5A41,41,0,0,1,58.37,74.12l.32.14.24-.25A45.72,45.72,0,0,1,91.5,60.5q1.14,0,2.25.06l.43,0,.09-.41a76,76,0,0,1,148.46,0l.09.4h.41l1.27,0a46.06,46.06,0,0,1,46,46,45.53,45.53,0,0,1-3.26,17Z"/><path class="cloud2Fill" d="M168.5,1a75.53,75.53,0,0,1,73.74,59.23l.18.81.82,0,1.26,0a45.49,45.49,0,0,1,42.4,62H2.66A40.53,40.53,0,0,1,58.17,74.57l.63.29...
    </div>
    <div class="thirdCloud">
        <svg id="svgClouds3" data-name="clouds2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 329 139"><defs><style>.cloud2Fill{fill:#d1dbd9;}</style></defs><title>Untitled-6</title><path class="cloud2Fill" d="M329,125a40.09,40.09,0,0,1-2.52,14H14.9A61.28,61.28,0,0,1,0,99C0,64.21,29.33,36,65.5,36a67.34,67.34,0,0,1,30,7A86,86,0,0,1,236.42,31.37,55.53,55.53,0,0,1,311,83.5a56.67,56.67,0,0,1,.55,7.75A39.93,39.93,0,0,1,329,125Z"/></svg>
    </div>    
</div>

.firstCloud {
    position: absolute;
    left: 0;
    top: 150px;
    ...
}

Explore the full code on CodePen

I've combed through different resources but have hit a roadblock in finding a solution to my specific requirement. Would appreciate any guidance or direction on how to achieve this effect?

Answer №1

Below is the solution I previously suggested in the comments:

To start, you can create an initial cloud (.initialCloud) that slides out of the screen and then transitions to the regular .firstCloud.

.clouds {
  position: relative;
  overflow: hidden;
  height: 400px;
}

.initialCloud {
  position: absolute;
  left: 100%;
  top: 150px;
  animation: moveFirst 5s linear .2s;
  animation-iteration-count: 1;
  width: 150px;
}

.firstCloud {
  position: absolute;
  left: -30%;
  top: 150px;
  animation: move 5s linear 5s infinite;
  width: 150px;
}

.secondCloud {
  position: absolute;
  left: -30%;
  top: 200px;
  animation: move 8s linear 0s infinite;
  width: 150px;
}

.thirdCloud {
  top: 250px;
  left: -30%;
  position: absolute;
  animation: move 11s linear 1s infinite;
  width: 150px;
}

@-webkit-keyframes move {
  from {
    left: -30%;
  }
  to {
    left: 100%;
  }
}

@-webkit-keyframes moveFirst {
  from {
    left: 50%;
  }
  to {
    left: 100%;
  }
}
<div class="clouds">
  <div class="initialCloud">
    <svg id="svgCloud" data-name="clouder" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348 164"><defs><style>.cloud1Fill{fill:#d1dbd9;}</style></defs><title>Untitled-5</title><path class="cloud1Fill" d="M348,107.5a54.5,54.5,0,0,1-94.87,36.61,77.55,77.55,0,0,1-81.57-1.43A73,73,0,0,1,71,145.07,42.48,42.48,0,1,1,49.61,71.59,73,73,0,0,1,154.85,26.84,77.51,77.51,0,0,1,287.16,53.37,53,53,0,0,1,293.5,53,54.5,54.5,0,0,1,348,107.5Z"/></svg>
  </div>
  <div class="firstCloud">
    <svg id="svgCloud" data-name="clouder" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348 164"><defs><style>.cloud1Fill{fill:#d1dbd9;}</style></defs><title>Untitled-5</title><path class="cloud1Fill" d="M348,107.5a54.5,54.5,0,0,1-94.87,36.61,77.55,77.55,0,0,1-81.57-1.43A73,73,0,0,1,71,145.07,42.48,42.48,0,1,1,49.61,71.59,73,73,0,0,1,154.85,26.84,77.51,77.51,0,0,1,287.16,53.37,53,53,0,0,1,293.5,53,54.5,54.5,0,0,1,348,107.5Z"/></svg>
  </div>
  <div class="secondCloud">
    <svg id="svgCloud2" data-name="cloud2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 291 124"><defs><style>.cloud1Fill{fill:#d3dddb;}.cloud2Fill{fill:#fff;}</style></defs><title>Untitled-4</title><path class="cloud1Fill" d="M2.29,123.5A41,41,0,0,1,58.37,74.12l.32.14.24-.25A45.72,45.72,0,0,1,91.5,60.5q1.14,0,2.25.06l.43,0,.09-.41a76,76,0,0,1,148.46,0l.09.4h.41l1.27,0a46.06,46.06,0,0,1,46,46,45.53,45.53,0,0,1-3.26,17Z"/><path class="cloud2Fill" d="M168.5,1a75.53,75.53,0,0,1,73.74,59.23l.18.81.82,0,1.26,0a45.49,45.49,0,0,1,42.4,62H2.66A40.53,40.53,0,0,1,58.17,74.57l.63.29.49-.49A45.2,45.2,0,0,1,91.5,61c.75,0,1.5,0,2.23.06l.85,0,.18-.83A75.51,75.51,0,0,1,168.5,1m0-1A76.52,76.52,0,0,0,93.78,60.06Q92.66,60,91.5,60A46.35,46.35,0,0,0,58.58,73.66,41.52,41.52,0,0,0,1.92,124H287.58A46.5,46.5,0,0,0,244.5,60l-1.28,0A76.53,76.53,0,0,0,168.5,0Z"/></svg>
  </div>
  <div class="thirdCloud">
    <svg id="svgClouds3" data-name="clouds2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 329 139"><defs><style>.cloud2Fill{fill:#d1dbd9;}</style></defs><title>Untitled-6</title><path class="cloud2Fill" d="M329,125a40.09,40.09,0,0,1-2.52,14H14.9A61.28,61.28,0,0,1,0,99C0,64.21,29.33,36,65.5,36a67.34,67.34,0,0,1,30,7A86,86,0,0,1,236.42,31.37,55.53,55.53,0,0,1,311,83.5a56.67,56.67,0,0,1,.55,7.75A39.93,39.93,0,0,1,329,125Z"/></svg>
  </div>
</div>

Answer №2

To create a cloud teleport effect from right to left, I added keyframes at 50% and 50.001%. Here is the code pen for reference: Cloud Teleport Code Pen

body {
  overflow: hidden;
}

#svgCloud {
  position: relative;
  height: 100px;
  width: 100px;
  animation: move 4s linear infinite;
  margin-left: 50vw;
  margin-top: 50vh;
  transform: translateX(-50%) translateY(-50%);
}

@keyframes move {
  50% {
    transform: translateX(50vw) translateY(-50%);
  }
  50.001% {
    transform: translateX(-60vw) translateY(-50%);
  }
}
<svg id="svgCloud" data-name="clouder" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348 164"><defs><style>.cloud1Fill{fill:#d1dbd9;}</style></defs><title>Untitled-5</title><path class="cloud1Fill" d="M348,107.5a54.5,54.5,0,0,1-94.87,36.61,77.55,77.55,0,0,1-81.57-1.43A73,73,0,0,1,71,145.07,42.48,42.48,0,1,1,49.61,71.59,73,73,0,0,1,154.85,26.84,77.51,77.51,0,0,1,287.16,53.37,53,53,0,0,1,293.5,53,54.5,54.5,0,0,1,348,107.5Z"/></svg>

Answer №3

Consider using the left property instead of translateX() since you can use percentages with left and detect the end of the screen.

.clouds {
  position: relative;
  overflow: hidden;
  height: 400px;
}

.firstCloud {
  position: absolute;
  left: -150px;
  top: 150px;
  animation: move 10s linear 2s infinite;
  width: 150px;
}

.secondCloud {
  position: absolute;
  left: -150px;
  top: 200px;
  animation: move 15s linear 0s infinite;
  width: 150px;
  }

.thirdCloud {
  top: 250px;
  left: -150px;
  position: absolute;
  animation: move 20s linear 5s infinite;
  width: 150px;
}

@-webkit-keyframes move {
  from {left: -150px;}
  to {left: 100%;}
}
  <div class="clouds">
    <div class="firstCloud">        
        <svg id="svgCloud" data-name="clouder" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348 164"><defs><style>.cloud1Fill{fill:#d1dbd9;}</style></defs><title>Untitled-5</title><path class="cloud1Fill" d="M348,107.5a54.5,54.5,0,0,1-94.87,36.61,77.55,77.55,0,0,1-81.57-1.43A73,73,0,0,1,71,145.07,42.48,42.48,0,1,1,49.61,71.59,73,73,0,0,1,154.85,26.84,77.51,77.51,0,0,1,287.16,53.37,53,53,0,0,1,293.5,53,54.5,54.5,0,0,1,348,107.5Z"/></svg>
    </div>  
    <div class="secondCloud">
        <svg id="svgCloud2" data-name="cloud2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 291 124"><defs><style>.cloud1Fill{fill:#d3dddb;}.cloud2Fill{fill:#fff;}</style></defs><title>Untitled-4</title><path class="cloud1Fill" d="M2.29,123.5A41,41,0,0,1,58.37,74.12l.32.14.24-.25A45.72,45.72,0,0,1,91.5,60.5q1.14,0,2.25.06l.43,0,.09-.41a76,76,0,0,1,148.46,0l.09.4h.41l1.27,0a46.06,46.06,0,0,1,46,46,45.53,45.53,0,0,1-3.26,17Z"/><path class="cloud2Fill" d="M168.5,1a75.53,75.53,0,0,1,73.74,59.23l.18.81.82,0,1.26,0a45.49,45.49,0,0,1,42.4,62H2.66A40.53,40.53,0,0,1,58.17,74.57l.63.29.49-.49A45.2,45.2,0,0,1,91.5,61c.75,0,1.5,0,2.23.06l.85,0,.18-.83A75.51,75.51,0,0,1,168.5,1m0-1A76.52,76.52,0,0,0,93.78,60.06Q92.66,60,91.5,60A46.35,46.35,0,0,0,58.58,73.66,41.52,41.52,0,0,0,1.92,124H287.58A46.5,46.5,0,0,0,244.5,60l-1.28,0A76.53,76.53,0,0,0,168.5,0Z"/></svg>
    </div>
    <div class="thirdCloud">
        <svg id="svgClouds3" data-name="clouds2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 329 139"><defs><style>.cloud2Fill{fill:#d1dbd9;}</style></defs><title>Untitled-6</title><path class="cloud2Fill" d="M329,125a40.09,40.09,0,0,1-2.52,14H14.9A61.28,61.28,0,0,1,0,99C0,64.21,29.33,36,65.5,36a67.34,67.34,0,0,1,30,7A86,86,0,0,1,236.42,31.37,55.53,55.53,0,0,1,311,83.5a56.67,56.67,0,0,1-.55,7.75A39.93,39.93,0,0,1,329,125Z"/></svg>
    </div>    
</div>

If you wish to start the animation when the middle screen is reached using jQuery:

$(document).ready(function(){
  $('.firstCloud,.secondCloud,.thirdCloud').animate({
     left:"100%"
  },10000,function(){$(this).addClass('anim')})
})
.clouds {
  position: relative;
  overflow: hidden;
  height: 400px;
}

.firstCloud {
  position: absolute;
  left: 0;
  top: 150px;
  animation-duration: 10s;
  animation-delay: 2s;
  width: 150px;
}

.secondCloud {
  position: absolute;
  left:  50%;
  top: 200px;
  animation-duration: 15s;
  width: 150px;
  }

.thirdCloud {
  top: 250px;
  left: 10%;
  position: absolute;
  animation-duration: 20s;
  animation-delay: 2s;
  width: 150px;
}


.anim {
  animation-name: move;
  animation-iteration-count: infinite;
}

@-webkit-keyframes move {
  from {left: -150px;}
  to {left: 100%;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="clouds">
    <div class="firstCloud">        
        <svg id="svgCloud" data-name="clouder" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348 164"><defs><style>.cloud1Fill{fill:#d1dbd9;}</style></defs><title>Untitled-5</title><path class="cloud1Fill" d="M348,107.5a54.5,54.5,0,0,1-94.87,36.61,77.55,77.55,0,0,1-81.57-1.43A73,73,0,0,1,71,145.07,42.48,42.48,0,1,1,49.61,71.59,73,73,0,0,1,154.85,26.84,77.51,77.51,0,0,1,287.16,53.37,53,53,0,0,1,293.5,53,54.5,54.5,0,0,1,348,107.5Z"/></svg>
    </div>  
    <div class="secondCloud">
        <svg id="svgCloud2" data-name="cloud2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 291 124"><defs><style>.cloud1Fill{fill:#d3dddb;}.cloud2Fill{fill:#fff;}</style></defs><title>Untitled-4</title><path class="cloud1Fill" d="M2.29,123.5A41,41,0,0,1,58.37,74.12l.32.14.24-.25A45.72,45.72,0,0,1,91.5,60.5q1.14,0,2.25.06l.43,0,.09-.41a76,76,0,0,1,148.46,0l.09.4h.41l1.27,0a46.06,46.06,0,0,1,46,46,45.53,45.53,0,0,1-3.26,17Z"/><path class="cloud2Fill" d="M168.5,1a75.53,75.53,0,0,1,73.74,59.23l.18.81.82,0,1.26,0a45.49,45.49,0,0,1,42.4,62H2.66A40.53,40.53,0,0,1,58.17,74.57l.63.29.49-.49A45.2,45.2,0,0,1,91.5,61c.75,0,1.5,0,2.23.06l.85,0,.18-.83A75.51,75.51,0,0,1,168.5,1m0-1A76.52,76.52,0,0,0,93.78,60.06Q92.66,60,91.5,60A46.35,46.35,0,0,0,58.58,73.66,41.52,41.52,0,0,0,1.92,124H287.58A46.5,46.5,0,0,0,244.5,60l-1.28,0A76.53,76.53,0,0,0,168.5,0Z"/></svg>
    </div>
    <div class="thirdCloud">
        <svg id="svgClouds3" data-name="clouds2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 329 139"><defs><style>.cloud2Fill{fill:#d1dbd9;}</style></defs><title>Untitled-6</title><path class="cloud2Fill" d="M329,125a40.09,40.09,0,0,1-2.52,14H14.9A61.28,61.28,0,0,1,0,99C0,64.21,29.33,36,65.5,36a67.34,67.34,0,0,1,30,7A86,86,0,0,1,236.42,31.37,55.53,55.53,0,0,1,311,83.5a56.67,56.67,0,0,1-.55,7.75A39.93,39.93,0,0,1,329,125Z"/></svg>
    </div>    
</div>

Answer №4

This example was created quickly to demonstrate the concept.

Initially, I positioned the cloud 50px from the left and applied a single iteration animation.

Next, I introduced a second cloud with an infinite animation, incorporating a delay to create the perception of a continuous loop despite being separate elements and animations.

For this scenario, utilizing CSS exclusively seemed to be the most optimal approach.

.wrapper {
  position: relative;
}

.clouds {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: gray;
}

.clouds.cloud1 {
  left: 50px;
  animation: cloud1 20s linear 1;
}

.clouds.cloud2 {
  left: -50px;
  animation: cloud1 20s 10s linear 1;
}

@keyframes cloud1 {
  0% {
    left: 20px;
  }
  100% {
    left: 3000px;
  }
}

@keyframes cloud2 {
  0% {
    left: -50px;
  }
  100% {
    left: 3000px;
  }
}
<div class="wrapper">
<div class="clouds cloud1"></div>
<div class="clouds cloud2"></div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Adjust the size of H1, H2... tags based on their own specifications, rather than the surrounding element

I have run into a bit of a conundrum with my code and cannot seem to find the right solution. Here is what I currently have: <div id="bloquetexto4" class="bloquetexto"> <H2><b>TITULO</b></H2> <p>Texto bla bla bla.</p ...

Thymeleaf is responsible for fetching the static resources by referencing the REST URI

I am currently utilizing thymeleaf as my chosen template engine for a spring boot project. Here is the directory structure: src/main/ |- java | - UserAdministrationController.java |- resources | - static | - admin | - css ...

The hover effect fails to function properly after altering the background color. The default color setting is transparent

<button class="button-main slide">Slide Left</button> .button-main{ color: black; outline: none; background: transparent; border: none; letter-spacing: 0.0625em; padding: 8px 10px; text-transform: uppercase; font: b ...

Does jQuery's click event not successfully hide an element on Internet Explorer?

In my dropdown menu, I have the following options: <div class="my_div"> <select name="selection" id="select_id"> <option value="0">A</option> <option value="5">B</option> ...

How to apply custom styling to a specific element within an Angular Material 2 component using CSS based on its Id or

My EntryComponent features a material button menu where I attempted to customize the default style using ::ng-deep. However, the changes affected all button components in the parent Component as well. <style> ::ng-deep .mat-button{ max-width: 50 ...

Alter the background image of a DIV based on the selected menu item

I am working on a project that involves a div element with the class "jumbotron" which currently has a background image applied to it. Additionally, I have a menu consisting of 6 items that I would like to interact with. My goal is to dynamically change ...

Is there a way to align these blocks in a single row?

Having trouble aligning these buttons horizontally. Any suggestions? I've been tinkering with this for a couple of hours now, so decided to seek help here. The desired effect should resemble the image below, but it's not quite there yet. Thank yo ...

The nth-child selector is not functioning correctly with material-ui components

Trying to figure out how to give two paragraphs different background colors using nth-child. Here's the JSX: <div className={classes.paragraphs}> <p>Test 1</p> <p>Test 2</p> </div> And the CSS: const useSty ...

Difficulty arises in designing a tableless layout due to the issue of auto

Wondering why my page is not expanding with its content? Check out my demo on Fiddle http://jsfiddle.net/msas3/. The light blue area should determine the overall height of the page. ...

Looking to create circular text using HTML, CSS, or JavaScript?

Is there a way to generate curved text in HTML5, CSS3, or JavaScript similar to the image linked above? I've experimented with transform: rotate(45deg); but that just rotates the text without curving it. Additionally, when using Lettering.JS to curve ...

attempting to eliminate on-screen buttons by hovering over the video

Is there a way to make my video play on loop like a GIF without the controls ever showing? I want it to have a seamless playback experience. Any ideas would be appreciated. P.s. Don't worry about any StackOverflow errors when running the snippet. Than ...

Position a Paper component in the center of a div

I'm having trouble centering my <Paper> element inside a div. Can anyone help me with this? I have placed both the <Paper> and <RaisedButton> elements inside the div and applied the following CSS: .timerArea { text-align: center; ...

Issue with CSS color gradient transparency

I've successfully implemented a gradient that transitions from transparent to white by using the following CSS code: linear-gradient(to right, transparent, white) If you want to see it in action, click on this link: http://jsfiddle.net/fs8gpha2/ Al ...

Eliminate borders surrounding WordPress text widgets

Looking for some help with removing the border around the widgets on my home page. Despite my theme's CSS removing borders universally, I thought targeting specific Div text widgets (such as text-7, text-6) would do the trick. While I can control the ...

Text area featuring unique border design, with border color change upon focus?

Currently, I have a text area with borders that are designed in a unique way. However, I am looking to change the border color when the user focuses on the text area. Do you have any suggestions on how I can achieve this effect without affecting the curre ...

The alignment issue persists in HTML/CSS despite troubleshooting efforts

I am facing a challenge while attempting to center text within a modal window, despite my efforts the text remains uncentered. This is my HTML code: <div ng-init="modalCompassDir()"> <div class="myModal"> <img class='floor ...

List arranged in order with a hyperlink in the center and an image positioned on the right side

I am trying to create an ordered list with a link to an article in the middle and a small png image file positioned directly to the right of it. For reference, here is an image depicting the exact type of list that I am aiming to achieve: https://i.stack. ...

Designing HTML columns to adapt to different screen resolutions

Looking for a clever jQuery or CSS trick to dynamically adjust the number of columns in a website layout based on the size of the viewport. For instance, an iPhone display would have 1 column, while an 800x600 screen would have 2, and a 1024x768 screen wou ...

Incorporating and designing an external document

Another website has a file that I would like to include in one of my own pages. The URL format is as follows: http://example.com/path/with/some/variables I could use an iframe to accomplish this, but I also want to customize the CSS of elements within th ...

What is causing the colored SVG to appear lighter than the intended color after using a mask to recolor it?

I have a project using VueJS where I am trying to change the color of SVGs by looping through them and using mask and rect tags. However, I am noticing that as the icon index increases, the color of the icon becomes lighter. What could be causing this issu ...