Transition not influencing the scale property when activating a class

My modal is not scaling in and out properly when I toggle the 'active' class. It either fully scales out or scales in without any transition.

Example:

const openPopupButtons = document.querySelectorAll('[data-popup-target]');
const closePopupButtons = document.querySelectorAll('[data-close-button]')
const overlay = document.getElementById('overlay')

openPopupButtons.forEach(button, () => {
  button.addEventListener('click', () => {
    const popup = document.querySelector(button.dataset.popupTarget)
    openPopup(popup)
  })
})

closePopupButtons.forEach(button, () => {
  button.addEventListener('click', () => {
    const popup = button.closest('.popup')
    closePopup(popup)
  })
})

function openPopup(popup) {
  if (popup == null) return
  popup.classList.add('active')
  overlay.classList.add('active')
}

function closePopup(popup) {
  if (popup == null) return
  popup.classList.remove('active')
  overlay.classList.remove('active')
}
.popup {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(.75);
  transition: 1s ease-in-out;
  border: 10px double #fff8fb;
  border-radius: 1em;
  padding: 0 1em;
  background-color: #fcdce9;
  width: 600px;
  max-width: 80%;
  z-index: 10;
}

.popup.active {
  transform: translate(-50%, -50%) scale(1);
}

.popup-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: .25rem .5rem;
}

.popup-header .title {
  font-size: 24px;
  font-weight: bold;
}

.popup-header .close-popup {
  cursor: pointer;
  background: none;
  border: none;
  outline: none;
  font-size: 24px;
  font-weight: bold;
}

.post-it {
  border: none;
  border-radius: 1em;
  width: 100%;
  padding: 10px 15px;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  font-size: 16;
}

.popup-footer {
  padding: .5rem 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.create-button {
  border: 3px solid #fff8fb;
  border-radius: 1em;
  background: none;
  outline: none;
  font-size: 18px;
  font-weight: bold;
  padding: 2.5px 20px;
  cursor: pointer;
}

#overlay {
  position: fixed;
  opacity: 0;
  transition: 500ms ease-in-out;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, .5);
  pointer-events: none;
}

#overlay.active {
  opacity: 1;
  pointer-events: all;
}
<body>
  <button data-popup-target="#popup" class="open-popup">Open Pop-up</button>
  <div class="popup active" id="popup">
    <header class="popup-header">
      <div class="title"> Insert Text </div>
      <button data-close-button class="close-popup"> &times; </button>
    </header>
    <div class="popup-body">
      <textarea name="post-it" id="post-it" cols="30" rows="10" class="post-it"></textarea>
    </div>
    <footer class="popup-footer">
      <button class="create-button"> Create </button>
    </footer>
  </div>
  <div class="" id="overlay"></div>
</body>

I'm facing issues with animating the modal on toggle. The hover animation works fine, but transitioning on adding/removing classes doesn't work as expected. I've tried different approaches to define transitions, like specifying properties or transitioning all, but still no luck.

Answer №1

If you're looking for a solution, consider this example that utilizes ES6 syntax:

const overlay = document.getElementById('overlay');
document.querySelectorAll('[data-popup-target]').forEach(button =>
  button.addEventListener('click', openPopup)
);

document.querySelectorAll('[data-close-button]').forEach(button =>
  button.addEventListener('click', closePopup)
);

function openPopup(event) {
  const popupTarget = event.target.dataset.popupTarget;
  const popup = document.querySelector(popupTarget);
  if (!popup) return;
  popup.classList.add('active');
  overlay.classList.add('active');
}

function closePopup(event) {
  const popup = event.target.closest('.popup');
  if (!popup) return;
  popup.classList.remove('active');
  overlay.classList.remove('active');
}
.popup {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(.75);
  transition: 1s ease-in-out;
  border: 10px double #fff8fb;
  border-radius: 1em;
  padding: 0 1em;
  background-color: #fcdce9;
  width: 600px;
  max-width: 80%;
  z-index: 10;
}

.popup.active {
  transform: translate(-50%, -50%) scale(1);
}

.popup-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: .25rem .5rem;
}

.popup-header .title {
  font-size: 24px;
  font-weight: bold;
}

.popup-header .close-popup {
  cursor: pointer;
  background: none;
  border: none;
  outline: none;
  font-size: 24px;
  font-weight: bold;
}

.post-it {
  border: none;
  border-radius: 1em;
  width: 100%;
  padding: 10px 15px;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  font-size: 16;
}

.popup-footer {
  padding: .5rem 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.create-button {
  border: 3px solid #fff8fb;
  border-radius: 1em;
  background: none;
  outline: none;
  font-size: 18px;
  font-weight: bold;
  padding: 2.5px 20px;
  cursor: pointer;
}

#overlay {
  position: fixed;
  opacity: 0;
  transition: 500ms ease-in-out;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, .5);
  pointer-events: none;
}

#overlay.active {
  opacity: 1;
  pointer-events: all;
}
<body>
  <button data-popup-target="#popup" class="open-popup">Open Pop-up</button>
  <div class="popup active" id="popup">
    <header class="popup-header">
      <div class="title"> Insert Text </div>
      <button data-close-button class="close-popup"> &times; </button>
    </header>
    <div class="popup-body">
      <textarea name="post-it" id="post-it" cols="30" rows="10" class="post-it"></textarea>
    </div>
    <footer class="popup-footer">
      <button class="create-button"> Create </button>
    </footer>
  </div>
  <div class="" id="overlay"></div>
</body>

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

Navigating through JSON data that has been returned

When I use AJAX (jQuery) to query my database, the data I receive back is causing some difficulties. While searching for a solution, I came across similar issues posted by others who pointed out that the PHP code (specifically how data is stored in the arr ...

Place two anchors side by side using inline-blocks without using the float property

Is there a way to align two buttons next to each other without using floating? I have encountered an issue where adding a width to one of the buttons causes it to jump down and be on a different line than the other button. The buttons are centered, so th ...

Achieving a Subset Using Functional Programming

Looking for suggestions on implementing a function that takes an array A containing n elements and a number k as input. The function should return an array consisting of all subsets of size k from A, with each subset represented as an array. Please define ...

Omit the element from the event listener

Is there a way to prevent the image from triggering a click event in this code snippet? $('#templtable .trhover *:not(#infoimg)').live('click', function(event) { event.stopPropagation(); $(this).toggleClass('selected&a ...

I am interested in creating a design where two DIVs are layered on top of each other with one having transparency, allowing visibility through to the background DIV. This can be achieved using a combination of

Looking to enhance the visual appeal of my website, I decided to incorporate a background image within a div. To add more depth and creativity, I am now striving to overlay a semi-transparent black box on top of the image. This overlay will not only allo ...

Modifying the border hue of Material-UI's Select Component

Here is the Select component I've created using materials-UI <FormControl variant="outlined"> <Select value={this.state.value} onChange = {this.handleChange} className={this.props.classes.select} inputProps = {{class ...

What is the process of transforming a tree into a JSON object?

I have a tree structure that I need to convert into JSON format for use with a jquery option tree. NodeId, Title, Level 1, cars, 0 2, boats, 0 3, oldtimer, 1 4, trucks, 1 5, heavytrucks, 4 The desired tree structure is as follows: boats cars - oldtimer - ...

`Is there a way to conceal certain options in HTML based on mysql data``

When using PHP: $query ="SELECT rent FROM mydatabase WHERE rent= '$rent'"; $rs=mysqli_query($connect,$query); if(!$rs) {echo "<script type ='text/javascript'>alert('Cannot connect to database')</script>" ...

Retrieve: Type 'string | undefined' does not match the parameter type 'RequestInfo'

When using the fetch function, I encountered an error with the "fetchUrl" argument: Error: Argument of type 'string | undefined' is not assignable to parameter of type 'RequestInfo'. This is the code snippet where the error occurred: ...

React Container failing to Re-Render despite Redux State Change

I have encountered an issue while working on Redux and React. I am developing a book list where clicking on a book will display its details. Upon selecting a book, the action is properly handled and the state is updated as expected. // reducer_active_boo ...

Conceal the information beneath a see-through fixed navigation bar when scrolling downward

the issue: I am facing a challenge with my transparent fixed navbar that has a margin-top gap. The content below the navbar needs to be positioned under it while scrolling down, but the background of the page is a dynamic slideshow of various images. This ...

Encountering difficulties with "removeChild" in React when attempting to dynamically update an array

In my React component's state, I have an array called "personArray." The component includes a search bar that triggers an API request and updates the "personArray" based on user input. In the render method, I map through this "personArray" to display ...

Tips for accessing a web service using JavaScript (AJAX)

I have two projects: one is a web service and the other is an ASP.NET web project. I am trying to insert data using JSON (with AJAX). I tested the web service file with code behind and it works fine, but I'm encountering an error with the JavaScript ...

Update the class name by utilizing template literals

I'm currently in the process of mastering template literals as I have a project where I need to utilize them. However, I seem to be encountering an issue that I can't quite figure out. Here is the code that is currently working: const classes = ...

Learn how to toggle the visibility of a gif image with a button click in an ASP.NET application

I am working on an asp page that includes a button. When the button is clicked, I need to display a gif image. Once the process is complete, the image should be hidden again. Here is the code behind: <head runat="server"> <title>Untitled ...

The reason behind the successful execution of the final .then in promise chaining

I am new to JavaScript and have encountered an interesting problem with the following code. Even though I haven't returned anything from the .then method, the last .then (blue color) works instead of the first one (red color). Can someone explain why ...

SyntaxError in ExpressJS: Encountered an unexpected token "C"

I'm having trouble saving my string to a comma-separated array. When I attempt to use the JSON.parse method, I encounter an error while sending a post request and trying to save a record: SyntaxError: Unexpected token c at Object.parse (native) ...

No error reported upon trying to render json output

I'm having an issue where the following code is not displaying any output. Can someone help me identify what mistake I might be making? This is the HTML file: <head> <script type = "text/javascript"> function ajax_get_json() { var h ...

Padding on hover for navigation bar dropdowns

Having issues with a drop-down navigation menu that works fine except for the "videos" item. The hover color change doesn't cover the entire width due to padding settings. Struggling to fix this without affecting the "photography" item. Need help figu ...

Tips for restricting navbar-fixed to the width of the container

Welcome to my first project utilizing Twitter Bootstrap. While using Twitter Bootstrap, I've noticed that whether I use container-fluid or just container for my fixed top navbar, it expands to full width of the browser once it reaches around 980px. T ...