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: https://i.sstatic.net/KINRM.jpg

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

Identify the browser dimensions and implement CSS styling for all screen resolutions

I am currently facing an issue with a function that I have created to apply CSS changes to a menu based on browser resizing and different resolutions. The problem lies in the fact that my function does not seem to be correctly interpreted by the browser. W ...

How can I make Bootstrap fit my Custom Grid?

I have received specific measurements from a customer for a customized grid layout, and I am unsure of how to implement it. Here are the measurements provided: **Width: 320px** Sides: (26px) (2 sides) Column: (52px) (4 columns) Gutter: (20px) (3 gutter ...

"Troubleshooting problems with jQuery accordion collapse and styling using CSS

I'm currently dealing with an issue regarding my accordion design. I have customized the stylesheet using themeroller, but when I collapse one of the sections, the header changes to black instead of reverting back to its original red color. I've ...

Unable to select the initial element

Having trouble targeting the first child in this code snippet. I've tried various methods but nothing seems to be working. Any suggestions on how to resolve this? <div id="main"> <div class="page"> <p>random 1</p> </div ...

Include an iframe with hidden overflow specifically for Safari browsers

I have a situation where I'm using a third-party iframe to display specific content. The iframe is enclosed within a div container that has border-radius and overflow: hidden properties applied. Strangely, the content inside the iframe doesn't se ...

Is there a way to prevent a tag from being clickable on the entire row, except for the actual link itself?

My question is why, when using the a tag, the entire row on the right becomes clickable as well? Despite there being no link, the area at the back of the row on the right side is clickable. Is there any way to remove this clickable area? <a id="ba ...

What are the steps for integrating a date and time picker bootstrap plugin?

Referencing a tutorial from http://www.w3schools.com/bootstrap/bootstrap_modal.asp: <button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button> <div id="myModal" class="modal fade" role= ...

What is the best way to arrange two divs inside a main div so they remain fixed in place at all times?

Struggling with aligning two smaller divs within a main wrapper for my website. Despite confining them to the main div, they don't stay fixed or aligned properly. How can this issue persist even when contained within a main div? I've attempted s ...

Can you tell me the proper term for the element that allows CSS properties to be changed after a link has been clicked?

I have integrated a horizontal scrolling date selector on my website, and it is functioning well. However, I am facing an issue while trying to change the CSS properties of a clicked date link using jQuery. Despite successfully firing the click event, I am ...

Can you provide me with instructions on utilizing PNGs to create edge masks for an image?

After experimenting with border-image and PNGs to achieve textured borders, I'm curious if there is a method for masking in a similar fashion? I recently came across the Rumchata website which showcases what I have in mind. Their background has a blu ...

Animating jQuery Accordion in Horizontal Direction Extending to the Far Right

After implementing a horizontal accordion in jQuery based on the tutorial found at the following link: A minor issue arose during animation where a slight space was added on the far right side, causing the tabs to shift slightly. This problem is particula ...

When you click on the column header to sort, the corresponding column row changes color in JavaScript

https://i.sstatic.net/4ELuv.jpg When a user clicks on a column to sort, the color of the column changes or highlights the row. In my tablesorter with ascending and descending sorting capabilities, I want the sorted column to change colors for better visib ...

Running the gulp uncss command with regex to ignore specific elements is not functioning as expected

I have been attempting to integrate uncss into my gulp workflow. In order to exclude certain classes, such as those added through javascript, I am specifying these classes with "ignore" (specifically, I am trying to remove the css from the jquery plugin m ...

What is the method to display HTML code using JavaScript within a span element in a JSP page?

While working on a jsp file, I came across a span tag with the following code: <span id="divBasicSearchResults" style="height:100%;"></span> Below is the Javascript function that generates HTML content for this span: function renderBasicSear ...

Utilize the inherited background color for a linear-gradient effect

Here is the code snippet I am working with: <label className={classes.trigger} htmlFor={uniqueId} ref={labelRef} style={{ background: val, borderColor: val }} /> This is the corresponding CSS: .trigger { display: block; posit ...

Tips for styling links in Nuxt/Vue based on specific conditions

Struggling with conditional styling in my Nuxt app. I want to change the background color of the active link based on the current page. Using .nuxt-link-exact-active works for styling the active link, but how can I customize it for each page? The links ar ...

Tips on aligning two divs horizontally on the same line

doc.html .column { background-color: orange; width: 75%; vertical-align: top; display: inline-block; height: 200px; } .nav { vertical-align: top; display: inline-block; width: 25%; background-color: lightgreen; height: 200px; } * { ...

Transform your table into an ASCII-art masterpiece using CSS styling techniques

My vision is to style a table "ASCII art" using CSS, like the example below: +------+---------+----+ | Jill | Smith | 50 | +------+---------+----+ | Eve | Jackson | 94 | +------+---------+----+ | John | Doe | 80 | +------+---------+----+ <ta ...

CSS exclusive - achieving a horizontal scrolling list with all list items in a single row

I am working with a div that has a fixed width. Inside this div, there is an unordered list (ul) containing a random number of list items (li) with varying widths. My project utilizes the Bootstrap framework. Below is an example of the code structure: & ...

Achieving a seamless scrolling effect using CSS

I recently completed the design of a basic website that includes both mobile and desktop versions. However, I am looking to incorporate some animation into the site to enhance its appearance. One specific feature is a "go up" link at the bottom of the mob ...