in tailwind, the position transition does not work as expected

I have a React component that I'm working on:

function DivModal() {
  const [isOpen, setIsOpen] = useState(true)

  return (
    <div>
      <button onClick={() => setIsOpen(prev => !prev)} className={buttonStyle}>Open</button>
      {isOpen && (
        <div className='fixed top-0 left-0 w-full h-full bg-black/50'>
          <div className={`fixed top-0 ${isOpen ? 'left-0' : '-left-full'} flex transition-left duration-1000 ease-in-out`}>
            <ul className='bg-white'>
              <li>first</li>
              <li>second</li>
              <li>third</li>
            </ul>
            <button onClick={() => setIsOpen(prev => !prev)}>close</button>
          </div>
        </div>
      )}
    </div>
  )
}

Although the component functions properly by appearing and disappearing when clicked, there seems to be an issue with the transitions. There is no smooth animation from left to right when opening and closing. How can this be resolved?

Answer №1

transition-left is not a default Tailwind class configuration. When setting a non-zero transition-duration using a duration-* class, it automatically implies transition-property: all, making the use of transition-left unnecessary.

To ensure the transition occurs, you must keep the element in the DOM:

const { useState } = React;
const buttonStyle = '';

function DivModal() {
  const [isOpen, setIsOpen] = useState(true)

  return (
    <div>
      <button onClick={() => setIsOpen(prev => !prev)} className={buttonStyle}>Open</button>
      <div className='fixed top-0 left-0 w-full h-full bg-black/50'>
        <div className={`fixed top-0 ${isOpen ? 'left-0' : '-left-full'} flex duration-1000 ease-in-out`}>
          <ul className='bg-white'>
            <li>first</li>
            <li>second</li>
            <li>third</li>
          </ul>
          <button onClick={() => setIsOpen(prev => !prev)}>close</button>
        </div>
      </div>
    </div>
  )
}

ReactDOM.createRoot(document.getElementById('app')).render(<DivModal/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.4.1"></script>

<div id="app"></div>

We can enhance this further by hiding the bg-black/50 overlay when the inner drawer is hidden, possibly with a fading effect:

const { useState } = React;
const buttonStyle = '';

function DivModal() {
  const [isOpen, setIsOpen] = useState(true)

  return (
    <div>
      <button onClick={() => setIsOpen(prev => !prev)} className={buttonStyle}>Open</button>
      <div className={`fixed top-0 left-0 w-full h-full bg-black/50 duration-200 ${isOpen ? '' : 'invisible bg-black/0'}`}>
        <div className={`fixed top-0 ${isOpen ? 'left-0' : '-left-full'} flex duration-1000 ease-in-out`}>
          <ul className='bg-white'>
            <li>first</li>
            <li>second</li>
            <li>third</li>
          </ul>
          <button onClick={() => setIsOpen(prev => !prev)}>close</button>
        </div>
      </div>
    </div>
  )
}

ReactDOM.createRoot(document.getElementById('app')).render(<DivModal/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.4.1"></script>

<div id="app"></div>

Another optimization to consider is using transform: translateX() instead of left. This change improves the transition performance as the browser does not need to recalculate layout every animation frame. Using transform: translateX(-100%) ensures the drawer only slides its width, eliminating delays associated with viewport-width transitions. This allows for synchronizing the durations of both the overlay and the drawer:

const { useState } = React;
const buttonStyle = '';

function DivModal() {
  const [isOpen, setIsOpen] = useState(true)

  return (
    <div>
      <button onClick={() => setIsOpen(prev => !prev)} className={buttonStyle}>Open</button>
      <div className={`fixed top-0 left-0 w-full h-full bg-black/50 duration-500 ${isOpen ? '' : 'invisible bg-black/0'}`}>
        <div className={`fixed top-0 ${isOpen ? '' : '-translate-x-full'} flex duration-500 ease-out`}>
          <ul className='bg-white'>
            <li>first</li>
            <li>second</li>
            <li>third</li>
          </ul>
          <button onClick={() => setIsOpen(prev => !prev)}>close</button>
        </div>
      </div>
    </div>
  )
}

ReactDOM.createRoot(document.getElementById('app')).render(<DivModal/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.4.1"></script>

<div id="app"></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

Guidelines on switching from Create React App 5.0.0 to version 4.0.3

I've encountered an issue with create-react-app where the latest release requires Node 14, but my workplace only approves version 12.16.3. In this scenario, I'm exploring ways to use create-react-app with an older version of Node. I attempted to ...

Aligning a div vertically in the center of its parent container

I am trying to vertically align a child element within its parent element <!DOCTYPE html> <html> <head> <title>Test</title> <style type="text/css"> #body { font-family: sans-serif, arial, 'Roboto'; } #outer ...

Implementing a pull-to-refresh feature in React Native using Redux

I need to implement pull to refresh functionality, but I'm unsure of what to call from _Refresh(). My actions, constants, and reducers are stored on another page. How can I trigger the API again? Thank you in advance for your assistance. class Homewo ...

What is the best way to customize the appearance of these two images within a div element?

While working on a small website project during my internship, I initially used an inline stylesheet. However, upon my boss's recommendation, I switched to an external stylesheet. Now, I'm trying to figure out how to style the two images within d ...

Troubleshooting: Twitter Bootstrap dropdown feature experiencing issues within navigation bar

I am facing an issue with getting the bootstrap dropdown to function properly. I have tested it on my mobile device and noticed that the menu does not drop down as expected. Here is a DEMO Below is the code snippet: <nav class="navbar navbar-inverse ...

Issue with setting a cookie on a separate domain using Express and React

My backend is hosted on a server, such as backend.vercel.app, and my frontend is on another server, like frontend.vercel.app. When a user makes a request to the /login route, I set the cookie using the following code: const setCookie = (req, res, token) = ...

On the first load, Next.js retrieves a token from an API and saves it for later use

Currently working on an application with next.js, the challenge lies in retrieving a guest token from an API and storing it in a cookie for use throughout the entire application. My goal is to have this token set in the cookie before any page is loaded. H ...

Update the state according to the selected option in a dropdown menu

How can I utilize the dropdown options to set the postType in my component's state? this.state = { posts: [], question: '', body: '', postType: '', } <select value ...

Issue with Next.js: Setting the width to 100vh prevents the height from being responsive on mobile devices

While I understand that using height: 100vh on mobile is generally discouraged for various reasons, I'm curious as to why height: 100vh paired with width: 100vh in Next.js doesn't produce the expected result. Instead of a full-height square, I en ...

Looking to utilize the <pre> tag without any external CSS styles defined in a separate stylesheet?

In my current project, I am using bootstreap v3.2. I am facing an issue where I need to display fetched content from the database on a page using the <pre></pre> tags. However, the problem is that the content is being displayed with the default ...

Error: The property 'json' is undefined and cannot be read. Please handle this promise rejection

answers.forEach((answer, index) => { answer_text = answer.answer_text; id = answer.id; fetch(BASE_URL + url, { method: 'PUT', headers: { 'Accept': 'application/json', 'Content-Type': &apo ...

I could use some help understanding how to identify the parent file so I can elevate a state

I'm facing a challenge in lifting up a state so that I can utilize it across various pages. The confusion lies in determining where to reference the states, given the uncertainty regarding the parent location. Since this is my first attempt at designi ...

Hold on until the page is reloaded: React

My current setup includes a React Component that contains a button. When this button is clicked, a sidePane is opened. What I want to achieve is refreshing the page first, waiting until it's completely refreshed, and then opening the sidepane. Below i ...

Having difficulty troubleshooting a Next.js application with Visual Studio Code

Currently, I am delving into the realm of Next.js and seeking guidance on how to efficiently debug using Visual Studio Code and Google Chrome. Despite experimenting with various configurations in the launch.json file for debugging a Next.js app in Visual S ...

obtainServerSideProps query parameter

Hey there, I'm trying to use NextJS and its getServerSideProps function to send an API Request, but I'm having trouble passing my ID Query Parameter along. The URL for my API is: http://localhost:3001/product/${id} Below is my code: const rout ...

Incorporating text sections into a div container and adjusting the width

Currently facing an issue with the canvas element on my project. <div id="app-container"> <div id="canvas-container"> <div id="canvas"></div> </div> </div> In the CSS stylesheet, the following styles ar ...

Resizing anchor element using CSS

Hey there, I'm having trouble scaling my anchor tag when hovering over it. Here's the code I'm using: a { color: red; text-decoration: none; transition: all 0.5s; } a:hover { ...

`Why Mui Datepicker always shows the wrong date?`

Currently utilizing the Mui Datepicker library from @mui/x-date-pickers/DatePicker. Below is a snippet of my code <LocalizationProvider dateAdapter={AdapterDateFns}> <DatePicker inputFormat="MM/dd/yy" value={date} minDate= ...

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

Lock in the top row (header row)

In a node.js application: How can I lock the top row of a table in place, similar to Excel's freeze panes feature? I think this might involve using some CSS styling, but I'm not exactly sure how to achieve it. When I tried using fixed, the entir ...