Problem: Enhancing input focus with JavaScript and CSS animations

Currently, I've come across a strange issue in javascript while working with the .focus() function and css transitions.

Check out the jsFiddle link below for reference.

In my setup, there's a modal containing a search input field. Upon clicking on the #trigger, a class is added to the modal along with a focus() event triggered on the input field (to enhance user experience).

This approach was functioning perfectly until... I decided to implement CSS transitions to provide a smoother appearance (applied on the opacity and visibility properties).

Any insights on where this complication might be originating from?

Thank you in advance!

let trigger = document.getElementById('trigger'),
    closer = document.getElementById('closer'),
    box = document.getElementById('wrapper'),
    sInput = document.getElementById('search__input')
    
trigger.addEventListener('click', () => {
  box.classList.add('is-visible')
  sInput.focus()
})

closer.addEventListener('click', () => {
  box.classList.remove('is-visible')
})
#wrapper {
  position: fixed;
  top: 0; left: 0; right: 0;
  width: 100%; height: 100%;
  
  background: rgba(0, 0, 0, 0.8);
  
  visibility: hidden;
  opacity: 0;
  
  transition: opacity .1s linear, visibility .1s linear .1s;
}

#wrapper.is-visible {
  opacity: 1;
  visibility: visible;
  
  transition: visibility .1s linear, opacity .1s linear .1s;
}

#closer {
  position: absolute;
  top: 10px; left: 10px;
  color: #000;
  background-color: white;
}

#search__input {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px;
  font-size: 24px;
}
<a href="#" id="trigger">Click me.</a>

<div id="wrapper">
  <a href="#" id="closer">Close me.</a>
  <input type="search" placeholder="Search here" id="search__input"/>
</div>

Similar approach without utilizing CSS transitions

let trigger = document.getElementById('trigger'),
    closer = document.getElementById('closer'),
    box = document.getElementById('wrapper'),
    sInput = document.getElementById('search__input')

trigger.addEventListener('click', () => {
  box.classList.add('is-visible')
  sInput.focus()
})

closer.addEventListener('click', () => {
  box.classList.remove('is-visible')
})
#wrapper {
  position: fixed;
  top: 0; left: 0; right: 0;
  width: 100%; height: 100%;

  background: rgba(0, 0, 0, 0.8);

  visibility: hidden;
  opacity: 0;
}

#wrapper.is-visible {
  opacity: 1;
  visibility: visible;
}

#closer {
  position: absolute;
  top: 10px; left: 10px;
  color: #000;
  background-color: white;
}

#search__input {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px;
  font-size: 24px;
}
<a href="#" id="trigger">Click me.</a>

<div id="wrapper">
  <a href="#" id="closer">Close me.</a>
  <input type="search" placeholder="Search here" id="search__input"/>
</div>

Answer №1

One reason for this issue might be that when an element is hidden, not displayed, or has opacity applied, it cannot be focused during a transition.

Have you ever wondered why changing visibility/display on focus does not work?

To solve this problem, I suggest using a timeout callback

let trigger = document.getElementById('trigger'),
    closer = document.getElementById('closer'),
    box = document.getElementById('wrapper'),
    sInput = document.getElementById('search__input')
    
trigger.addEventListener('click', function() {
  box.classList.add('is-visible');
  setTimeout(()=>{
    sInput.focus();
  },1000);
  
})

closer.addEventListener('click', () => {
  box.classList.remove('is-visible')
})
#wrapper {
  position: fixed;
  top: 0; left: 0; right: 0;
  width: 100%; height: 100%;
  
  background: rgba(0, 0, 0, 0.8);
  
  visibility: hidden;
  opacity: 0;
  
  transition: opacity .1s linear, visibility .1s linear .1s;
}

#wrapper.is-visible {
  opacity: 1;
  visibility: visible;
  
  transition: visibility .1s linear, opacity .1s linear .1s;
}

#closer {
  position: absolute;
  top: 10px; left: 10px;
  color: #000;
  background-color: white;
}

#search__input {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px;
  font-size: 24px;
}
<a href="#" id="trigger">Click me.</a>

<div id="wrapper">
  <a href="#" id="closer">Close me.</a>
  <input type="search" placeholder="Search here" id="search__input"/>
</div>

Answer №2

After a thorough investigation, I have discovered the root of the issue.

element.focus() will not work on its target if the target has a CSS property of visibility: hidden. Previously, I believed this behavior only occurred with the display: none property, but it turns out that invisible elements cannot be focused at all.

I am answering my own question here, but I am leaving it in case it proves helpful to someone else.

CLOSED.

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

Is the Angular $watch function able to track changes on an object's prototype members as well?

I have encountered a challenge with a tree structure implemented in Javascript which has circular references. The objects in the structure contain an array of children, but these children also need to reference their parent for deletion purposes. To monit ...

When array.push is used inside another array, it results in an undefined value

While working on defining an array within the Fire array in my code, I encountered a problem. When I tried to use console.log() to display the length of the array inside the Fire[] array for debugging, I received an error indicating that the array was und ...

Having trouble with Next.js and Next-auth? When I make an HTTP request in getServerSideProps, getSession is returning null in my secured API Route

I am currently working on securing an API Route that is being called from both the Client and Server-side on different pages. When accessing the test page, it returns a 401 error. However, when accessing the test2 page, the content is retrieved successfu ...

Issue: Unable to locate module '/node_modulesprogressbar/package.json'

Currently, I am facing an issue with the generation of a progress bar using Browserify and progressbar.js. When I try to var ProgressBar = require('node_modules/progressbar');, an error pops up saying Error: Cannot find module '/node_modules ...

Have you ever wondered how to disable a tooltip in React Material UI after clicking on it? Let

I am working with a Material-UI tab component and I would like to include a tooltip feature. The issue I am facing is that the tooltip does not disappear when I click on the tab. It should hide after clicking on the tab. Currently, the tooltip remains vi ...

Adjust THREE.PerspectiveCamera's distance without altering its viewing orientation

I have a PerspectiveCamera in THREE.js positioned somewhere in space as a child of a mesh. The camera is currently looking at the mesh with local coordinates [0, 0, 0]. I am looking for a way to change the distance of the camera from the mesh without chang ...

What solution can I implement to address the font sizing issue inherited from HTML input elements?

It seems like there may be a bug in Chrome, but I wanted to reach out to the community to see if anyone has found a workaround for this issue. When creating an HTML input with the style font: inherit along with a web font, the input size appears incorrect ...

"The props received by the component in componentWillReceiveProps are not the same as those rendered in the

To implement infinite scroll, I attempted to detect changes in items using the componentWillReceiveProps method. Here is how: componentWillReceiveProps(nextProps) { //if infinite load triggered if(!isEqual(nextProps.items, this.props.item ...

Uploading information by merging form data with a fetch API reply

In my project, I am looking to merge two sets of data into a specific format and then make a post request. After using the fetch API, I received the following response: { "id":"some-id" } The JSON format of my form data is as follows: { "origin_ ...

The Javascript function is malfunctioning, unable to assign the 'onclick' property to null

Here's the code snippet I'm working with: var exit = document.getElementById("exit"); exit.onclick = function() { "use strict"; document.getElementById("fadedDiv").style.display = "none" ; }; However, when I check the console, it shows ...

Issue with Vue and Laravel Form Validation failing to return 422 response

I've been working on validating form data using Laravel and Vue on the backend, but I'm facing an issue with receiving a 422 response. Within my controller function: $this->validate($request, [ 'name' => 'required' ...

Troubleshooting Flexbox: Content within a Flex Item is not displaying properly within a scrollable container

I recently embarked on converting one of my websites to flexbox and encountered an issue with vertical scrolling within a flex container. It appears that Firefox displays it correctly, while Chrome and Safari do not. You can check out the code here. . ...

Is there a way to establish the starting content/value for this tinymce editor?

I have integrated tinymce editor from this repository into my application: https://github.com/dyonir/vue-tinymce-editor. My goal is to pre-populate the editor with content upon initialization. Although I attempted using v-model, it did not work as expect ...

Adjust SVG Checkbox to eliminate any unnecessary padding

I am attempting to customize the MUI5 checkbox CSS fields, and here is the current status: https://i.stack.imgur.com/BROpS.png These are my CSS classes: MuiCheckbox: { styleOverrides: { root: { ".MuiSvgIcon-root": { backgro ...

What is the execution sequence of arrow functions in JavaScript?

I am a beginner in using redux with react and I'm curious about the presence of two arrow functions in the code below and their purpose export const loadName = () => (dispatch: any) => { const name = localStorage.getItem('name'); ...

Creating red fields on validation errors in CodeIgniter using AJAX

I am facing an issue with making input fields red on validation errors in code-igniter using ajax and jquery. Currently, all input fields turn red when there is an error, even if only one field has a mistake. I want to modify it so that only the specific i ...

Is there a space added after applying overflow:hidden to a div?

.d1 { height: 10px; } .dd { display: inline-block; overflow: hidden; } .dd1 { display: inline-block; } <div class="d1"> <div class="dd"></div> <div class="dd1"></div> </div> To adjust the layout so that th ...

Inflexible lists refusing to wrap

I have a straightforward requirement: I need a list <ul /> containing items <div />s of the same fixed size. These items should be displayed from left to right, filling up all available space before wrapping onto the next line. Below is the ba ...

Issue with hidden.bs.modal event not triggering in Bootstrap

Even after using the hidden.bs.modal event, it still doesn't seem to work for me. I have attempted to implement the code below, but unfortunately, it's not functioning as expected. Any guidance on what I should try next would be greatly appreciat ...

Automatically press the button when the display style is set to block

Hello everyone, I am completely inexperienced with this and I had a question - is there a way to automatically click a button when using display:block in styling? I would greatly appreciate it if someone could guide me in the right direction. <div i ...