Ways to halt a CSS animation when it reaches the screen boundary

I put together this demo:

By clicking, a red box falls down.

The issue arises when trying to determine the screen size using only CSS. In my demo, I set the box to fall for 1000px regardless of the actual screen height.

Here is the keyframe code snippet:

@include keyframes("fall"){
   to{
      top: 1000px;
   }
 }

Unfortunately, using bottom: 0px; isn't viable as it doesn't solve the main problem of determining where the fall should start from.

This is the JavaScript script called FallBox.js:

function FallBox(x, side, parent){
  this.x = x;
  this.parent = parent || $("body");
  this.side = side || Math.random()*200;
  this.createBox();
  this.fall();
}

FallBox.prototype.createBox = function(){
  box = document.createElement('div');
  $box = $(box); // I dislike brackets
  $box.addClass("box");
  $box.css({
      width: this.side+"px",
      height: this.side+"px",
      left: this.x+"px",
      top: "-"+(this.side+5)+"px"
  });
  this.box = $box;
}

FallBox.prototype.fall = function(){
  this.parent.append(this.box);
  this.box.addClass("fall");
}

Using overflow: hidden; in the parent div could be a solution, but it's not ideal. It may restrict users with larger screens and I want the box to stop when reaching the edge, similar to hitting the ground and not passing through.

An alternative solution involving the CSSOM API was found online, however, even Mozilla developers are unsure about its compatibility.

So, how can I halt the animation upon hitting the screen edge when properties cannot be injected via JavaScript?

Thank you.

Answer №1

If you are in search of a pure CSS solution, consider utilizing the 'calc' feature within CSS along with the 'vh' unit.

document.querySelector(".box").addEventListener("click", function() {
  this.classList.toggle("is-dropped");
})
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.box {
  position: absolute;
  top: 0;
  left: 200px;
  width: 100px;
  height: 100px;
  background: red;
  transition: top 2s;
}
.box.is-dropped {
  top: calc(100vh - 100px);
}
<div class="box"></div>

Answer №2

You can utilize the translatey() CSS transform function to move each div upward by 100% of its own height. This approach allows for only 2 rules to adjust the value of the top position without needing to consider the height in each instance.

(function(d,M){
    var  div=d.createElement("div"),
         wait=0,size;
    d.body.addEventListener("click",function(){
      if(!wait){
        wait=1;
        div=div.cloneNode(1);
        div.classList.remove("go");// necessary so that newly created divs don't just get added to the bottom of the page
        size=M.max(M.floor(M.random()*200),50);
        div.style.height=div.style.width=size+"px";
        div.style.left=M.max(M.floor(M.random()*this.offsetWidth)-size,0)+"px";
        this.appendChild(div);
        setTimeout(function(){
          div.classList.add("go");// adding this class starts the animation.
          wait=0;
        },5);
       }
    },0);
})(document,Math);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
  background:#000;
  border:1px solid #fff;
  transition:top 2s linear;
  position:absolute;
  top:0;
  transform:translatey(-100%);
}
div.go{
  top:100%;
}


INNOVATIVE SOLUTION

Since the height of the box is dynamically set in your JavaScript, your CSS does not have prior knowledge of each box's height. However, you can still use the CSS calc() function to define the desired top position to animate each box to, similar to how you specify the starting top position. Below is a basic example with an alternative solution provided in the comments, which avoids using calc(), if preferred.

var  div=document.createElement("div"),
     wait=0,size;
document.body.addEventListener("click",function(){
  if(!wait){
    wait=1;
    div=div.cloneNode(0);
    size=Math.max(Math.floor(Math.random()*200),50);
    div.style.height=div.style.width=size+"px";
    div.style.left=Math.max(Math.floor(Math.random()*this.offsetWidth)-size,0)+"px";
    div.style.top="-"+size+"px";
    this.appendChild(div);
    setTimeout(function(){
      div.style.top="calc(100% - "+size+"px)"; /* Important calculation */
//    div.style.top=document.body.offsetHeight-size+"px"; /* Alternate solution without calc() */
      wait=0;
    },5);
   }
},0);
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%}
div{
  background:#000;
  border:1px solid #fff;
  transition:top 2s linear; /* Transition instead of animation for smoother effect */
  position:absolute;
}

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

Interactive JavaScript button that navigates me to a document without the need to click

I'm facing an issue with my small project. I've been learning javascript and managed to create a script that calculates the square of a number provided by the user. var checkIt = function(){ var theNumber = Number(prompt("Please enter a number ...

Executing a Javascript function through Typescript in an Ionic application

I integrated a plugin into my ionic project, which includes both Java and JS code: cordova.define("cordova-sms-plugin.Sms", function(require, exports, module) { 'use strict'; var exec = require('cordova/exec'); var sms = {}; functio ...

Attempting to display an HTML image utilizing data storage

I'm currently working on building a database for animals at an animal shelter. I have created tables containing species information and when a user selects a specific species, all available animals are displayed. Now, I want users to be able to click ...

The angularjs response data is mysteriously missing from the console display

I am struggling with the code below, as the data is not showing in the console log. I am new to Angular and would appreciate some help on how to display the data in HTML. this.$http.get(properties.client+'/123') .then(response => { ...

Creating custom styles using Material-UI's makeStyles function with both before and after

Currently, I'm tasked with a project that involves utilizing the CSS code below. .hexagon, .hexagon::before, .hexagon::after { width: 67px; height: 116px; border-radius: 18%/5%; } I am wondering if there is a method to apply the specified style ...

Sending a form using an AngularJS dropdown menu

I have recently started using angularjs and decided to switch out a traditional html <select> box for an angular modal select box. The select box successfully populates with data from a $http ajax request, but I am facing issues with form submission ...

Is there a way to update specific content within a view in express.js without having to re-render the entire view?

I'm in the process of creating a calendar that allows users to click on dates, triggering a popup window displaying events for that specific date. The challenge lies in not knowing which date the user will click on prior to rendering, making it diffic ...

Vows, Tobi, and Node.js come together for comprehensive REST API testing

Currently, I am in the process of merging the examples here and here to create a vows test for my node.js / express application that does the following: Creates a new user object Verifies that the response is correct Utilizes the returned _id to perform ...

What is causing my images to fail loading on IE but display properly on other browsers?

I am facing an issue where the images for my css header class load correctly in Chrome and FF, but not in IE8 or 7. Can anyone help me figure out what I may be missing? Below is the css class code that I am using: .TBox { color:#333333; font-size ...

Move to Fieldset Upon Link Click

Here's an example of what I have implemented so far here It's evident that this is not fully functional due to the PHP and jQuery integration. This demo is just a showcase of my progress. I am looking to create a functionality where clicking on ...

JavaScript embedded in an HTML document, which in turn is embedded within JavaScript

Is it possible to nest tags within other tags to control the functionality of a download button in a chat bot? Unfortunately, nesting tags is not allowed, so I'm looking for an alternative solution. Below is the complete HTML file I'm working wit ...

Unable to view any output in the console while attempting to troubleshoot a login functionality

My current setup involves using Node.js with Express and Pug templates. I have encountered an issue with a login function that is not functioning as expected. In order to troubleshoot the problem, I attempted to log the credentials (email and password) to ...

Tips for extracting data from various select drop-down menus within a single webpage

As a newcomer to JQuery, I apologize if this question seems basic. I have a page with 20 categories, each offering a selection of products in a drop-down menu. The user will choose a product from each category, triggering an ajax call to retrieve the pric ...

How can you start a jQuery script following a triumphant Ajax callback?

Having some trouble getting jQuery to execute after a successful Ajax response. Even though I have it in the success callback, it doesn't seem to be working as expected. I came across a potential solution here, but I'm having difficulty understan ...

Refreshing the site to submit the form

I am facing an issue with the page reloading every time I click submit on the form. Whenever I hit send, the form reloads and takes me to http://localhost:3000/mail.php. I would prefer if the site did not reload (I am using a jQuery validation form plugin) ...

Ways to engage with a fixed html page generated by an Express router?

Let me start by mentioning that I am relatively new to working with NodeJs. Currently, I am dealing with a situation where I need to render a static HTML web page (which includes JavaScript code) as a response to a post request. Below is the relevant snipp ...

What is the best way to send a JSON Object containing option parameters in order to open a new window?

Have you noticed the interesting parameter list for the window.open() object? Is there a possibility to use window.open({options..}); instead? What are your thoughts on this matter? ...

The React modal window stubbornly refuses to close

import c from '../Profile.module.css'; import { useState } from 'react'; import { createPortal } from 'react-dom'; import Modal from '../Modal/Modal'; const TransactionItem = (props) => { const modalRoot = ...

Implementing personalized font styles in HTML on a WordPress platform

I recently followed a tutorial on how to upload custom fonts to my WordPress website, which you can find at the link below. I completed all the necessary steps, such as uploading to the ftp, modifying the header.php file to include the font stylesheet, and ...

What steps can I take to ensure that the submenu remains visible for users to make their selection?

I'm currently working on implementing a drop-down sub-menu next to the navigation bar located in the center of the image. I have uploaded an image of a transparent box (representing the background of the sub-menu) and used the following codes: When h ...